From d9e4568b7109b9b0e05c94108604f4f325c29e02 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 11 Dec 2023 17:01:08 +0100 Subject: [PATCH 01/92] (bug) unable to show wallet payment mean for invoice --- CHANGELOG.md | 3 +++ app/models/invoice.rb | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a9a6a444..93977467a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog Fab-manager +- Fix a bug: unable to show wallet payment mean for invoice +- [TODO DEPLOY] `rails fablab:setup:build_accounting_lines` + ## v6.3.6 2023 December 6 - fix a bug: fix event service diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 63f8fd04d..fb4c0ed90 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -165,6 +165,8 @@ class Invoice < PaymentDocument if paid_by_card? res.push(means: :card, amount: amount_paid) + elsif paid_by_wallet? + res.push(means: :wallet, amount: amount_paid) else res.push(means: :other, amount: amount_paid) end From 11205bb1b35894427a6ac232258b213d6b3cd73d Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 11 Dec 2023 17:01:37 +0100 Subject: [PATCH 02/92] update Gemfile --- Gemfile.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile.lock b/Gemfile.lock index b60dfdf10..b798e07fe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -532,6 +532,7 @@ GEM PLATFORMS x86_64-darwin-20 x86_64-darwin-21 + x86_64-darwin-23 x86_64-linux DEPENDENCIES From c75fa4b954e8af0b7dbef3b2eafd44283486718f Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 15 Dec 2023 15:08:33 +0100 Subject: [PATCH 03/92] (quality) Cleanup unused feature --- .../javascript/controllers/admin/members.js | 3 --- app/frontend/src/javascript/models/setting.ts | 3 +-- app/frontend/src/javascript/router.js | 4 ++-- .../templates/admin/settings/compte.html | 22 ------------------- app/helpers/settings_helper.rb | 1 - config/locales/app.admin.en.yml | 1 - config/locales/en.yml | 1 - db/seeds/settings.rb | 2 -- test/frontend/__fixtures__/settings.ts | 6 ----- 9 files changed, 3 insertions(+), 40 deletions(-) diff --git a/app/frontend/src/javascript/controllers/admin/members.js b/app/frontend/src/javascript/controllers/admin/members.js index 9cc5e6adc..860cb71aa 100644 --- a/app/frontend/src/javascript/controllers/admin/members.js +++ b/app/frontend/src/javascript/controllers/admin/members.js @@ -165,9 +165,6 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce', if ($scope.enableUserValidationRequired) { $scope.member.memberFilters.push('not_validated'); } - // should we display the username in the list? - $scope.displayUsername = (settingsPromise.show_username_in_admin_list === 'true'); - // Admins ordering/sorting. Default: not sorted $scope.orderAdmin = null; diff --git a/app/frontend/src/javascript/models/setting.ts b/app/frontend/src/javascript/models/setting.ts index ae114d96c..926c51d1a 100644 --- a/app/frontend/src/javascript/models/setting.ts +++ b/app/frontend/src/javascript/models/setting.ts @@ -219,8 +219,7 @@ export const registrationSettings = [ ] as const; export const adminSettings = [ - 'feature_tour_display', - 'show_username_in_admin_list' + 'feature_tour_display' ] as const; export const pricingSettings = [ diff --git a/app/frontend/src/javascript/router.js b/app/frontend/src/javascript/router.js index 2005f7bb2..74d83f59e 100644 --- a/app/frontend/src/javascript/router.js +++ b/app/frontend/src/javascript/router.js @@ -1037,7 +1037,7 @@ angular.module('application.router', ['ui.router']) groupsPromise: ['Group', function (Group) { return Group.query().$promise; }], tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }], authProvidersPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.query().$promise; }], - settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display', 'user_validation_required', 'show_username_in_admin_list']" }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['feature_tour_display', 'user_validation_required']" }).$promise; }] } }) .state('app.admin.members_new', { @@ -1198,7 +1198,7 @@ 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', " + "'store_module', 'machine_reservation_deadline', 'training_reservation_deadline', 'event_reservation_deadline', " + "'space_reservation_deadline', 'reservation_context_feature']" }).$promise; diff --git a/app/frontend/templates/admin/settings/compte.html b/app/frontend/templates/admin/settings/compte.html index 241196c69..44f0f14a9 100644 --- a/app/frontend/templates/admin/settings/compte.html +++ b/app/frontend/templates/admin/settings/compte.html @@ -105,28 +105,6 @@ -
-
- {{ 'app.admin.settings.accounts_management' }} -
-
-
-

{{ 'app.admin.settings.members_list' }}

-

- {{ 'app.admin.settings.members_list_info' }} -

-
- - -
-
-
-
-
{{ 'app.admin.settings.account.customize_account_settings' }} diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index c82f0f62c..da4c92808 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -166,7 +166,6 @@ module SettingsHelper user_change_group user_validation_required user_validation_required_list - show_username_in_admin_list family_account child_validation_required store_module diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index 7f3efc37c..67341f678 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -1859,7 +1859,6 @@ en: extended_prices_info_html: "Spaces can have different prices depending on the cumulated duration of the booking. You can choose if this apply to all bookings or only to those starting within the same day." extended_prices_in_same_day: "Extended prices in the same day" public_registrations: "Public registrations" - show_username_in_admin_list: "Show the username in the list" projects_list_member_filter_presence: "Presence of member filter on projects list" projects_list_date_filters_presence: "Presence of date filters on projects list" project_categories_filter_placeholder: "Placeholder for categories filter in project gallery" diff --git a/config/locales/en.yml b/config/locales/en.yml index 625dcfff9..cc3437fe5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -721,7 +721,6 @@ en: flickr: "flickr" 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" store_withdrawal_instructions: "Withdrawal instructions" store_hidden: "Store hidden to the public" diff --git a/db/seeds/settings.rb b/db/seeds/settings.rb index 7962b9194..fcfb09328 100644 --- a/db/seeds/settings.rb +++ b/db/seeds/settings.rb @@ -686,8 +686,6 @@ end Setting.set('extended_prices_in_same_day', false) unless Setting.find_by(name: 'extended_prices_in_same_day').try(:value) -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) Setting.set('store_hidden', true) unless Setting.find_by(name: 'store_hidden').try(:value) diff --git a/test/frontend/__fixtures__/settings.ts b/test/frontend/__fixtures__/settings.ts index c43dcf0be..407218cfa 100644 --- a/test/frontend/__fixtures__/settings.ts +++ b/test/frontend/__fixtures__/settings.ts @@ -508,12 +508,6 @@ export const settings: Array = [ last_update: '2022-11-28T16:01:00+0200', localized: 'Adresse requise' }, - { - name: 'show_username_in_admin_list', - value: 'false', - last_update: '2022-11-21T15:20:03+0100', - localized: "Afficher le nom d'utilisateur dans la liste des membres de l'administrateur" - }, { name: 'store_module', value: 'true', From 13311906bbf0847565018d072b37b75fef5d4910 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Fri, 15 Dec 2023 18:09:33 +0100 Subject: [PATCH 04/92] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93977467a..08c6607ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog Fab-manager - Fix a bug: unable to show wallet payment mean for invoice +- improvement: remove show_username_in_admin_list setting - [TODO DEPLOY] `rails fablab:setup:build_accounting_lines` ## v6.3.6 2023 December 6 From 5a88ff5aa4d1787840c6c872127b00926160088f Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 21 Dec 2023 15:49:11 +0100 Subject: [PATCH 05/92] (feat) show invoice payment method in accounting line --- CHANGELOG.md | 1 + app/models/accounting_line.rb | 12 ++++++++++++ app/views/open_api/v1/accounting/index.json.jbuilder | 1 + 3 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08c6607ca..68e466357 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Fix a bug: unable to show wallet payment mean for invoice - improvement: remove show_username_in_admin_list setting +- improvement: show invoice payment method in accounting line - [TODO DEPLOY] `rails fablab:setup:build_accounting_lines` ## v6.3.6 2023 December 6 diff --git a/app/models/accounting_line.rb b/app/models/accounting_line.rb index 2f94fa990..4c980fe5b 100644 --- a/app/models/accounting_line.rb +++ b/app/models/accounting_line.rb @@ -5,4 +5,16 @@ class AccountingLine < ApplicationRecord belongs_to :invoice belongs_to :invoicing_profile + + def invoice_payment_method + # if the invoice was 100% payed with the wallet ... + return 'wallet' if (!invoice.wallet_amount.nil? && (invoice.wallet_amount - invoice.total == 0)) || invoice.payment_method == 'wallet' + + # else + if invoice.paid_by_card? + 'card' + else + 'other' + end + end end diff --git a/app/views/open_api/v1/accounting/index.json.jbuilder b/app/views/open_api/v1/accounting/index.json.jbuilder index 017ba53a8..44b161f0b 100644 --- a/app/views/open_api/v1/accounting/index.json.jbuilder +++ b/app/views/open_api/v1/accounting/index.json.jbuilder @@ -9,6 +9,7 @@ json.lines @lines do |line| json.extract! line.invoice, :reference, :id json.label Invoices::LabelService.build(line.invoice) json.url download_open_api_v1_invoice_path(line.invoice) + json.payment_method line.invoice_payment_method if @codes.values.include?(line.account_code) # if this is a 'payment' line mean = @codes.select { |_key, value| value == line.account_code } json.payment_details line.invoice.payment_details(mean.keys[0]) From 04c5dc58e7c668428fec5fbf2bcba6d16b9c7a92 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 28 Dec 2023 17:54:47 +0100 Subject: [PATCH 06/92] (bug) PayZen amount of subscription compute error for Coupon validity per user = forever --- CHANGELOG.md | 1 + lib/pay_zen/service.rb | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68e466357..7e2bd4923 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog Fab-manager - Fix a bug: unable to show wallet payment mean for invoice +- Fix a bug: PayZen amount of subscription compute error for Coupon validity per user = forever - improvement: remove show_username_in_admin_list setting - improvement: show invoice payment method in accounting line - [TODO DEPLOY] `rails fablab:setup:build_accounting_lines` diff --git a/lib/pay_zen/service.rb b/lib/pay_zen/service.rb index 4f2dfbac6..e9597af0f 100644 --- a/lib/pay_zen/service.rb +++ b/lib/pay_zen/service.rb @@ -16,9 +16,11 @@ class PayZen::Service < Payment::Service order = PayZen::Order.new.get(order_id, operation_type: 'VERIFICATION') client = PayZen::Charge.new token_id = order['answer']['transactions'].first['paymentMethodToken'] + coupon = payment_schedule.coupon + amount = coupon && coupon.validity_per_user == 'forever' ? first_item.amount : first_item.details['recurring'].to_i params = { - amount: payzen_amount(first_item.details['recurring'].to_i), + amount: payzen_amount(amount), effect_date: first_item.due_date.iso8601, payment_method_token: token_id, rrule: rrule(payment_schedule, first_item.due_date), From be034c1c067946975f116e44074b7f81a697d658 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 28 Dec 2023 18:32:16 +0100 Subject: [PATCH 07/92] (bug) unable to create Stripe coupon with duration = forever --- CHANGELOG.md | 1 + lib/stripe/service.rb | 2 +- lib/tasks/fablab/fix.rake | 14 ++++++++++++++ test/fixtures/coupons.yml | 2 +- test/models/coupon_test.rb | 2 +- 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e2bd4923..b066a8ee5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Fix a bug: unable to show wallet payment mean for invoice - Fix a bug: PayZen amount of subscription compute error for Coupon validity per user = forever +- Fix a bug: unable to create Stripe coupon with duration = forever - improvement: remove show_username_in_admin_list setting - improvement: show invoice payment method in accounting line - [TODO DEPLOY] `rails fablab:setup:build_accounting_lines` diff --git a/lib/stripe/service.rb b/lib/stripe/service.rb index 49b13b62a..f9ee3cbce 100644 --- a/lib/stripe/service.rb +++ b/lib/stripe/service.rb @@ -66,7 +66,7 @@ class Stripe::Service < Payment::Service stp_coupon[:currency] = Setting.get('stripe_currency') end - stp_coupon[:duration] = coupon.validity_per_user == 'always' ? 'forever' : 'once' + stp_coupon[:duration] = coupon.validity_per_user stp_coupon[:redeem_by] = coupon.valid_until.to_i unless coupon.valid_until.nil? stp_coupon[:max_redemptions] = coupon.max_usages unless coupon.max_usages.nil? diff --git a/lib/tasks/fablab/fix.rake b/lib/tasks/fablab/fix.rake index 507f4ab56..bf3b1b629 100644 --- a/lib/tasks/fablab/fix.rake +++ b/lib/tasks/fablab/fix.rake @@ -1,4 +1,5 @@ # frozen_string_literal: true +require 'stripe/service' # Correctives for bugs or upgrades migrations tasks namespace :fablab do @@ -348,5 +349,18 @@ namespace :fablab do end end end + + desc '[release 6.3.6] fix stripe coupon duration' + task stripe_coupon_duration: :environment do |_task, _args| + if Setting.get('payment_gateway') == 'stripe' + Coupon.where(validity_per_user: 'forever').each do |c| + cpn = Stripe::Coupon.retrieve(c.code, api_key: Setting.get('stripe_secret_key')) + cpn.delete + Stripe::Service.new.create_coupon(c.id) + rescue Stripe::InvalidRequestError => e + puts "Unable to create coupon #{c.code} on stripe: #{e}" + end + end + end end end diff --git a/test/fixtures/coupons.yml b/test/fixtures/coupons.yml index 11673d6c7..f19fecb77 100644 --- a/test/fixtures/coupons.yml +++ b/test/fixtures/coupons.yml @@ -16,7 +16,7 @@ two: valid_until: <%= 1.month.from_now.utc.strftime('%Y-%m-%d %H:%M:%S.%9N %Z') %> max_usages: 10 active: true - validity_per_user: always + validity_per_user: forever cash: name: Cash Code diff --git a/test/models/coupon_test.rb b/test/models/coupon_test.rb index 701afdc25..bef300f4e 100644 --- a/test/models/coupon_test.rb +++ b/test/models/coupon_test.rb @@ -22,7 +22,7 @@ class CouponTest < ActiveSupport::TestCase end test 'two coupons cannot have the same code' do - c = Coupon.new({ name: 'Summer deals', code: 'SUNNYFABLAB', percent_off: 15, validity_per_user: 'always' }) + c = Coupon.new({ name: 'Summer deals', code: 'SUNNYFABLAB', percent_off: 15, validity_per_user: 'forever' }) assert c.invalid? end From dac874d915f030d999f87276666d158fd1c3d084 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 28 Dec 2023 18:34:31 +0100 Subject: [PATCH 08/92] (i18n) updated translations --- config/locales/app.admin.de.yml | 1 - config/locales/app.admin.es-MX.yml | 1 - config/locales/app.admin.es.yml | 1 - config/locales/app.admin.fr.yml | 1 - config/locales/app.admin.it.yml | 1 - config/locales/app.admin.no.yml | 1 - config/locales/app.admin.pt.yml | 1 - config/locales/app.admin.zu.yml | 7 +++---- config/locales/de.yml | 1 - config/locales/es-MX.yml | 1 - config/locales/es.yml | 1 - config/locales/fr.yml | 3 +-- config/locales/it.yml | 1 - config/locales/no.yml | 1 - config/locales/pt.yml | 1 - config/locales/zu.yml | 1 - 16 files changed, 4 insertions(+), 20 deletions(-) diff --git a/config/locales/app.admin.de.yml b/config/locales/app.admin.de.yml index 45bc26b04..24940b797 100644 --- a/config/locales/app.admin.de.yml +++ b/config/locales/app.admin.de.yml @@ -1859,7 +1859,6 @@ de: extended_prices_info_html: "Räume können je nach Dauer der Buchung unterschiedliche Preise haben. Sie können wählen, ob dies für alle Buchungen oder nur für diejenigen gilt, die am selben Tag beginnen." extended_prices_in_same_day: "Erweiterte Preise am selben Tag" public_registrations: "Öffentliche Registrierungen" - show_username_in_admin_list: "Show the username in the list" projects_list_member_filter_presence: "Presence of member filter on projects list" projects_list_date_filters_presence: "Presence of date filters on projects list" project_categories_filter_placeholder: "Placeholder for categories filter in project gallery" diff --git a/config/locales/app.admin.es-MX.yml b/config/locales/app.admin.es-MX.yml index ac434ca8a..f7da2de92 100644 --- a/config/locales/app.admin.es-MX.yml +++ b/config/locales/app.admin.es-MX.yml @@ -1859,7 +1859,6 @@ es-MX: extended_prices_info_html: "Los espacios pueden tener diferentes precios dependiendo de la duración acumulada de la reserva. Puede elegir si esto se aplica a todas las reservas o solo a las que empiezan en el mismo día." extended_prices_in_same_day: "Precios extendidos en el mismo día" public_registrations: "Registros públicos" - show_username_in_admin_list: "Mostrar el nombre de usuario en la lista" projects_list_member_filter_presence: "Presencia del filtro de miembros en la lista de proyectos" projects_list_date_filters_presence: "Presencia de filtros de fecha en la lista de proyectos" project_categories_filter_placeholder: "Marcador para el filtro de categorías en la galería de proyectos" diff --git a/config/locales/app.admin.es.yml b/config/locales/app.admin.es.yml index 9206d4f92..2aacd4d97 100644 --- a/config/locales/app.admin.es.yml +++ b/config/locales/app.admin.es.yml @@ -1859,7 +1859,6 @@ es: extended_prices_info_html: "Los espacios pueden tener diferentes precios dependiendo de la duración acumulada de la reserva. Puede elegir si esto se aplica a todas las reservas o solo a las que empiezan en el mismo día." extended_prices_in_same_day: "Precios extendidos en el mismo día" public_registrations: "Registros públicos" - show_username_in_admin_list: "Mostrar el nombre de usuario en la lista" projects_list_member_filter_presence: "Presencia del filtro de miembros en la lista de proyectos" projects_list_date_filters_presence: "Presencia de filtros de fecha en la lista de proyectos" project_categories_filter_placeholder: "Marcador para el filtro de categorías en la galería de proyectos" diff --git a/config/locales/app.admin.fr.yml b/config/locales/app.admin.fr.yml index c62964e7e..259b69fbf 100644 --- a/config/locales/app.admin.fr.yml +++ b/config/locales/app.admin.fr.yml @@ -1859,7 +1859,6 @@ fr: extended_prices_info_html: "Les espaces peuvent avoir des prix différents selon la durée cumulée de la réservation. Vous pouvez choisir si cela s'applique à toutes les réservations ou seulement à celles qui commencent dans la même journée." extended_prices_in_same_day: "Prix étendus le même jour" public_registrations: "Inscriptions publiques" - show_username_in_admin_list: "Afficher le nom d'utilisateur dans la liste" projects_list_member_filter_presence: "Permettre la recherche de projets par membre" projects_list_date_filters_presence: "Permettre la recherche de projets par dates" project_categories_filter_placeholder: "Dans la galerie de projets, renommer le filtre \"Toutes les catégories\"" diff --git a/config/locales/app.admin.it.yml b/config/locales/app.admin.it.yml index e7822af7e..3c2a52d67 100644 --- a/config/locales/app.admin.it.yml +++ b/config/locales/app.admin.it.yml @@ -1859,7 +1859,6 @@ it: extended_prices_info_html: "Gli spazi possono avere prezzi diversi a seconda della durata cumulata della prenotazione. È possibile scegliere se questo si applica a tutte le prenotazioni o solo a quelli che iniziano entro lo stesso giorno." extended_prices_in_same_day: "Prezzi estesi nello stesso giorno" public_registrations: "Registri pubblici" - show_username_in_admin_list: "Mostra il nome utente nella lista" projects_list_member_filter_presence: "Presence of member filter on projects list" projects_list_date_filters_presence: "Presence of date filters on projects list" project_categories_filter_placeholder: "Placeholder for categories filter in project gallery" diff --git a/config/locales/app.admin.no.yml b/config/locales/app.admin.no.yml index f64183496..a8c15cc33 100644 --- a/config/locales/app.admin.no.yml +++ b/config/locales/app.admin.no.yml @@ -1859,7 +1859,6 @@ extended_prices_info_html: "Spaces can have different prices depending on the cumulated duration of the booking. You can choose if this apply to all bookings or only to those starting within the same day." extended_prices_in_same_day: "Extended prices in the same day" public_registrations: "Public registrations" - show_username_in_admin_list: "Show the username in the list" projects_list_member_filter_presence: "Presence of member filter on projects list" projects_list_date_filters_presence: "Presence of date filters on projects list" project_categories_filter_placeholder: "Placeholder for categories filter in project gallery" diff --git a/config/locales/app.admin.pt.yml b/config/locales/app.admin.pt.yml index 75e779d24..f21df745d 100644 --- a/config/locales/app.admin.pt.yml +++ b/config/locales/app.admin.pt.yml @@ -1859,7 +1859,6 @@ pt: extended_prices_info_html: "Os espaços podem ter preços diferentes dependendo da duração acumulada da reserva. Você pode escolher se isso se aplica a todas as reservas ou apenas àqueles que iniciam no mesmo dia." extended_prices_in_same_day: "Preços estendidos no mesmo dia" public_registrations: "Inscrições públicas" - show_username_in_admin_list: "Mostrar o nome de usuário na lista" projects_list_member_filter_presence: "Presence of member filter on projects list" projects_list_date_filters_presence: "Presence of date filters on projects list" project_categories_filter_placeholder: "Placeholder for categories filter in project gallery" diff --git a/config/locales/app.admin.zu.yml b/config/locales/app.admin.zu.yml index d5b1aa2f9..b6f1ea81d 100644 --- a/config/locales/app.admin.zu.yml +++ b/config/locales/app.admin.zu.yml @@ -957,13 +957,13 @@ zu: n_digits_annual_amount_of_orders: "crwdns25076:0crwdne25076:0" add_a_notice_regarding_the_online_sales_only_if_the_invoice_is_concerned: "crwdns25078:0crwdne25078:0" this_will_never_be_added_when_a_refund_notice_is_present: "crwdns25080:0crwdne25080:0" - eg_XVL_will_add_VL_to_the_invoices_settled_by_card: 'crwdns25082:0[/VL]crwdne25082:0' + eg_XVL_will_add_VL_to_the_invoices_settled_by_card: 'crwdns25082:0crwdne25082:0' add_a_notice_regarding_refunds_only_if_the_invoice_is_concerned: "crwdns25084:0crwdne25084:0" this_will_never_be_added_when_an_online_sales_notice_is_present: "crwdns25086:0crwdne25086:0" - eg_RA_will_add_A_to_the_refund_invoices: 'crwdns25088:0[/A]crwdne25088:0' + eg_RA_will_add_A_to_the_refund_invoices: 'crwdns25088:0crwdne25088:0' add_a_notice_regarding_payment_schedule: "crwdns25090:0crwdne25090:0" this_will_never_be_added_with_other_notices: "crwdns25092:0crwdne25092:0" - eg_SE_to_schedules: 'crwdns25094:0[/E]crwdne25094:0' + eg_SE_to_schedules: 'crwdns25094:0crwdne25094:0' code: "crwdns25096:0crwdne25096:0" enable_the_code: "crwdns25098:0crwdne25098:0" enabled: "crwdns25100:0crwdne25100:0" @@ -1859,7 +1859,6 @@ zu: extended_prices_info_html: "crwdns26750:0crwdne26750:0" extended_prices_in_same_day: "crwdns26752:0crwdne26752:0" public_registrations: "crwdns26754:0crwdne26754:0" - show_username_in_admin_list: "crwdns26756:0crwdne26756:0" projects_list_member_filter_presence: "crwdns37627:0crwdne37627:0" projects_list_date_filters_presence: "crwdns37629:0crwdne37629:0" project_categories_filter_placeholder: "crwdns37631:0crwdne37631:0" diff --git a/config/locales/de.yml b/config/locales/de.yml index 2b07ea625..9a8917ddf 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -721,7 +721,6 @@ de: flickr: "Flickr" machines_module: "Maschinenmodul" 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" store_withdrawal_instructions: "Withdrawal instructions" store_hidden: "Store hidden to the public" diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 357e8492b..c1589fcce 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -721,7 +721,6 @@ es-MX: flickr: "flickr" machines_module: "Módulo de máquinas" user_change_group: "Permitir a los usuarios cambiar su grupo" - show_username_in_admin_list: "Mostrar el nombre de usuario en la lista de miembros del administrador" store_module: "Módulo de tienda" store_withdrawal_instructions: "Instrucciones de retirada" store_hidden: "Tienda oculta al público" diff --git a/config/locales/es.yml b/config/locales/es.yml index 7f48dd107..b0fddcaf2 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -721,7 +721,6 @@ es: flickr: "flickr" machines_module: "Módulo de máquinas" user_change_group: "Permitir a los usuarios cambiar su grupo" - show_username_in_admin_list: "Mostrar el nombre de usuario en la lista de miembros del administrador" store_module: "Módulo de tienda" store_withdrawal_instructions: "Instrucciones de retirada" store_hidden: "Tienda oculta al público" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index c3de87a5e..7977f5bc1 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -24,7 +24,7 @@ fr: extension_whitelist_error: "Vous n'êtes pas autorisé à envoyer des fichiers %{extension}, les types autorisés sont : %{allowed_types}" extension_blacklist_error: "Vous n'êtes pas autorisé à envoyer des fichiers %{extension}, les types interdits sont : %{prohibited_types}" content_type_whitelist_error: "Vous n'êtes pas autorisé à envoyer des fichiers %{content_type}, les types autorisés sont : %{allowed_types}" - rmagick_processing_error: "Impossible de manipuler avec rmagick. Peut-être que ce n'est pas une image ?" + rmagick_processing_error: "Impossible à manipuler avec rmagick. Peut-être que ce n'est pas une image ?" mime_types_processing_error: "Impossible de traiter le fichier avec MIME::Types. Le type de contenu n'est peut-être pas valide ?" mini_magick_processing_error: "Impossible de manipuler le fichier. Peut-être que ce n'est pas une image ?" wrong_size: "ne fait pas la bonne taille (doit comporter %{file_size})" @@ -721,7 +721,6 @@ fr: flickr: "flickr" machines_module: "Module machines" user_change_group: "Permettre aux utilisateurs de changer leur groupe" - show_username_in_admin_list: "Afficher le nom d'utilisateur dans la liste des membres de l'administrateur" store_module: "Module boutique" store_withdrawal_instructions: "Instructions de retrait" store_hidden: "Boutique masquée au public" diff --git a/config/locales/it.yml b/config/locales/it.yml index 86ee5a8a7..cccafc44c 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -721,7 +721,6 @@ it: flickr: "flickr" machines_module: "Modulo macchine" user_change_group: "Consenti all'utente di cambiare il loro gruppo" - show_username_in_admin_list: "Mostra il nome utente nell'elenco dei membri dell'amministratore" store_module: "Modulo del negozio" store_withdrawal_instructions: "Istruzioni per il ritiro" store_hidden: "Negozio nascosto al pubblico" diff --git a/config/locales/no.yml b/config/locales/no.yml index 66ce5d5bb..d4eadb082 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -721,7 +721,6 @@ flickr: "flickr" 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" store_withdrawal_instructions: "Withdrawal instructions" store_hidden: "Store hidden to the public" diff --git a/config/locales/pt.yml b/config/locales/pt.yml index e00a3127e..852dfda05 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -721,7 +721,6 @@ pt: flickr: "flickr" machines_module: "Módulo de Máquinas" user_change_group: "Permitir que os usuários mudem de grupo" - show_username_in_admin_list: "Mostrar o nome de usuário na lista de membros do administrador" store_module: "Store module" store_withdrawal_instructions: "Withdrawal instructions" store_hidden: "Store hidden to the public" diff --git a/config/locales/zu.yml b/config/locales/zu.yml index 1f15e36d4..3a2295f32 100644 --- a/config/locales/zu.yml +++ b/config/locales/zu.yml @@ -721,7 +721,6 @@ zu: flickr: "crwdns23036:0crwdne23036:0" machines_module: "crwdns23038:0crwdne23038:0" user_change_group: "crwdns23040:0crwdne23040:0" - show_username_in_admin_list: "crwdns24016:0crwdne24016:0" store_module: "crwdns31723:0crwdne31723:0" store_withdrawal_instructions: "crwdns31725:0crwdne31725:0" store_hidden: "crwdns31727:0crwdne31727:0" From 4fcdd51f253218e22b7c322f1a63da3a5f43c54c Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 28 Dec 2023 18:36:05 +0100 Subject: [PATCH 09/92] update Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b066a8ee5..ba156ff8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - improvement: remove show_username_in_admin_list setting - improvement: show invoice payment method in accounting line - [TODO DEPLOY] `rails fablab:setup:build_accounting_lines` +- [TODO DEPLOY] `rails fablab:fix:stripe_coupon_duration` ## v6.3.6 2023 December 6 From 32c5b010533b4981aa01b52a7e8523e8684a4f8e Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 28 Dec 2023 18:37:16 +0100 Subject: [PATCH 10/92] Version 6.3.7 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba156ff8f..18a9f4c2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog Fab-manager +## v6.3.7 2023 December 28 + - Fix a bug: unable to show wallet payment mean for invoice - Fix a bug: PayZen amount of subscription compute error for Coupon validity per user = forever - Fix a bug: unable to create Stripe coupon with duration = forever diff --git a/package.json b/package.json index 86010da48..83c22de38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fab-manager", - "version": "6.3.6", + "version": "6.3.7", "description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.", "keywords": [ "fablab", From 34e9a0cc9726f233c4dd3db4ffc06bec1df1fc43 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Fri, 2 Feb 2024 18:57:53 +0100 Subject: [PATCH 11/92] Version 6.3.11 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8690fff9e..500debb22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +## v6.3.11 2024 February 2 + - Fix a bug: if there is a reservation with a deleted user, it is not possible to delete the event - Fix a bug: postgres client isnt added docker image - Support for SAML in Single-Sign-On authentication providers diff --git a/package.json b/package.json index 34c0c45c6..f3fc01be1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fab-manager", - "version": "6.3.10", + "version": "6.3.11", "description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.", "keywords": [ "fablab", From ff80216d9b433960d0d75511a0cd9bfa2b2852ca Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 8 Feb 2024 15:59:17 +0100 Subject: [PATCH 12/92] (feat) Allow the admin to update payment method only the overdue subscription item without cancel PayZen subscription --- CHANGELOG.md | 2 ++ app/controllers/api/payment_schedules_controller.rb | 7 ++++--- app/frontend/src/javascript/api/payment-schedule.ts | 4 ++-- .../payment-schedule-item-actions.tsx | 10 ++++++---- .../payment-schedule/payment-schedules-table.tsx | 3 ++- .../payment-schedule/update-payment-mean-modal.tsx | 12 +++++++----- app/services/payment_schedule_service.rb | 5 ++--- app/workers/payment_schedule_item_worker.rb | 4 ++-- config/locales/app.admin.en.yml | 2 +- 9 files changed, 28 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 500debb22..10fbead69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +- improvement: Allow the admin to update payment method only the overdue subscription item without cancel PayZen subscription + ## v6.3.11 2024 February 2 - Fix a bug: if there is a reservation with a deleted user, it is not possible to delete the event diff --git a/app/controllers/api/payment_schedules_controller.rb b/app/controllers/api/payment_schedules_controller.rb index ae5169f70..1b32a88b4 100644 --- a/app/controllers/api/payment_schedules_controller.rb +++ b/app/controllers/api/payment_schedules_controller.rb @@ -89,10 +89,11 @@ class API::PaymentSchedulesController < API::APIController def update authorize PaymentSchedule - if PaymentScheduleService.new.update_payment_mean(@payment_schedule, update_params) + payment_schedule_item = PaymentScheduleItem.find(update_params[:payment_schedule_item_id]) + if PaymentScheduleService.new.update_payment_mean(payment_schedule_item, update_params[:payment_method]) render :show, status: :ok, location: @payment_schedule else - render json: @payment_schedule.errors, status: :unprocessable_entity + render json: payment_schedule_item.errors, status: :unprocessable_entity end end @@ -107,6 +108,6 @@ class API::PaymentSchedulesController < API::APIController end def update_params - params.require(:payment_schedule).permit(:payment_method) + params.permit(:payment_method, :payment_schedule_item_id) end end diff --git a/app/frontend/src/javascript/api/payment-schedule.ts b/app/frontend/src/javascript/api/payment-schedule.ts index c5ce67cf3..3bcf6bf73 100644 --- a/app/frontend/src/javascript/api/payment-schedule.ts +++ b/app/frontend/src/javascript/api/payment-schedule.ts @@ -48,8 +48,8 @@ export default class PaymentScheduleAPI { return res?.data; } - static async update (paymentSchedule: PaymentSchedule): Promise { - const res:AxiosResponse = await apiClient.patch(`/api/payment_schedules/${paymentSchedule.id}`, paymentSchedule); + static async update (paymentScheduleId: number, paymentScheduleItemId: number, paymentMethod: string): Promise { + const res:AxiosResponse = await apiClient.patch(`/api/payment_schedules/${paymentScheduleId}`, { payment_method: paymentMethod, payment_schedule_item_id: paymentScheduleItemId }); return res?.data; } } diff --git a/app/frontend/src/javascript/components/payment-schedule/payment-schedule-item-actions.tsx b/app/frontend/src/javascript/components/payment-schedule/payment-schedule-item-actions.tsx index 7a7e8f307..5aeb111ab 100644 --- a/app/frontend/src/javascript/components/payment-schedule/payment-schedule-item-actions.tsx +++ b/app/frontend/src/javascript/components/payment-schedule/payment-schedule-item-actions.tsx @@ -169,10 +169,10 @@ export const PaymentScheduleItemActions: React.FC { if (isPrivileged()) { - if (paymentSchedule.payment_method === PaymentMethod.Transfer) { + if (paymentSchedule.payment_method === PaymentMethod.Transfer || paymentScheduleItem.payment_method === PaymentMethod.Transfer) { return confirmTransferButton(); } - if (paymentSchedule.payment_method === PaymentMethod.Check) { + if (paymentSchedule.payment_method === PaymentMethod.Check || paymentScheduleItem.payment_method === PaymentMethod.Check) { return confirmCheckButton(); } } else { @@ -202,7 +202,7 @@ export const PaymentScheduleItemActions: React.FC => { const buttons = []; - if (paymentSchedule.payment_method === PaymentMethod.Card) { + if (paymentSchedule.payment_method === PaymentMethod.Card && !paymentScheduleItem.payment_method) { buttons.push(updateCardButton()); } if (isPrivileged()) { @@ -400,7 +400,9 @@ export const PaymentScheduleItemActions: React.FC + paymentSchedule={paymentSchedule} + paymentScheduleItemId={paymentScheduleItem.id} + />
); diff --git a/app/frontend/src/javascript/components/payment-schedule/payment-schedules-table.tsx b/app/frontend/src/javascript/components/payment-schedule/payment-schedules-table.tsx index 8bfa2dbe6..f9b439930 100644 --- a/app/frontend/src/javascript/components/payment-schedule/payment-schedules-table.tsx +++ b/app/frontend/src/javascript/components/payment-schedule/payment-schedules-table.tsx @@ -104,7 +104,8 @@ const PaymentSchedulesTable: React.FC = ({ paymentSc * Return the human-readable string for the status of the provided deadline. */ const formatState = (item: PaymentScheduleItem, schedule: PaymentSchedule): JSX.Element => { - let res = t(`app.shared.payment_schedules_table.state_${item.state}${item.state === 'pending' ? '_' + schedule.payment_method : ''}`); + const paymentMethod = item.payment_method || schedule.payment_method; + let res = t(`app.shared.payment_schedules_table.state_${item.state}${item.state === 'pending' ? '_' + paymentMethod : ''}`); if (item.state === 'paid') { const key = `app.shared.payment_schedules_table.method_${item.payment_method}`; res += ` (${t(key)})`; diff --git a/app/frontend/src/javascript/components/payment-schedule/update-payment-mean-modal.tsx b/app/frontend/src/javascript/components/payment-schedule/update-payment-mean-modal.tsx index ad5ecaa34..95589bd71 100644 --- a/app/frontend/src/javascript/components/payment-schedule/update-payment-mean-modal.tsx +++ b/app/frontend/src/javascript/components/payment-schedule/update-payment-mean-modal.tsx @@ -12,12 +12,13 @@ interface UpdatePaymentMeanModalProps { onError: (message: string) => void, afterSuccess: () => void, paymentSchedule: PaymentSchedule + paymentScheduleItemId: number, } /** * Component to allow the member to change his payment mean for the given payment schedule (e.g. from card to transfer) */ -export const UpdatePaymentMeanModal: React.FC = ({ isOpen, toggleModal, onError, afterSuccess, paymentSchedule }) => { +export const UpdatePaymentMeanModal: React.FC = ({ isOpen, toggleModal, onError, afterSuccess, paymentSchedule, paymentScheduleItemId }) => { const { t } = useTranslation('admin'); const [paymentMean, setPaymentMean] = React.useState(); @@ -42,10 +43,11 @@ export const UpdatePaymentMeanModal: React.FC = ({ * When the user clicks on the update button, update the default payment mean for the given payment schedule */ const handlePaymentMeanUpdate = (): void => { - PaymentScheduleAPI.update({ - id: paymentSchedule.id, - payment_method: paymentMean - }).then(() => { + PaymentScheduleAPI.update( + paymentSchedule.id, + paymentScheduleItemId, + paymentMean + ).then(() => { afterSuccess(); }).catch(error => { onError(error.message); diff --git a/app/services/payment_schedule_service.rb b/app/services/payment_schedule_service.rb index ff42945f5..a30dde574 100644 --- a/app/services/payment_schedule_service.rb +++ b/app/services/payment_schedule_service.rb @@ -177,9 +177,8 @@ class PaymentScheduleService ## # Update the payment mean associated with the given PaymentSchedule and reset the erroneous items ## - def update_payment_mean(payment_schedule, payment_mean) - PaymentGatewayService.new.cancel_subscription(payment_schedule) - payment_schedule.update(payment_mean) && reset_erroneous_payment_schedule_items(payment_schedule) + def update_payment_mean(payment_schedule_item, payment_method) + payment_schedule_item.update(payment_method: payment_method, state: payment_schedule_item.due_date < Time.current ? 'pending' : 'new') end private diff --git a/app/workers/payment_schedule_item_worker.rb b/app/workers/payment_schedule_item_worker.rb index 10c5eceaa..3c3c393d2 100644 --- a/app/workers/payment_schedule_item_worker.rb +++ b/app/workers/payment_schedule_item_worker.rb @@ -19,12 +19,12 @@ class PaymentScheduleItemWorker # @param psi [PaymentScheduleItem] def check_item(psi) # the following depends on the payment method (card/check) - if psi.payment_schedule.payment_method == 'card' + if psi.payment_schedule.payment_method == 'card' && psi.payment_method.nil? ### Cards PaymentGatewayService.new.process_payment_schedule_item(psi) elsif psi.state == 'new' ### Check/Bank transfer (only new deadlines, to prevent spamming) - NotificationCenter.call type: "notify_admin_payment_schedule_#{psi.payment_schedule.payment_method}_deadline", + NotificationCenter.call type: "notify_admin_payment_schedule_#{psi.payment_method || psi.payment_schedule.payment_method}_deadline", receiver: User.admins_and_managers, attached_object: psi psi.update(state: 'pending') diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index 57b6c3470..3ad1ddc67 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -1147,7 +1147,7 @@ en: date: "Date" update_payment_mean_modal: title: "Update the payment mean" - update_info: "Please specify below the new payment mean for this payment schedule to continue." + update_info: "Please specify below the payment method to update this payment schedule." select_payment_mean: "Select a new payment mean" method_Transfer: "By bank transfer" method_Check: "By check" From cf998e62204a4366cc2458deefb34d94e72fd7a9 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 12 Feb 2024 11:39:33 +0100 Subject: [PATCH 13/92] (feat) add payment transfer/check to accounting settings --- CHANGELOG.md | 1 + app/controllers/open_api/v1/accounting_controller.rb | 2 ++ .../accounting/accounting-codes-settings.tsx | 12 ++++++++++++ app/frontend/src/javascript/models/setting.ts | 6 ++++++ app/helpers/settings_helper.rb | 6 ++++++ app/models/accounting_line.rb | 4 ++++ app/models/invoice.rb | 12 ++++++++++++ config/locales/app.admin.en.yml | 2 ++ db/seeds/settings.rb | 6 ++++++ 9 files changed, 51 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10fbead69..5548ef4bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Next release - improvement: Allow the admin to update payment method only the overdue subscription item without cancel PayZen subscription +- improvement: add payment transfer/check to accounting settings ## v6.3.11 2024 February 2 diff --git a/app/controllers/open_api/v1/accounting_controller.rb b/app/controllers/open_api/v1/accounting_controller.rb index c92a654ce..86be5db41 100644 --- a/app/controllers/open_api/v1/accounting_controller.rb +++ b/app/controllers/open_api/v1/accounting_controller.rb @@ -13,6 +13,8 @@ class OpenAPI::V1::AccountingController < OpenAPI::V1::BaseController @codes = { card: Setting.get('accounting_payment_card_code'), wallet: Setting.get('accounting_payment_wallet_code'), + transfer: Setting.get('accounting_payment_transfer_code'), + check: Setting.get('accounting_payment_check_code'), other: Setting.get('accounting_payment_other_code') } diff --git a/app/frontend/src/javascript/components/accounting/accounting-codes-settings.tsx b/app/frontend/src/javascript/components/accounting/accounting-codes-settings.tsx index d6fc9bde4..c78c732e0 100644 --- a/app/frontend/src/javascript/components/accounting/accounting-codes-settings.tsx +++ b/app/frontend/src/javascript/components/accounting/accounting-codes-settings.tsx @@ -69,6 +69,18 @@ export const AccountingCodesSettings: React.FC = (
+
{t('app.admin.accounting_codes_settings.transfer')}
+
+ + + +
+
{t('app.admin.accounting_codes_settings.check')}
+
+ + + +
{t('app.admin.accounting_codes_settings.other')}
diff --git a/app/frontend/src/javascript/models/setting.ts b/app/frontend/src/javascript/models/setting.ts index 926c51d1a..604a58a28 100644 --- a/app/frontend/src/javascript/models/setting.ts +++ b/app/frontend/src/javascript/models/setting.ts @@ -113,6 +113,12 @@ export const accountingSettings = [ 'accounting_payment_other_code', 'accounting_payment_other_label', 'accounting_payment_other_journal_code', + 'accounting_payment_transfer_code', + 'accounting_payment_transfer_label', + 'accounting_payment_transfer_journal_code', + 'accounting_payment_check_code', + 'accounting_payment_check_label', + 'accounting_payment_check_journal_code', 'accounting_wallet_code', 'accounting_wallet_label', 'accounting_wallet_journal_code', diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index da4c92808..79885b5b1 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -74,6 +74,12 @@ module SettingsHelper accounting_payment_other_code accounting_payment_other_label accounting_payment_other_journal_code + accounting_payment_transfer_code + accounting_payment_transfer_label + accounting_payment_transfer_journal_code + accounting_payment_check_code + accounting_payment_check_label + accounting_payment_check_journal_code accounting_wallet_code accounting_wallet_label accounting_wallet_journal_code diff --git a/app/models/accounting_line.rb b/app/models/accounting_line.rb index 4c980fe5b..bbe4831af 100644 --- a/app/models/accounting_line.rb +++ b/app/models/accounting_line.rb @@ -13,6 +13,10 @@ class AccountingLine < ApplicationRecord # else if invoice.paid_by_card? 'card' + elsif invoice.paid_by_transfer? + 'transfer' + elsif invoice.paid_by_check? + 'check' else 'other' end diff --git a/app/models/invoice.rb b/app/models/invoice.rb index fb4c0ed90..454671423 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -167,6 +167,10 @@ class Invoice < PaymentDocument res.push(means: :card, amount: amount_paid) elsif paid_by_wallet? res.push(means: :wallet, amount: amount_paid) + elsif paid_by_transfer? + res.push(means: :transfer, amount: amount_paid) + elsif paid_by_check? + res.push(means: :check, amount: amount_paid) else res.push(means: :other, amount: amount_paid) end @@ -202,6 +206,14 @@ class Invoice < PaymentDocument (wallet_transaction && wallet_amount.positive?) || payment_method == 'wallet' end + def paid_by_transfer? + payment_method == 'transfer' + end + + def paid_by_check? + payment_method == 'check' + end + def render_resource { partial: 'api/invoices/invoice', locals: { invoice: self } } end diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index 3ad1ddc67..bcbabea7a 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -276,6 +276,8 @@ en: card: "Card payments" wallet_debit: "Virtual wallet payments" other: "Other payment means" + transfer: "Transfer" + check: "Check" wallet_credit: "Virtual wallet credit" VAT: "VAT" sales: "Sales" diff --git a/db/seeds/settings.rb b/db/seeds/settings.rb index fcfb09328..2b62e06a9 100644 --- a/db/seeds/settings.rb +++ b/db/seeds/settings.rb @@ -702,6 +702,12 @@ Setting.set('accounting_payment_wallet_journal_code', 'WA01') unless Setting.fin Setting.set('accounting_payment_other_code', '5803') unless Setting.find_by(name: 'accounting_payment_other_code').try(:value) Setting.set('accounting_payment_other_label', 'Payments on site') unless Setting.find_by(name: 'accounting_payment_other_label').try(:value) Setting.set('accounting_payment_other_journal_code', 'SI01') unless Setting.find_by(name: 'accounting_payment_other_journal_code').try(:value) +Setting.set('accounting_payment_transfer_code', '5804') unless Setting.find_by(name: 'accounting_payment_transfer_code').try(:value) +Setting.set('accounting_payment_transfer_label', 'Transfer Payments ') unless Setting.find_by(name: 'accounting_payment_transfer_label').try(:value) +Setting.set('accounting_payment_transfer_journal_code', 'TR01') unless Setting.find_by(name: 'accounting_payment_transfer_journal_code').try(:value) +Setting.set('accounting_payment_check_code', '5805') unless Setting.find_by(name: 'accounting_payment_check_code').try(:value) +Setting.set('accounting_payment_check_label', 'Payments by check') unless Setting.find_by(name: 'accounting_payment_check_label').try(:value) +Setting.set('accounting_payment_check_journal_code', 'CH01') unless Setting.find_by(name: 'accounting_payment_check_journal_code').try(:value) Setting.set('accounting_wallet_code', '4191') unless Setting.find_by(name: 'accounting_wallet_code').try(:value) Setting.set('accounting_wallet_label', 'Wallet credit') unless Setting.find_by(name: 'accounting_wallet_label').try(:value) Setting.set('accounting_wallet_journal_code', 'WC01') unless Setting.find_by(name: 'accounting_wallet_journal_code').try(:value) From 35d0d240effc76c81bf39a14bee27799bd09ca02 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 12 Feb 2024 11:50:33 +0100 Subject: [PATCH 14/92] (i18n) update translations --- CHANGELOG.md | 1 + config/locales/app.admin.de.yml | 4 +- config/locales/app.admin.es-MX.yml | 4 +- config/locales/app.admin.es.yml | 4 +- config/locales/app.admin.fr.yml | 4 +- config/locales/app.admin.it.yml | 4 +- config/locales/app.admin.no.yml | 4 +- config/locales/app.admin.pt.yml | 4 +- config/locales/app.admin.sv.yml | 2990 ++++++++++++++-------------- config/locales/app.admin.zu.yml | 4 +- config/locales/app.public.sv.yml | 2 +- 11 files changed, 1522 insertions(+), 1503 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5548ef4bb..43bf0391f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - improvement: Allow the admin to update payment method only the overdue subscription item without cancel PayZen subscription - improvement: add payment transfer/check to accounting settings +- updates translations ## v6.3.11 2024 February 2 diff --git a/config/locales/app.admin.de.yml b/config/locales/app.admin.de.yml index ef91ed4c3..f887adb28 100644 --- a/config/locales/app.admin.de.yml +++ b/config/locales/app.admin.de.yml @@ -276,6 +276,8 @@ de: card: "Card payments" wallet_debit: "Virtual wallet payments" other: "Other payment means" + transfer: "Transfer" + check: "Check" wallet_credit: "Virtual wallet credit" VAT: "VAT" sales: "Sales" @@ -1147,7 +1149,7 @@ de: date: "Datum" update_payment_mean_modal: title: "Zahlungsmittel aktualisieren" - update_info: "Bitte geben Sie unten das neue Zahlungsmittel an, damit der Zahlungszeitplan fortgesetzt werden kann." + update_info: "Please specify below the payment method to update this payment schedule." select_payment_mean: "Neues Zahlungsmittel auswählen" method_Transfer: "Per Banküberweisung" method_Check: "Per Scheck" diff --git a/config/locales/app.admin.es-MX.yml b/config/locales/app.admin.es-MX.yml index 0a1cdf607..f9537dd5f 100644 --- a/config/locales/app.admin.es-MX.yml +++ b/config/locales/app.admin.es-MX.yml @@ -276,6 +276,8 @@ es-MX: card: "Pagos con tarjeta" wallet_debit: "Pagos con cartera virtual" other: "Otros medios de pago" + transfer: "Transfer" + check: "Check" wallet_credit: "Crédito de cartera virtual" VAT: "IVA" sales: "Ventas" @@ -1147,7 +1149,7 @@ es-MX: date: "Fecha" update_payment_mean_modal: title: "Actualizar el medio de pago" - update_info: "Por favor, especifique a continuación el nuevo medio de pago para que este calendario de pagos continúe." + update_info: "Please specify below the payment method to update this payment schedule." select_payment_mean: "Seleccione un nuevo medio de pago" method_Transfer: "Por transferencia bancaria" method_Check: "Por cheque" diff --git a/config/locales/app.admin.es.yml b/config/locales/app.admin.es.yml index 11d4ce82f..6fcbdf1f2 100644 --- a/config/locales/app.admin.es.yml +++ b/config/locales/app.admin.es.yml @@ -276,6 +276,8 @@ es: card: "Pagos con tarjeta" wallet_debit: "Pagos con cartera virtual" other: "Otros medios de pago" + transfer: "Transfer" + check: "Check" wallet_credit: "Crédito de cartera virtual" VAT: "IVA" sales: "Ventas" @@ -1147,7 +1149,7 @@ es: date: "Fecha" update_payment_mean_modal: title: "Actualizar el medio de pago" - update_info: "Por favor, especifique a continuación el nuevo medio de pago para que este calendario de pagos continúe." + update_info: "Please specify below the payment method to update this payment schedule." select_payment_mean: "Seleccione un nuevo medio de pago" method_Transfer: "Por transferencia bancaria" method_Check: "Por cheque" diff --git a/config/locales/app.admin.fr.yml b/config/locales/app.admin.fr.yml index abaff8a61..8447dd0cb 100644 --- a/config/locales/app.admin.fr.yml +++ b/config/locales/app.admin.fr.yml @@ -276,6 +276,8 @@ fr: card: "Paiements par carte" wallet_debit: "Paiements par porte-monnaie virtuel" other: "Autres moyens de paiement" + transfer: "Paiements par virement" + check: "Paiements par chèque" wallet_credit: "Crédit du porte-monnaie virtuel" VAT: "TVA" sales: "Ventes" @@ -1147,7 +1149,7 @@ fr: date: "Date" update_payment_mean_modal: title: "Mettre à jour le moyen de paiement" - update_info: "Veuillez indiquer ci-dessous le nouveau moyen de paiement pour que cet échéancier de paiement puisse continuer." + update_info: "Veuillez indiquer ci-dessous le moyen de paiement pour mettre à jour cette échéance." select_payment_mean: "Sélectionner un nouveau moyen de paiement" method_Transfer: "Par virement bancaire" method_Check: "Par chèques" diff --git a/config/locales/app.admin.it.yml b/config/locales/app.admin.it.yml index 3699cd582..bb49b0859 100644 --- a/config/locales/app.admin.it.yml +++ b/config/locales/app.admin.it.yml @@ -276,6 +276,8 @@ it: card: "Pagamenti con carta" wallet_debit: "Pagamenti del portafoglio virtuale" other: "Altri mezzi di pagamento" + transfer: "Transfer" + check: "Check" wallet_credit: "Credito portafoglio virtuale" VAT: "IVA" sales: "Vendite" @@ -1147,7 +1149,7 @@ it: date: "Data" update_payment_mean_modal: title: "Aggiorna il metodo di pagamento" - update_info: "Si prega di specificare di seguito il nuovo mezzo di pagamento per questo programma di pagamenti per continuare." + update_info: "Please specify below the payment method to update this payment schedule." select_payment_mean: "Selezionare un nuovo metodo di pagamento" method_Transfer: "Con bonifico bancario" method_Check: "Con assegno" diff --git a/config/locales/app.admin.no.yml b/config/locales/app.admin.no.yml index 317f2ebc2..b6d2e9fda 100644 --- a/config/locales/app.admin.no.yml +++ b/config/locales/app.admin.no.yml @@ -276,6 +276,8 @@ card: "Card payments" wallet_debit: "Virtual wallet payments" other: "Other payment means" + transfer: "Transfer" + check: "Check" wallet_credit: "Virtual wallet credit" VAT: "VAT" sales: "Sales" @@ -1147,7 +1149,7 @@ date: "Dato" update_payment_mean_modal: title: "Update the payment mean" - update_info: "Please specify below the new payment mean for this payment schedule to continue." + update_info: "Please specify below the payment method to update this payment schedule." select_payment_mean: "Select a new payment mean" method_Transfer: "By bank transfer" method_Check: "By check" diff --git a/config/locales/app.admin.pt.yml b/config/locales/app.admin.pt.yml index badb74982..2e2ad24c9 100644 --- a/config/locales/app.admin.pt.yml +++ b/config/locales/app.admin.pt.yml @@ -276,6 +276,8 @@ pt: card: "Card payments" wallet_debit: "Virtual wallet payments" other: "Other payment means" + transfer: "Transfer" + check: "Check" wallet_credit: "Virtual wallet credit" VAT: "VAT" sales: "Sales" @@ -1147,7 +1149,7 @@ pt: date: "Data" update_payment_mean_modal: title: "Atualizar o método de pagamento" - update_info: "Por favor especifique abaixo o novo método de pagamento para este calendário de pagamentos continuar." + update_info: "Please specify below the payment method to update this payment schedule." select_payment_mean: "Selecione um novo método de pagamento" method_Transfer: "Por transferência bancária" method_Check: "Por cheque" diff --git a/config/locales/app.admin.sv.yml b/config/locales/app.admin.sv.yml index 5021b1183..c24e89186 100644 --- a/config/locales/app.admin.sv.yml +++ b/config/locales/app.admin.sv.yml @@ -276,6 +276,8 @@ sv: card: "Kortbetalningar" wallet_debit: "Virtuella plånboksbetalningar" other: "Andra betalningsmetoder" + transfer: "Transfer" + check: "Check" wallet_credit: "Virtuell plånbokskredit" VAT: "Moms" sales: "Försäljning" @@ -519,33 +521,33 @@ sv: edition_of_the_description_tooltip: "Upplagan av beskrivningens verktygstips" describe_the_training_in_a_few_words: "Beskriv utbildningen med några ord." description_is_limited_to_255_characters: "Beskrivningen är begränsad till 255 tecken." - description_was_successfully_saved: "Description was successfully saved." - training_successfully_deleted: "Training successfully deleted." - unable_to_delete_the_training_because_some_users_already_booked_it: "Unable to delete the training because some users already booked it." - confirmation_required: "Confirmation required" - do_you_really_want_to_delete_this_training: "Do you really want to delete this training?" + description_was_successfully_saved: "Beskrivningen har sparats." + training_successfully_deleted: "Utbildningen har tagits bort." + unable_to_delete_the_training_because_some_users_already_booked_it: "Det går inte att ta bort utbildningen eftersom användare redan bokat den." + confirmation_required: "Bekräftelse krävs" + do_you_really_want_to_delete_this_training: "Vill du verkligen ta bort den här utbildningen?" filter_status: "Filter:" - status_enabled: "Enabled" - status_disabled: "Disabled" - status_all: "All" - trainings_settings: "Settings" + status_enabled: "Aktiverad" + status_disabled: "Inaktiverad" + status_all: "Alla" + trainings_settings: "Inställningar" #create a new training trainings_new: - add_a_new_training: "Add a new training" + add_a_new_training: "Lägg till en ny utbildning" trainings_settings: - title: "Settings" - automatic_cancellation: "Trainings automatic cancellation" - automatic_cancellation_info: "Minimum number of participants required to maintain a session. You will be notified if a session is cancelled. Credit notes and refunds will be automatic if the wallet is enabled. Otherwise you will have to do it manually." - automatic_cancellation_switch: "Activate automatic cancellation for all the trainings" - automatic_cancellation_threshold: "Minimum number of registrations to maintain a session" - must_be_positive: "You must specify a number above or equal to 0" - automatic_cancellation_deadline: "Deadline, in hours, before automatic cancellation" - must_be_above_zero: "You must specify a number above or equal to 1" - authorization_validity: "Authorisations validity period" - authorization_validity_info: "Define a validity period for all training authorisations. After this period, the authorisation will lapse" - authorization_validity_switch: "Activate an authorization validity period" - authorization_validity_period: "Validity period in months" - validation_rule: "Authorisations cancellation rule" + title: "Inställningar" + automatic_cancellation: "Automatisk avbokning av utbildningar" + automatic_cancellation_info: "Minst antal deltagare som krävs för att ett tillfälle ska bli av. Du kommer att meddelas om ett tillfälle ställs in. Kreditnotor och återbetalningar kommer att skapas automatiskt om plånboken är aktiverad. Annars måste du göra det manuellt." + automatic_cancellation_switch: "Aktivera automatisk avbokning för alla utbildningar" + automatic_cancellation_threshold: "Minsta antal bokningar för att ett tillfälle ska bli av" + must_be_positive: "Du måste ange ett nummer över eller lika med 0" + automatic_cancellation_deadline: "Deadline, i timmar, före automatisk annullering" + must_be_above_zero: "Du måste ange ett nummer över eller lika med 1" + authorization_validity: "Giltighetstid för tillstånd" + authorization_validity_info: "Definiera en giltighetstid för alla utbildningstillstånd. Efter denna period kommer behörigheten att upphöra" + authorization_validity_switch: "Aktivera en giltighetsperiod för auktorisering" + authorization_validity_period: "Giltighetstid i månader" + validation_rule: "Auktorisering annuleras enligt" validation_rule_info: "Definiera en regel som upphäver ett tillstånd om utrustningen i samband med utbildningen inte är bokade för en viss tidsperiod. Denna regel råder över giltighetstiden för tillstånd." validation_rule_switch: "Aktivera valideringsregeln" validation_rule_period: "Tidsgräns i månader" @@ -599,63 +601,63 @@ sv: add_a_price_category: "Lägg till priskategori" usages_count: "Användningar" price_category: "Priskategori" - category_name: "Category's name" + category_name: "Kategorins namn" category_name_is_required: "Kategorins namn är obligatoriskt." enter_here_the_conditions_under_which_this_price_is_applicable: "Ange här de villkor under vilka detta pris är tillämpligt" conditions_are_required: "Förutsättningar krävs." - price_category_successfully_created: "Price category successfully created." - unable_to_add_the_price_category_check_name_already_used: "Unable to add the price category, check that the name is not already used." - unexpected_error_occurred_please_refresh: "An unexpected error occurred, please refresh the page." - price_category_successfully_updated: "Price category successfully updated." - unable_to_update_the_price_category: "Unable to update the price category." - unable_to_delete_this_price_category_because_it_is_already_used: "Unable to delete this price category because it is already used." - do_you_really_want_to_delete_this_price_category: "Do you really want to delete this price category?" - price_category_successfully_deleted: "Price category successfully deleted." - price_category_deletion_failed: "Price category deletion failed." - types: "Types" + price_category_successfully_created: "Priskategorin har skapats." + unable_to_add_the_price_category_check_name_already_used: "Det går inte att lägga till priskategorin, kontrollera att namnet inte redan används." + unexpected_error_occurred_please_refresh: "Ett oväntat fel uppstod, vänligen uppdatera sidan." + price_category_successfully_updated: "Priskategorin har uppdaterats." + unable_to_update_the_price_category: "Det går inte att uppdatera priskategorin." + unable_to_delete_this_price_category_because_it_is_already_used: "Det går inte att ta bort denna priskategori eftersom den redan används." + do_you_really_want_to_delete_this_price_category: "Vill du verkligen ta bort denna priskategori?" + price_category_successfully_deleted: "Priskategorin har tagits bort." + price_category_deletion_failed: "Priskategorin raderades inte." + types: "Typer" event_type: standard: "Standard" - family: "Reserved for members" - nominative: "Nominative" - pre_registration: "Pre-registration" - NUMBER_pre_registered: " {NUMBER} pre-registered" + family: "Reserverat för Medlemmar" + nominative: "Namngivet" + pre_registration: "Föranmälan" + NUMBER_pre_registered: " {NUMBER} förregistrerad" #add a new event events_new: - add_an_event: "Add an event" - none: "None" - every_days: "Every days" - every_week: "Every week" - every_month: "Every month" - every_year: "Every year" + add_an_event: "Lägg till ett evenemang" + none: "Inget" + every_days: "Varje dag" + every_week: "Varje vecka" + every_month: "Varje månad" + every_year: "Varje år" #edit an existing event events_edit: - edit_the_event: "Edit the event" - confirmation_required: "Confirmation required" - edit_recurring_event: "You're about to update a periodic event. What do you want to update?" - edit_this_event: "Only this event" + edit_the_event: "Redigera evenemanget" + confirmation_required: "Bekräftelse krävs" + edit_recurring_event: "Du håller på att uppdatera ett återkommande evenemang. Vad vill du uppdatera?" + edit_this_event: "Bara detta evenemang" edit_this_and_next: "Detta evenemang samt framtida" edit_all: "Alla evenemang" date_wont_change: "Varning: du har ändrat evenemangsdatumet. Denna ändring kommer inte att spridas till andra tillfällen av det återkommande evenemanget." event_successfully_updated: "Evenemanget är uppdaterat." events_updated: "Evenemanget och {COUNT, plural, one {}=1{en annan} other{{COUNT} andra}}har uppdaterats" unable_to_update_the_event: "Det gick inte att uppdatera evenemanget" - events_not_updated: "On {TOTAL} events, {COUNT, plural, =1{one was not updated} other{{COUNT} were not deleted}}." - error_deleting_reserved_price: "Unable to delete the requested price because it is associated with some reservations" - other_error: "An unexpected error occurred while updating the event" + events_not_updated: "Av {TOTAL} evenemang har {COUNT, plural, one {}=1{ett inte uppdaterats} other{{COUNT} inte tagits bort}}." + error_deleting_reserved_price: "Det går inte att ta bort det begärda priset eftersom det är associerat med vissa bokningar" + other_error: "Ett oväntat fel inträffade när evenemanget uppdaterades" #event reservations list event_reservations: - the_reservations: "Reservations:" - user: "User" - payment_date: "Payment date" - full_price_: "Full price:" - reserved_tickets: "Reserved tickets" - show_the_event: "Show the event" - no_reservations_for_now: "No reservation for now." - back_to_monitoring: "Back to monitoring" - canceled: "Canceled" - date: "Date" - booked_by: "Booked by" - reservations: "Reservations" + the_reservations: "Bokningar:" + user: "Användare" + payment_date: "Betalningsdatum" + full_price_: "Ordinarie pris:" + reserved_tickets: "Reserverade biljetter" + show_the_event: "Visa evenemanget" + no_reservations_for_now: "Ingen bokning för tillfället." + back_to_monitoring: "Tillbaka till övervakning" + canceled: "Avbruten" + date: "Datum" + booked_by: "Bokad av" + reservations: "Bokningar" status: "Status" gestion: "Förvaltning" validation: "Godkännande" @@ -710,56 +712,56 @@ sv: group: "Grupp" category: "Kategori" prominence: "Prominens" - price: "Price" - machine_hours: "Machine slots" - prices_calculated_on_hourly_rate_html: "All the prices will be automatically calculated based on the hourly rate defined here.
For example, if you define an hourly rate at {RATE}: a slot of {DURATION} minutes, will be charged {PRICE}." - you_can_override: "You can override this duration for each availability you create in the agenda. The price will then be adjusted accordingly." - machines: "Machines" - credits: "Credits" - subscription: "Subscription" - related_trainings: "Related trainings" - add_a_machine_credit: "Add a machine credit" - machine: "Machine" - hours: "Slots (default {DURATION} minutes)" - related_subscriptions: "Related subscriptions" - please_specify_a_number: "Please specify a number." - none: "None" #grammar concordance with training. - an_error_occurred_while_saving_the_number_of_credits: "An error occurred while saving the number of credits." - an_error_occurred_while_deleting_credit_with_the_TRAINING: "An error occurred while deleting credit with the {TRAINING}." - an_error_occurred_unable_to_find_the_credit_to_revoke: "An error occurred: unable to find the credit to revoke." - an_error_occurred_while_creating_credit_with_the_TRAINING: "An error occurred while creating credit with the {TRAINING}." - not_set: "Not set" - error_a_credit_linking_this_machine_with_that_subscription_already_exists: "Error: a credit linking this machine with that subscription already exists." - changes_have_been_successfully_saved: "Changes have been successfully saved." - credit_was_successfully_saved: "Credit was successfully saved." - error_creating_credit: "Unable to create credit, an error occurred" - do_you_really_want_to_delete_this_subscription_plan: "Do you really want to delete this subscription plan?" - subscription_plan_was_successfully_deleted: "Subscription plan was successfully deleted." - unable_to_delete_the_specified_subscription_an_error_occurred: "Unable to delete the specified subscription, an error occurred." - coupons: "Coupons" - list_of_the_coupons: "List of the coupons" - discount: "Discount" - nb_of_usages: "Number of usages" + price: "Pris" + machine_hours: "Utrustning" + prices_calculated_on_hourly_rate_html: "Alla priser beräknas automatiskt baserat på den timtaxa som anges här.
Till exempel, om du definierar en timtaxa på {RATE}: kommer en plats på {DURATION} minuter, att debiteras {PRICE}." + you_can_override: "Du kan åsidosätta denna varaktighet för varje tillgänglighet du skapar på agendan. Priset kommer då att justeras därefter." + machines: "Utrustning" + credits: "Krediter" + subscription: "Prenumeration" + related_trainings: "Relaterade utbildningar" + add_a_machine_credit: "Lägg till en utrustningskredit" + machine: "Utrustning" + hours: "Plats (standard {DURATION} minuter)" + related_subscriptions: "Relaterade prenumerationer" + please_specify_a_number: "Ange ett nummer." + none: "Inget" #grammar concordance with training. + an_error_occurred_while_saving_the_number_of_credits: "Ett fel inträffade när antalet krediter skulle sparas." + an_error_occurred_while_deleting_credit_with_the_TRAINING: "Ett fel inträffade vid borttagning av kredit med {TRAINING}." + an_error_occurred_unable_to_find_the_credit_to_revoke: "Ett fel uppstod: kan inte hitta krediten att återkalla." + an_error_occurred_while_creating_credit_with_the_TRAINING: "Ett fel inträffade när krediten skulle skapas med {TRAINING}." + not_set: "Har inte angetts" + error_a_credit_linking_this_machine_with_that_subscription_already_exists: "Fel: en kredit som länkar denna utrustning med prenumerationen finns redan." + changes_have_been_successfully_saved: "Ändringarna har sparats." + credit_was_successfully_saved: "Krediten har sparats." + error_creating_credit: "Det gick inte att skapa kredit, ett fel uppstod" + do_you_really_want_to_delete_this_subscription_plan: "Vill du verkligen ta bort denna prenumerationsplan?" + subscription_plan_was_successfully_deleted: "Prenumerationsplanen har tagits bort." + unable_to_delete_the_specified_subscription_an_error_occurred: "Det gick inte att ta bort den angivna prenumerationen, ett fel inträffade." + coupons: "Rabattkuponger" + list_of_the_coupons: "Lista över rabattkuponger" + discount: "Rabatt" + nb_of_usages: "Antal användningsområden" status: "Status" - add_a_new_coupon: "Add a new coupon" - display_more_coupons: "Display the next coupons" - disabled: "Disabled" - expired: "Expired" - sold_out: "Sold out" - active: "Active" - all: "Display all" - confirmation_required: "Confirmation required" - do_you_really_want_to_delete_this_coupon: "Do you really want to delete this coupon?" - coupon_was_successfully_deleted: "Coupon was successfully deleted." - unable_to_delete_the_specified_coupon_already_in_use: "Unable to delete the specified coupon: it is already used with some invoices and/or some payment schedules." - unable_to_delete_the_specified_coupon_an_unexpected_error_occurred: "Unable to delete the specified coupon: an unexpected error occurred." - send_a_coupon: "Send a coupon" - coupon: "Coupon" - usages: "Usages" - unlimited: "Unlimited" - coupon_successfully_sent_to_USER: "Coupon successfully sent to {USER}" - an_error_occurred_unable_to_send_the_coupon: "An unexpected error prevent from sending the coupon." - code: "Code" + add_a_new_coupon: "Lägg till en ny kupong" + display_more_coupons: "Visa nästa kupong" + disabled: "Inaktiverad" + expired: "Utgått" + sold_out: "Slutsåld" + active: "Aktiv" + all: "Visa allt" + confirmation_required: "Bekräftelse krävs" + do_you_really_want_to_delete_this_coupon: "Vill du verkligen ta bort denna kupong?" + coupon_was_successfully_deleted: "Kupongen har tagits bort." + unable_to_delete_the_specified_coupon_already_in_use: "Det går inte att ta bort den angivna kupongen: den används redan med vissa fakturor och/eller vissa betalningsscheman." + unable_to_delete_the_specified_coupon_an_unexpected_error_occurred: "Det går inte att ta bort den angivna kupongen: ett oväntat fel inträffade." + send_a_coupon: "Skicka en kupong" + coupon: "Rabattkupong" + usages: "Användningsområden" + unlimited: "Obegränsat" + coupon_successfully_sent_to_USER: "Kupongen har skickats till {USER}" + an_error_occurred_unable_to_send_the_coupon: "Ett oväntat fel förhindrar att kupongen skickas." + code: "Kod" enabled: "Aktiverad" validity_per_user: "Giltighet per användare" once: "Bara en gång" @@ -819,76 +821,76 @@ sv: create_pack: "Skapa detta paket" pack_successfully_created: "Det nya förbetalda paketet har skapats." create_extended_price: - new_extended_price: "New extended price" - new_extended_price_info: "Extended prices allows you to define prices based on custom durations, instead of the default hourly rates." - create_extended_price: "Create extended price" - extended_price_successfully_created: "The new extended price was successfully created." + new_extended_price: "Nytt utökat pris" + new_extended_price_info: "Utökade priser gör att du kan definiera priser baserat på anpassade varaktigheter, i stället för standard timpriser." + create_extended_price: "Nytt utökat pris" + extended_price_successfully_created: "Det nya utökade priset har skapats." delete_extended_price: - extended_price_deleted: "The extended price was successfully deleted." - unable_to_delete: "Unable to delete the extended price: " - delete_extended_price: "Delete the extended price" - confirm_delete: "Delete" - delete_confirmation: "Are you sure you want to delete this extended price?" + extended_price_deleted: "Det utökade priset har tagits bort." + unable_to_delete: "Kan inte ta bort det utökade priset: " + delete_extended_price: "Ta bort det utökade priset" + confirm_delete: "Ta bort" + delete_confirmation: "Är du säker på att du vill ta bort detta utökade pris?" edit_extended_price: - edit_extended_price: "Edit the extended price" - confirm_changes: "Confirm changes" - extended_price_successfully_updated: "The extended price was successfully updated." + edit_extended_price: "Redigera det utökade priset" + confirm_changes: "Bekräfta ändringar" + extended_price_successfully_updated: "Det utökade priset har uppdaterats." plans_categories: - manage_plans_categories: "Manage plans' categories" + manage_plans_categories: "Hantera plankategorier" plan_categories_list: - categories_list: "List of the plan's categories" - no_categories: "No categories" - name: "Name" - description: "Description" - significance: "Significance" + categories_list: "Lista över plankategorier" + no_categories: "Inga kategorier" + name: "Namn" + description: "Beskrivning" + significance: "Signifikans" manage_plan_category: - create: "New category" - update: "Edit the category" + create: "Ny kategori" + update: "Redigera kategori" plan_category_form: - name: "Name" - description: "Description" - significance: "Significance" - info: "Categories will be shown ordered by signifiance. The higher you set the significance, the first the category will be shown." + name: "Namn" + description: "Beskrivning" + significance: "Signifikans" + info: "Kategorier kommer att visas efter signifikans. Ju högre signifikans du anger, desto tidigare kommer kategorin att visas." create: - title: "New category" - cta: "Create the category" - success: "The new category was successfully created" - error: "Unable to create the category: " + title: "Ny kategori" + cta: "Redigera kategori" + success: "Den nya kategorin har skapats" + error: "Det går inte att skapa kategori: " update: - title: "Edit the category" - cta: "Validate" - success: "The category was successfully updated" - error: "Unable to update the category: " + title: "Redigera kategori" + cta: "Bekräfta" + success: "Kategorin har uppdaterats" + error: "Det går inte att uppdatera kategorin: " delete_plan_category: - title: "Delete a category" - confirm: "Are you sure you want to delete this category? If you do, the plans associated with this category won't be sorted anymore." - cta: "Delete" - success: "The category was successfully deleted" - error: "Unable to delete the category: " + title: "Ta bort en kategori" + confirm: "Är du säker på att du vill ta bort denna kategori? Om du gör det kommer planerna som är kopplade till denna kategori inte att sorteras längre." + cta: "Ta bort" + success: "Kategorin har tagits bort" + error: "Det går inte att ta bort kategorin: " #ajouter un code promotionnel coupons_new: - add_a_coupon: "Add a coupon" - unable_to_create_the_coupon_check_code_already_used: "Unable to create the coupon. Please check that the code is not already used." + add_a_coupon: "Lägg till kupong" + unable_to_create_the_coupon_check_code_already_used: "Det gick inte att skapa kupongen. Kontrollera att koden inte redan används." #mettre à jour un code promotionnel coupons_edit: - coupon: "Coupon:" - unable_to_update_the_coupon_an_error_occurred: "Unable to update the coupon: an error occurred." + coupon: "Rabattkupong:" + unable_to_update_the_coupon_an_error_occurred: "Det gick inte att uppdatera kupongen: ett fel inträffade." plans: #add a subscription plan on the platform new: - add_a_subscription_plan: "Add a subscription plan" + add_a_subscription_plan: "Lägg till en prenumerationsplan" #edit a subscription plan / machine slots prices edit: - subscription_plan: "Subscription plan:" + subscription_plan: "Prenumerationsplan:" #list of all invoices & invoicing parameters invoices: - invoices: "Invoices" - accounting_periods: "Accounting periods" - invoices_list: "Invoices list" - filter_invoices: "Filter invoices" - operator_: "Operator:" - invoice_num_: "Invoice #:" - customer_: "Customer:" + invoices: "Fakturor" + accounting_periods: "Redovisningsperioder" + invoices_list: "Lista med fakturor" + filter_invoices: "Filtrera fakturor" + operator_: "Operatör:" + invoice_num_: "Fakturanr:" + customer_: "Kund:" date_: "Datum:" invoice_num: "Fakturanr" date: "Datum" @@ -939,56 +941,56 @@ sv: refund: "Återbetala" payment_schedule: "Betalningsschema" model: "Modell" - documentation: "Documentation" - 2_digits_year: "2 digits year (eg. 70)" - 4_digits_year: "4 digits year (eg. 1970)" - month_number: "Month number (eg. 1)" - 2_digits_month_number: "2 digits month number (eg. 01)" - 3_characters_month_name: "3 characters month name (eg. JAN)" - day_in_the_month: "Day in the month (eg. 1)" - 2_digits_day_in_the_month: "2 digits in the month (eg. 01)" - n_digits_daily_count_of_invoices: "(n) digits, daily count of invoices (eg. ddd => 002 : 2nd invoice of the day)" - n_digits_monthly_count_of_invoices: "(n) digits, monthly count of invoices (eg. mmmm => 0012 : 12th invoice of the month)" - n_digits_annual_amount_of_invoices: "(n) digits, annual count of invoices (ex. yyyyyy => 000008 : 8th invoice of this year)" - beware_if_the_number_exceed_the_specified_length_it_will_be_truncated_by_the_left: "Beware: if the number exceed the specified length, it will be truncated by the left." - n_digits_count_of_orders: "(n) digits, count of invoices (eg. nnnn => 0327 : 327th order)" - n_digits_daily_count_of_orders: "(n) digits, daily count of orders (eg. ddd => 002 : 2nd order of the day)" - n_digits_monthly_count_of_orders: "(n) digits, monthly count of orders (eg. mmmm => 0012 : 12th order of the month)" - n_digits_annual_amount_of_orders: "(n) digits, annual count of orders (ex. yyyyyy => 000008 : 8th order of this year)" - add_a_notice_regarding_the_online_sales_only_if_the_invoice_is_concerned: "Add a notice regarding the online sales, only if the invoice is concerned." - this_will_never_be_added_when_a_refund_notice_is_present: "This will never be added when a refund notice is present." - eg_XVL_will_add_VL_to_the_invoices_settled_by_card: '(eg. X[/VL] will add "/VL" to the invoices settled by online card)' - add_a_notice_regarding_refunds_only_if_the_invoice_is_concerned: "Add a notice regarding refunds, only if the invoice is concerned." - this_will_never_be_added_when_an_online_sales_notice_is_present: "This will never be added when an online sales notice is present." - eg_RA_will_add_A_to_the_refund_invoices: '(eg. R[/A] will add "/A" to the refund invoices)' - add_a_notice_regarding_payment_schedule: "Add a notice regarding the payment schedules, only for concerned documents." - this_will_never_be_added_with_other_notices: "This will never be added when any other notice is present." - eg_SE_to_schedules: '(eg. S[/E] will add "/E" to the payment schedules)' - code: "Code" - enable_the_code: "Enable the code" - enabled: "Enabled" - disabled: "Disabled" - order_number: "Order number" - elements: "Elements" - VAT: "VAT" - enable_VAT: "Enable VAT" - VAT_rate: "VAT rate" - VAT_history: "VAT rates history" - VAT_notice: "This parameter configures the general case of the VAT rate and applies to everything sold by the Fablab. It is possible to override this parameter by setting a specific VAT rate for each object." - edit_multi_VAT_button: "More options" - multiVAT: "Advanced VAT" - multi_VAT_notice: "Please note: The current general rate is {RATE}%. Here you can define different VAT rates for each category.

For example, you can override this value, only for machine reservations, by filling in the corresponding field below. If no value is filled in, the general rate will apply." - VAT_rate_machine: "Machine reservation" - VAT_rate_space: "Space reservation" - VAT_rate_training: "Training reservation" - VAT_rate_event: "Event reservation" - VAT_rate_subscription: "Subscription" - VAT_rate_product: "Products (store)" - changed_at: "Changed at" - changed_by: "By" - deleted_user: "Deleted user" - refund_invoice_successfully_created: "Refund invoice successfully created." - create_a_refund_on_this_invoice: "Create a refund on this invoice" + documentation: "Dokumentation" + 2_digits_year: "Årtal i två positioner (t. ex. 70)" + 4_digits_year: "Årtal i fyra positioner (t. ex. 1970)" + month_number: "Månadsnummer (t. ex. 1)" + 2_digits_month_number: "2 siffrors månadsnummer (t. ex. 01)" + 3_characters_month_name: "3 teckens månadsnamn (t. ex. JAN)" + day_in_the_month: "Dag i månaden (t. ex. 1)" + 2_digits_day_in_the_month: "2 siffror i månaden (t. ex. 01)" + n_digits_daily_count_of_invoices: "(n) siffror, daglig räkning av fakturor (t. ex. ddd => 002 : Andra fakturan för dagen)" + n_digits_monthly_count_of_invoices: "(n) siffror, månadsantal fakturor (t. ex. mmmm => 0012 : 12: e faktura i månaden)" + n_digits_annual_amount_of_invoices: "(n) siffror, årligt antal fakturor (t. ex. yyyyyy => 000008 : 8: e fakturan för detta år)" + beware_if_the_number_exceed_the_specified_length_it_will_be_truncated_by_the_left: "Observera: om antalet överskrider den angivna längden, kommer det att trunkeras till vänster." + n_digits_count_of_orders: "(n) siffror, antal fakturor (t. ex. nnn => 0327 : 327: e beställningen)" + n_digits_daily_count_of_orders: "(n) siffror, dagligt antal beställningar (t. ex. ddd => 002 : Andra beställningen för dagen)" + n_digits_monthly_count_of_orders: "(n) siffror, månadsantal fakturor (t. ex. mmmm => 0012 : 12: e fakturan för månaden)" + n_digits_annual_amount_of_orders: "(n) siffror, antal beställningar för året (t. ex. yyyyyy => 000008: 8: e beställningen i år)" + add_a_notice_regarding_the_online_sales_only_if_the_invoice_is_concerned: "Lägg till ett meddelande om onlineförsäljning, endast om fakturan berörs." + this_will_never_be_added_when_a_refund_notice_is_present: "Detta kommer aldrig att läggas till när en kreditnota finns." + eg_XVL_will_add_VL_to_the_invoices_settled_by_card: '(t. ex. X[/VL] kommer att lägga till "/VL" till fakturorna betalade online med kort)' + add_a_notice_regarding_refunds_only_if_the_invoice_is_concerned: "Lägg till ett meddelande om återbetalning, endast om fakturan berörs." + this_will_never_be_added_when_an_online_sales_notice_is_present: "Detta kommer aldrig att läggas till när ett onlinesäljmeddelande finns." + eg_RA_will_add_A_to_the_refund_invoices: '(t. ex. R[/A] kommer att lägga till "/A" till kreditnotorna)' + add_a_notice_regarding_payment_schedule: "Lägg till ett meddelande om betalningsscheman, endast för berörda dokument." + this_will_never_be_added_with_other_notices: "Detta kommer aldrig att läggas till när något annat meddelande finns." + eg_SE_to_schedules: '(t. ex. S[/E] kommer att lägga till "/E" till betalningsscheman)' + code: "Kod" + enable_the_code: "Aktivera koden" + enabled: "Aktiverad" + disabled: "Inaktiverad" + order_number: "Beställningsnummer" + elements: "Element" + VAT: "Moms" + enable_VAT: "Aktivera moms" + VAT_rate: "Momssats" + VAT_history: "Historik för momssatser" + VAT_notice: "Denna parameter konfigurerar standardmomssatsen och gäller allt som säljs. Det är möjligt att åsidosätta denna parameter genom att ställa in en specifik momssats för varje objekt." + edit_multi_VAT_button: "Fler alternativ" + multiVAT: "Avancerad moms" + multi_VAT_notice: "Notera: Den nuvarande generella momssatsen är {RATE}%. Här kan du ange olika momssatser för varje kategori.

Du kan till exempel åsidosätta detta värde, vid bokning av utrustning, genom att fylla i motsvarande fält nedan. Om inget värde fylls i gäller det allmänna priset." + VAT_rate_machine: "Utrustningsbokning" + VAT_rate_space: "Lokalbokning" + VAT_rate_training: "Bokning av utbildning" + VAT_rate_event: "Evenmangsbokning" + VAT_rate_subscription: "Prenumeration" + VAT_rate_product: "Produkter (butik)" + changed_at: "Ändrad vid" + changed_by: "Av" + deleted_user: "Raderad användare" + refund_invoice_successfully_created: "Kreditnota har skapats." + create_a_refund_on_this_invoice: "Skapa en återbetalning för denna faktura" refund_mode: "Återbetalningsläge:" do_you_want_to_disable_the_user_s_subscription: "Vill du avaktivera användarens prenumeration:" elements_to_refund: "Element att återbetala" @@ -1039,1536 +1041,1536 @@ sv: start_date: "Från" end_date: "Till" closed_at: "Stängd vid" - closed_by: "By" - period_total: "Period total" - perpetual_total: "Perpetual total" - integrity: "Integrity check" - confirmation_required: "Confirmation required" - confirm_close_START_END: "Do you really want to close the accounting period between {START} and {END}? Any subsequent changes will be impossible." - period_must_match_fiscal_year: "A closing must occur at the end of a minimum annual period, or per financial year when it is not calendar-based." - this_may_take_a_while: "This operation will take some time to complete." - period_START_END_closed_success: "The accounting period from {START} to {END} has been successfully closed. Archive generation is running, you'll be notified when it's done." - failed_to_close_period: "An error occurred, unable to close the accounting period" - no_periods: "No closings for now" - accounting_codes: "Accounting codes" - export_accounting_data: "Export accounting data" + closed_by: "Av" + period_total: "Perioden totalt" + perpetual_total: "Evigt totalt" + integrity: "Integritetskontroll" + confirmation_required: "Bekräftelse krävs" + confirm_close_START_END: "Vill du verkligen stänga redovisningsperioden mellan {START} och {END}? Eventuella ändringar är omöjliga." + period_must_match_fiscal_year: "En avslutning måste ske i slutet av en årsperiod eller per räkenskapsår när den inte är kalenderbaserad." + this_may_take_a_while: "Denna operation kommer att ta lite tid att slutföra." + period_START_END_closed_success: "Redovisningsperioden från {START} till {END} har stängts framgångsrikt. Skapandet av arkiv körs, du kommer att meddelas när det är klart." + failed_to_close_period: "Ett fel uppstod, kan inte stänga redovisningsperioden" + no_periods: "Inga avslutningar just nu" + accounting_codes: "Redovisningskoder" + export_accounting_data: "Exportera redovisningsdata" export_what: "What do you want to export?" - export_VAT: "Export the collected VAT" - export_to_ACD: "Export all data to the accounting software ACD" - export_is_running: "Export is running. You'll be notified when it's ready." - export_form_date: "Export from" - export_to_date: "Export until" - format: "File format" - encoding: "Encoding" + export_VAT: "Exportera den upptagna momsen" + export_to_ACD: "Exportera all data till bokföringsprogrammet ACD" + export_is_running: "Exporten körs. Du kommer att meddelas när den är klar." + export_form_date: "Exportera från" + export_to_date: "Exportera till" + format: "Filformat" + encoding: "Textkodning" separator: "Separator" - dateFormat: "Date format" - labelMaxLength: "Label (max)" - decimalSeparator: "Decimal separator" - exportInvoicesAtZero: "Export invoices equal to 0" - columns: "Columns" + dateFormat: "Datumformat" + labelMaxLength: "Etikett (max)" + decimalSeparator: "Decimalavgränsare" + exportInvoicesAtZero: "Exportera fakturor lika med 0" + columns: "Kolumner" exportColumns: - journal_code: "Journal code" - date: "Entry date" - account_code: "Account code" - account_label: "Account label" - piece: "Document" - line_label: "Entry label" - debit_origin: "Origin debit" - credit_origin: "Origin credit" - debit_euro: "Euro debit" - credit_euro: "Euro credit" - lettering: "Lettering" - start_date: "Start date" - end_date: "End date" - vat_rate: "VAT rate" - amount: "Total amount" + journal_code: "Journalkod" + date: "Transaktionsdatum" + account_code: "Kontokod" + account_label: "Kontonamn" + piece: "Dokument" + line_label: "Postens etikett" + debit_origin: "Ursprungsdebitering" + credit_origin: "Ursprungskredititering" + debit_euro: "Euro debitering" + credit_euro: "Euro kreditering" + lettering: "Textning" + start_date: "Startdatum" + end_date: "Slutdatum" + vat_rate: "Momssats" + amount: "Totalt belopp" payzen_keys_form: - payzen_keys_info_html: "

To be able to collect online payments, you must configure the PayZen identifiers and keys.

Retrieve them from your merchant back office.

" - client_keys: "Client key" - payzen_public_key: "Client public key" - api_keys: "API keys" - payzen_username: "Username" - payzen_password: "Password" - payzen_endpoint: "REST API server name" + payzen_keys_info_html: "

För att kunna ta betalt online måste du konfigurera PayZen identifierare och nycklar.

Hämta dem från din betalningsleverantör.

" + client_keys: "Klientnyckel" + payzen_public_key: "Publik klientnyckel" + api_keys: "API-nyckel" + payzen_username: "Användarnamn" + payzen_password: "Lösenord" + payzen_endpoint: "REST API servernamn" payzen_hmac: "HMAC-SHA-256 key" stripe_keys_form: - stripe_keys_info_html: "

To be able to collect online payments, you must configure the Stripe API keys.

Retrieve them from your dashboard.

Updating these keys will trigger a synchronization of all users on Stripe, this may take some time. You'll receive a notification when it's done.

" - public_key: "Public key" - secret_key: "Secret key" + stripe_keys_info_html: "

För att kunna ta betalt online måste du konfigurera Stripe API-nycklar.

Hämta dem från din instrumentpanel.

Uppdatering av dessa nycklar kommer att utlösa en synkronisering av alla användare på Stripe, detta kan ta lite tid. Du får ett meddelande när det är klart.

" + public_key: "Publik nyckel" + secret_key: "Hemlig nyckel" payment: - payment_settings: "Payment settings" - online_payment: "Online payment" - online_payment_info_html: "You can enable your members to book directly online, paying by card. Alternatively, you can restrict the booking and payment processes for administrators and managers." - enable_online_payment: "Enable online payment" - stripe_keys: "Stripe keys" - public_key: "Public key" - secret_key: "Secret key" - error_check_keys: "Error: please check your Stripe keys." - stripe_keys_saved: "Stripe keys successfully saved." - error_saving_stripe_keys: "Unable to save the Stripe keys. Please try again later." - api_keys: "API keys" - edit_keys: "Edit keys" - currency: "Currency" - currency_info_html: "Please specify below the currency used for online payment. You should provide a three-letter ISO code, from the list of Stripe supported currencies." - currency_alert_html: "Warning: the currency cannot be changed after the first online payment was made. Please define this setting carefully before opening Fab-manager to your members." - stripe_currency: "Stripe currency" - gateway_configuration_error: "An error occurred while configuring the payment gateway: " + payment_settings: "Betalningsinställningar" + online_payment: "Onlinebetalning" + online_payment_info_html: "Du kan göra det möjligt för dina medlemmar att boka direkt online, betala med kort. Alternativt kan du begränsa boknings- och betalningsprocesserna för administratörer och ansvariga." + enable_online_payment: "Aktivera onlinebetalning" + stripe_keys: "Stripe Api-nycklar" + public_key: "Publik nyckel" + secret_key: "Hemlig nyckel" + error_check_keys: "Fel: kontrollera dina Stripe-nycklar." + stripe_keys_saved: "Stripenycklar sparades framgångsrikt." + error_saving_stripe_keys: "Det gick inte att spara Stripe-nycklarna. Försök igen senare." + api_keys: "API nycklar" + edit_keys: "Redigera nycklar" + currency: "Valuta" + currency_info_html: "Vänligen ange valuta som används för online-betalning. Du bör ange en ISO-kod med tre bokstäver från listan över stödda valutor." + currency_alert_html: "Varning: valutan kan inte ändras efter den första onlinebetalningen. Vänligen definiera denna inställning noga innan du öppnar systemet för dina medlemmar." + stripe_currency: "Stripe valuta" + gateway_configuration_error: "Ett fel inträffade när betalningsgatewayen skulle konfigureras: " payzen_settings: - payzen_keys: "PayZen keys" - edit_keys: "Edit keys" - payzen_public_key: "Client public key" - payzen_username: "Username" - payzen_password: "Password" - payzen_endpoint: "REST API server name" + payzen_keys: "PayZen nycklar" + edit_keys: "Redigera nycklar" + payzen_public_key: "Publik klientnyckel" + payzen_username: "Användarnamn" + payzen_password: "Lösenord" + payzen_endpoint: "REST API servernamn" payzen_hmac: "HMAC-SHA-256 key" - currency: "Currency" - payzen_currency: "PayZen currency" - currency_info_html: "Please specify below the currency used for online payment. You should provide a three-letter ISO code, from the list of PayZen supported currencies." - save: "Save" - currency_error: "The inputted value is not a valid currency" - error_while_saving: "An error occurred while saving the currency: " - currency_updated: "The PayZen currency was successfully updated to {CURRENCY}." + currency: "Valuta" + payzen_currency: "PayZen valuta" + currency_info_html: "Vänligen ange nedan den valuta som används för online-betalning. Du bör ange en ISO-kod med tre bokstäver från listan över stödda valutor." + save: "Spara" + currency_error: "Det inmatade värdet är inte en giltig valuta" + error_while_saving: "Ett fel inträffade när valutan skulle sparas: " + currency_updated: "PayZen-valutan har uppdaterats till {CURRENCY}." #select a payment gateway select_gateway_modal: - select_gateway_title: "Select a payment gateway" - gateway_info: "To securely collect and process payments online, Fab-manager needs to use an third-party service authorized by the financial institutions, called a payment gateway." - select_gateway: "Please select an available gateway" + select_gateway_title: "Välj din betalningsgateway" + gateway_info: "För att på ett säkert sätt samla in och hantera betalningar online måste Fab-manager använda en tredjepartstjänst som godkänts av de finansiella institutionerna, en betalningsgateway." + select_gateway: "Välj en tillgänglig gateway" stripe: "Stripe" payzen: "PayZen" - confirm_button: "Validate the gateway" + confirm_button: "Validera gateway" payment_schedules_list: - filter_schedules: "Filter schedules" - no_payment_schedules: "No payment schedules to display" - load_more: "Load more" - card_updated_success: "The user's card was successfully updated" + filter_schedules: "Filtrera scheman" + no_payment_schedules: "Inga betalningsscheman att visa" + load_more: "Ladda mer" + card_updated_success: "Användarens kort har uppdaterats" document_filters: - reference: "Reference" - customer: "Customer" - date: "Date" + reference: "Referens" + customer: "Kund" + date: "Datum" update_payment_mean_modal: - title: "Update the payment mean" - update_info: "Please specify below the new payment mean for this payment schedule to continue." - select_payment_mean: "Select a new payment mean" - method_Transfer: "By bank transfer" - method_Check: "By check" - confirm_button: "Update" + title: "Uppdatera betalningsmedel" + update_info: "Please specify below the payment method to update this payment schedule." + select_payment_mean: "Välj ett nytt betalsätt" + method_Transfer: "Banköverföring" + method_Check: "Med check" + confirm_button: "Uppdatera" #management of users, labels, groups, and so on members: - users_management: "Users management" - import: "Import members from a CSV file" - users: "Users" - members: "Members" - subscriptions: "Subscriptions" - search_for_an_user: "Search for an user" - add_a_new_member: "Add a new member" - reservations: "Reservations" - username: "Username" - surname: "Last name" - first_name: "First name" - email: "Email" - phone: "Phone" - user_type: "User type" - subscription: "Subscription" - display_more_users: "Display more users..." - administrators: "Administrators" - search_for_an_administrator: "Search for an administrator" - add_a_new_administrator: "Add a new administrator" - managers: "Managers" - managers_info: "A manager is a restricted administrator that cannot modify the settings of the application. However, he will be able to take reservations for any members and for all managers, including himself, and to process payments and refunds." - search_for_a_manager: "Search for a manager" - add_a_new_manager: "Add a new manager" - delete_this_manager: "Do you really want to delete this manager? This cannot be undone." - manager_successfully_deleted: "Manager successfully deleted." - unable_to_delete_the_manager: "Unable to delete the manager." - partners: "Partners" - partners_info: "A partner is a special user that can be associated with the «Partner» plans. These users won't be able to connect and will just receive notifications about subscriptions to their associated plan." - search_for_a_partner: "Search for a partner" - add_a_new_partner: "Add a new partner" - delete_this_partner: "Do you really want to delete this partner? This cannot be undone." - partner_successfully_deleted: "Partner successfully deleted." - unable_to_delete_the_partner: "Unable to delete the partner." - associated_plan: "Associated plan" - groups: "Groups" - tags: "Tags" - authentication: "Authentication" - confirmation_required: "Confirmation required" - confirm_delete_member: "Do you really want to delete this member? This cannot be undone." - member_successfully_deleted: "Member successfully deleted." - unable_to_delete_the_member: "Unable to delete the member." - do_you_really_want_to_delete_this_administrator_this_cannot_be_undone: "Do you really want to delete this administrator? This cannot be undone." - this_may_take_a_while_please_wait: "Warning: this may take a while, please be patient." - administrator_successfully_deleted: "Administrator successfully deleted." - unable_to_delete_the_administrator: "Unable to delete the administrator." - changes_successfully_saved: "Changes successfully saved." - an_error_occurred_while_saving_changes: "An error occurred when saving changes." - export_is_running_you_ll_be_notified_when_its_ready: "Export is running. You'll be notified when it's ready." + users_management: "Användarhantering" + import: "Importera användare från CSV-fil" + users: "Användare" + members: "Medlemmar" + subscriptions: "Prenumerationer" + search_for_an_user: "Sök användare" + add_a_new_member: "Lägg till en ny medlem" + reservations: "Bokningar" + username: "Användarnamn" + surname: "Efternamn" + first_name: "Förnamn" + email: "E-post" + phone: "Telefon" + user_type: "Användartyp" + subscription: "Prenumeration" + display_more_users: "Visa fler medlemmar..." + administrators: "Administratörer" + search_for_an_administrator: "Sök efter administratör" + add_a_new_administrator: "Lägg till administratör" + managers: "Ansvariga" + managers_info: "En ansvarig är en begränsad administratör som inte kan ändra inställningarna i programmet. Den kommer dock att kunna ta bokningar för alla medlemmar och för alla ansvariga, inklusive sig själv, och behandla betalningar och återbetalningar." + search_for_a_manager: "Sök efter en ansvarig" + add_a_new_manager: "Lägg till en ny ansvarig" + delete_this_manager: "Vill du verkligen ta bort denna ansvariga? Detta kan inte ångras." + manager_successfully_deleted: "Ansvarig har tagits bort." + unable_to_delete_the_manager: "Det går inte att ta bort ansvarig." + partners: "Samarbetspartners" + partners_info: "En samarbetspartner är en speciell användare som kan associeras med planerna «Partner». Dessa användare kommer inte att kunna ansluta och kommer bara att få meddelanden om prenumerationer på deras tillhörande plan." + search_for_a_partner: "Sök efter en samarbetspartner" + add_a_new_partner: "Lägg till en ny samarbetspartner" + delete_this_partner: "Vill du verkligen ta bort denna partner? Detta kan inte ångras." + partner_successfully_deleted: "Samarbetspartnern har tagits bort." + unable_to_delete_the_partner: "Det går inte att ta bort samarbetspartnern." + associated_plan: "Associerad plan" + groups: "Grupper" + tags: "Taggar" + authentication: "Authentisering" + confirmation_required: "Bekräftelse krävs" + confirm_delete_member: "Vill du verkligen ta bort denna medlem? Detta kan inte ångras." + member_successfully_deleted: "Medlemmen har tagits bort." + unable_to_delete_the_member: "Det går inte att ta bort medlemmen." + do_you_really_want_to_delete_this_administrator_this_cannot_be_undone: "Vill du verkligen ta bort denna administratör? Detta kan inte ångras." + this_may_take_a_while_please_wait: "Varning: detta kan ta ett tag, var tålmodig." + administrator_successfully_deleted: "Administratören har tagits bort." + unable_to_delete_the_administrator: "Kunde inte ta bort administratören." + changes_successfully_saved: "Ändringar sparade." + an_error_occurred_while_saving_changes: "Ett fel uppstod när ändringarna skulle sparas." + export_is_running_you_ll_be_notified_when_its_ready: "Exporten körs. Du kommer att meddelas när den är klar." tag_form: - tags: "Tags" - add_a_tag: "Add a tag" - tag_name: "Tag name" - new_tag_successfully_saved: "New tag successfully saved." - an_error_occurred_while_saving_the_new_tag: "An error occurred while saving the new tag." - confirmation_required: "Delete this tag?" - confirm_delete_tag_html: "Do you really want to delete this tag?
Users and slots currently associated with this tag will be dissociated.
Warning: This cannot be undone!" - tag_successfully_deleted: "Tag successfully deleted." - an_error_occurred_and_the_tag_deletion_failed: "An error occurred and the tag deletion failed." + tags: "Taggar" + add_a_tag: "Lägg till en tagg" + tag_name: "Taggnamn" + new_tag_successfully_saved: "Ny tagg sparad." + an_error_occurred_while_saving_the_new_tag: "Ett fel inträffade när den nya taggen skulle sparas." + confirmation_required: "Ta bort denna tagg?" + confirm_delete_tag_html: "Vill du verkligen ta bort denna tagg?
Användare och platser som för närvarande är associerade med denna tagg kommer att separeras.
Varning: Detta kan inte ångras!" + tag_successfully_deleted: "Taggen har tagits bort." + an_error_occurred_and_the_tag_deletion_failed: "Ett fel inträffade och taggen raderades inte." authentication_form: - search_for_an_authentication_provider: "Search for an authentication provider" - add_a_new_authentication_provider: "Add a new authentication provider" - name: "Name" - strategy_name: "Strategy's name" - type: "Type" - state: "State" - unknown: "Unknown: " - active: "Active" - pending: "Pending" - previous_provider: "Previous provider" - confirmation_required: "Delete the provider?" - do_you_really_want_to_delete_the_TYPE_authentication_provider_NAME: "Do you really want to delete the {TYPE} authentication provider: {NAME}?" - authentication_provider_successfully_deleted: "Authentication provider successfully deleted." - an_error_occurred_unable_to_delete_the_specified_provider: "An error occurred: unable to delete the specified provider." - local_database: "Local database" + search_for_an_authentication_provider: "Sök efter en autentiseringsleverantör" + add_a_new_authentication_provider: "Lägg till en ny autentiseringsleverantör" + name: "Namn" + strategy_name: "Strategins namn" + type: "Typ" + state: "Län" + unknown: "Okänd: " + active: "Aktiv" + pending: "Väntar" + previous_provider: "Föregående leverantör" + confirmation_required: "Ta bort leverantören?" + do_you_really_want_to_delete_the_TYPE_authentication_provider_NAME: "Vill du verkligen ta bort {TYPE} autentiseringsleverantören: {NAME}?" + authentication_provider_successfully_deleted: "Autentiseringsleverantören har tagits bort." + an_error_occurred_unable_to_delete_the_specified_provider: "Ett fel inträffade: det går inte att ta bort den angivna leverantören." + local_database: "Lokal databas" o_auth2: "OAuth 2.0" openid_connect: "OpenID Connect" saml: "SAML" group_form: - add_a_group: "Add a group" - group_name: "Group name" - disable: "Disable" - enable: "Enable" - changes_successfully_saved: "Changes successfully saved." - an_error_occurred_while_saving_changes: "An error occurred when saving changes." - new_group_successfully_saved: "New group successfully saved." - an_error_occurred_when_saving_the_new_group: "An error occurred when saving the new group." - group_successfully_deleted: "Group successfully deleted." - unable_to_delete_group_because_some_users_and_or_groups_are_still_linked_to_it: "Unable to delete group because some users and/or groups are still linked to it." - group_successfully_enabled_disabled: "Group successfully {STATUS, select, true{disabled} other{enabled}}." - unable_to_enable_disable_group: "Unable to {STATUS, select, true{disable} other{enable}} group." - unable_to_disable_group_with_users: "Unable to disable group because it still contains {USERS} active {USERS, plural, =1{user} other{users}}." - status_enabled: "Enabled" - status_disabled: "Disabled" - status_all: "All" - member_filter_all: "All" - member_filter_not_confirmed: "Unconfirmed" - member_filter_inactive_for_3_years: "Inactive for 3 years" - member_filter_not_validated: "Not validated" + add_a_group: "Lägg till en grupp" + group_name: "Gruppnamn" + disable: "Inaktivera" + enable: "Aktivera" + changes_successfully_saved: "Ändringar sparade." + an_error_occurred_while_saving_changes: "Ett fel uppstod när ändringarna skulle sparas." + new_group_successfully_saved: "Ny grupp sparad." + an_error_occurred_when_saving_the_new_group: "Ett fel inträffade när den nya gruppen skulle sparas." + group_successfully_deleted: "Gruppen raderades." + unable_to_delete_group_because_some_users_and_or_groups_are_still_linked_to_it: "Det går inte att ta bort gruppen eftersom vissa användare och/eller grupper fortfarande är kopplade till den." + group_successfully_enabled_disabled: "Gruppen {STATUS, select, true{inaktiverad} other{aktiverad}}." + unable_to_enable_disable_group: "Det gick inte att {STATUS, select, true{inaktivera} other{aktivera}} grupp." + unable_to_disable_group_with_users: "Det går inte att inaktivera gruppen eftersom den fortfarande innehåller {USERS} aktiv {USERS, plural, one {}=1{användare} other{användare}}." + status_enabled: "Aktiverad" + status_disabled: "Inaktiverad" + status_all: "Alla" + member_filter_all: "Alla" + member_filter_not_confirmed: "Obekräftade" + member_filter_inactive_for_3_years: "Inaktiv i 3 år" + member_filter_not_validated: "Ej validerad" members_list_item: - item_type: "member" - surname: "Surname" - first_name: "First name" - phone: "Phone" - email: "Email" - group: "Group" - subscription: "Subscription" + item_type: "medlem" + surname: "Efternamn" + first_name: "Förnamn" + phone: "Telefon" + email: "E-post" + group: "Grupp" + subscription: "Prenumeration" #add a member members_new: - add_a_member: "Add a member" - user_is_an_organization: "User is an organization" - create_success: "Member successfully created" + add_a_member: "Lägg till medlem" + user_is_an_organization: "Användaren är en organisation" + create_success: "Medlemmen har skapats" #members bulk import members_import: - import_members: "Import members" - info: "You can upload a CSV file to create new members or update existing ones. Your file must user the identifiers below to specify the group, the trainings and the tags of the members." - required_fields: "Your file must contain, at least, the following information for each user to create: email, name, first name and group. If the password is empty, it will be generated. On updates, the empty fields will be kept as is." - about_example_html: "Please refer to the provided example file to generate a correct CSV file.
This example will:
  1. create a new member (Jean Dupont) with a generated password
  2. update the password of an existing membre (ID 43) using the new given password

Be careful to use Unicode UTF-8 encoding." - groups: "Groups" - group_name: "Group name" - group_identifier: "Identifier to use" - trainings: "Trainings" - training_name: "Training name" - training_identifier: "Identifier to use" - plans: "Plans" - plan_name: "Plan name" - plan_identifier: "Identifier to use" - tags: "Tags" - tag_name: "Tag name" - tag_identifier: "Identifier to use" - download_example: "Example file" - select_file: "Choose a file" - import: "Import" - update_field: "Reference field for users to update" + import_members: "Importera medlemmar" + info: "Du kan ladda upp en CSV-fil för att skapa nya medlemmar eller uppdatera befintliga. Filen måste ange identifierarna nedan för att ange gruppen, utbildningarna och medlemmarnas taggar." + required_fields: "Din fil måste åtminstone innehålla följande information för varje användare att skapa: e-post, namn, förnamn och grupp. Om lösenordet är tomt kommer det att genereras. Vid uppdateringar kommer de tomma fälten att behållas som de är." + about_example_html: "Se den angivna exempelfilen för att generera en korrekt CSV-fil.
Detta exempel kommer:
  1. skapa en ny medlem (Jean Dupont) med ett genererat lösenord
  2. uppdatera lösenordet för en befintlig medlem (ID 43) med det nya givna lösenordet

Var försiktig med att använda Unicode UTF-8 kodning." + groups: "Grupper" + group_name: "Gruppnamn" + group_identifier: "Identifierare att använda" + trainings: "Utbildningar" + training_name: "Utbildningsnamn" + training_identifier: "Identifierare att använda" + plans: "Planer" + plan_name: "Namn på plan" + plan_identifier: "Identifierare att använda" + tags: "Taggar" + tag_name: "Taggnamn" + tag_identifier: "Identifierare att använda" + download_example: "Exempelfil" + select_file: "Välj en fil" + import: "Importera" + update_field: "Referensfält för användare att uppdatera" update_on_id: "ID" - update_on_username: "Username" - update_on_email: "Email address" + update_on_username: "Användarnamn" + update_on_email: "E-postadress" #import results members_import_result: - import_results: "Import results" - import_details: "Import # {ID}, of {DATE}, initiated by {USER}" - results: "Results" - pending: "Pending..." - status_create: "Creating a new user" - status_update: "Updating user {ID}" - success: "Success" - failed: "Failed" - error_details: "Error's details:" + import_results: "Importera resultat" + import_details: "Import # {ID}, av {DATE}, initierat av {USER}" + results: "Resultat" + pending: "Väntar..." + status_create: "Skapa en ny användare" + status_update: "Uppdaterar användare {ID}" + success: "Lyckades" + failed: "Misslyckades" + error_details: "Felinformation:" user_validation: - validate_member_success: "Member successfully validated" - invalidate_member_success: "Member successfully invalidated" - validate_member_error: "An unexpected error occurred: unable to validate this member." - invalidate_member_error: "An unexpected error occurred: unable to invalidate this member." - validate_account: "Validate the account" + validate_member_success: "Medlemmen har validerats" + invalidate_member_success: "Medlemmen har ogiltigförklarats" + validate_member_error: "Ett oväntat fel inträffade: det går inte att validera medlemmen." + invalidate_member_error: "Ett oväntat fel inträffade: det går inte att ogiltigförklara denna medlem." + validate_account: "Validera kontot" child_validation: - validate_child_success: "Child successfully validated" - invalidate_child_success: "Child successfully invalidated" - validate_child_error: "An unexpected error occurred: unable to validate this child." - invalidate_child_error: "An unexpected error occurred: unable to invalidate this child." - validate_child: "Validate the child" + validate_child_success: "Barnet har validerats" + invalidate_child_success: "Barnet har ogiltigförklarats" + validate_child_error: "Ett oväntat fel inträffade: det gick inte att validera detta barn." + invalidate_child_error: "Ett oväntat fel inträffade: det går inte att ogiltigförklara detta barn." + validate_child: "Validera barnet" supporting_documents_refusal_form: - refusal_comment: "Comment" - comment_placeholder: "Please type a comment here" + refusal_comment: "Kommentar" + comment_placeholder: "Skriv en kommentar här" supporting_documents_refusal_modal: - title: "Refuse some supporting documents" - refusal_successfully_sent: "The refusal has been successfully sent." - unable_to_send: "Unable to refuse the supporting documents: " - confirm: "Confirm" + title: "Neka underlag" + refusal_successfully_sent: "Vägran har skickats." + unable_to_send: "Det går inte att neka underlagen: " + confirm: "Bekräfta" supporting_documents_validation: - title: "Supporting documents" - find_below_documents_files: "You will find below the supporting documents submitted by the member." - to_complete: "To complete" - refuse_documents: "Refusing the documents" - refuse_documents_info: "After verification, you may notify the member that the evidence submitted is not acceptable. You can specify the reasons for your refusal and indicate the actions to be taken. The member will be notified by e-mail." + title: "Underlag" + find_below_documents_files: "Nedan hittar du underlag som lämnats in av medlemmen." + to_complete: "Att slutföra" + refuse_documents: "Avböj dokumenten" + refuse_documents_info: "Efter verifiering kan du meddela medlemmen att de bevis som lämnats in inte är acceptabla. Du kan ange skälen till din vägran och ange vilka åtgärder som ska vidtas. Medlemmen kommer att meddelas via e-post." change_role_modal: - change_role: "Change role" - warning_role_change: "

Warning: changing the role of a user is not a harmless operation.

  • Members can only book reservations for themselves, paying by card or wallet.
  • Managers can book reservations for themselves, paying by card or wallet, and for other members and managers, by collecting payments at the checkout.
  • Administrators as managers, they can book reservations for themselves and for others. Moreover, they can change every settings of the application.
" - new_role: "New role" - admin: "Administrator" - manager: "Manager" - member: "Member" - new_group: "New group" - new_group_help: "Users with a running subscription cannot be changed from their current group." - confirm: "Change role" - role_changed: "Role successfully changed from {OLD} to {NEW}." - error_while_changing_role: "An error occurred while changing the role. Please try again later." + change_role: "Ändra roll" + warning_role_change: "

Varning: ändra en användares roll är inte en harmlös operation.

  • Medlemmar kan bara boka bokningar för sig själva, betala med kort eller plånbok.
  • Ansvariga kan boka bokningar för sig själva, betala med kort eller plånbok, och för andra medlemmar och ansvariga, genom att samla in betalningar i kassan.
  • Administratörer har samma behörighet som ansvariga, de kan boka reservationer för sig själva och för andra. Dessutom kan de ändra alla inställningar i programmet.
" + new_role: "Ny roll" + admin: "Administratör" + manager: "Ansvarig" + member: "Medlem" + new_group: "Ny grupp" + new_group_help: "Användare med en pågående prenumeration kan inte ändras från deras nuvarande grupp." + confirm: "Ändra roll" + role_changed: "Rollen har ändrats från {OLD} till {NEW}." + error_while_changing_role: "Ett fel inträffade när rollen skulle ändras. Försök igen senare." #edit a member members_edit: - subscription: "Subscription" - reservations: "Reservations" - duration: "Duration:" - expires_at: "Expires at:" - price_: "Price:" - offer_free_days: "Offer free days" - renew_subscription: "Renew the subscription" - cancel_subscription: "Cancel the subscription" - user_has_no_current_subscription: "User has no current subscription." - subscribe_to_a_plan: "Subscribe to a plan" - trainings: "Trainings" - no_trainings: "No trainings" - next_trainings: "Next trainings" - passed_trainings: "Passed trainings" - validated_trainings: "Validated trainings" - events: "Events" - next_events: "Next events" - no_upcoming_events: "No upcoming events" - NUMBER_full_price_tickets_reserved: "{NUMBER, plural, =0{} one{1 full price ticket reserved} other{{NUMBER} full price tickets reserved}}" - NUMBER_NAME_tickets_reserved: "{NUMBER, plural, =0{} one{1 {NAME} ticket reserved} other{{NUMBER} {NAME} tickets reserved}}" - passed_events: "Passed events" - no_passed_events: "No passed events" - invoices: "Invoices" - invoice_num: "Invoice #" - date: "Date" - price: "Price" - download_the_invoice: "Download the invoice" - download_the_refund_invoice: "Download the refund invoice" - no_invoices_for_now: "No invoices for now." - you_successfully_changed_the_expiration_date_of_the_user_s_subscription: "You successfully changed the expiration date of the user's subscription" - a_problem_occurred_while_saving_the_date: "A problem occurred while saving the date." - new_subscription: "New subscription" - you_are_about_to_purchase_a_subscription_to_NAME: "You are about to purchase a subscription to {NAME}." - with_schedule: "Subscribe with a monthly payment schedule" - subscription_successfully_purchased: "Subscription successfully purchased." - a_problem_occurred_while_taking_the_subscription: "A problem occurred while taking the subscription" - wallet: "Wallet" - to_credit: 'Credit' - cannot_credit_own_wallet: "You cannot credit your own wallet. Please ask another manager or an administrator to credit your wallet." - cannot_extend_own_subscription: "You cannot extend your own subscription. Please ask another manager or an administrator to extend your subscription." - update_success: "Member's profile successfully updated" - my_documents: "My documents" - save: "Save" - confirm: "Confirm" - cancel: "Cancel" - validate_account: "Validate the account" - validate_member_success: "The member is validated" - invalidate_member_success: "The member is invalidated" - validate_member_error: "An error occurred: impossible to validate from this member." - invalidate_member_error: "An error occurred: impossible to invalidate from this member." - supporting_documents: "Supporting documents" - change_role: "Change role" + subscription: "Prenumeration" + reservations: "Bokningar" + duration: "Varaktighet:" + expires_at: "Förfaller den:" + price_: "Pris:" + offer_free_days: "Erbjud gratis dagar" + renew_subscription: "Förnya prenumerationen" + cancel_subscription: "Avsluta prenumerationen" + user_has_no_current_subscription: "Användaren har ingen aktuell prenumeration." + subscribe_to_a_plan: "Teckna prenumeration" + trainings: "Utbildningar" + no_trainings: "Inga utbildningar" + next_trainings: "Kommande utbildningar" + passed_trainings: "Godkända utbildningar" + validated_trainings: "Validerade utbildningar" + events: "Evenemang" + next_events: "Kommande evenemang" + no_upcoming_events: "Inga kommande evenemang" + NUMBER_full_price_tickets_reserved: "{NUMBER, plural, =0{} one{1 biljett till fullt pris reserverad} other{{NUMBER} biljetter till fullt pris reserverade}}" + NUMBER_NAME_tickets_reserved: "{NUMBER, plural, =0{} one{1 {NAME} biljett reserverad} other{{NUMBER} {NAME} biljetter reserverade}}" + passed_events: "Tidigare evenemang" + no_passed_events: "Inga tidigare evenemang" + invoices: "Fakturor" + invoice_num: "Fakturanr" + date: "Datum" + price: "Pris" + download_the_invoice: "Hämta faktura" + download_the_refund_invoice: "Hämta kreditnota" + no_invoices_for_now: "Inga fakturor för tillfället." + you_successfully_changed_the_expiration_date_of_the_user_s_subscription: "Du har ändrat utgångsdatumet för användarens prenumeration" + a_problem_occurred_while_saving_the_date: "Ett problem uppstod när datumet skulle sparas." + new_subscription: "Ny prenumeration" + you_are_about_to_purchase_a_subscription_to_NAME: "Du är på väg att köpa en prenumeration till {NAME}." + with_schedule: "Prenumerera med en månatlig betalningsschema" + subscription_successfully_purchased: "Prenumerationen har köpts." + a_problem_occurred_while_taking_the_subscription: "Ett problem uppstod när prenumerationen beställdes" + wallet: "Plånbok" + to_credit: 'Kredit' + cannot_credit_own_wallet: "Du kan inte kreditera din egen plånbok. Be en annan ansvarig eller administratör att kreditera din plånbok." + cannot_extend_own_subscription: "Du kan inte förlänga ditt eget abonnemang. Be en annan ansvarig eller administratör att förlänga ditt abonnemang." + update_success: "Medlemmens profil har uppdaterats" + my_documents: "Mina dokument" + save: "Spara" + confirm: "Bekräfta" + cancel: "Avbryt" + validate_account: "Validera kontot" + validate_member_success: "Medlemmen är validerad" + invalidate_member_success: "Medlemmen är ogiltig" + validate_member_error: "Ett fel uppstod: omöjligt att validera från denna medlem." + invalidate_member_error: "Ett fel uppstod: omöjligt att ogiltigförklara från denna medlem." + supporting_documents: "Underlag" + change_role: "Ändra roll" #extend a subscription for free free_extend_modal: - extend_subscription: "Extend the subscription" - offer_free_days_infos: "You are about to extend the user's subscription by offering him free additional days." - credits_will_remain_unchanged: "The balance of free credits (training / machines / spaces) of the user will remain unchanged." - current_expiration: "Current subscription will expire at:" + extend_subscription: "Förläng prenumeration" + offer_free_days_infos: "Du är på väg att förlänga användarens prenumeration genom att erbjuda ytterligare dagar gratis." + credits_will_remain_unchanged: "Saldot av gratispoäng (utbildning / utrustning / lokaler) för användaren kommer att förbli oförändrat." + current_expiration: "Nuvarande abonnemang löper ut den:" DATE_TIME: "{DATE} {TIME}" - new_expiration_date: "New expiration date:" - number_of_free_days: "Number of free days:" - extend: "Extend" - extend_success: "The subscription was successfully extended for free" + new_expiration_date: "Nytt utgångsdatum:" + number_of_free_days: "Antal gratisdagar:" + extend: "Förläng" + extend_success: "Prenumerationen har förlängts utan kostnad" #renew a subscription renew_modal: - renew_subscription: "Renew the subscription" - renew_subscription_info: "You are about to renew the user's subscription by charging him again for his current subscription." - credits_will_be_reset: "The balance of free credits (training / machines / spaces) of the user will be reset, unused credits will be lost." - current_expiration: "Current subscription will expire at:" - new_start: "The new subscription will start at:" - new_expiration_date: "The new subscription will expire at:" - pay_in_one_go: "Pay in one go" - renew: "Renew" - renew_success: "The subscription was successfully renewed" + renew_subscription: "Förnya prenumeration" + renew_subscription_info: "Du är på väg att förnya användarens abonnemang genom att debitera för dess nuvarande abonnemang." + credits_will_be_reset: "Balansen av fria krediter (utbildning / utrustning / lokaler) för användaren kommer att återställas, outnyttjade krediter kommer att förloras." + current_expiration: "Nuvarande abonnemang löper ut den:" + new_start: "Den nya prenumerationen börjar den:" + new_expiration_date: "Den nya prenumerationen löper ut den:" + pay_in_one_go: "Betala på en gång" + renew: "Förnya" + renew_success: "Prenumerationen har förnyats" DATE_TIME: "{DATE} {TIME}" #take a new subscription subscribe_modal: - subscribe_USER: "Subscribe {USER}" - subscribe: "Subscribe" - select_plan: "Please select a plan" - pay_in_one_go: "Pay in one go" - subscription_success: "Subscription successfully subscribed" + subscribe_USER: "Prenumerera på {USER}" + subscribe: "Prenumerera" + select_plan: "Välj en plan" + pay_in_one_go: "Betala på en gång" + subscription_success: "Prenumeration är aktiverad" #cancel the current subscription cancel_subscription_modal: - title: "Confirmation required" - confirmation_html: "You are about to cancel the subscription {NAME} of this user. From now, he won't be able to benefit from the advantages of this subscription, and all his unused credits will be lost. Are your sure?" - confirm: "Cancel this subscription" - subscription_canceled: "The subscription was successfully canceled." + title: "Bekräftelse krävs" + confirmation_html: "Du håller på att avbryta prenumerationen {NAME} för den här användaren. Från och med nu kommer den inte att kunna dra nytta av fördelarna med detta abonnemang, och alla dess outnyttjade krediter kommer att gå förlorade. Är du säker?" + confirm: "Avbryt prenumeration" + subscription_canceled: "Prenumerationen har avbrutits." #add a new administrator to the platform admins_new: - add_an_administrator: "Add an administrator" - administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Successful creation. Connection directives were sent to the new administrator by e-mail." - failed_to_create_admin: "Unable to create the administrator:" + add_an_administrator: "Lägg till administratör" + administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Anslutningsdirektiven skickades till den nya administratören via e-post." + failed_to_create_admin: "Det gick inte att skapa administratören:" man: "Man" - woman: "Woman" + woman: "Kvinna" pseudonym: "Pseudonym" - pseudonym_is_required: "Pseudonym is required." - first_name: "First name" - first_name_is_required: "First name is required." - surname: "Last name" - surname_is_required: "Last name is required." - email_address: "Email address" - email_is_required: "Email address is required." - birth_date: "Date of birth" - address: "Address" - phone_number: "Phone number" + pseudonym_is_required: "Pseudonym krävs." + first_name: "Förnamn" + first_name_is_required: "Förnamn måste fyllas i." + surname: "Efternamn" + surname_is_required: "Efternamn måste fyllas i." + email_address: "E-postadress" + email_is_required: "E-postadress krävs." + birth_date: "Födelsedatum" + address: "Adress" + phone_number: "Telefonnummer" #add a new manager to the platform manager_new: - add_a_manager: "Add a manager" - manager_successfully_created: "Successful creation. Connection directives were sent to the new manager by e-mail." - failed_to_create_manager: "Unable to create the manager:" + add_a_manager: "Lägg till en ny ansvarig" + manager_successfully_created: "Anslutningsdirektiven skickades till den nya ansvariga via e-post." + failed_to_create_manager: "Det går inte att ta bort ansvarig:" man: "Man" - woman: "Woman" + woman: "Kvinna" pseudonym: "Pseudonym" - pseudonym_is_required: "Pseudonym is required." - first_name: "First name" - first_name_is_required: "First name is required." - surname: "Last name" - surname_is_required: "Last name is required." - email_address: "Email address" - email_is_required: "Email address is required." - birth_date: "Date of birth" - address: "Address" - phone_number: "Phone number" + pseudonym_is_required: "Pseudonym krävs." + first_name: "Förnamn" + first_name_is_required: "Förnamn måste fyllas i." + surname: "Efternamn" + surname_is_required: "Efternamn måste fyllas i." + email_address: "E-postadress" + email_is_required: "E-postadress krävs." + birth_date: "Födelsedatum" + address: "Adress" + phone_number: "Telefonnummer" #authentication providers (SSO) components authentication: boolean_mapping_form: - mappings: "Mappings" - true_value: "True value" - false_value: "False value" + mappings: "Kopplingar" + true_value: "Verkligt värde" + false_value: "Falskt värde" date_mapping_form: - input_format: "Input format" - date_format: "Date format" + input_format: "Inmatningsformat" + date_format: "Datumformat" integer_mapping_form: - mappings: "Mappings" - mapping_from: "From" - mapping_to: "To" + mappings: "Kopplingar" + mapping_from: "Från" + mapping_to: "Till" string_mapping_form: - mappings: "Mappings" - mapping_from: "From" - mapping_to: "To" + mappings: "Kopplingar" + mapping_from: "Från" + mapping_to: "Till" data_mapping_form: - define_the_fields_mapping: "Define the fields mapping" - add_a_match: "Add a match" - model: "Model" - field: "Field" - data_mapping: "Data mapping" + define_the_fields_mapping: "Definiera fältkopplingar" + add_a_match: "Lägg till en träff" + model: "Modell" + field: "Fält" + data_mapping: "Datakoppling" oauth2_data_mapping_form: - api_endpoint_url: "API endpoint or URL" - api_type: "API type" - api_field: "API field" - api_field_help_html: 'JsonPath syntax is supported.
If many fields are selected, the first one will be used.
Example: $.data[*].name' + api_endpoint_url: "API slutpunkt eller URL" + api_type: "API-typ" + api_field: "API-fält" + api_field_help_html: 'JsonPath syntax stöds.
Om många fält väljs kommer den första att användas.
Exempel: $.data[*].name' openid_connect_data_mapping_form: - api_field: "Userinfo claim" - api_field_help_html: 'Set the field providing the corresponding data through the userinfo endpoint.
JsonPath syntax is supported. If many fields are selected, the first one will be used.
Example: $.data[*].name' - openid_standard_configuration: "Use the OpenID standard configuration" + api_field: "Anspråk för användarinformation" + api_field_help_html: 'Ange fältet som avser motsvarande data genom Ändpunkt för användarinfo.
JsonPath syntax stöds. Om många fält väljs kommer den första att användas.
Exempel: $.data[*].name' + openid_standard_configuration: "Använd OpenID standardkonfiguration" saml_data_mapping_form: - api_field: "Userinfo field" - api_field_help_html: "Set the field providing the corresponding data through the SAML assertion.
If many fields are selected, the first one will be used.
Example: $.data[*].name" - openid_standard_configuration: "Use the SAML standard configuration" + api_field: "Användarinfo fält" + api_field_help_html: "Ställ in fältet som ger motsvarande data genom SAML-assertion.
Om många fält väljs kommer den första att användas.
Exempel: $.data[*].name" + openid_standard_configuration: "Använd SAML-standardkonfiguration" type_mapping_modal: - data_mapping: "Data mapping" - TYPE_expected: "{TYPE} expected" + data_mapping: "Datakoppling" + TYPE_expected: "{TYPE} förväntat" types: - integer: "integer" - string: "string" + integer: "heltal" + string: "sträng" text: "text" - date: "date" - boolean: "boolean" + date: "datum" + boolean: "boolesk" oauth2_form: - authorization_callback_url: "Authorization callback URL" - common_url: "Server root URL" - authorization_endpoint: "Authorization endpoint" - token_acquisition_endpoint: "Token acquisition endpoint" - profile_edition_url: "Profil edition URL" - profile_edition_url_help: "The URL of the page where the user can edit his profile." + authorization_callback_url: "URL för auktoriseringscallback" + common_url: "Server root-URL" + authorization_endpoint: "Ändpunkt för auktorisering" + token_acquisition_endpoint: "Ändpunkt för Token acquisition" + profile_edition_url: "URL för Profilutgåva" + profile_edition_url_help: "URL till sidan där användaren kan redigera sin profil." client_identifier: "Client identifier" - client_secret: "Client secret" - scopes: "Scopes" + client_secret: "Klient-hemlighet" + scopes: "Omfång" openid_connect_form: - issuer: "Issuer" - issuer_help: "Root url for the authorization server." + issuer: "Utfärdare" + issuer_help: "Root url för auktoriseringsservern." discovery: "Discovery" - discovery_help: "Should OpenID discovery be used. This is recommended if the IDP provides a discovery endpoint." - discovery_unavailable: "Discovery is unavailable for the configured issuer." - discovery_enabled: "Enable discovery" - discovery_disabled: "Disable discovery" - client_auth_method: "Client authentication method" - client_auth_method_help: "Which authentication method to use to authenticate Fab-manager with the authorization server." - client_auth_method_basic: "Basic" + discovery_help: "Om OpenID discovery används. Detta rekommenderas om IDP: n tillhandahåller en discovery-ändpunkt." + discovery_unavailable: "Discovery är inte tillgänglig för den konfigurerade utfärdaren." + discovery_enabled: "Aktivera discovery" + discovery_disabled: "Inaktivera discovery" + client_auth_method: "Kundens autentiseringsmetod" + client_auth_method_help: "Vilken autentiseringsmetod att använda för att autentisera Fab-manager med auktoriseringsservern." + client_auth_method_basic: "Grundläggande" client_auth_method_jwks: "JWKS" - scope: "Scope" - scope_help_html: "Which OpenID scopes to include (openid is always required).
If Discovery is enabled, the available scopes will be automatically proposed." - prompt: "Prompt" - prompt_help_html: "Which OpenID pages the user will be shown.
None - no authentication or consent user interface pages are shown.
Login - the authorization server prompt the user for reauthentication.
Consent - the authorization server prompt the user for consent before returning information to Fab-manager.
Select account - the authorization server prompt the user to select a user account." - prompt_none: "None" - prompt_login: "Login" - prompt_consent: "Consent" - prompt_select_account: "Select account" - send_scope_to_token_endpoint: "Send scope to token endpoint?" - send_scope_to_token_endpoint_help: "Should the scope parameter be sent to the authorization token endpoint?" - send_scope_to_token_endpoint_false: "No" - send_scope_to_token_endpoint_true: "Yes" - profile_edition_url: "Profil edition URL" - profile_edition_url_help: "The URL of the page where the user can edit his profile." - client_options: "Client options" - client__identifier: "Identifier" - client__secret: "Secret" - client__authorization_endpoint: "Authorization endpoint" - client__token_endpoint: "Token endpoint" - client__userinfo_endpoint: "Userinfo endpoint" + scope: "Omfattning" + scope_help_html: "Vilka OpenID scope (openid krävs alltid).
Om Discovery är aktiverad, kommer de tillgängliga omfattningarna att automatiskt föreslås." + prompt: "Fråga" + prompt_help_html: "Vilka OpenID-sidor användaren kommer att visas.
Ingen - inga sidor med autentisering eller samtycke visas.
Logga in - auktoriseringsservern uppmanar användaren till återautentisering.
Samtycke - auktoriseringsservern uppmanar användaren att godkänna innan information skickas tillbaka till Fab-manager.
Välj konto - behörighetsservern uppmanar användaren att välja ett användarkonto." + prompt_none: "Inget" + prompt_login: "Logga in" + prompt_consent: "Samtycke" + prompt_select_account: "Välj konto" + send_scope_to_token_endpoint: "Skicka urval till ändpunkt?" + send_scope_to_token_endpoint_help: "Borde omfattningsparametern skickas till auktoriseringsändpunkt?" + send_scope_to_token_endpoint_false: "Nej" + send_scope_to_token_endpoint_true: "Ja" + profile_edition_url: "URL för Profilutgåva" + profile_edition_url_help: "URL till sidan där användaren kan redigera sin profil." + client_options: "Klient alternativ" + client__identifier: "Identifierare" + client__secret: "Hemlighet" + client__authorization_endpoint: "Ändpunkt för auktorisering" + client__token_endpoint: "Ändpunkt för token" + client__userinfo_endpoint: "Ändpunkt för användarinfo" client__jwks_uri: "JWKS URI" - client__end_session_endpoint: "End session endpoint" - client__end_session_endpoint_help: "The url to call to log the user out at the authorization server." - extra_authorize_params: "Extra authorize parameters" - extra_authorize_params_help: "A hash of extra fixed parameters that will be merged to the authorization request" + client__end_session_endpoint: "Ändpunkt för sessionen" + client__end_session_endpoint_help: "Webbadressen att anropa för att logga ut användaren från auktoriseringsservern." + extra_authorize_params: "Extra auktorisationsparametrar" + extra_authorize_params_help: "En hash av extra fasta parametrar som kommer att slås samman med behörighetsbegäran" saml_form: - authorization_callback_url: "Authorization callback URL" - sp_entity_id: "Service provider entity ID" - sp_entity_id_help: "The name of your application. Some identity providers might need this to establish the identity of the service provider requesting the login." - idp_sso_service_url: "Identity provider SSO service URL" - idp_sso_service_url_help: "The URL to which the authentication request should be sent. This would be on the identity provider." - idp_cert_fingerprint: "Identity provider certificate fingerprint" - idp_cert: "Identity provider certificate" - profile_edition_url: "Profil edition URL" - profile_edition_url_help: "The URL of the page where the user can edit his profile." + authorization_callback_url: "URL för auktoriseringscallback" + sp_entity_id: "Tjänsteleverantörens entitets-ID" + sp_entity_id_help: "Namnet på din ansökan. Vissa identitetsleverantörer kan behöva detta för att fastställa identiteten hos den tjänsteleverantör som begär inloggningen." + idp_sso_service_url: "Identitetsleverantör SSO-tjänst-URL" + idp_sso_service_url_help: "URL till vilken autentiseringsbegäran ska skickas. Detta ska vara hos identitetsleverantören." + idp_cert_fingerprint: "Identitetsleverantörens certifikatfingeravtryck" + idp_cert: "Identitetsleverantörens certifikat" + profile_edition_url: "URL för Profilutgåva" + profile_edition_url_help: "URL till sidan där användaren kan redigera sin profil." provider_form: - name: "Name" - authentication_type: "Authentication type" - save: "Save" - create_success: "Authentication provider created" - update_success: "Authentication provider updated" + name: "Namn" + authentication_type: "Autentiseringstyp" + save: "Spara" + create_success: "Autentiseringsleverantör skapad" + update_success: "Autentiseringsleverantör uppdaterad" methods: - local_database: "Local database" + local_database: "Lokal databas" oauth2: "OAuth 2.0" openid_connect: "OpenID Connect" saml: "SAML" #create a new authentication provider (SSO) authentication_new: - add_a_new_authentication_provider: "Add a new authentication provider" + add_a_new_authentication_provider: "Lägg till en ny autentiseringsleverantör" #edit an authentication provider (SSO) authentication_edit: - provider: "Provider:" + provider: "Leverantör:" #statistics tables statistics: - statistics: "Statistics" - evolution: "Evolution" - age_filter: "Age filter" - from_age: "From" #e.g. from 8 to 40 years old - to_age: "to" #e.g. from 8 to 40 years old + statistics: "Statistik" + evolution: "Utveckling" + age_filter: "Åldersfilter" + from_age: "Från" #e.g. from 8 to 40 years old + to_age: "till" #e.g. from 8 to 40 years old start: "Start:" - end: "End:" - custom_filter: "Custom filter" - NO_: "NO" - criterion: "Criterion:" - value: "Value:" - exclude: "Exclude" - from_date: "From" #eg: from 01/01 to 01/05 - to_date: "to" #eg: from 01/01 to 01/05 - entries: "Entries:" - revenue_: "Revenue:" - average_age: "Average age:" - years_old: "years old" - total: "Total" - available_hours: "Hours available for booking:" - available_tickets: "Tickets available for booking:" - date: "Date" - reservation_date: "Reservation date" - user: "User" - gender: "Gender" - age: "Age" - type: "Type" - revenue: "Revenue" - unknown: "Unknown" - user_id: "User ID" - display_more_results: "Display more results" - export_statistics_to_excel: "Export statistics to Excel" - export_all_statistics: "Export all statistics" - export_the_current_search_results: "Export the current search results" - export: "Export" - deleted_user: "Deleted user" + end: "Slut:" + custom_filter: "Anpassat filter" + NO_: "NEJ" + criterion: "Kriterium:" + value: "Värde:" + exclude: "Exkludera" + from_date: "Från" #eg: from 01/01 to 01/05 + to_date: "till" #eg: from 01/01 to 01/05 + entries: "Inlägg:" + revenue_: "Intäkter:" + average_age: "Medelålder:" + years_old: "år gammal" + total: "Totalt" + available_hours: "Tider tillgängliga för bokning:" + available_tickets: "Biljetter tillgängliga för bokning:" + date: "Datum" + reservation_date: "Bokningsdatum" + user: "Användare" + gender: "Kön" + age: "Ålder" + type: "Typ" + revenue: "Intäkter" + unknown: "Okänd" + user_id: "Användar-ID" + display_more_results: "Visa fler resultat" + export_statistics_to_excel: "Exportera statistik till Excel" + export_all_statistics: "Exportera all statistik" + export_the_current_search_results: "Exportera nuvarande sökresultat" + export: "Exportera" + deleted_user: "Raderad användare" man: "Man" - woman: "Woman" - export_is_running_you_ll_be_notified_when_its_ready: "Export is running. You'll be notified when it's ready." - create_plans_to_start: "Start by creating new subscription plans." - click_here: "Click here to create your first one." - average_cart: "Average cart:" - reservation_context: Reservation context - project_author: Author + woman: "Kvinna" + export_is_running_you_ll_be_notified_when_its_ready: "Exporten körs. Du kommer att meddelas när den är klar." + create_plans_to_start: "Börja med att skapa nya prenumerationsplaner." + click_here: "Klicka här för att skapa din första." + average_cart: "Genomsnittlig varukorg:" + reservation_context: Kontext för bokning + project_author: Upphovsman #statistics graphs stats_graphs: - statistics: "Statistics" + statistics: "Statistik" data: "Data" - day: "Day" - week: "Week" - from_date: "From" #eg: from 01/01 to 01/05 - to_date: "to" #eg: from 01/01 to 01/05 - month: "Month" + day: "Dag" + week: "Vecka" + from_date: "Från" #eg: from 01/01 to 01/05 + to_date: "till" #eg: from 01/01 to 01/05 + month: "Månad" start: "Start:" - end: "End:" - type: "Type" - revenue: "Revenue" - top_list_of: "Top list of" - number: "Number" - week_short: "Week" - week_of_START_to_END: "Week of {START} to {END}" - no_data_for_this_period: "No data for this period" - date: "Date" + end: "Slut:" + type: "Typ" + revenue: "Intäkter" + top_list_of: "Topplista över" + number: "Nummer" + week_short: "Vecka" + week_of_START_to_END: "Vecka {START} till {END}" + no_data_for_this_period: "Ingen data för denna period" + date: "Datum" boolean_setting: - customization_of_SETTING_successfully_saved: "Customization of the {SETTING} successfully saved." - error_SETTING_locked: "Unable to update the setting: {SETTING} is locked. Please contact your system administrator." - an_error_occurred_saving_the_setting: "An error occurred while saving the setting. Please try again later." - save: "save" + customization_of_SETTING_successfully_saved: "Anpassning av {SETTING} har sparats." + error_SETTING_locked: "Det går inte att uppdatera inställningen: {SETTING} är låst. Kontakta din systemadministratör." + an_error_occurred_saving_the_setting: "Ett fel inträffade när inställningen skulle sparas. Försök igen senare." + save: "spara" #global application parameters and customization settings: - customize_the_application: "Customize the application" - fablab_name: "FabLab name" - about: "About" - customize_information_messages: "Customize information messages" - message_of_the_machine_booking_page: "Message of the machine booking page:" - type_the_message_content: "Type the message content" - warning_message_of_the_training_booking_page: "Warning message of the training booking page:" - information_message_of_the_training_reservation_page: "Information message of the training reservation page:" - message_of_the_subscriptions_page: "Message of the subscriptions page:" - message_of_the_events_page: "Message of the events page:" - message_of_the_spaces_page: "Message of the spaces page:" - legal_documents: "Legal documents" - if_these_documents_are_not_filled_no_consent_about_them_will_be_asked_to_the_user: "If these documents are not filled, no consent about them will be asked." - general_terms_and_conditions: "General terms and conditions (T&C)" - terms_of_service: "Terms of service (TOS)" - customize_the_graphics: "Customize the graphics" - for_an_optimal_rendering_the_logo_image_must_be_at_the_PNG_format_with_a_transparent_background_and_with_an_aspect_ratio_3.5_times_wider_than_the_height: "For an optimal rendering, the logo image must be at the PNG format with a transparent background and an aspect ratio 3.5 wider than the height." - concerning_the_favicon_it_must_be_at_ICO_format_with_a_size_of_16x16_pixels: "Concerning the favicon, it must be at ICO format with a size of 16x16 pixels." - remember_to_refresh_the_page_for_the_changes_to_take_effect: "Remember to refresh the page for the changes to take effect." - logo_white_background: "Logo (white background)" - change_the_logo: "Change the logo" - logo_black_background: "Logo (black background)" + customize_the_application: "Anpassa programmet" + fablab_name: "FabLab namn" + about: "Om" + customize_information_messages: "Anpassa informationsmeddelanden" + message_of_the_machine_booking_page: "Meddelande på sidan för bokning av maskinen:" + type_the_message_content: "Skriv meddelandets innehåll" + warning_message_of_the_training_booking_page: "Varningsmeddelande på utbildningsbokningen:" + information_message_of_the_training_reservation_page: "Förklaringsmeddelande på bokningssidan för utbildningar:" + message_of_the_subscriptions_page: "Meddelande på sidan för prenumerationer:" + message_of_the_events_page: "Meddelande på evenemangssidan:" + message_of_the_spaces_page: "Meddelande på sidan för lokaler:" + legal_documents: "Juridiska dokument" + if_these_documents_are_not_filled_no_consent_about_them_will_be_asked_to_the_user: "Om dessa dokument inte fylls i kommer inget samtycke om dem att tillfrågas." + general_terms_and_conditions: "Allmänna villkor" + terms_of_service: "Villkor för tjänsten (TOS)" + customize_the_graphics: "Anpassa grafiken" + for_an_optimal_rendering_the_logo_image_must_be_at_the_PNG_format_with_a_transparent_background_and_with_an_aspect_ratio_3.5_times_wider_than_the_height: "För en optimal rendering måste logotypbilden vara i PNG-format med en transparent bakgrund och ett bildförhållande med bredden 3.5 x höjden." + concerning_the_favicon_it_must_be_at_ICO_format_with_a_size_of_16x16_pixels: "Angående faviconen måste den vara på ICO-format med en storlek på 16x16 pixlar." + remember_to_refresh_the_page_for_the_changes_to_take_effect: "Kom ihåg att uppdatera sidan för att ändringarna ska träda i kraft." + logo_white_background: "Logotyp (vit bakgrund)" + change_the_logo: "Ändra logotyp" + logo_black_background: "Logotyp (svart bakgrund)" favicon: "Favicon" - change_the_favicon: "Change the favicon" - main_colour: "Main colour:" - primary: "Primary" - secondary_colour: "Secondary colour:" - secondary: "Secondary" - background_picture_of_the_profile_banner: "Background picture of the profile banner" - background_picture_recommendation: "Only .png file. Recommended size: 4/1 ratio, 1600*400 px." - change_the_profile_banner: "Change the profile banner" - home_page: "Home page" - news_of_the_home_page: "News of the home page:" - type_your_news_here: "Type your news here" - leave_it_empty_to_not_bring_up_any_news_on_the_home_page: "Leave it empty to not bring up any news on the home page" - twitter_stream: "Twitter Stream:" - name_of_the_twitter_account: "Name of the Twitter account" - link: "Link" - link_to_about: 'Link title to the "About" page' - content: "Content" - title_of_the_about_page: "Title of the About page" - shift_enter_to_force_carriage_return: "SHIFT + ENTER to force carriage return" - input_the_main_content: "Input the main content" - drag_and_drop_to_insert_images: "Drag and drop to insert images" - input_the_fablab_contacts: "Input the FabLab contacts" - reservations: "Reservations" - reservations_parameters: "Reservations parameters" - confine_the_booking_agenda: "Confine the booking agenda" - opening_time: "Opening time" - closing_time: "Closing time" - max_visibility: "Maximum visibility (in months)" - visibility_for_yearly_members: "For currently running subscriptions, at least 1 year long" - visibility_for_other_members: "For all other members" - reservation_deadline: "Prevent last minute booking" - reservation_deadline_help: "If you increase the prior period, members won't be able to book a slot X minutes before its start." - machine_deadline_minutes: "Machine prior period (minutes)" - training_deadline_minutes: "Training prior period (minutes)" - event_deadline_minutes: "Event prior period (minutes)" - space_deadline_minutes: "Space prior period (minutes)" - ability_for_the_users_to_move_their_reservations: "Ability for the users to move their reservations" - reservations_shifting: "Reservations shifting" - prior_period_hours: "Prior period (hours)" - enabled: "Enabled" - disabled: "Disabled" - ability_for_the_users_to_cancel_their_reservations: "Ability for the users to cancel their reservations" - reservations_cancelling: "Reservations cancelling" - reservations_reminders: "Reservations reminders" - notification_sending_before_the_reservation_occurs: "Notification sending before the reservation occurs" - customization_of_SETTING_successfully_saved: "Customization of the {SETTING} successfully saved." - file_successfully_updated: "File successfully updated." - name_genre: "title concordance" - machine_explications_alert: "explanation message on the machine reservation page" - training_explications_alert: "explanation message on the training reservation page" - training_information_message: "information message on the machine reservation page" - subscription_explications_alert: "explanation message on the subscription page" - event_explications_alert: "explanation message on the event reservation page" - space_explications_alert: "explanation message on the space reservation page" - main_color: "main colour" - secondary_color: "secondary colour" - customize_home_page: "Customize home page" - reset_home_page: "Reset the home page to its initial state" - confirmation_required: "Confirmation required" - confirm_reset_home_page: "Do you really want to reset the home page to its factory value?" - home_items: "Home page items" - item_news: "News" - item_projects: "Last projects" - item_twitter: "Last tweet" - item_members: "Last members" - item_events: "Next events" - home_content: "the home page" - home_content_reset: "Home page was successfully reset to its initial configuration." - home_css: "the stylesheet of the home page" - home_blogpost: "homepage's brief" - twitter_name: "Twitter feed name" - link_name: "link title to the \"About\" page" - about_title: "\"About\" page title" - about_body: "\"About\" page content" - about_contacts: "\"About\" page contacts" - about_follow_us: "Follow us" - about_networks: "Social networks" - privacy_draft: "privacy policy draft" - privacy_body: "privacy policy" - privacy_dpo: "data protection officer address" - booking_window_start: "opening time" - booking_window_end: "closing time" - booking_move_enable: "reservation moving enabling" - booking_move_delay: "preventive delay of moving" - booking_cancel_enable: "reservation canceling enabling" - booking_cancel_delay: "preventive delay of canceling" - reminder_enable: "reservation reminding enabling" - reminder_delay: "delay before sending the reminder" - default_value_is_24_hours: "If the field is leaved empty: 24 hours." - visibility_yearly: "maximum visibility for annual subscribers" - visibility_others: "maximum visibility for other members" - display: "Display" - display_name_info_html: "When enabled, connected members browsing the calendar or booking a resource will see the name of the members who has already booked some slots. When disabled, only administrators and managers will view the names.
Warning: if you enable this feature, please write it down in your privacy policy." - display_reservation_user_name: "Display the full name of the user(s) who booked a slots" - display_name: "Display the name" - display_name_enable: "name display" - events_in_the_calendar: "Display the events in the calendar" - events_in_calendar_info: "When enabled, the admin calendar will display the scheduled events, as read-only items." - show_event: "Show the events" - events_in_calendar: "events display in the calendar" - machines_sort_by: "machines display order" - fab_analytics: "Fab Analytics" - phone_required: "phone required" - address_required: "address required" - tracking_id: "tracking ID" - facebook_app_id: "Facebook App ID" - twitter_analytics: "Twitter analytics account" - book_overlapping_slots: "book overlapping slots" - slot_duration: "slots duration" - advanced: "Advanced settings" - customize_home_page_css: "Customise the stylesheet of the home page" - home_css_notice_html: "You can customize the stylesheet which will apply to the home page, using the SCSS syntax. These styles will be automatically subordinated to the .home-page selector to prevent any risk of breaking the application. Meanwhile please be careful, any changes in the home page editor at the top of the page may broke your styles, always refer to the HTML code." - error_SETTING_locked: "Unable to update the setting: {SETTING} is locked. Please contact your system administrator." - an_error_occurred_saving_the_setting: "An error occurred while saving the setting. Please try again later." - book_overlapping_slots_info: "Allow / prevent the reservation of overlapping slots" - allow_booking: "Allow booking" - overlapping_categories: "Overlapping categories" - overlapping_categories_info: "Preventing booking on overlapping slots will be done by comparing the date and time of the following categories of reservations." - default_slot_duration: "Default duration for slots" - duration_minutes: "Duration (in minutes)" - default_slot_duration_info: "Machine and space availabilities are divided in multiple slots of this duration. This value can be overridden per availability." - modules: "Modules" - machines: "Machines" - machines_info_html: "The module Reserve a machine module can be disabled." - enable_machines: "Enable the machines" - machines_module: "machines module" - spaces: "Spaces" - spaces_info_html: "

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.

Warning: It is not recommended to disable spaces if at least one space reservation was made on the system.

" - enable_spaces: "Enable the spaces" - spaces_module: "spaces module" - plans: "Plans" - plans_info_html: "

Subscriptions provide a way to segment your prices and provide benefits to regular users.

Warning: It is not recommended to disable plans if at least one subscription is active on the system.

" - enable_plans: "Enable the plans" - plans_module: "plans module" - trainings: "Trainings" - trainings_info_html: "

Trainings are fully integrated Fab-manager's agenda. If enabled, your members will be able to book and pay trainings.

Trainings provides a way to prevent members to book some machines, if they do have not taken the prerequisite course.

" - 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 sell various products and consumables to your members. This module also allows you to manage stocks and track orders." - enable_store: "Enable the store" - store_module: "store module" - invoicing: "Invoicing" - invoicing_info_html: "

You can fully disable the invoicing module.

This is useful if you have your own invoicing system, and you don't want Fab-manager generates and sends invoices to the members.

Warning: 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.

" - enable_invoicing: "Enable invoicing" - invoicing_module: "invoicing module" - account_creation: "Account creation" - accounts_management: "Accounts management" - members_list: "Members list" - members_list_info: "You can customize the fields to display in the member management list" - phone: "Phone" - phone_is_required: "Phone required" - phone_required_info: "You can define if the phone number should be required to register a new user on Fab-manager." - address: "Address" - address_required_info_html: "You can define if the address should be required to register a new user on Fab-manager.
Please note that, depending on your country, the regulations may requires addresses for the invoices to be valid." - address_is_required: "Address is required" - external_id: "External identifier" - external_id_info_html: "You can set up an external identifier for your users, which cannot be modified by the user himself." - enable_external_id: "Enable the external ID" + change_the_favicon: "Ändra ikonen" + main_colour: "Primär färg:" + primary: "Primär" + secondary_colour: "Sekundär färg:" + secondary: "Sekundär" + background_picture_of_the_profile_banner: "Bakgrundsbild av profilbannern" + background_picture_recommendation: "Endast .png-fil. Rekommenderad storlek: 4/1 förhållande, 1600*400 px." + change_the_profile_banner: "Ändra profilbannern" + home_page: "Startsida" + news_of_the_home_page: "Nyheter på startsidan:" + type_your_news_here: "Skriv dina nyheter här" + leave_it_empty_to_not_bring_up_any_news_on_the_home_page: "Lämna det tomt för att inte ta upp några nyheter på startsidan" + twitter_stream: "Twitterflöde:" + name_of_the_twitter_account: "Namnet på Twitter-kontot" + link: "Länk" + link_to_about: 'Länk till sidan "Om"' + content: "Innehåll" + title_of_the_about_page: "Titel på sidan Om" + shift_enter_to_force_carriage_return: "SKIFT + ENTER för att tvinga ny rad" + input_the_main_content: "Mata in huvudinnehållet" + drag_and_drop_to_insert_images: "Dra och släpp för att infoga bilder" + input_the_fablab_contacts: "Skriv in FabLab kontakter" + reservations: "Bokningar" + reservations_parameters: "Parametrar för bokning" + confine_the_booking_agenda: "Begränsa bokningsagendan" + opening_time: "Öppningstid" + closing_time: "Stängningstid" + max_visibility: "Maximal synlighet (i månader)" + visibility_for_yearly_members: "För pågående abonnemang, minst 1 år lång" + visibility_for_other_members: "För alla andra medlemmar" + reservation_deadline: "Förhindra sista minuten-bokning" + reservation_deadline_help: "Om du ökar den tidigare perioden, kommer medlemmarna inte att kunna boka en kortplats X minuter före starten." + machine_deadline_minutes: "Utrustningens tidigare period (minuter)" + training_deadline_minutes: "Tidigare utbildningsperiod (minuter)" + event_deadline_minutes: "Evenemangets tidigare period (minuter)" + space_deadline_minutes: "Lokalens tidigare period (minuter)" + ability_for_the_users_to_move_their_reservations: "Möjlighet för användarna att flytta sina bokningar" + reservations_shifting: "Reservationer skiftar" + prior_period_hours: "Tidigare period (timmar)" + enabled: "Aktiverad" + disabled: "Inaktiverad" + ability_for_the_users_to_cancel_their_reservations: "Möjlighet för användarna att avboka sina bokningar" + reservations_cancelling: "Avbokning av bokningar" + reservations_reminders: "Bokningspåminnelser" + notification_sending_before_the_reservation_occurs: "Notifiering skickas innan bokningen sker" + customization_of_SETTING_successfully_saved: "Anpassning av {SETTING} har sparats." + file_successfully_updated: "Filen har uppdaterats." + name_genre: "titels överensstämmelse" + machine_explications_alert: "förklaringsmeddelande på sidan för bokning av utrustning" + training_explications_alert: "förklaringsmeddelande på bokningssidan för utbildningar" + training_information_message: "informationsmeddelande på sidan för bokning av utrustning" + subscription_explications_alert: "förklaringsmeddelande på prenumerationssidan" + event_explications_alert: "förklaringsmeddelande på sidan för bokning av evenemang" + space_explications_alert: "förklaringsmeddelande på sidan för lokalreservation" + main_color: "primär färg" + secondary_color: "sekundär färg" + customize_home_page: "Anpassa startsidan" + reset_home_page: "Återställ startsidan till sitt ursprungliga läge" + confirmation_required: "Bekräftelse krävs" + confirm_reset_home_page: "Vill du verkligen återställa startsidan till ursprungsvärdet?" + home_items: "Snabbstart" + item_news: "Nyheter" + item_projects: "Senaste projekt" + item_twitter: "Senaste tweet" + item_members: "Senaste medlemmar" + item_events: "Kommande evenemang" + home_content: "startsidan" + home_content_reset: "Startsidan har återställts till sin ursprungliga konfiguration." + home_css: "stilmallen för startsidan" + home_blogpost: "startsidans sammanfattning" + twitter_name: "Namn på Twitter-flöde" + link_name: "länk till sidan \"Om\"" + about_title: "\"Om\"-sidans titel" + about_body: "\"Om\"-sidans innehåll" + about_contacts: "\"Om\"-sidans kontaktinformation" + about_follow_us: "Följ oss" + about_networks: "Sociala nätverk" + privacy_draft: "utkast till integritetspolicy" + privacy_body: "integritetspolicy" + privacy_dpo: "adress till dataskyddsombud" + booking_window_start: "öppningstid" + booking_window_end: "stängningstid" + booking_move_enable: "flyttning av bokning aktiverad" + booking_move_delay: "förebyggande dröjsmål innan flyttning" + booking_cancel_enable: "flyttning av bokning aktiverad" + booking_cancel_delay: "förebyggande dröjsmål innan avbrytning" + reminder_enable: "flyttning av bokning aktiverad" + reminder_delay: "fördröjning innan påminnelse skickas" + default_value_is_24_hours: "Om fältet lämnas tomt: 24 timmar." + visibility_yearly: "maximal synlighet för årsabonnenter" + visibility_others: "maximal synlighet för andra medlemmar" + display: "Visa" + display_name_info_html: "När detta är aktiverat kommer anslutna medlemmar som bläddrar i kalendern eller bokar en resurs att se namnet på de medlemmar som redan har bokat vissa platser. När den är inaktiverad, kommer endast administratörer och chefer att visa namnen.
Varning: om du aktiverar den här funktionen, vänligen skriv ner den i din sekretesspolicy." + display_reservation_user_name: "Visa det fullständiga namnet på de användare som bokat en plats" + display_name: "Visa namnet" + display_name_enable: "visa namn" + events_in_the_calendar: "Visa evenemang i kalendern" + events_in_calendar_info: "När den är aktiverad kommer admin-kalendern att visa de schemalagda evenemangen, som skrivskyddade objekt." + show_event: "Visa evenemang" + events_in_calendar: "evenemang som visas i kalendern" + machines_sort_by: "utrustnings visningsordning" + fab_analytics: "Fab Analys" + phone_required: "telefon krävs" + address_required: "adress krävs" + tracking_id: "spårnings-ID" + facebook_app_id: "ID för Facebook-app" + twitter_analytics: "Twitter analytics-konto" + book_overlapping_slots: "boka överlappande platser" + slot_duration: "platsers varaktighet" + advanced: "Avancerade inställningar" + customize_home_page_css: "Anpassa stilmallen för startsidan" + home_css_notice_html: "Du kan anpassa formatmallen som kommer att gälla på startsidan, med hjälp av syntaxen SCSS. Dessa stilar kommer automatiskt att underordnas . home-page selectorn för att förhindra risk för att bryta programmet. Under tiden var försiktig, eventuella förändringar i hemsideseditorn högst upp på sidan kan bryta dina stilar, hänvisa alltid till HTML-koden." + error_SETTING_locked: "Det går inte att uppdatera inställningen: {SETTING} är låst. Kontakta din systemadministratör." + an_error_occurred_saving_the_setting: "Ett fel inträffade när inställningen skulle sparas. Försök igen senare." + book_overlapping_slots_info: "Tillåt / förhindra bokning av överlappande platser" + allow_booking: "Tillåt bokning" + overlapping_categories: "Överlappande kategorier" + overlapping_categories_info: "Förhindra bokning på överlappande platser kommer att göras genom att jämföra datum och tid för följande kategorier av bokningar." + default_slot_duration: "Standardvaraktighet för platser" + duration_minutes: "Varaktighet i minuter" + default_slot_duration_info: "Utrustnings- och lokaltillgänglighet är indelad i flera platser av denna varaktighet. Detta värde kan åsidosättas per tillgänglighet." + modules: "Moduler" + machines: "Utrustning" + machines_info_html: "Modulen Reservera utrustning kan inaktiveras." + enable_machines: "Aktivera utrustningen" + machines_module: "utrustningsmodul" + spaces: "Lokaler" + spaces_info_html: "

En lokal kan till exempel vara en bygdegård eller ett mötesrum. Deras särdrag är att de kan bokas av flera personer samtidigt.

Varning: Det rekommenderas inte att inaktivera mellanslag om minst en mellanslagsreservation gjordes på systemet.

" + enable_spaces: "Aktivera lokalerna" + spaces_module: "modulen Lokaler" + plans: "Planer" + plans_info_html: "

Prenumerationer ger ett sätt att segmentera dina priser och ge fördelar för återkommande användare.

Varning: Det rekommenderas inte att inaktivera planer om minst en prenumeration är aktiv på systemet.

" + enable_plans: "Aktivera planerna" + plans_module: "modulen Planer" + trainings: "Utbildningar" + trainings_info_html: "

Utbildningar är helt integrerade systemets kalendarium. Om aktiverad, kommer dina medlemmar att kunna boka och betala utbildningar.

Utbildningar ger ett sätt att hindra medlemmar att boka viss utrustning, om de inte har gått förkunskapskursen.

" + enable_trainings: "Aktivera utbildningarna" + trainings_module: "utbildningsmodul" + store: "Butik" + store_info_html: "Du kan aktivera butiksmodulen som ger ett enkelt sätt att sälja olika produkter och förbrukningsvaror till dina medlemmar. Modulen låter dig även att hantera lager och spåra beställningar." + enable_store: "Aktivera butiken" + store_module: "butiksmodul" + invoicing: "Fakturering" + invoicing_info_html: "

Du kan helt inaktivera faktureringsmodulen.

Detta är användbart om du har ett eget faktureringssystem och du inte vill att systemet genererar och skickar fakturor till medlemmarna.

Varning: även om du inaktiverar faktureringsmodulen, du måste konfigurera momsen för att förhindra fel i bokföring och priser. Gör det från modulen « Fakturor > Faktureringsinställningar ».

" + enable_invoicing: "Aktivera fakturering" + invoicing_module: "faktureringsmodul" + account_creation: "Skapa konto" + accounts_management: "Kontohantering" + members_list: "Medlemslista" + members_list_info: "Du kan anpassa de fält som ska visas i listan över medlemmar" + phone: "Telefon" + phone_is_required: "Telefon krävs" + phone_required_info: "Du kan ange om telefonnumret ska vara obligatoriskt för att registrera en ny användare i systemet." + address: "Adress" + address_required_info_html: "Du kan definiera om adress krävs för att registrera en ny användare.
OBS: beroende på landstillhörighet kan lagen kräva att giltiga fakturor har en faktureringsadress." + address_is_required: "Adress måste fyllas i" + external_id: "Extern identifierare" + external_id_info_html: "Du kan ställa in en extern identifierare för dina användare, som inte kan ändras av användaren själv." + enable_external_id: "Aktivera externt ID" captcha: "Captcha" - captcha_info_html: "You can setup a protection against robots, to prevent them creating members accounts. This protection is using Google reCAPTCHA. Sign up for an API key pair to start using the captcha." - site_key: "Site key" - secret_key: "Secret key" - recaptcha_site_key: "reCAPTCHA Site Key" - recaptcha_secret_key: "reCAPTCHA Secret Key" - feature_tour_display: "feature tour display" - email_from: "expeditor's address" - disqus_shortname: "Disqus shortname" - COUNT_items_removed: "{COUNT, plural, =1{One item} other{{COUNT} items}} removed" - item_added: "One item added" + captcha_info_html: "Du kan ställa in ett skydd mot robotar, för att förhindra att de skapar medlemskonton. Detta skydd använder Google reCAPTCHA. Registrera dig för ett API-nyckelpar för att börja använda captcha." + site_key: "Webbplatsnyckel" + secret_key: "Hemlig nyckel" + recaptcha_site_key: "reCAPTCHA webbplatsnyckel" + recaptcha_secret_key: "reCAPTCHA hemlig nyckel" + feature_tour_display: "visningsläge för guidad tur" + email_from: "utförarens adress" + disqus_shortname: "Disqus kortnamn" + COUNT_items_removed: "{COUNT, plural, one {}=1{Ett objekt} other{{COUNT} objekt}} borttaget" + item_added: "Ett objekt tillagt" openlab_app_id: "OpenLab ID" - openlab_app_secret: "OpenLab secret" - openlab_default: "default gallery view" - online_payment_module: "online payment module" - stripe_currency: "Stripe currency" - account_confirmation: "Account confirmation" - confirmation_required_info: "Optionally, you can force the users to confirm their email address before being able to access Fab-manager." - confirmation_is_required: "Confirmation required" - change_group: "Group change" - change_group_info: "After an user has created his account, you can restrict him from changing his group. In that case, only managers and administrators will be able to change the user's group." - allow_group_change: "Allow group change" - user_change_group: "users can change their group" - wallet_module: "wallet module" - public_agenda_module: "public agenda module" - statistics_module: "statistics module" - upcoming_events_shown: "display limit for upcoming events" - display_invite_to_renew_pack: "Display the invite to renew prepaid-packs" - packs_threshold_info_html: "You can define under how many hours the user will be invited to buy a new prepaid-pack, if his stock of prepaid hours is under this threshold.
You can set a number of hours (eg. 5) or a percentage of his current pack pack (eg. 0.05 means 5%)." - renew_pack_threshold: "threshold for packs renewal" - pack_only_for_subscription_info_html: "If this option is activated, the purchase and use of a prepaid pack is only possible for the user with a valid subscription." - pack_only_for_subscription: "Subscription valid for purchase and use of a prepaid pack" - pack_only_for_subscription_info: "Make subscription mandatory for prepaid packs" - extended_prices: "Extended prices" - extended_prices_info_html: "Spaces can have different prices depending on the cumulated duration of the booking. You can choose if this apply to all bookings or only to those starting within the same day." - extended_prices_in_same_day: "Extended prices in the same day" - public_registrations: "Public registrations" - projects_list_member_filter_presence: "Presence of member filter on projects list" - projects_list_date_filters_presence: "Presence of date filters on projects list" - project_categories_filter_placeholder: "Placeholder for categories filter in project gallery" - project_categories_wording: "Wording used to replace \"Categories\" on public pages" - reservation_context_feature_title: Reservation context - reservation_context_feature_info: "If you enable this feature, members will have to enter the context of their reservation when reserving." - reservation_context_feature: "Enable the feature \"Reservation context\"" - reservation_context_options: Reservation context options - add_a_reservation_context: Add a new context - do_you_really_want_to_delete_this_reservation_context: "Do you really want to delete this context?" - unable_to_delete_reservation_context_already_related_to_reservations: "Unable to delete this context because it is already associated to a reservation" - unable_to_delete_reservation_context_an_error_occured: "Unable to delete: an error occurred" - family_account: "family account" - family_account_info_html: "The Family account allows your members to add their children under 18 years old to their own account and directly register them for Family events. You can also request supporting documents for each child and validate their account." - enable_family_account: "Enable the Family Account option" - child_validation_required: "the account validation option for children" - child_validation_required_label: "Activate the account validation option for children" + openlab_app_secret: "OpenLab hemlighet" + openlab_default: "standardvy för galleri" + online_payment_module: "onlinebetalningsmodul" + stripe_currency: "Stripe valuta" + account_confirmation: "Kontobekräftelse" + confirmation_required_info: "Alternativt kan du tvinga användarna att bekräfta sin e-postadress innan de kan komma åt systemet." + confirmation_is_required: "Bekräftelse krävs" + change_group: "Ändra grupp" + change_group_info: "Efter att en användare har skapat sitt konto kan du begränsa honom från att ändra sin grupp. I så fall kan endast ansvariga och administratörer ändra användarens grupp." + allow_group_change: "Tillåt gruppändring" + user_change_group: "tillåt användare att ändra sin grupp" + wallet_module: "plånboksmodul" + public_agenda_module: "modul för publikt kalendarium" + statistics_module: "statistikmodul" + upcoming_events_shown: "visningsgräns för kommande evenemang" + display_invite_to_renew_pack: "Visa inbjudan för att förnya förbetalda paket" + packs_threshold_info_html: "Du kan definiera under hur många timmar användaren kommer att bjudas in att köpa ett nytt förbetalt paket, Om dess lager av förbetalda timmar ligger under denna tröskel.
Du kan ange ett antal timmar (t. ex.. 5) eller en procentandel av dess nuvarande förpackningspaket (t. ex.. 0,05 betyder 5%)." + renew_pack_threshold: "tröskelvärde för förnyelse av paket" + pack_only_for_subscription_info_html: "Om detta alternativ är aktiverat, är köp och användning av ett kontantpaket endast möjligt för användaren med en giltig prenumeration." + pack_only_for_subscription: "Abonnemang giltigt för köp och användning av ett förbetalt paket" + pack_only_for_subscription_info: "Gör prenumerationen obligatorisk för förbetalda paket" + extended_prices: "Utökade priser" + extended_prices_info_html: "Lokaler kan ha olika priser beroende på den sammanlagda varaktigheten av bokningen. Du kan välja om detta gäller för alla bokningar eller endast för dem som startar inom samma dag." + extended_prices_in_same_day: "Utökade priser samma dag" + public_registrations: "Öppna registreringar" + projects_list_member_filter_presence: "Filtrera på närvaro i projektlistan" + projects_list_date_filters_presence: "Förekomst av datumfilter på projektlistan" + project_categories_filter_placeholder: "Platshållare för kategorifilter i projektgalleriet" + project_categories_wording: "Ord som används för att ersätta \"Kategorier\" på publika sidor" + reservation_context_feature_title: Kontext för bokning + reservation_context_feature_info: "Om du aktiverar den här funktionen kommer medlemmarna att behöva gå in i sin bokning när de bokar." + reservation_context_feature: "Aktivera funktionen \"Bokningssammanhang\"" + reservation_context_options: Alternativ för bokningssammanhang + add_a_reservation_context: Lägg till en nytt sammanhang + do_you_really_want_to_delete_this_reservation_context: "Vill du verkligen ta bort detta sammanhang?" + unable_to_delete_reservation_context_already_related_to_reservations: "Det går inte att ta bort detta sammanhang eftersom det redan är kopplat till en bokning" + unable_to_delete_reservation_context_an_error_occured: "Det gick inte att ta bort: ett fel inträffade" + family_account: "familjekonto" + family_account_info_html: "Med familjekontot kan dina medlemmar lägga till sina barn under 18 år på sitt eget konto och direkt registrera dem för familjeevenemang. Du kan också begära underlag för varje barn och validera deras konto." + enable_family_account: "Aktivera alternativet Familjekonto" + child_validation_required: "valideringsalternativet för konto för barn" + child_validation_required_label: "Aktivera valideringsalternativet för konto för barn" overlapping_options: - training_reservations: "Trainings" - machine_reservations: "Machines" - space_reservations: "Spaces" - events_reservations: "Events" + training_reservations: "Utbildningar" + machine_reservations: "Utrustning" + space_reservations: "Lokaler" + events_reservations: "Evenemang" general: - general: "General" - title: "Title" + general: "Allmänt" + title: "Titel" fablab_title: "FabLab title" - title_concordance: "Title concordance" - male: "Male." - female: "Female." + title_concordance: "Titels överensstämmelse" + male: "Man." + female: "Kvinna." neutral: "Neutral." - eg: "eg:" - the_team: "The team of" - male_preposition: "the" - female_preposition: "the" + eg: "t. ex:" + the_team: "Teamet av" + male_preposition: "den" + female_preposition: "den" neutral_preposition: "" - elements_ordering: "Elements ordering" - machines_order: "Machines order" - display_machines_sorted_by: "Display machines sorted by" + elements_ordering: "Sortering av element" + machines_order: "Utrustningens ordning" + display_machines_sorted_by: "Visa utrustning sorterad efter" sort_by: - default: "Default" - name: "Name" - created_at: "Creation date" - updated_at: "Last update date" - public_registrations: "Public registrations" - public_registrations_info: "Allow everyone to register a new account on the platform. If disabled, only administrators and managers can create new accounts." - public_registrations_allowed: "Public registrations allowed" - help: "Help" - feature_tour: "Feature tour" - feature_tour_info_html: "

When an administrator or a manager in logged-in, a feature tour will be triggered the first time he visits each section of the application. You can change this behavior to one of the following values:

  • « Once » to keep the default behavior.
  • « By session » to display the tours each time you reopen the application.
  • « Manual trigger » to prevent displaying the tours automatically. It'll still be possible to trigger them by pressing the F1 key or by clicking on « Help » in the user's menu.
" - feature_tour_display_mode: "Feature tour display mode" + default: "Standard" + name: "Namn" + created_at: "Skapandedatum" + updated_at: "Senast uppdaterad" + public_registrations: "Öppna registreringar" + public_registrations_info: "Tillåt alla att registrera ett nytt konto på plattformen. Om inaktiverad kan endast administratörer och ansvariga skapa nya konton." + public_registrations_allowed: "Offentliga registreringar tillåtna" + help: "Hjälp" + feature_tour: "Guide för funktioner" + feature_tour_info_html: "

När en administratör eller en ansvarig är inloggad, kommer en rundtur att erbjudas första gången den besöker varje avsnitt i programmet. Du kan ändra detta beteende till ett av följande värden:

  • « En gång » för att behålla standardbeteendet.
  • « Per session » för att visa turerna varje gång du öppnar ansökan igen.
  • « Manuell start » för att förhindra att turerna visas automatiskt. Det kommer fortfarande att vara möjligt att utlösa dem genom att trycka på F1-tangenten eller genom att klicka på « Hjälp » i användarens meny.
" + feature_tour_display_mode: "Visningsläge för guidad tur" display_mode: - once: "Once" - session: "By session" - manual: "Manual trigger" - notifications: "Notifications" - email: "Email" - email_info: "The email address from which notifications will be sent. You can use a non-existing address (like noreply@...) or an existing address if you want to allow your members to reply to the notifications they receive." - email_from: "Expeditor's address" - wallet: "Wallet" - wallet_info_html: "

The virtual wallet allows you to allocate a sum of money to users. Then, can spend this money as they wish, in Fab-manager.

Members cannot credit their wallet themselves, it's a privilege of managers and administrators.

" - enable_wallet: "Enable wallet" - public_agenda: "Public agenda" - public_agenda_info_html: "

The public agenda offers to members and visitors a general overview of the Fablab's planning.

Please note that, even logged, users won't be able to book a reservation or modify anything from this agenda: this is a read-only page.

" - enable_public_agenda: "Enable public agenda" - statistics: "Statistics" - statistics_info_html: "

Enable or disable the statistics module.

If enabled, every nights, the data of the day just passed will be consolidated in the database of a powerful analysis engine. Then, every administrators will be able to browse statistical charts and tables in the corresponding section.

" - enable_statistics: "Enable statistics" + once: "En gång" + session: "Utifrån session" + manual: "Manuell start" + notifications: "Aviseringar" + email: "E-post" + email_info: "E-postadressen från vilken aviseringar kommer att skickas. Du kan använda en icke-existerande adress (som noreply@..) eller en befintlig adress om du vill tillåta dina medlemmar att svara på de meddelanden de får." + email_from: "Utförarens adress" + wallet: "Plånbok" + wallet_info_html: "

Den virtuella plånboken låter dig fördela en summa pengar till användarna som edan kan spendera dessa pengar som de vill i systemet.

Medlemmar kan inte kreditera sin plånbok själva, det är förunnat ansvariga och administratörer.

" + enable_wallet: "Aktivera plånbok" + public_agenda: "Publikt kalendarium" + public_agenda_info_html: "

Det publika kalendariet ger medlemmar och besökare en allmän översikt över Ringamålas planering.

Observera att inloggade användare inte kan boka en bokning eller ändra något från denna sida: detta är en skrivskyddad sida.

" + enable_public_agenda: "Aktivera publikt kalendarium" + statistics: "Statistik" + statistics_info_html: "

Aktivera eller inaktivera statistikmodulen.

Om aktiverad så kommer varje natt data för dagen som just passerat konsolideras i databasen av en kraftfull analysmotor. Sedan kommer varje administratör att kunna bläddra i statistiska diagram och tabeller i motsvarande avsnitt.

" + enable_statistics: "Aktivera statistik" account: - account: "Account" - customize_account_settings: "Customize account settings" - user_validation_required: "validation of accounts" - user_validation_required_title: "Validation of accounts" - user_validation_required_info: "By activating this option, only members whose account is validated by an administrator or a manager will be able to make reservations." + account: "Konto" + customize_account_settings: "Anpassa kontoinställningar" + user_validation_required: "validering av konton" + user_validation_required_title: "Validering av konton" + user_validation_required_info: "Genom att aktivera detta alternativ kommer endast medlemmar vars konto är validerat av en administratör eller en ansvarig att kunna göra bokningar." user_validation_setting: - customization_of_SETTING_successfully_saved: "Customization of the {SETTING} successfully saved." - error_SETTING_locked: "Unable to update the setting: {SETTING} is locked. Please contact your system administrator." - an_error_occurred_saving_the_setting: "An error occurred while saving the setting. Please try again later." - user_validation_required_option_label: "Activate the account validation option" - user_validation_required_list_title: "Member account validation information message" - user_validation_required_list_info: "Your administrator must validate your account. Then, you will be able to access all the booking features." - user_validation_required_list_other_info: "The resources selected below will be subject to member account validation." - save: "Save" + customization_of_SETTING_successfully_saved: "Anpassning av {SETTING} har sparats." + error_SETTING_locked: "Det går inte att uppdatera inställningen: {SETTING} är låst. Kontakta din systemadministratör." + an_error_occurred_saving_the_setting: "Ett fel uppstod medan filen laddades. Vänligen försök igen senare." + user_validation_required_option_label: "Aktivera valideringsalternativet för konto" + user_validation_required_list_title: "Valideringsmeddelande för medlemskonto" + user_validation_required_list_info: "Administratören måste validera ditt konto. Då får du tillgång till alla bokningsfunktioner." + user_validation_required_list_other_info: "De resurser som valts nedan kommer att godkännas av medlemskontot." + save: "Spara" user_validation_required_list: - subscription: "Subscriptions" - machine: "Machines" - event: "Events" - space: "Spaces" - training: "Trainings" - pack: "Prepaid pack" - confirm: "Confirm" - confirmation_required: "Confirmation required" - organization: "Organization" - organization_profile_custom_fields_info: "You can display additional fields for users who declare themselves to be an organization. You can also choose to make them mandatory at account creation." - organization_profile_custom_fields_alert: "Warning: the activated fields will be automatically displayed on the issued invoices. Once configured, please do not modify them." + subscription: "Prenumerationer" + machine: "Utrustning" + event: "Evenemang" + space: "Lokaler" + training: "Utbildningar" + pack: "Förbetalda paket" + confirm: "Bekräfta" + confirmation_required: "Bekräftelse krävs" + organization: "Organisation" + organization_profile_custom_fields_info: "Du kan visa ytterligare fält för användare som förklarar sig vara en organisation. Du kan också välja att göra dem obligatoriska vid skapande av konto." + organization_profile_custom_fields_alert: "Varning: de aktiverade fälten kommer att visas automatiskt på de utfärdade fakturorna. När du har konfigurerat dem, vänligen ändra dem inte." supporting_documents_type_modal: - successfully_created: "The new supporting documents request has been created." - unable_to_create: "Unable to delete the supporting documents request: " - successfully_updated: "The supporting documents request has been updated." - unable_to_update: "Unable to modify the supporting documents request: " - new_type: "Create a supporting documents request" - edit_type: "Edit the supporting documents request" - create: "Create" - edit: "Edit" + successfully_created: "Begäran om underlag har skapats." + unable_to_create: "Det går inte att neka underlagen: " + successfully_updated: "Begäran om underlag har uppdaterats." + unable_to_update: "Det går inte att ändra begäran om underlag: " + new_type: "Skapa en begäran om underlag" + edit_type: "Redigera begäran om underlag" + create: "Skapa" + edit: "Redigera" supporting_documents_type_form: - type_form_info: "Please define the supporting documents request settings below" - select_group: "Choose one or many group(s)" - name: "Name" + type_form_info: "Vänligen definiera inställningarna för underlagsbegäran nedan" + select_group: "Välj en eller flera grupp(er)" + name: "Namn" supporting_documents_types_list: - add_supporting_documents_types: "Add supporting documents" - all_groups: 'All groups' - supporting_documents_type_info: "You can ask for supporting documents, according to the user's groups. This will ask your members to deposit those kind of documents in their personnal space. Each members will be informed that supporting documents are required to be provided in their personal space (My supporting documents tab). On your side, you'll be able to check the provided supporting documents and validate the member's account (if the Account Validation option is enabled)." - no_groups_info: "Supporting documents are necessarily applied to groups.
If you do not have any group yet, you can create one from the \"Users/Groups\" page (button on the right)." - create_groups: "Create groups" - supporting_documents_type_title: "Supporting documents requests" - add_type: "Add new document" - group_name: "Group" - name: "Supporting documents" - no_types: "You do not have any supporting documents requests.
Make sure you have created at least one group in order to add a request." + add_supporting_documents_types: "Lägg till underlag" + all_groups: 'Alla grupper' + supporting_documents_type_info: "Du kan be om underlag, enligt användarens grupper. Detta kommer att be dina medlemmar att deponera dessa typer av dokument i deras personliga utrymme. Varje medlem kommer att informeras om att underlag handlingar måste tillhandahållas i deras personliga utrymme (fliken Mina underlag). På din sida kommer du att kunna kontrollera de bifogade dokumenten och validera medlemmens konto (om alternativet Kontovalidering är aktiverat)." + no_groups_info: "Underlag tillämpa på vissa grupper.
Om du inte har någon grupp ännu, kan du skapa en från sidan \"Användare/Grupper\" (knappen till höger)." + create_groups: "Skapa grupp" + supporting_documents_type_title: "Begäran om underlag" + add_type: "Lägg till ett dokument" + group_name: "Grupp" + name: "Underlag" + no_types: "Du har inga förfrågningar om underlag.
Se till att du har skapat minst en grupp för att lägga till en begäran." delete_supporting_documents_type_modal: - confirmation_required: "Confirmation required" - confirm: "Confirm" - deleted: "The supporting documents request has been deleted." - unable_to_delete: "Unable to delete the supporting documents request: " - confirm_delete_supporting_documents_type: "Do you really want to remove this requested type of supporting documents?" + confirmation_required: "Bekräftelse krävs" + confirm: "Bekräfta" + deleted: "Begäran om underlag har tagits bort." + unable_to_delete: "Det går inte att ta bort begäran om underlag: " + confirm_delete_supporting_documents_type: "Vill du verkligen ta bort denna begärda typ av underlag?" profile_custom_fields_list: - field_successfully_updated: "The organization field has been updated." - unable_to_update: "Impossible to modify the field : " - required: "Confirmation required" - actived: "Activate the field" + field_successfully_updated: "Organisationsfältet har uppdaterats." + unable_to_update: "Omöjligt att ändra fältet : " + required: "Bekräftelse krävs" + actived: "Aktivera fältet" home: - show_upcoming_events: "Show upcoming events" + show_upcoming_events: "Visa kommande evenemang" upcoming_events: - until_start: "Until they start" - 2h_before_end: "Until 2 hours before they end" - until_end: "Until they end" + until_start: "Tills de börjar" + 2h_before_end: "Fram till 2 timmar innan de slutar" + until_end: "Tills de slutar" privacy: - title: "Privacy" - privacy_policy: "Privacy policy" - input_the_dpo: "Data Protection Officer" - current_policy: "Current policy" - draft_from_USER_DATE: "Draft, saved by {USER}, on {DATE}" - save_or_publish: "Save or publish?" - save_or_publish_body: "Do you want to publish a new version of the privacy policy or save it as a draft?" - publish_will_notify: "Publish a new version will send a notification to every users." - publish: "Publish" - users_notified: "Platform users will be notified of the update." - about_analytics: "I agree to share anonymous data with the development team to help improve Fab-manager." - read_more: "Which data do we collect?" - statistics: "Statistics" + title: "Sekretess" + privacy_policy: "Integritetspolicy" + input_the_dpo: "Dataskyddsombud" + current_policy: "Aktuell policy" + draft_from_USER_DATE: "Utkast, sparat av {USER}, den {DATE}" + save_or_publish: "Spara eller publicera?" + save_or_publish_body: "Vill du publicera en ny version av sekretesspolicyn eller spara den som ett utkast?" + publish_will_notify: "Publicera en ny version kommer att skicka ett meddelande till alla användare." + publish: "Publicera" + users_notified: "Plattformsanvändare kommer att meddelas om uppdateringen." + about_analytics: "Jag samtycker till att dela anonym data med utvecklingsteamet för att hjälpa till att förbättra Fab-manager." + read_more: "Vilka uppgifter samlar vi in?" + statistics: "Statistik" google_analytics: "Google Analytics" facebook: "Facebook" - facebook_info_html: "To enable the statistical tracking of the shares on the Facebook social network, set your App ID here. Refer to this guide to get one." - app_id: "App ID" + facebook_info_html: "För att möjliggöra statistisk spårning av delningar på Facebook, ange ditt app-ID här. Se denna guide för att få ett." + app_id: "App-ID" twitter: "Twitter" - twitter_info_html: "To enable the statistical tracking of the shares on the Twitter social network, Twitter analytics, set the name of your Twitter account here." - twitter_analytics: "Twitter account" + twitter_info_html: "För att möjliggöra statistisk spårning av delningar på Twitter Twitter analytics, ange namnet på ditt Twitter-konto här." + twitter_analytics: "Twitter-konto" analytics: - title: "Application improvement" - intro_analytics_html: "You'll find below a detailed view of all the data, Fab-manager will collect if permission is granted." - version: "Application version" - members: "Number of members" - admins: "Number of administrators" - managers: "Number of managers" - availabilities: "Number of availabilities of the last 7 days" - reservations: "Number of reservations during the last 7 days" - orders: "Number of store orders during the last 7 days" - plans: "Is the subscription module active?" - spaces: "Is the space management module active?" - online_payment: "Is the online payment module active?" - gateway: "The payment gateway used to collect online payments" - wallet: "Is the wallet module active?" - statistics: "Is the statistics module active?" - trainings: "Is the trainings module active?" - public_agenda: "Is the public agenda module active?" - machines: "Is the machines module active?" - store: "Is the store module active?" - invoices: "Is the invoicing module active?" - openlab: "Is the project sharing module (OpenLab) active?" - tracking_id_info_html: "To enable the statistical tracking of the visits using Google Analytics V4, set your tracking ID here. It is in the form G-XXXXXX. Visit the Google Analytics website to get one.
Warning: if you enable this feature, a cookie will be created. Remember to write it down in your privacy policy, above." - tracking_id: "Tracking ID" + title: "Förbättring av programmet" + intro_analytics_html: "Nedan hittar du en detaljerad vy över alla data, Fab-manager kommer att samla in om tillstånd beviljas." + version: "Programversion" + members: "Antal medlemmar" + admins: "Antal administratörer" + managers: "Antal ansvariga" + availabilities: "Tillgänglighet för de senaste 7 dagarna" + reservations: "Antal bokningar under de senaste 7 dagarna" + orders: "Antal butiksbeställningar under de senaste 7 dagarna" + plans: "Är prenumerationsmodulen aktiv?" + spaces: "Är utrymmesadministrationsmodulen aktiv?" + online_payment: "Är betalningsmodulen online aktiv?" + gateway: "Betalningsporten som används för att ta emot betalningar online" + wallet: "Är plånboksmodulen aktiv?" + statistics: "Är statistikmodulen aktiv?" + trainings: "Är utbildningsmodulen aktiv?" + public_agenda: "Är det publika kalendariet aktivt?" + machines: "Är utrustningsmodulen aktiv?" + store: "Är butiksmodulen aktiv?" + invoices: "Är faktureringsmodulen aktiv?" + openlab: "Är projektdelningsmodulen (OpenLab) aktiv?" + tracking_id_info_html: "För att möjliggöra statistisk spårning av besöken med Google Analytics V4, ange ditt spårnings-ID här. Det är i formen G-XXXXXX. Besök Google Analytics webbplats för att få en.
Varning: om du aktiverar den här funktionen kommer en cookie att skapas. Kom ihåg att skriva ner det i din sekretesspolicy, ovan." + tracking_id: "Spårnings-ID" open_api_clients: - add_new_client: "Create new API client" - api_documentation: "API documentation" - open_api_clients: "OpenAPI clients" - name: "Name" - calls_count: "Calls count" + add_new_client: "Skapa ny API-klient" + api_documentation: "API-dokumentation" + open_api_clients: "OpenAPI-klienter" + name: "Namn" + calls_count: "Antal anrop" token: "Token" - created_at: "Creation date" - reset_token: "Revoke access" - client_name: "Client's name" - confirmation_required: "Confirmation required" - do_you_really_want_to_delete_this_open_api_client: "Do you really want to delete this OpenAPI client?" - do_you_really_want_to_revoke_this_open_api_access: "Do you really want to revoke this access? It will erase and replace the current token." - client_successfully_created: "Client successfully created." - client_successfully_updated: "Client successfully updated." - client_successfully_deleted: "Client successfully deleted." - access_successfully_revoked: "Access successfully revoked." + created_at: "Skapandedatum" + reset_token: "Återkalla åtkomst" + client_name: "Klientens namn" + confirmation_required: "Bekräftelse krävs" + do_you_really_want_to_delete_this_open_api_client: "Vill du verkligen ta bort denna OpenAPI-klient?" + do_you_really_want_to_revoke_this_open_api_access: "Vill du verkligen återkalla denna åtkomst? Det kommer att radera och ersätta den nuvarande token." + client_successfully_created: "Klienten har skapats." + client_successfully_updated: "Klienten har uppdaterats." + client_successfully_deleted: "Klienten har tagits bort." + access_successfully_revoked: "Åtkomst har återkallats." #create a new space space_new: - add_a_new_space: "Add a new space" + add_a_new_space: "Lägg till utrymme" #modify an exiting space space_edit: - edit_the_space_NAME: "Edit the space: {NAME}" - validate_the_changes: "Validate the changes" + edit_the_space_NAME: "Redigera utrymmet: {NAME}" + validate_the_changes: "Godkänn ändringar" #process and delete abuses reports manage_abuses: - abuses_list: "Reports list" - no_reports: "No reports for now" - published_by: "published by" - at_date: "on" - has_reported: "made the following report:" - confirmation_required: "Confirm the processing of the report" - report_will_be_destroyed: "Once the report has been processed, it will be deleted. This can't be undone, continue?" - report_removed: "The report has been deleted" - failed_to_remove: "An error occurred, unable to delete the report" + abuses_list: "Rapportlista" + no_reports: "Inga rapporter just nu" + published_by: "publicerad av" + at_date: "på" + has_reported: "gjorde följande rapport:" + confirmation_required: "Bekräfta behandlingen av rapporten" + report_will_be_destroyed: "När rapporten har bearbetats kommer den att raderas. Detta kan inte ångras, fortsätta?" + report_removed: "Rapporten har tagits bort" + failed_to_remove: "Ett fel uppstod, kan inte ta bort rapporten" local_payment_form: - about_to_cash: "You're about to confirm the cashing by an external payment mean. Please do not click on the button below until you have fully cashed the requested payment." - about_to_confirm: "You're about to confirm your {ITEM, select, subscription{subscription} reservation{reservation} other{order}}." - payment_method: "Payment method" - method_card: "Online by card" - method_check: "By check" - method_transfer: "By bank transfer" - card_collection_info: "By validating, you'll be prompted for the member's card number. This card will be automatically charged at the deadlines." - check_collection_info: "By validating, you confirm that you have {DEADLINES} checks, allowing you to collect all the monthly payments." - transfer_collection_info: "

By validating, you confirm that you set up {DEADLINES} bank direct debits, allowing you to collect all the monthly payments.

Please note: the bank transfers are not automatically handled by Fab-manager.

" - online_payment_disabled: "Online payment is not available. You cannot collect this payment schedule by online card." + about_to_cash: "Du är på väg att bekräfta inlösen av en extern betalning. Klicka inte på knappen nedan förrän du har betalat ut den begärda betalningen." + about_to_confirm: "Du håller på att bekräfta din {ITEM, select, subscription{prenumeration} reservation{bokning} other{order}}." + payment_method: "Betalningsmetod" + method_card: "Online med kort" + method_check: "Med swish" + method_transfer: "Banköverföring" + card_collection_info: "Genom att validera kommer du att bli tillfrågad om medlemmens kortnummer. Detta kort kommer att debiteras automatiskt vid deadlines." + check_collection_info: "Genom att validera bekräftar du att du har {DEADLINES} kontroller, så att du kan samla in alla månadsbetalningar." + transfer_collection_info: "

Genom att validera bekräftar du att du konfigurerar {DEADLINES} bank autogiro så att du kan samla in alla månatliga betalningar.

Observera: banköverföringarna hanteras inte automatiskt av Fab-manager.

" + online_payment_disabled: "Online-betalning är inte tillgänglig. Du kan inte hämta detta betalningsschema med onlinekort." local_payment_modal: - validate_cart: "Validate my cart" - offline_payment: "Payment on site" + validate_cart: "Validera min kundvagn" + offline_payment: "Betalning på plats" check_list_setting: - save: 'Save' - customization_of_SETTING_successfully_saved: "Customization of the {SETTING} successfully saved." + save: 'Spara' + customization_of_SETTING_successfully_saved: "Anpassning av {SETTING} har sparats." #feature tour tour: conclusion: - title: "Thank you for your attention" - content: "

If you want to restart this contextual help, press F1 at any time or click on [? Help] from the user's menu.

If you need additional help, you can check the user guide (only in French for now).

The Fab-manager's team also provides personalized support (help with getting started, help with installation, customization, etc.), contact-us for more info.

" + title: "Tack för er uppmärksamhet" + content: "

Om du vill starta om denna kontextuella hjälp, tryck på F1 när som helst eller klicka på [? Hjälp] från användarens meny.

Om du behöver ytterligare hjälp kan du kolla användarhandboken (endast på franska just nu).

Fab-managerns team ger även personlig support (hjälp med att komma igång, hjälp med installation, anpassning etc., Kontakta oss för mer information.

" trainings: welcome: - title: "Trainings" - content: "Here you can create, modify and delete trainings. It is also the place where you can validate the training courses followed by your members." + title: "Utbildningar" + content: "Här kan du skapa, ändra och ta bort utbildningar. Det är också platsen där du kan validera de kurser som följs av dina medlemmar." welcome_manager: - title: "Trainings" - content: "This is the place where you can view the trainings and their associations with the machines. It is also the place where you can validate the training courses followed by your members." + title: "Utbildningar" + content: "Här kan du se utbildningarna och deras koppling med utrustning. Det är också platsen där du kan validera de kurser som genomförs av dina medlemmar." trainings: - title: "Manage trainings" - content: "

With each training, a default number of places is associated. However, the number of actual places may be modified for each session.

The training sessions are scheduled from the administrator tab « Calendar ».

Furthermore, a training may be associated with one or more machines. This makes it a prerequisite for the reservation of these machines.

" + title: "Hantera utbildningar" + content: "

Vid varje utbildning associeras ett standardantal platser. Antalet platser kan dock ändras för varje session.

Utbildningarna är schemalagda från administratörsfliken « Kalender ».

Dessutom kan en utbildning kopplas till utrustning. Detta gör det till en förutsättning för bokning av denna utrustning.

" filter: - title: "Filter" - content: "By default, only active courses are displayed here. Display the others by choosing another filter here." + title: "Filtrera" + content: "Som standard visas endast aktiva kurser här. Visa de andra genom att välja ett annat filter här." tracking: - title: "Trainings monitoring" - content: "Once a training session is finished, you can validate the training for the members present from this screen. This validation is essential to allow them to use the associated machines, if applicable." + title: "Övervakning av utbildningar" + content: "När ett träningspass är avslutat kan du validera utbildningen för de medlemmar som är närvarande från den här skärmen. Denna validering är nödvändig för att tillåta dem att använda tillhörande utrustning, om tillämpligt." calendar: welcome: - title: "Calendar" - content: "From this screen, you can plan the slots during which training, machines and spaces will be bookable by members." + title: "Kalender" + content: "Från den här skärmen kan du planera de platser under vilka utbildning, utrustning och lokaler kommer att vara bokningsbara för medlemmar." agenda: - title: "The calendar" - content: "Click in the calendar to start creating a new availability range. You can directly select the entire time range desired by maintaining your click." + title: "Kalendern" + content: "Klicka i kalendern för att börja skapa ett nytt tillgänglighetsintervall. Du kan direkt välja hela det tidsintervall som önskas genom att behålla ditt klick." export: - title: "Export" - content: "Start generating an Excel file, listing all the availability slots created in the calendar." + title: "Exportera" + content: "Börja generera en Excel-fil, lista alla tillgängliga platser som skapats i kalendern." import: - title: "Import external calendars" - content: "Allows you to import calendars from an external source in iCal format." + title: "Importera externa kalendrar" + content: "Låter dig importera kalendrar från en extern källa i iCal-format." members: welcome: - title: "Users" - content: "Here you can create, modify and delete members and administrators. You can also manage groups, labels, import / export with spreadsheet files and connect SSO software." + title: "Användare" + content: "Här kan du skapa, modifiera och ta bort medlemmar och administratörer. Du kan också hantera grupper, etiketter, importera / exportera med kalkylblad filer och ansluta SSO-program." list: - title: "Members list" - content: "By default, this table lists all the members of your Fab-manager. You can sort the list in a different order by clicking on the header of each column." + title: "Medlemslista" + content: "Som standard visar denna tabell alla medlemmar i din Fab-manager. Du kan sortera listan i en annan ordning genom att klicka på rubriken i varje kolumn." search: - title: "Find a user" - content: "This input field allows you to search for any text on all of the columns in the table below." + title: "Hitta en användare" + content: "Detta inmatningsfält låter dig söka efter någon text på alla kolumner i tabellen nedan." filter: - title: "Filter the list" - content: "

Filter the list below to display only users who have not confirmed their email address or inactive accounts for more than 3 years.

Please notice that the GDPR requires that you delete any accounts inactive for more than 3 years.

" + title: "Filtrera listan" + content: "

Filtrera listan nedan för att visa endast användare som inte har bekräftat sin e-postadress eller inaktiva konton i mer än 3 år.

Observera att GDPR kräver att du tar bort alla konton som är inaktiva i mer än 3 år.

" actions: - title: "Members actions" - content: "

The buttons in this column allow you to display and modify all of the member's parameters, or to delete them irreversibly.

In the event of a deletion, the billing information will be kept for 10 years and statistical data will also be kept anonymously.

" + title: "Medlemmar åtgärder" + content: "

Knapparna i den här kolumnen låter dig visa och ändra alla medlems parametrar, eller ta bort dem oåterkalleligt.

I händelse av en radering, faktureringsuppgifterna kommer att sparas i 10 år och statistiska uppgifter kommer också att lagras anonymt.

" exports: - title: "Export" - content: "Each of these buttons starts the generation of an Excel file listing all the members, subscriptions or reservations, current and past." + title: "Exportera" + content: "Var och en av dessa knappar startar genereringen av en Excel-fil som listar alla medlemmar, prenumerationer eller reservationer, nuvarande och förflutna." import: - title: "Import members" - content: "Allows you to import a list of members to create in Fab-manager, from a CSV file." + title: "Importera medlemmar" + content: "Låter dig importera en lista med medlemmar att skapa i Fab-manager, från en CSV-fil." admins: - title: "Manage administrators" - content: "In the same way as the members, manage the administrators of your Fab-manager here.
The administrators can take reservations for any member as well as modify all the parameters of the software." + title: "Hantera administratörer" + content: "På samma sätt som med medlemmarna, förvalta administratörerna i din Fab-manager här.
Administratörerna kan ta reservationer för alla medlemmar samt ändra alla parametrar i programvaran." groups: - title: "Manage groups" - content: "

Groups allow you to better segment your price list.

When you set up Fab-manager for the first time, it is recommended to start by defining the groups.

" + title: "Hantera grupper" + content: "

Grupper tillåter dig att bättre segmentera din prislista.

När du ställer in Fab-manager för första gången rekommenderas det att börja med att definiera grupperna.

" labels: - title: "Manage tags" - content: "The labels allow you to reserve certain slots for users associated with these same labels." + title: "Hantera taggar" + content: "Etiketterna ger dig möjlighet att reservera vissa platser för användare som är associerade med samma etiketter." sso: - title: "Single Sign-On" - content: "Here you can set up and manage a single authentication system (SSO)." + title: "SSO" + content: "Här kan du konfigurera och hantera ett enda autentiseringssystem (SSO)." invoices: welcome: - title: "Invoices" - content: "

Here you will be able to download invoices and credit notes issued, as well as manage everything related to accounting and invoicing.

If you use third-party software to manage your invoices, it is possible to deactivate the billing module. For this, contact your system administrator.

" + title: "Fakturor" + content: "

Här kommer du att kunna ladda ner utfärdade fakturor och kreditfakturor , samt hantera allt som rör redovisning och fakturering.

Om du använder tredjepartsprogramvara för att hantera dina fakturor är det möjligt att inaktivera faktureringsmodulen. För detta, kontakta din systemadministratör.

" welcome_manager: - title: "Invoices" - content: "Here you will be able to download invoices and create credit notes." + title: "Fakturor" + content: "Här kan du ladda ner fakturor och skapa kreditfaktura." list: - title: "Invoices list" - content: "By default, this table lists all the invoices and credit notes issued by Fab-manager. You can sort the list in a different order by clicking on the header of each column." + title: "Lista med fakturor" + content: "Som standard listar denna tabell alla fakturor och kreditfakturor utfärdade av systemet. Du kan sortera listan i en annan ordning genom att klicka på rubriken i varje kolumn." chained: - title: "Chaining indicator" - content: "

This icon ensures the inalterability of the accounting data of the invoice on this line, in accordance with the French finance law of 2018 against VAT fraud.

If a red icon appears instead of this one , please contact technical support immediately.

" + title: "Kedjande indikator" + content: "

Denna ikon säkerställer att räkenskaperna för fakturan är oföränderliga på denna rad, i enlighet med bokföringslagen.

Om en röd ikon visas istället för den här , vänligen kontakta teknisk support omedelbart.

" download: - title: "Download" - content: "Click here to download the invoice in PDF format." + title: "Ladda ner" + content: "Klicka här för att ladda ner fakturan i PDF-format." refund: - title: "Credit note" - content: "Allows you to generate a credit note for the invoice on this line or some of its sub-elements. Warning: This will only generate the accounting document, the actual refund of the user will always be your responsibility." + title: "Kreditfaktura" + content: "Låter dig generera en kreditfaktura för fakturan på den här raden eller några av dess underelement. Varning: Detta kommer bara generera bokföringsdokumentet, den faktiska återbetalningen av användaren kommer alltid att vara ditt ansvar." payment-schedules: - title: "Payment schedules" - content: "

Some subscription plans may be configured to allow the members to pay them with a monthly payment schedule.

Here you can view all existing payment schedules and manage their deadlines.

Click on [+] at the beginning of a row to display all deadlines associated with a payment schedule, and run some actions on them.

" + title: "Betalningsschema" + content: "

Vissa prenumerationsplaner kan konfigureras så att medlemmarna kan betala dem med en månatlig betalningsschema.

Här kan du se alla befintliga betalningsscheman och hantera deras deadlines.

Klicka på [+] i början av en rad för att visa alla deadlines kopplade till ett betalningsschema, och köra några åtgärder på dem.

" settings: - title: "Settings" - content: "

Here you can modify the parameters for invoices generation. Click on the item you are interested in to start editing.

In particular, this is where you can set if you are subject to VAT and the applicable rate.

" + title: "Inställningar" + content: "

Här kan du ändra parametrarna för generering av fakturor. Klicka på det objekt du är intresserad av för att börja redigera.

I synnerhet är det här du kan ställa in om du är momsbelagd och tillämplig taxa.

" codes: - title: "Accounting codes" - content: "Set the accounting codes here for all kinds of entries generated by the software. This setting is only required if you use the accounting export functionality." + title: "Redovisningskoder" + content: "Ange redovisningskoderna här för alla typer av poster som genereras av programvaran. Denna inställning krävs endast om du använder funktionen för export av bokföring." export: - title: "Accounting export" - content: "Once the codes have been configured, click here to access the interface allowing you to export the entries to a third-party accounting software." + title: "Bokföringsexporter" + content: "När koderna har konfigurerats, klicka här för att komma åt gränssnittet så att du kan exportera poster till en tredje parts redovisningsprogram." payment: - title: "Payment settings" - content: "If you want to allow your members to book directly online by paying by credit card, you can activate and configure this feature from this page." + title: "Betalningsinställningar" + content: "Om du vill tillåta dina medlemmar att boka direkt online genom att betala med kreditkort, kan du aktivera och konfigurera denna funktion från denna sida." periods: - title: "Close accounting periods" - content: "

The regulations of your country may require you to close your accounts regularly. The interface accessible from this button allows you to do this.

In France, if you are subject to VAT anti-fraud law BOI-TVA-DECLA-30-10-30-20160803, this closing is mandatory at least once a year.

As a reminder, if you have to use a certified software (take the test here), you are under the legal obligation to provide a certificate of compliance of the software. Contact-us to get it.

" + title: "Stäng bokföringsperioder" + content: "

Reglerna i ditt land kan kräva att du stänger dina konton regelbundet. Gränssnittet tillgängligt från denna knapp låter dig göra detta.

I Frankrike, om du omfattas av momsskyddslagen BOI-TVA-DECLA-30-10-20160803, Denna stängning är obligatorisk minst en gång per år.

Som en påminnelse, om du måste använda en certifierad programvara (ta testet här), du har en rättslig skyldighet att tillhandahålla ett intyg om efterlevnad av programvaran. Kontakt-oss för att få den.

" pricing: welcome: - title: "Subscriptions & Prices" - content: "Manage subscription plans and prices for the various services you offer to your members." + title: "Prenumerationer och priser" + content: "Hantera prenumerationsplaner och priser för de olika tjänster du erbjuder till dina medlemmar." new_plan: - title: "New subscription plan" - content: "Create subscription plans to offer preferential prices on machines and spaces to regular users." + title: "En prenumerationsplan" + content: "Skapa prenumerationsplaner för att erbjuda förmånliga priser på maskiner och utrymmen till återkommande användare." trainings: - title: "Trainings" - content: "Define training prices here, by user group." + title: "Utbildningar" + content: "Definiera utbildningspriserna här, efter användargrupp." machines: - title: "Machines" - content: "Define here the prices of the machine slots, by user group. These prices will be applied to users who do not have subscriptions." + title: "Utrustning" + content: "Definiera här priserna på platser, efter användargrupp. Dessa priser kommer att tillämpas på användare som inte har prenumerationer." spaces: - title: "Spaces" - content: "In the same way, define here the prices of the spaces slots, for the users without subscriptions." + title: "Utrymmen" + content: "På samma sätt, definiera här priserna på platser, för användare utan abonnemang." credits: - title: "Credits" - content: "

Credits allow you to give certain services for free to users who subscribe to a plan.

You can, for example, offer 2 hours of 3D printer for all annual subscriptions; or training of your choice for student subscribers, etc.

" + title: "Krediter" + content: "

Krediter tillåter dig att ge vissa tjänster gratis till användare som prenumererar på en plan.

Du kan till exempel erbjuda 2 timmars hoolabaloo för alla årliga prenumerationer; eller utbildning av ditt val för studentprenumeranter, etc.

" coupons: - title: "Coupons" - content: "Create and manage promotional coupons allowing to offer punctual discounts to their holders." + title: "Rabattkuponger" + content: "Skapa och hantera kampanjkuponger som gör det möjligt att erbjuda punktliga rabatter till sina innehavare." events: welcome: - title: "Events" - content: "Create events, track their reservations and organize them from this page." + title: "Evenemang" + content: "Skapa händelser, spåra deras bokningar och organisera dem från denna sida." list: - title: "The events" - content: "This list displays all past or future events, as well as the number of reservations for each of them." + title: "Evenemangen" + content: "Denna lista visar alla tidigare eller kommande evenemang, samt antalet bokningar för vart och ett av dem." filter: - title: "Filter events" - content: "Only display upcoming events in the list below; or on the contrary, only those already passed." + title: "Filtrera evenemang" + content: "Visa endast kommande evenemang i listan nedan; eller tvärtom, bara de som redan passerat." categories: - title: "Categories" - content: "Categories help your users know what type of event it is. A category is required for each of the newly created events." + title: "Kategorier" + content: "Kategorier hjälper dina användare att veta vilken typ av händelse det är. En kategori krävs för varje nyskapad händelse." themes: - title: "Themes" - content: "

Themes are an additional (and optional) categorization of your events. They can group together different events of very different forms.

For example, a two-day course about marquetry and an evening workshop about the handling of the wood planer, can be found in the theme « carpentry ».

" + title: "Teman" + content: "

Teman är ytterligare en (och frivillig) kategorisering av dina evenemang. De kan gruppera ihop olika evenemang av mycket olika former.

Till exempel en tvådagars kurs om mattvävning och en kvällsworkshop om broderi, kan hittas i temat « textil ».

" ages: - title: "Age groups" - content: "This other optional filter will help your users find events suited to their profile." + title: "Åldersgrupp" + content: "Detta andra valfria filter hjälper dina användare att hitta händelser som passar deras profil." prices: - title: "Pricing categories" - content: "The price of events does not depend on groups or subscriptions, but on the categories you define on this page." + title: "Priskategorier" + content: "Priset för evenemang beror inte på grupper eller prenumerationer, utan på vilka kategorier du definierar på denna sida." projects: welcome: - title: "Projects" - content: "Here you can define all the elements that will be available for members to document the projects they carry out. You can also define various parameters related to the projects." + title: "Projekt" + content: "Här kan du definiera alla element som kommer att vara tillgängliga för medlemmar att dokumentera de projekt som de utför. Du kan också definiera olika parametrar relaterade till projekten." abuses: - title: "Manage reports" - content: "

Access here the management of reports.

Visitors can signal projects, for example for copyright infringement or for hate speech.

GDPR requires you to delete this reporting data once the required actions have been taken.

" + title: "Hantera rapporter" + content: "

Åtkomst för hantering av rapporter.

Besökare kan signalera projekt, till exempel för upphovsrättsintrång eller för hatretorik.

GDPR kräver att du tar bort denna rapporteringsdata när de nödvändiga åtgärderna har vidtagits.

" settings: - title: "Settings" - content: "

Comments, CAD files ... Manage project parameters here

You can also activate OpenLab projects, in order to display the projects shared by other Fab Labs in your gallery.

" + title: "Inställningar" + content: "

Kommentarer, CAD-filer ... Hantera projektparametrar här

Du kan också aktivera OpenLab-projekt, För att visa projekt som delas av andra Fab Labs i ditt galleri.

" statistics: welcome: - title: "Statistics" - content: "

From here, you will be able to access many statistics on your members and their uses within your Fab Lab.

In accordance with GDPR, users who have deleted their account continue to be reported in the statistics, but anonymously.

" + title: "Statistik" + content: "

Härifrån kommer du att kunna få tillgång till statistik om dina medlemmar och deras användning av ditt Fab Lab.

I enlighet med GDPR fortsätter användare som har raderat sitt konto att rapporteras i statistiken, men anonymt.

" export: - title: "Export data" - content: "You can choose to export all or part of the statistical data to an Excel file." + title: "Exportera data" + content: "Du kan välja att exportera hela eller delar av statistikuppgifterna till en Excel-fil." trending: - title: "Evolution" - content: "Visualize the evolution over time of the main uses of your Fab Lab, thanks to graphs and curves." + title: "Utveckling" + content: "Visualisera utvecklingen över tid för de viktigaste användningsområdena för ditt Fab Lab, med hjälp av grafer och kurvor." settings: welcome: - title: "Application customization" - content: "From here, you can configure the general settings of Fab-manager, enable or disable the optional modules and customize various elements of the interface." + title: "Anpassning av program" + content: "Härifrån kan du konfigurera de allmänna inställningarna för Fab-manager, aktivera eller inaktivera de valfria modulerna och anpassa olika delar av gränssnittet." general: - title: "General settings" - content: "A lot a settings can be customized from here. Take time to look all over this page, it will let you customize messages, documents, optional modules, registrations, visual aspect of Fab-manager, and much more." + title: "Allmänna inställningar" + content: "En hel del en inställningar kan anpassas härifrån. Ta dig tid att titta över hela denna sida, det kommer att låta dig anpassa meddelanden, dokument, valfria moduler, registreringar, visuell aspekt av Fab-Manager och mycket mer." home: - title: "Customize home page" - content: "

This WYSIWYG editor allows you to customize the appearance of the home page while using different components (last tweet, brief, etc.).

Warning: Keep in mind that any uncontrolled changes can break the appearance of the home page.

" + title: "Anpassa startsidan" + content: "

Denna WYSIWYG-redigerare låter dig anpassa utseendet på startsidan när du använder olika komponenter (senaste tweet, kort etc.).

Varning: Tänk på att eventuella okontrollerade förändringar kan bryta utseendet på startsidan.

" components: title: "Insert a component" - content: "Click here to insert a pre-existing component into the home page." + content: "Klicka här för att infoga en befintlig komponent i startsidan." codeview: - title: "Display HTML code" - content: "This button allows you to directly view and modify the code of the home page. This is the recommended way to proceed, but it requires prior knowledge of HTML." + title: "Visa HTML-kod" + content: "Denna knapp låter dig direkt visa och ändra koden för startsidan. Detta är det rekommenderade sättet att gå vidare, men det kräver förkunskaper i HTML." reset: - title: "Go back" - content: "At any time, you can restore the original home page by clicking here." + title: "Gå tillbaka" + content: "När som helst kan du återställa den ursprungliga hemsidan genom att klicka här." css: - title: "Customize the style sheet" - content: "For advanced users, it is possible to define a custom style sheet (CSS) for the home page." + title: "Anpassa formatmallen" + content: "För avancerade användare är det möjligt att definiera en anpassad formatmall (CSS) för startsidan." about: - title: "About" - content: "Fully personalize this page to present your activity." + title: "Om" + content: "Helt anpassa denna sida för att presentera din aktivitet." privacy: - title: "Privacy policy" - content: "

Explain here how you use the data you collect about your members.

GDPR requires that a confidentiality policy is defined, as well as a data protection officer.

" + title: "Integritetspolicy" + content: "

Förklara här hur du använder de uppgifter du samlar in om dina medlemmar.

GDPR kräver att en sekretesspolicy definieras, liksom ett dataskyddsombud.

" draft: - title: "Draft" - content: "Click here to view a privacy policy draft with holes, which you just need to read and complete." + title: "Utkast" + content: "Klicka här för att se en sekretesspolicy utkast med hål, som du bara behöver läsa och slutföra." reservations: - title: "Reservations" - content: "Opening hours, chance to cancel reservations... Each Fablab has its own reservation rules, which you can define on this page." + title: "Bokningar" + content: "Öppettider, möjlighet att avboka... Varje Fablab har sina egna bokningsregler, som du kan definiera på denna sida." open_api: welcome: title: "OpenAPI" - content: "Fab-manager offers an open API allowing third-party software to deal simply with its data. This screen allows you to grant accesses to this API." + content: "Fab-manager erbjuder ett öppet API som gör det möjligt för tredjepartsprogram att hantera sina data. Denna skärm låter dig ge åtkomst till detta API." doc: - title: "Documentation" - content: "Click here to access the API online documentation." + title: "Dokumentation" + content: "Klicka här för att komma åt API: et online dokumentation." store: - manage_the_store: "Manage the Store" - settings: "Settings" - all_products: "All products" - categories_of_store: "Store categories" - the_orders: "Orders" - back_to_list: "Back to list" + manage_the_store: "Hantera rapporter" + settings: "Inställningar" + all_products: "Alla produkter" + categories_of_store: "Butikskategorier" + the_orders: "Beställningar" + back_to_list: "Tillbaka till listan" product_categories: - title: "All categories" - info: "Arrange categories with a drag and drop on a maximum of two levels. The order of the categories will be identical between the list below and the public view. Please note that you can delete a category or a sub-category even if they are associated with products. Those products will be left without categories. If you delete a category that contains sub-categories, the latter will also be deleted." + title: "Alla kategorier" + info: "Ordna kategorier genom dra och släpp på högst två nivåer. Ordningen för kategorierna kommer att vara identisk mellan listan nedan och den publika vyn. Observera att du kan ta bort en kategori eller en underkategori även om de är associerade med produkter. Dessa produkter kommer att lämnas utan kategorier. Om du tar bort en kategori som innehåller underkategorier kommer de senare också att raderas." manage_product_category: - create: "Create a product category" - update: "Modify the product category" - delete: "Delete the product category" + create: "Skapa en produktkategori" + update: "Ändra produktkategorin" + delete: "Ta bort produktkategorin" product_category_modal: - new_product_category: "Create a category" - edit_product_category: "Modify a category" + new_product_category: "Skapa en kategori" + edit_product_category: "Ändra en kategori" product_category_form: - name: "Name of category" + name: "Namn på kategori" slug: "URL" - select_parent_product_category: "Choose a parent category (N1)" - no_parent: "No parent" + select_parent_product_category: "Välj en överordnad kategori (N1)" + no_parent: "Ingen förälder" create: - error: "Unable to create the category: " - success: "The new category has been created." + error: "Det går inte att skapa kategori: " + success: "Den nya kategorin har skapats." update: - error: "Unable to modify the category: " - success: "The category has been modified." + error: "Det går inte att uppdatera kategorin: " + success: "Kategorin har ändrats." delete: - confirm: "Do you really want to delete {CATEGORY}?
If it has sub-categories, they will also be deleted." - save: "Delete" - error: "Unable to delete the category: " - success: "The category has been successfully deleted" - save: "Save" - required: "This field is required" - slug_pattern: "Only lowercase alphanumeric groups of characters separated by an hyphen" + confirm: "Vill du verkligen ta bort {CATEGORY}?
Om det finns underkategorier kommer de också att raderas." + save: "Ta bort" + error: "Det går inte att ta bort kategorin: " + success: "Kategorin har tagits bort" + save: "Spara" + required: "Detta fält är obligatoriskt" + slug_pattern: "Endast gemener alfanumeriska grupper av tecken åtskilda av ett bindestreck" categories_filter: - filter_categories: "By categories" - filter_apply: "Apply" + filter_categories: "Efter kategorier" + filter_apply: "Verkställ" machines_filter: - filter_machines: "By machines" - filter_apply: "Apply" + filter_machines: "Utrustningen" + filter_apply: "Verkställ" keyword_filter: - filter_keywords_reference: "By keywords or reference" - filter_apply: "Apply" + filter_keywords_reference: "Med sökord eller referens" + filter_apply: "Verkställ" stock_filter: - stock_internal: "Private stock" - stock_external: "Public stock" - filter_stock: "By stock status" - filter_stock_from: "From" - filter_stock_to: "to" - filter_apply: "Apply" + stock_internal: "Privat lager" + stock_external: "Publikt lager" + filter_stock: "Efter lagerstatus" + filter_stock_from: "Från" + filter_stock_to: "till" + filter_apply: "Verkställ" products: - unexpected_error_occurred: "An unexpected error occurred. Please try again later." - all_products: "All products" - create_a_product: "Create a product" - filter: "Filter" - filter_clear: "Clear all" - filter_apply: "Apply" - filter_categories: "By categories" - filter_machines: "By machines" - filter_keywords_reference: "By keywords or reference" - filter_stock: "By stock status" - stock_internal: "Private stock" - stock_external: "Public stock" - filter_stock_from: "From" - filter_stock_to: "to" + unexpected_error_occurred: "Ett oväntat fel inträffade. Var god försök senare." + all_products: "Alla produkter" + create_a_product: "Skapa en produkt" + filter: "Filtrera" + filter_clear: "Rensa allt" + filter_apply: "Verkställ" + filter_categories: "Efter kategorier" + filter_machines: "Utrustningen" + filter_keywords_reference: "Med sökord eller referens" + filter_stock: "Efter lagerstatus" + stock_internal: "Privat lager" + stock_external: "Publikt lager" + filter_stock_from: "Från" + filter_stock_to: "till" sort: - name_az: "A-Z" - name_za: "Z-A" - price_low: "Price: low to high" - price_high: "Price: high to low" + name_az: "A-Ö" + name_za: "Ö-A" + price_low: "Pris: lågt till högt" + price_high: "Pris: högt till lågt" store_list_header: - result_count: "Result count:" - sort: "Sort:" - visible_only: "Visible products only" + result_count: "Antal resultat:" + sort: "Sortera:" + visible_only: "Endast synliga produkter" product_item: - product: "product" - visible: "visible" - hidden: "hidden" + product: "produkt" + visible: "synlig" + hidden: "dolt" stock: - internal: "Private stock" - external: "Public stock" - unit: "unit" + internal: "Privat lager" + external: "Publikt lager" + unit: "enhet" new_product: - add_a_new_product: "Add a new product" - successfully_created: "The new product has been created." + add_a_new_product: "Lägg till en ny produkt" + successfully_created: "Den nya produkten har skapats." edit_product: - successfully_updated: "The product has been updated." - successfully_cloned: "The product has been duplicated." + successfully_updated: "Produkten har uppdaterats." + successfully_cloned: "Produkten har duplicerats." product_form: - product_parameters: "Product parameters" - stock_management: "Stock management" - description: "Description" - description_info: "The text will be presented in the product sheet. You have a few editorial styles at your disposal." - name: "Name of product" - sku: "Product reference (SKU)" + product_parameters: "Produktparametrar" + stock_management: "Lagerhantering" + description: "Beskrivning" + description_info: "Texten kommer att presenteras i produktbladet. Du har några redaktionella stilar till ditt förfogande." + name: "Namn på produkt" + sku: "Produktreferens (SKU)" slug: "URL" - is_show_in_store: "Available in the store" - is_active_price: "Activate the price" - active_price_info: "Is this product visible by the members on the store?" - price_and_rule_of_selling_product: "Price and rule for selling the product" - price: "Price of product" - quantity_min: "Minimum number of items for the shopping cart" - linking_product_to_category: "Linking this product to an existing category" - assigning_category: "Assigning a category" - assigning_category_info: "You can only declare one category per product. If you assign this product to a sub-category, it will automatically be assigned to its parent category as well." - assigning_machines: "Assigning machines" - assigning_machines_info: "You can link one or more machines from your workshop to your product. This product will then be subject to the filters on the catalogue view. The selected machines will be linked to the product." - product_files: "Document" - product_files_info: "Add documents related to this product. They will be presented in the product sheet, in a separate block. You can only upload PDF documents." - add_product_file: "Add a document" - product_images: "Visuals of the product" - product_images_info: "We advise you to use a square format, JPG or PNG. For JPG, please use white for the background colour. The main visual will be the first presented in the product sheet." - add_product_image: "Add a visual" - save: "Save" - clone: "Duplicate" + is_show_in_store: "Finns i butiken" + is_active_price: "Aktivera priset" + active_price_info: "Är denna produkt synlig för medlemmarna i butiken?" + price_and_rule_of_selling_product: "Pris och regel för försäljning av produkten" + price: "Produktpris" + quantity_min: "Minsta antal varor för varukorgen" + linking_product_to_category: "Länka denna produkt till en befintlig kategori" + assigning_category: "Tilldela en kategori" + assigning_category_info: "Du kan bara deklarera en kategori per produkt. Om du tilldelar denna produkt till en underkategori kommer den även automatiskt att tilldelas dess överordnade kategori." + assigning_machines: "Tilldela utrustning" + assigning_machines_info: "Du kan länka utrustning i din lokal till din produkt. Denna produkt kommer då att omfattas av filtren på katalogvyn. Den valda utrustningen kommer att länkas till produkten." + product_files: "Dokument" + product_files_info: "Lägg till dokument relaterade till denna produkt. De kommer att presenteras i produktbladet, i ett separat block. Du kan endast ladda upp PDF-dokument." + add_product_file: "Lägg till ett dokument" + product_images: "Bilder av produkten" + product_images_info: "Vi råder dig att använda ett fyrkantigt format, JPG eller PNG. För JPG, använd vit för bakgrundsfärg. Den huvudsakliga bilden kommer att vara den första som presenteras i produktbladet." + add_product_image: "Lägg till en bild" + save: "Spara" + clone: "Duplicera" product_stock_form: - stock_up_to_date: "Stock up to date" - date_time: "{DATE} - {TIME}" - ongoing_operations: "Ongoing stock operations" - save_reminder: "Don't forget to save your operations" - low_stock_threshold: "Define a low stock threshold" - stock_threshold_toggle: "Activate stock threshold" - stock_threshold_info: "Define a low stock threshold and receive a notification when it's reached. When the threshold is reached, the product quantity is labeled as low." - low_stock: "Low stock" - threshold_level: "Minimum threshold level" - threshold_alert: "Notify me when the threshold is reached" - events_history: "Events history" - event_type: "Events:" - reason: "Reason" - stocks: "Stock:" - internal: "Private stock" - external: "Public stock" - edit: "Edit" - all: "All types" - remaining_stock: "Remaining stock" - type_in: "Add" - type_out: "Remove" - cancel: "Cancel this operation" + stock_up_to_date: "Lager uppdaterat" + date_time: "{DATE} {TIME}" + ongoing_operations: "Pågående lagerverksamhet" + save_reminder: "Glöm inte att spara dina ändringar" + low_stock_threshold: "Definiera en låg lagergräns" + stock_threshold_toggle: "Aktivera lagertröskel" + stock_threshold_info: "Definiera en låg lagergräns och få ett meddelande när den har nåtts. När tröskeln är nådd, är produktens kvantitet märkt som låg." + low_stock: "Lågt lagersaldo" + threshold_level: "Minsta tröskelnivå" + threshold_alert: "Meddela mig när tröskeln är nådd" + events_history: "Evenemangshistorik" + event_type: "Evenemang:" + reason: "Orsak" + stocks: "Lagersaldo:" + internal: "Privat lager" + external: "Publikt lager" + edit: "Redigera" + all: "Alla typer" + remaining_stock: "Återstående lager" + type_in: "Lägg till" + type_out: "Ta bort" + cancel: "Avbryt åtgärden" product_stock_modal: - modal_title: "Manage stock" - internal: "Private stock" - external: "Public stock" - new_event: "New stock event" - addition: "Addition" - withdrawal: "Withdrawal" - update_stock: "Update stock" - reason_type: "Reason" - stocks: "Stock:" - quantity: "Quantity" + modal_title: "Hantera lager" + internal: "Privat lager" + external: "Publikt lager" + new_event: "Ny lagerhändelse" + addition: "Lägga till" + withdrawal: "Uttag" + update_stock: "Uppdatera lager" + reason_type: "Orsak" + stocks: "Lagersaldo:" + quantity: "Kvantitet" stock_movement_reason: - inward_stock: "Inward stock" - returned: "Returned by client" - cancelled: "Canceled by client" - inventory_fix: "Inventory fix" - sold: "Sold" - missing: "Missing in stock" - damaged: "Damaged product" - other_in: "Other (in)" - other_out: "Other (out)" + inward_stock: "Ingående lager" + returned: "Returnerad av klient" + cancelled: "Avbruten av kund" + inventory_fix: "Fixera lager" + sold: "Såld" + missing: "Saknas i lager" + damaged: "Skadad produkt" + other_in: "Annat (in)" + other_out: "Annat (ut)" clone_product_modal: - clone_product: "Duplicate the product" - clone: "Duplicate" - name: "Name" - sku: "Product reference (SKU)" - is_show_in_store: "Available in the store" - active_price_info: "Is this product visible by the members on the store?" + clone_product: "Duplicera produkten" + clone: "Duplicera" + name: "Namn" + sku: "Produktreferens (SKU)" + is_show_in_store: "Finns i butiken" + active_price_info: "Är denna produkt synlig för medlemmarna i butiken?" orders: - heading: "Orders" - create_order: "Create an order" - filter: "Filter" - filter_clear: "Clear all" - filter_apply: "Apply" - filter_ref: "By reference" - filter_status: "By status" - filter_client: "By client" - filter_period: "By period" - filter_period_from: "From" - filter_period_to: "to" + heading: "Beställningar" + create_order: "Skapa beställning" + filter: "Filtrera" + filter_clear: "Rensa allt" + filter_apply: "Verkställ" + filter_ref: "Efter referens" + filter_status: "Efter status" + filter_client: "Efter kund" + filter_period: "Efter period" + filter_period_from: "Från" + filter_period_to: "till" state: - cart: 'Cart' - in_progress: 'Under preparation' - paid: "Paid" - payment_failed: "Payment error" - canceled: "Canceled" - ready: "Ready" - refunded: "Refunded" - delivered: "Delivered" + cart: 'Varukorg' + in_progress: 'Under behandling' + paid: "Betald" + payment_failed: "Fel vid betalning" + canceled: "Avbruten" + ready: "Färdig" + refunded: "Återbetald" + delivered: "Levererat" sort: - newest: "Newest first" - oldest: "Oldest first" + newest: "Senaste först" + oldest: "Äldsta först" store_settings: - title: "Settings" - withdrawal_instructions: 'Product withdrawal instructions' - withdrawal_info: "This text is displayed on the checkout page to inform the client about the products withdrawal method" - store_hidden_title: "Store publicly available" - store_hidden_info: "You can hide the store to the eyes of the members and the visitors." - store_hidden: "Hide the store" - save: "Save" - update_success: "The settings were successfully updated" + title: "Inställningar" + withdrawal_instructions: 'Instruktioner för produktuttag' + withdrawal_info: "Denna text visas på kassan sida för att informera kunden om produkter uttagsmetod" + store_hidden_title: "Butiken är offentligt tillgänglig" + store_hidden_info: "Du kan gömma butiken för medlemmarna och besökarna." + store_hidden: "Dölj butiken" + save: "Spara" + update_success: "Inställningarna sparades" invoices_settings_panel: - disable_invoices_zero: "Disable the invoices at 0" - disable_invoices_zero_label: "Do not generate invoices at {AMOUNT}" - filename: "Edit the file name" - filename_info: "Information

The invoices are generated as PDF files, named with the following prefix.

" - schedule_filename: "Edit the payment schedule file name" - schedule_filename_info: "Information

The payment shedules are generated as PDF files, named with the following prefix.

" + disable_invoices_zero: "Inaktivera fakturor på 0" + disable_invoices_zero_label: "Generera inte fakturor på {AMOUNT}" + filename: "Redigera filnamnet" + filename_info: "Information

Fakturorna genereras som PDF-filer, namngivna med följande prefix.

" + schedule_filename: "Redigera filnamnet för betalningsschemat" + schedule_filename_info: "Information

Betalningsplanerna genereras som PDF-filer, namngivna med följande prefix.

" prefix: "Prefix" - example: "Example" - save: "Save" - update_success: "The settings were successfully updated" + example: "Exempel" + save: "Spara" + update_success: "Inställningarna sparades" vat_settings_modal: - title: "VAT settings" - update_success: "The VAT settings were successfully updated" - enable_VAT: "Enable VAT" - VAT_name: "VAT name" - VAT_name_help: "Some countries or regions may require that the VAT is named according to their specific local regulation" - VAT_rate: "VAT rate" - VAT_rate_help: "This parameter configures the general case of the VAT rate and applies to everything sold by the Fablab. It is possible to override this parameter by setting a specific VAT rate for each object." - advanced: "More rates" - hide_advanced: "Less rates" - show_history: "Show the changes history" - VAT_rate_machine: "Machine reservation" - VAT_rate_space: "Space reservation" - VAT_rate_training: "Training reservation" - VAT_rate_event: "Event reservation" - VAT_rate_subscription: "Subscription" - VAT_rate_product: "Products (store)" - multi_VAT_notice: "Please note: The current general rate is {RATE}%. You can define different VAT rates for each category.

For example, you can override this value, only for machine reservations, by filling in the corresponding field beside. If you don't fill any value, the general rate will apply." - save: "Save" + title: "Inställningar för moms" + update_success: "Momsinställningarna har uppdaterats" + enable_VAT: "Aktivera moms" + VAT_name: "Momsbeteckning" + VAT_name_help: "Vissa länder eller regioner kan kräva att mervärdesskatten anges i enlighet med deras specifika lokala regler" + VAT_rate: "Momssats" + VAT_rate_help: "Denna parameter konfigurerar det allmänna fallet med momssatsen och gäller allt som säljs av Fablab. Det är möjligt att åsidosätta denna parameter genom att ställa in en specifik momssats för varje objekt." + advanced: "Fler momssatser" + hide_advanced: "Färre momssatser" + show_history: "Visa ändringshistorik" + VAT_rate_machine: "Utrustningsbokning" + VAT_rate_space: "Lokalbokning" + VAT_rate_training: "Bokning av utbildning" + VAT_rate_event: "Evenmangsbokning" + VAT_rate_subscription: "Prenumeration" + VAT_rate_product: "Produkter (butik)" + multi_VAT_notice: "Observera: Den nuvarande generella skattesatsen är {RATE}%. Du kan ange olika momssatser för varje kategori.

Till exempel kan du åsidosätta detta värde, endast för utrustningsreservationer, genom att fylla i motsvarande fält bredvid. Om du inte fyller något värde kommer det allmänna priset att gälla." + save: "Spara" setting_history_modal: - title: "Changes history" - no_history: "No changes for now." - setting: "Setting" - value: "Value" - date: "Changed at" - operator: "By" + title: "Ändringshistorik" + no_history: "Inga ändringar för tillfället." + setting: "Inställning" + value: "Värde" + date: "Ändrad" + operator: "Av" editorial_block_form: - content: "Content" - content_is_required: "You must provide a content. If you wish to disable the banner, toggle the switch above this field." - label_is_required: "You must provide a label. If you wish to disable the button, toggle the switch above this field." - url_is_required: "You must provide a link for your button." - url_must_be_safe: "The button link should start with http://... or https://..." + content: "Innehåll" + content_is_required: "Du måste ange ett innehåll. Om du vill inaktivera bannern, växla knappen ovanför detta fält." + label_is_required: "Du måste ange en etikett. Om du vill inaktivera knappen, växla knappen ovanför detta fält." + url_is_required: "Du måste ange en länk för din knapp." + url_must_be_safe: "Knapplänken bör börja med http://... eller https://..." title: "Banner" - switch: "Display the banner" - cta_switch: "Display a button" - cta_label: "Button label" - cta_url: "Button link" + switch: "Visa bannern" + cta_switch: "Visa en knapp" + cta_label: "Knappetikett" + cta_url: "Knapplänk" reservation_contexts: - name: "Name" - applicable_on: "Applicable on" - machine: Machine - training: Training - space: Space + name: "Namn" + applicable_on: "Tillämpligt på" + machine: Utrustning + training: Utbildning + space: Lokal diff --git a/config/locales/app.admin.zu.yml b/config/locales/app.admin.zu.yml index 8aa309b99..b25b35f71 100644 --- a/config/locales/app.admin.zu.yml +++ b/config/locales/app.admin.zu.yml @@ -276,6 +276,8 @@ zu: card: "crwdns32011:0crwdne32011:0" wallet_debit: "crwdns32013:0crwdne32013:0" other: "crwdns32015:0crwdne32015:0" + transfer: "crwdns38166:0crwdne38166:0" + check: "crwdns38168:0crwdne38168:0" wallet_credit: "crwdns32017:0crwdne32017:0" VAT: "crwdns32019:0crwdne32019:0" sales: "crwdns32021:0crwdne32021:0" @@ -1147,7 +1149,7 @@ zu: date: "crwdns25532:0crwdne25532:0" update_payment_mean_modal: title: "crwdns25534:0crwdne25534:0" - update_info: "crwdns25536:0crwdne25536:0" + update_info: "crwdns38170:0crwdne38170:0" select_payment_mean: "crwdns25538:0crwdne25538:0" method_Transfer: "crwdns25540:0crwdne25540:0" method_Check: "crwdns25542:0crwdne25542:0" diff --git a/config/locales/app.public.sv.yml b/config/locales/app.public.sv.yml index d0bfb8706..847b0149e 100644 --- a/config/locales/app.public.sv.yml +++ b/config/locales/app.public.sv.yml @@ -3,7 +3,7 @@ sv: public: #header and "about" page common: - about_the_fablab: "Om {GENDER, select, male{den} female{den} neutral{} other{den}} {NAME}" + about_the_fablab: "Om {GENDER, select, male{} female{} neutral{} other{}} {NAME}" return: "Tillbaka" #cookies cookies: From d897d05cdf90974bbc5d9610cafb51100672ea3b Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 12 Feb 2024 11:53:52 +0100 Subject: [PATCH 15/92] Version 6.3.12 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43bf0391f..c8026f9ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +## v6.3.12 2024 February 12 + - improvement: Allow the admin to update payment method only the overdue subscription item without cancel PayZen subscription - improvement: add payment transfer/check to accounting settings - updates translations diff --git a/package.json b/package.json index f3fc01be1..4aa743575 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fab-manager", - "version": "6.3.11", + "version": "6.3.12", "description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.", "keywords": [ "fablab", From f79c2fe0a98c2fbcc83651c7c79d9ab7c4343622 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 15 Feb 2024 15:29:30 +0100 Subject: [PATCH 16/92] (feat) add settlement by transfer/check to invoice paiement info --- CHANGELOG.md | 2 ++ app/services/invoices/payment_details_service.rb | 4 ++++ config/locales/en.yml | 2 ++ 3 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8026f9ed..a10840ff4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +- improvement: add settlement by transfer/check to invoice paiement info + ## v6.3.12 2024 February 12 - improvement: Allow the admin to update payment method only the overdue subscription item without cancel PayZen subscription diff --git a/app/services/invoices/payment_details_service.rb b/app/services/invoices/payment_details_service.rb index 56181f504..7d7ace7bd 100644 --- a/app/services/invoices/payment_details_service.rb +++ b/app/services/invoices/payment_details_service.rb @@ -62,6 +62,10 @@ class Invoices::PaymentDetailsService # else if invoice.paid_by_card? I18n.t('invoices.settlement_by_debit_card') + elsif paid_by_transfer? + I18n.t('invoices.settlement_by_transfer') + elsif paid_by_check? + I18n.t('invoices.settlement_by_check') else I18n.t('invoices.settlement_done_at_the_reception') end diff --git a/config/locales/en.yml b/config/locales/en.yml index cc3437fe5..9252146be 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -126,6 +126,8 @@ en: by_wallet: "by wallet" no_refund: "No refund" settlement_by_debit_card: "Settlement by debit card" + settlement_by_transfer: "Settlement by transfer" + settlement_by_check: "Settlement by check" settlement_done_at_the_reception: "Settlement done at the reception" settlement_by_wallet: "Settlement by wallet" on_DATE_at_TIME: "on %{DATE} at %{TIME}," From 45bbd99340b4502a17f0186f667418c46d89bdd4 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 19 Feb 2024 12:55:28 +0100 Subject: [PATCH 17/92] (bug) missing payment transfer journal code in accouting line --- CHANGELOG.md | 1 + app/services/accounting/accounting_journal_service.rb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a10840ff4..d2a15a33f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Next release +- Fix a bug: missing payment transfer journal code in accouting line - improvement: add settlement by transfer/check to invoice paiement info ## v6.3.12 2024 February 12 diff --git a/app/services/accounting/accounting_journal_service.rb b/app/services/accounting/accounting_journal_service.rb index 454d01836..1747289a8 100644 --- a/app/services/accounting/accounting_journal_service.rb +++ b/app/services/accounting/accounting_journal_service.rb @@ -13,6 +13,8 @@ class Accounting::AccountingJournalService payment: { card: Setting.get('accounting_payment_card_journal_code') || '', wallet: Setting.get('accounting_payment_wallet_journal_code') || '', + transfer: Setting.get('accounting_payment_transfer_journal_code') || '', + check: Setting.get('accounting_payment_check_journal_code') || '', other: Setting.get('accounting_payment_other_journal_code') || '' } } From 015a1d7532354dbff0a519e2ca7f6affb5b2010c Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 19 Feb 2024 12:55:55 +0100 Subject: [PATCH 18/92] (bug) Unable to sync iCalendar correctly --- CHANGELOG.md | 1 + app/services/i_calendar_import_service.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2a15a33f..65053097f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Next release - Fix a bug: missing payment transfer journal code in accouting line +- Fix a bug: unable to sync iCalendar correctly - improvement: add settlement by transfer/check to invoice paiement info ## v6.3.12 2024 February 12 diff --git a/app/services/i_calendar_import_service.rb b/app/services/i_calendar_import_service.rb index 2664436bd..3f3edf6e1 100644 --- a/app/services/i_calendar_import_service.rb +++ b/app/services/i_calendar_import_service.rb @@ -18,7 +18,7 @@ class ICalendarImportService cal.events.each do |evt| uids.push(evt.uid.to_s) ICalendarEvent.update_or_create_by( - { uid: evt.uid.to_s }, + { uid: evt.uid.to_s, i_calendar_id: i_calendar_id}, { dtstart: evt.dtstart, dtend: evt.dtend, From 8686931ef3f11c6c51877e80e3c848290248bdc5 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 19 Feb 2024 14:32:41 +0100 Subject: [PATCH 19/92] (feat) hide machines/themes/components filter in project list if machines module is disable or themes/components is empty --- CHANGELOG.md | 1 + app/frontend/templates/projects/index.html | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65053097f..959207ac5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Fix a bug: missing payment transfer journal code in accouting line - Fix a bug: unable to sync iCalendar correctly - improvement: add settlement by transfer/check to invoice paiement info +- improvement: hide machines/themes/components filter in project list if machines module is disable or themes/components is empty ## v6.3.12 2024 February 12 diff --git a/app/frontend/templates/projects/index.html b/app/frontend/templates/projects/index.html index 1fd2dca66..6aabdbc52 100644 --- a/app/frontend/templates/projects/index.html +++ b/app/frontend/templates/projects/index.html @@ -53,11 +53,11 @@ - - @@ -65,7 +65,7 @@ - From 0f7b1f4b8ec6ade6374b5cf2a7f0ee283e2af15d Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 19 Feb 2024 14:44:28 +0100 Subject: [PATCH 20/92] (i18n) update translations --- CHANGELOG.md | 1 + config/locales/app.public.sv.yml | 12 ++++++------ config/locales/app.shared.sv.yml | 4 ++-- config/locales/de.yml | 2 ++ config/locales/es-MX.yml | 2 ++ config/locales/es.yml | 2 ++ config/locales/fr.yml | 2 ++ config/locales/it.yml | 2 ++ config/locales/no.yml | 2 ++ config/locales/pt.yml | 2 ++ config/locales/sv.yml | 2 ++ config/locales/zu.yml | 2 ++ 12 files changed, 27 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 959207ac5..d1d7241d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Fix a bug: unable to sync iCalendar correctly - improvement: add settlement by transfer/check to invoice paiement info - improvement: hide machines/themes/components filter in project list if machines module is disable or themes/components is empty +- updates translations ## v6.3.12 2024 February 12 diff --git a/config/locales/app.public.sv.yml b/config/locales/app.public.sv.yml index 847b0149e..2f4082591 100644 --- a/config/locales/app.public.sv.yml +++ b/config/locales/app.public.sv.yml @@ -38,10 +38,10 @@ sv: reduce_panel: "Minska panelen" #left menu (public) home: "Startsida" - reserve_a_machine: "Boka en maskin" - trainings_registrations: "Registrera utbildning" - events_registrations: "Registrera evenemang" - reserve_a_space: "Boka lokal" + reserve_a_machine: "Boka utrustning" + trainings_registrations: "Utbildningar" + events_registrations: "Evenemang" + reserve_a_space: "Lokaler" projects_gallery: "Projektgalleri" subscriptions: "Prenumerationer" public_calendar: "Kalender" @@ -95,7 +95,7 @@ sv: address: "Adress" address_is_required: "Adress måste fyllas i" i_authorize_Fablab_users_registered_on_the_site_to_contact_me: "Jag samtycker till att dela min e-postadress med registrerade medlemmar på denna sida" - i_accept_to_receive_information_from_the_fablab: "Jag accepterar att få information från FabLab" + i_accept_to_receive_information_from_the_fablab: "Jag accepterar att få information" i_ve_read_and_i_accept_: "Jag har läst och accepterat" _the_fablab_policy: "användarvillkoren" field_required: "Obligatoriskt fält" @@ -244,7 +244,7 @@ sv: all_machines: "All utrustning" machine_card: book: "Boka" - consult: "Fråga" + consult: "Detaljer" #details of a machine machines_show: book_this_machine: "Boka utrustning" diff --git a/config/locales/app.shared.sv.yml b/config/locales/app.shared.sv.yml index f2cf9de79..564ba7036 100644 --- a/config/locales/app.shared.sv.yml +++ b/config/locales/app.shared.sv.yml @@ -4,7 +4,7 @@ sv: #translations of common buttons buttons: confirm_changes: "Bekräfta ändringar" - consult: "Fråga" + consult: "Detaljer" edit: "Redigera" change: "Ändra" delete: "Ta bort" @@ -127,7 +127,7 @@ sv: project: name: "Namn" name_is_required: "Namn måste fyllas i." - illustration: "Visuellt" + illustration: "Bild" illustration_recommendation: "Maximal skärmstorlek: 932 * 700 px (obegränsad förhållande)." add_an_illustration: "Lägg till en illustration" CAD_file: "CAD-fil" diff --git a/config/locales/de.yml b/config/locales/de.yml index 9a8917ddf..1ec779b13 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -126,6 +126,8 @@ de: by_wallet: "durch Guthaben" no_refund: "Keine Rückerstattung" settlement_by_debit_card: "Abrechnung per Debitkarte" + settlement_by_transfer: "Settlement by transfer" + settlement_by_check: "Settlement by check" settlement_done_at_the_reception: "Abrechnung an der Rezeption durchgeführt" settlement_by_wallet: "Abrechnung per Guthaben" on_DATE_at_TIME: "am %{DATE} um %{TIME}," diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index c1589fcce..97b9f76ff 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -126,6 +126,8 @@ es-MX: by_wallet: "por cartera" no_refund: "Sin devolución" settlement_by_debit_card: "Liquidación por tarjeta de débito" + settlement_by_transfer: "Settlement by transfer" + settlement_by_check: "Settlement by check" settlement_done_at_the_reception: "Liquidación realizada en la recepción" settlement_by_wallet: "Liquidación con cartera" on_DATE_at_TIME: "el %{DATE} a las %{TIME}," diff --git a/config/locales/es.yml b/config/locales/es.yml index b0fddcaf2..699dd8d36 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -126,6 +126,8 @@ es: by_wallet: "por cartera" no_refund: "Sin devolución" settlement_by_debit_card: "Liquidación por tarjeta de débito" + settlement_by_transfer: "Settlement by transfer" + settlement_by_check: "Settlement by check" settlement_done_at_the_reception: "Liquidación realizada en la recepción" settlement_by_wallet: "Liquidación con cartera" on_DATE_at_TIME: "el %{DATE} a las %{TIME}," diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 6dbfb6d84..53dd1d4f0 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -126,6 +126,8 @@ fr: by_wallet: "par porte-monnaie" no_refund: "Pas de remboursement" settlement_by_debit_card: "Règlement effectué par carte bancaire" + settlement_by_transfer: "Règlement effectué par virement" + settlement_by_check: "Règlement effectué par chèque" settlement_done_at_the_reception: "Règlement effectué à l'accueil" settlement_by_wallet: "Règlement effectué par porte-monnaie" on_DATE_at_TIME: "le %{DATE} à %{TIME}," diff --git a/config/locales/it.yml b/config/locales/it.yml index cccafc44c..2bd2c07e1 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -126,6 +126,8 @@ it: by_wallet: "mediante il portafoglio" no_refund: "Nessun rimborso" settlement_by_debit_card: "Pagamento con carta di debito" + settlement_by_transfer: "Settlement by transfer" + settlement_by_check: "Settlement by check" settlement_done_at_the_reception: "Pagamento effettuato al banco" settlement_by_wallet: "Pagamento effettuato tramite il portafoglio" on_DATE_at_TIME: "il %{DATE} alle %{TIME}," diff --git a/config/locales/no.yml b/config/locales/no.yml index d4eadb082..799d07c45 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -126,6 +126,8 @@ by_wallet: "til lommebok" no_refund: "Ingen refusjon" settlement_by_debit_card: "Oppgjør med betalingskort" + settlement_by_transfer: "Settlement by transfer" + settlement_by_check: "Settlement by check" settlement_done_at_the_reception: "Oppgjør i resepsjonen" settlement_by_wallet: "Oppgjør via lommebok" on_DATE_at_TIME: "på %{DATE} kl. %{TIME}," diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 852dfda05..487ec3225 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -126,6 +126,8 @@ pt: by_wallet: "pela carteira" no_refund: "Sem reembolso" settlement_by_debit_card: "Liquidação por cartão de débito" + settlement_by_transfer: "Settlement by transfer" + settlement_by_check: "Settlement by check" settlement_done_at_the_reception: "Liquidação feita na recepção" settlement_by_wallet: "Liquidação por carteira" on_DATE_at_TIME: "em %{DATE} ás %{TIME}," diff --git a/config/locales/sv.yml b/config/locales/sv.yml index d171bde7d..da6871229 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -126,6 +126,8 @@ sv: by_wallet: "med plånbok" no_refund: "Ingen återbetalning" settlement_by_debit_card: "Betalning med betalkort" + settlement_by_transfer: "Settlement by transfer" + settlement_by_check: "Settlement by check" settlement_done_at_the_reception: "Betalning görs i receptionen" settlement_by_wallet: "Betalning med plånbok" on_DATE_at_TIME: "den %{DATE} kl %{TIME}," diff --git a/config/locales/zu.yml b/config/locales/zu.yml index 3a2295f32..bb8a72616 100644 --- a/config/locales/zu.yml +++ b/config/locales/zu.yml @@ -126,6 +126,8 @@ zu: by_wallet: "crwdns3353:0crwdne3353:0" no_refund: "crwdns3355:0crwdne3355:0" settlement_by_debit_card: "crwdns3357:0crwdne3357:0" + settlement_by_transfer: "crwdns38172:0crwdne38172:0" + settlement_by_check: "crwdns38174:0crwdne38174:0" settlement_done_at_the_reception: "crwdns3359:0crwdne3359:0" settlement_by_wallet: "crwdns3361:0crwdne3361:0" on_DATE_at_TIME: "crwdns3363:0%{DATE}crwdnd3363:0%{TIME}crwdne3363:0" From 68251b88b24945528502c5eb9a86c747999b5bc0 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 19 Feb 2024 14:45:34 +0100 Subject: [PATCH 21/92] Version 6.3.13 --- CHANGELOG.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1d7241d2..e159883ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,14 @@ ## Next release +## v6.3.13 2024 February 19 + - Fix a bug: missing payment transfer journal code in accouting line - Fix a bug: unable to sync iCalendar correctly - improvement: add settlement by transfer/check to invoice paiement info - improvement: hide machines/themes/components filter in project list if machines module is disable or themes/components is empty - updates translations +- [TODO DEPLOY] `rails fablab:setup:build_accounting_lines` ## v6.3.12 2024 February 12 diff --git a/package.json b/package.json index 4aa743575..c6a62a964 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fab-manager", - "version": "6.3.12", + "version": "6.3.13", "description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.", "keywords": [ "fablab", From 5b9bdd2b462e3939361b76fb3519c74a4ecb0182 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Tue, 20 Feb 2024 15:58:52 +0100 Subject: [PATCH 22/92] (feat) add idp_slo_service_url --- CHANGELOG.md | 2 ++ app/controllers/api/auth_providers_controller.rb | 2 +- .../components/authentication-provider/saml-form.tsx | 7 +++++++ .../src/javascript/models/authentication-provider.ts | 1 + app/views/api/auth_providers/show.json.jbuilder | 2 +- app/views/auth_provider/provider.json.jbuilder | 2 +- config/initializers/devise.rb | 1 + config/locales/app.admin.en.yml | 2 ++ ...0220140225_add_idp_slo_service_url_to_saml_providers.rb | 5 +++++ db/structure.sql | 6 ++++-- 10 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20240220140225_add_idp_slo_service_url_to_saml_providers.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index e159883ac..a6be6ef51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +- improvement: add idp_slo_service_url(logout requests url) to saml provider + ## v6.3.13 2024 February 19 - Fix a bug: missing payment transfer journal code in accouting line diff --git a/app/controllers/api/auth_providers_controller.rb b/app/controllers/api/auth_providers_controller.rb index 379c2a315..642236355 100644 --- a/app/controllers/api/auth_providers_controller.rb +++ b/app/controllers/api/auth_providers_controller.rb @@ -108,7 +108,7 @@ class API::AuthProvidersController < API::APIController elsif params['auth_provider']['providable_type'] == SamlProvider.name params.require(:auth_provider) .permit(:id, :name, :providable_type, - providable_attributes: [:id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert], + providable_attributes: [:id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url], auth_provider_mappings_attributes: [:id, :local_model, :local_field, :api_field, :api_endpoint, :api_data_type, :_destroy, { transformation: [:type, :format, :true_value, :false_value, { mapping: %i[from to] }] }]) diff --git a/app/frontend/src/javascript/components/authentication-provider/saml-form.tsx b/app/frontend/src/javascript/components/authentication-provider/saml-form.tsx index 5fdbd9221..70a16603a 100644 --- a/app/frontend/src/javascript/components/authentication-provider/saml-form.tsx +++ b/app/frontend/src/javascript/components/authentication-provider/saml-form.tsx @@ -58,6 +58,13 @@ export const SamlForm = ({ register, strategyN tooltip={t('app.admin.authentication.saml_form.profile_edition_url_help')} rules={{ required: true, pattern: ValidationLib.urlRegex }} formState={formState} /> +
); }; diff --git a/app/frontend/src/javascript/models/authentication-provider.ts b/app/frontend/src/javascript/models/authentication-provider.ts index a9e61cd09..f56c94bf8 100644 --- a/app/frontend/src/javascript/models/authentication-provider.ts +++ b/app/frontend/src/javascript/models/authentication-provider.ts @@ -72,6 +72,7 @@ export interface SamlProvider { idp_cert_fingerprint: string, idp_cert: string, profile_url: string, + idp_slo_service_url: string, } export interface MappingFields { diff --git a/app/views/api/auth_providers/show.json.jbuilder b/app/views/api/auth_providers/show.json.jbuilder index 55531d9c6..18a2ab3e0 100644 --- a/app/views/api/auth_providers/show.json.jbuilder +++ b/app/views/api/auth_providers/show.json.jbuilder @@ -22,6 +22,6 @@ end if @provider.providable_type == SamlProvider.name json.providable_attributes do - json.extract! @provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert + json.extract! @provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url end end diff --git a/app/views/auth_provider/provider.json.jbuilder b/app/views/auth_provider/provider.json.jbuilder index efbfbdce8..dda5a9a72 100644 --- a/app/views/auth_provider/provider.json.jbuilder +++ b/app/views/auth_provider/provider.json.jbuilder @@ -23,6 +23,6 @@ end if provider.providable_type == 'SamlProvider' json.providable_attributes do - json.extract! provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert + json.extract! provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url end end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 5b5b71555..716ff45ca 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -250,6 +250,7 @@ Devise.setup do |config| config.omniauth active_provider.strategy_name.to_sym, sp_entity_id: active_provider.providable.sp_entity_id, idp_sso_service_url: active_provider.providable.idp_sso_service_url, + idp_slo_service_url: active_provider.providable.idp_slo_service_url, idp_cert: active_provider.providable.idp_cert, idp_cert_fingerprint: active_provider.providable.idp_cert_fingerprint, strategy_class: OmniAuth::Strategies::SsoSamlProvider diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index bcbabea7a..ed86a193e 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -1569,6 +1569,8 @@ en: idp_cert: "Identity provider certificate" profile_edition_url: "Profil edition URL" profile_edition_url_help: "The URL of the page where the user can edit his profile." + idp_slo_service_url: "Single logout request URL" + idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." provider_form: name: "Name" authentication_type: "Authentication type" diff --git a/db/migrate/20240220140225_add_idp_slo_service_url_to_saml_providers.rb b/db/migrate/20240220140225_add_idp_slo_service_url_to_saml_providers.rb new file mode 100644 index 000000000..4eca9b578 --- /dev/null +++ b/db/migrate/20240220140225_add_idp_slo_service_url_to_saml_providers.rb @@ -0,0 +1,5 @@ +class AddIdpSloServiceUrlToSamlProviders < ActiveRecord::Migration[7.0] + def change + add_column :saml_providers, :idp_slo_service_url, :string + end +end diff --git a/db/structure.sql b/db/structure.sql index aad684c7c..edf633649 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -3278,7 +3278,8 @@ CREATE TABLE public.saml_providers ( updated_at timestamp(6) without time zone NOT NULL, profile_url character varying, idp_cert character varying, - idp_cert_fingerprint character varying + idp_cert_fingerprint character varying, + idp_slo_service_url character varying ); @@ -9324,6 +9325,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20231108094433'), ('20240116163703'), ('20240126145351'), -('20240126192110'); +('20240126192110'), +('20240220140225'); From 35fdf531e8a44b512448e8498b63184febd59a54 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Tue, 20 Feb 2024 19:19:30 +0100 Subject: [PATCH 23/92] (i18n) update translation --- config/locales/app.admin.de.yml | 2 ++ config/locales/app.admin.es-MX.yml | 2 ++ config/locales/app.admin.es.yml | 2 ++ config/locales/app.admin.fr.yml | 2 ++ config/locales/app.admin.it.yml | 2 ++ config/locales/app.admin.no.yml | 2 ++ config/locales/app.admin.pt.yml | 2 ++ config/locales/app.admin.sv.yml | 2 ++ config/locales/app.admin.zu.yml | 2 ++ 9 files changed, 18 insertions(+) diff --git a/config/locales/app.admin.de.yml b/config/locales/app.admin.de.yml index f887adb28..01e52ee4e 100644 --- a/config/locales/app.admin.de.yml +++ b/config/locales/app.admin.de.yml @@ -1569,6 +1569,8 @@ de: idp_cert: "Identity provider certificate" profile_edition_url: "Profil edition URL" profile_edition_url_help: "The URL of the page where the user can edit his profile." + idp_slo_service_url: "Single logout request URL" + idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." provider_form: name: "Name" authentication_type: "Authentifizierungsart" diff --git a/config/locales/app.admin.es-MX.yml b/config/locales/app.admin.es-MX.yml index f9537dd5f..9c236e8ca 100644 --- a/config/locales/app.admin.es-MX.yml +++ b/config/locales/app.admin.es-MX.yml @@ -1569,6 +1569,8 @@ es-MX: idp_cert: "Identity provider certificate" profile_edition_url: "Profil edition URL" profile_edition_url_help: "The URL of the page where the user can edit his profile." + idp_slo_service_url: "Single logout request URL" + idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." provider_form: name: "Nombre" authentication_type: "Tipo de autenticación" diff --git a/config/locales/app.admin.es.yml b/config/locales/app.admin.es.yml index 6fcbdf1f2..c0367f6fa 100644 --- a/config/locales/app.admin.es.yml +++ b/config/locales/app.admin.es.yml @@ -1569,6 +1569,8 @@ es: idp_cert: "Identity provider certificate" profile_edition_url: "Profil edition URL" profile_edition_url_help: "The URL of the page where the user can edit his profile." + idp_slo_service_url: "Single logout request URL" + idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." provider_form: name: "Nombre" authentication_type: "Tipo de autenticación" diff --git a/config/locales/app.admin.fr.yml b/config/locales/app.admin.fr.yml index 8447dd0cb..1bf7f9d40 100644 --- a/config/locales/app.admin.fr.yml +++ b/config/locales/app.admin.fr.yml @@ -1569,6 +1569,8 @@ fr: idp_cert: "Certificat de fournisseur d'identité" profile_edition_url: "URL d'édition du profil" profile_edition_url_help: "L'URL de la page où l'utilisateur peut modifier son profil." + idp_slo_service_url: "URL de demande de déconnexion" + idp_slo_service_url_help: "L'URL à laquelle la requête d'authentification doit être envoyée. Cela serait sur le fournisseur d'identité." provider_form: name: "Nom" authentication_type: "Type d'authentification" diff --git a/config/locales/app.admin.it.yml b/config/locales/app.admin.it.yml index bb49b0859..51406d6a2 100644 --- a/config/locales/app.admin.it.yml +++ b/config/locales/app.admin.it.yml @@ -1569,6 +1569,8 @@ it: idp_cert: "Identity provider certificate" profile_edition_url: "Profil edition URL" profile_edition_url_help: "The URL of the page where the user can edit his profile." + idp_slo_service_url: "Single logout request URL" + idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." provider_form: name: "Nome" authentication_type: "Tipo di autenticazione" diff --git a/config/locales/app.admin.no.yml b/config/locales/app.admin.no.yml index b6d2e9fda..126778db2 100644 --- a/config/locales/app.admin.no.yml +++ b/config/locales/app.admin.no.yml @@ -1569,6 +1569,8 @@ idp_cert: "Identity provider certificate" profile_edition_url: "Profil edition URL" profile_edition_url_help: "The URL of the page where the user can edit his profile." + idp_slo_service_url: "Single logout request URL" + idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." provider_form: name: "Name" authentication_type: "Authentication type" diff --git a/config/locales/app.admin.pt.yml b/config/locales/app.admin.pt.yml index 2e2ad24c9..f14aa3805 100644 --- a/config/locales/app.admin.pt.yml +++ b/config/locales/app.admin.pt.yml @@ -1569,6 +1569,8 @@ pt: idp_cert: "Identity provider certificate" profile_edition_url: "Profil edition URL" profile_edition_url_help: "The URL of the page where the user can edit his profile." + idp_slo_service_url: "Single logout request URL" + idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." provider_form: name: "Nome" authentication_type: "Tipo de autenticação" diff --git a/config/locales/app.admin.sv.yml b/config/locales/app.admin.sv.yml index c24e89186..2c2af9633 100644 --- a/config/locales/app.admin.sv.yml +++ b/config/locales/app.admin.sv.yml @@ -1569,6 +1569,8 @@ sv: idp_cert: "Identitetsleverantörens certifikat" profile_edition_url: "URL för Profilutgåva" profile_edition_url_help: "URL till sidan där användaren kan redigera sin profil." + idp_slo_service_url: "Single logout request URL" + idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." provider_form: name: "Namn" authentication_type: "Autentiseringstyp" diff --git a/config/locales/app.admin.zu.yml b/config/locales/app.admin.zu.yml index b25b35f71..771983579 100644 --- a/config/locales/app.admin.zu.yml +++ b/config/locales/app.admin.zu.yml @@ -1569,6 +1569,8 @@ zu: idp_cert: "crwdns38158:0crwdne38158:0" profile_edition_url: "crwdns38160:0crwdne38160:0" profile_edition_url_help: "crwdns38162:0crwdne38162:0" + idp_slo_service_url: "crwdns38176:0crwdne38176:0" + idp_slo_service_url_help: "crwdns38178:0crwdne38178:0" provider_form: name: "crwdns26204:0crwdne26204:0" authentication_type: "crwdns26206:0crwdne26206:0" From 51c4e020f91f454792522206302fc7458121e80d Mon Sep 17 00:00:00 2001 From: Du Peng Date: Tue, 20 Feb 2024 19:19:45 +0100 Subject: [PATCH 24/92] (doc) add saml config doc --- doc/sso_saml.md | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 doc/sso_saml.md diff --git a/doc/sso_saml.md b/doc/sso_saml.md new file mode 100644 index 000000000..9c379d210 --- /dev/null +++ b/doc/sso_saml.md @@ -0,0 +1,79 @@ +# Single-Sign-On authentication using SAML +This document provides instructions on how to configure SAML (Security Assertion Markup Language) in FabManager. SAML enables secure single sign-on (SSO) authentication between a service provider (SP), such as FabManager, and an identity provider (IdP), which could be your organization's authentication system. + +## Configuration Steps: + +1. Gather Required Information: +Before configuring SAML in FabManager, ensure you have the following information from your identity provider: + +* Service provider entity ID +* Identity provider SSO service URL (required) +* Identity provider certificate fingerprint (SHA1 format) or Identity provider certificate (PEM format) +* Single logout request URL (option) + +2. Access FabManager Configuration: +Log in to your FabManager instance with administrative privileges. + +3. Navigate to Users Settings -> Authentication: +Add a new authentication provider, enter your name of new authentification + +4. Select SAML: +Locate the authentication type option to enable SAML. + +5. Enter SAML Configuration Details: +Now, enter the SAML configuration details obtained from your identity provider into the corresponding fields in FabManager's SAML settings. These fields typically include: + +SP Entity ID: Enter the Service Provider entity ID. (required) +IdP SSO Service URL: Provide the Identity Provider SSO service URL. (required) +IdP Certificate Fingerprint: Enter the fingerprint of the Identity Provider certificate.(SHA1 format) +IdP Certificate: Enter the Identity Provider certificate.(PEM format) +Profile URL: Enter the Profile edition URL.(required) +IdP SLO Service URL: Provide the Single Logout Request URL. (option) + +6. Configuring User Profile Attributes Mapping in FabManager +FabManager allows you to map user profile attributes to ensure that essential information, such as user UID, email, first name, and last name, is accurately synchronized between the identity provider (IdP) and FabManager. +Before proceeding with mapping, ensure you understand the user profile attributes you want to synchronize. Based on your requirements, identify the following attributes: + +user.uid: Unique identifier for the user. +user.email: User's email address. +profile.first_name: User's first name. +profile.last_name: User's last name. + +7. Save Configuration: +After entering all the required information, save the SAML configuration settings. + +## After configuring SAML integration in FabManager, you need to follow these steps to activate SAML authentication within the application: + +1. Access FabManager Docker Container: +Use the following command to enter the FabManager Docker container: +```bash +docker exec -it CONTAINER_NAME_APP bash +``` +Replace `CONTAINER_NAME_APP` with the actual name of your FabManager Docker container. + +2. Switch to SAML Authentication: +Once inside the Docker container, switch to SAML authentication mode using the following command: +```bash +rails fablab:auth:switch_provider[NAME_OF_SAML] +``` +Replace NAME_OF_SAML with the name you assigned to your SAML provider during the configuration. + +3. Exit FabManager docker container and Restart the Application: +```bash +docker rm -f CONTAINER_NAME_APP +docker-compose up -d +``` + +4. Notify Current Users to login with SAML: +It's essential to inform current users about the authentication method change. Use the following command to notify them: +```bash +docker exec -it CONTAINER_NAME_APP bash +rails fablab:auth:notify_changed +``` +To ensure a seamless transition for existing users to the new SAML authentication method, you can send them an email containing a link that will enable them to connect their existing FabManager accounts with their SAML identities. +This link include a token to authenticate the user and link their accounts. Upon successful connection, provide users with confirmation that their accounts have been linked to their SAML identities with authentification code. +By following these steps, existing users can seamlessly transition to SAML authentication without needing to re-enter their profile information. + +## After user login via SAML +FabManager requires certain user attributes such as username, email, first name, last name, gender, and birthday to be mandatory. +Users provide all necessary information required by FabManager, even if certain attributes are not directly mapped through the SAML authentication process. From f8edc5bf9e366b858ffcf944768991a019cba30b Mon Sep 17 00:00:00 2001 From: Du Peng Date: Fri, 23 Feb 2024 12:50:59 +0100 Subject: [PATCH 25/92] (bug) event canceled places error --- CHANGELOG.md | 2 ++ app/models/slots_reservation.rb | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6be6ef51..04f7b1390 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## Next release - improvement: add idp_slo_service_url(logout requests url) to saml provider +- Fix a bug: event canceled places error +- [TODO DEPLOY] `rails fablab:setup:build_places_cache` ## v6.3.13 2024 February 19 diff --git a/app/models/slots_reservation.rb b/app/models/slots_reservation.rb index f81ef4c59..9fb35d500 100644 --- a/app/models/slots_reservation.rb +++ b/app/models/slots_reservation.rb @@ -66,10 +66,13 @@ class SlotsReservation < ApplicationRecord # @param target_slot [Slot] def update_places_cache(operation, target_slot = slot) if reservation.reservable_type == 'Event' + total_booked_seats = reservation.nb_reserve_places + total_booked_seats += reservation.tickets.map(&:booked).map(&:to_i).reduce(:+) if reservation.tickets.count.positive? + total_booked_seats = 0 if reservation.reservable.pre_registration Slots::PlacesCacheService.change_places(target_slot, reservation.reservable_type, reservation.reservable_id, - reservation.reservable.pre_registration ? 0 : reservation.total_booked_seats, + total_booked_seats, operation) else Slots::PlacesCacheService.change_places(target_slot, reservation.reservable_type, reservation.reservable_id, 1, operation) From a523b564f150b445b25f36ce0acc77fff25cc332 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:26:09 +0100 Subject: [PATCH 26/92] Bump sidekiq-unique-jobs from 7.1.23 to 7.1.33 (#466) Bumps [sidekiq-unique-jobs](https://github.com/mhenrixon/sidekiq-unique-jobs) from 7.1.23 to 7.1.33. - [Release notes](https://github.com/mhenrixon/sidekiq-unique-jobs/releases) - [Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/main/CHANGELOG.md) - [Commits](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.1.23...v7.1.33) --- updated-dependencies: - dependency-name: sidekiq-unique-jobs dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Gemfile b/Gemfile index dfdd5557d..29d463c77 100644 --- a/Gemfile +++ b/Gemfile @@ -95,7 +95,7 @@ gem 'aasm' gem 'sidekiq', '6.5.12' # Recurring jobs for Sidekiq gem 'sidekiq-scheduler', '5.0.3' -gem 'sidekiq-unique-jobs', '~> 7.1.23' +gem 'sidekiq-unique-jobs', '~> 7.1.33' gem 'stripe', '5.29.0' diff --git a/Gemfile.lock b/Gemfile.lock index 0495981c7..1917985da 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -94,9 +94,9 @@ GEM bindex (0.8.1) bootsnap (1.16.0) msgpack (~> 1.2) - brpoplpush-redis_script (0.1.2) + brpoplpush-redis_script (0.1.3) concurrent-ruby (~> 1.0, >= 1.0.5) - redis (>= 1.0, <= 5.0) + redis (>= 1.0, < 6) builder (3.2.4) bullet (7.0.0) activesupport (>= 3.0.0) @@ -124,7 +124,7 @@ GEM coderay (1.1.3) coercible (1.0.0) descendants_tracker (~> 0.0.1) - concurrent-ruby (1.2.2) + concurrent-ruby (1.2.3) connection_pool (2.4.1) coveralls_reborn (0.18.0) simplecov (>= 0.18.1, < 0.20.0) @@ -345,7 +345,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.6.2) - rack (2.2.6.4) + rack (2.2.8.1) rack-oauth2 (1.21.3) activesupport attr_required @@ -394,7 +394,7 @@ GEM recurrence (1.3.0) activesupport i18n - redis (4.6.0) + redis (4.8.1) redis-session-store (0.11.4) actionpack (>= 3, < 8) redis (>= 3, < 5) @@ -462,10 +462,11 @@ GEM rufus-scheduler (~> 3.2) sidekiq (>= 6, < 8) tilt (>= 1.4.0) - sidekiq-unique-jobs (7.1.23) + sidekiq-unique-jobs (7.1.33) brpoplpush-redis_script (> 0.1.1, <= 2.0.0) concurrent-ruby (~> 1.0, >= 1.0.5) - sidekiq (>= 5.0, < 8.0) + redis (< 5.0) + sidekiq (>= 5.0, < 7.0) thor (>= 0.20, < 3.0) silencer (2.0.0) simplecov (0.19.0) @@ -487,7 +488,7 @@ GEM ffi (~> 1.1) term-ansicolor (1.7.1) tins (~> 1.0) - thor (1.2.1) + thor (1.3.0) thread_safe (0.3.6) tilt (2.3.0) timeout (0.3.2) @@ -618,7 +619,7 @@ DEPENDENCIES shakapacker (= 6.6.0) sidekiq (= 6.5.12) sidekiq-scheduler (= 5.0.3) - sidekiq-unique-jobs (~> 7.1.23) + sidekiq-unique-jobs (~> 7.1.33) silencer spring (~> 4) spring-watcher-listen (~> 2.1.0) From e54fd0503e177a57f8458c5d2bdc8ca51abe3609 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:31:50 +0100 Subject: [PATCH 28/92] Bump puma from 6.1.0 to 6.4.2 (#470) * Bump puma from 6.1.0 to 6.4.2 Bumps [puma](https://github.com/puma/puma) from 6.1.0 to 6.4.2. - [Release notes](https://github.com/puma/puma/releases) - [Changelog](https://github.com/puma/puma/blob/master/History.md) - [Commits](https://github.com/puma/puma/compare/v6.1.0...v6.4.2) --- updated-dependencies: - dependency-name: puma dependency-type: direct:production ... Signed-off-by: dependabot[bot] --------- Signed-off-by: dependabot[bot] Co-authored-by: Nicolas Florentin Co-authored-by: Du Peng Co-authored-by: Vincent Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 4 ++-- Gemfile.lock | 25 +++++++++++++------------ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Gemfile b/Gemfile index dfdd5557d..67f86ae1c 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gem 'rails', '~> 7.0' # Used by rails 5.2 to reduce the app boot time by over 50% gem 'bootsnap' # Use Puma as web server -gem 'puma', '6.1.0' +gem 'puma', '6.4.2' gem 'shakapacker', '6.6.0' # rails 6 compatibility with ruby 3 (may not be required after upgrade to rails 7) @@ -95,7 +95,7 @@ gem 'aasm' gem 'sidekiq', '6.5.12' # Recurring jobs for Sidekiq gem 'sidekiq-scheduler', '5.0.3' -gem 'sidekiq-unique-jobs', '~> 7.1.23' +gem 'sidekiq-unique-jobs', '~> 7.1.33' gem 'stripe', '5.29.0' diff --git a/Gemfile.lock b/Gemfile.lock index 0495981c7..a5279cb17 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -94,9 +94,9 @@ GEM bindex (0.8.1) bootsnap (1.16.0) msgpack (~> 1.2) - brpoplpush-redis_script (0.1.2) + brpoplpush-redis_script (0.1.3) concurrent-ruby (~> 1.0, >= 1.0.5) - redis (>= 1.0, <= 5.0) + redis (>= 1.0, < 6) builder (3.2.4) bullet (7.0.0) activesupport (>= 3.0.0) @@ -124,7 +124,7 @@ GEM coderay (1.1.3) coercible (1.0.0) descendants_tracker (~> 0.0.1) - concurrent-ruby (1.2.2) + concurrent-ruby (1.2.3) connection_pool (2.4.1) coveralls_reborn (0.18.0) simplecov (>= 0.18.1, < 0.20.0) @@ -270,7 +270,7 @@ GEM timeout net-smtp (0.3.3) net-protocol - nio4r (2.5.8) + nio4r (2.7.0) nokogiri (1.14.3-x86_64-darwin) racc (~> 1.4) nokogiri (1.14.3-x86_64-linux) @@ -339,13 +339,13 @@ GEM coderay (~> 1.1) method_source (~> 1.0) public_suffix (5.0.1) - puma (6.1.0) + puma (6.4.2) nio4r (~> 2.0) pundit (2.1.0) activesupport (>= 3.0.0) raabro (1.4.0) racc (1.6.2) - rack (2.2.6.4) + rack (2.2.8.1) rack-oauth2 (1.21.3) activesupport attr_required @@ -394,7 +394,7 @@ GEM recurrence (1.3.0) activesupport i18n - redis (4.6.0) + redis (4.8.1) redis-session-store (0.11.4) actionpack (>= 3, < 8) redis (>= 3, < 5) @@ -462,10 +462,11 @@ GEM rufus-scheduler (~> 3.2) sidekiq (>= 6, < 8) tilt (>= 1.4.0) - sidekiq-unique-jobs (7.1.23) + sidekiq-unique-jobs (7.1.33) brpoplpush-redis_script (> 0.1.1, <= 2.0.0) concurrent-ruby (~> 1.0, >= 1.0.5) - sidekiq (>= 5.0, < 8.0) + redis (< 5.0) + sidekiq (>= 5.0, < 7.0) thor (>= 0.20, < 3.0) silencer (2.0.0) simplecov (0.19.0) @@ -487,7 +488,7 @@ GEM ffi (~> 1.1) term-ansicolor (1.7.1) tins (~> 1.0) - thor (1.2.1) + thor (1.3.0) thread_safe (0.3.6) tilt (2.3.0) timeout (0.3.2) @@ -595,7 +596,7 @@ DEPENDENCIES prawn prawn-table pry - puma (= 6.1.0) + puma (= 6.4.2) pundit railroady rails (~> 7.0) @@ -618,7 +619,7 @@ DEPENDENCIES shakapacker (= 6.6.0) sidekiq (= 6.5.12) sidekiq-scheduler (= 5.0.3) - sidekiq-unique-jobs (~> 7.1.23) + sidekiq-unique-jobs (~> 7.1.33) silencer spring (~> 4) spring-watcher-listen (~> 2.1.0) From 13c74ccd2e2fcd413c2e86a831dcb4e74a6dd642 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:45:42 +0100 Subject: [PATCH 29/92] Bump axios from 0.21.2 to 0.28.0 (#468) * Bump axios from 0.21.2 to 0.28.0 Bumps [axios](https://github.com/axios/axios) from 0.21.2 to 0.28.0. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v0.28.0/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v0.21.2...v0.28.0) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production ... Signed-off-by: dependabot[bot] --------- Signed-off-by: dependabot[bot] Co-authored-by: Nicolas Florentin Co-authored-by: Du Peng Co-authored-by: Vincent Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index c6a62a964..7c59558b1 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ "angular-unsavedchanges": "0.2", "angular-xeditable": "0.10", "assert": "^2.0.0", - "axios": "^0.21.2", + "axios": "^0.28.0", "babel-loader": "^9.1.2", "babel-plugin-macros": "^3.1.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", diff --git a/yarn.lock b/yarn.lock index 29b0287bb..7c86567a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4303,12 +4303,14 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -axios@^0.21.2: - version "0.21.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.2.tgz#21297d5084b2aeeb422f5d38e7be4fbb82239017" - integrity sha512-87otirqUw3e8CzHTMO+/9kh/FSgXt/eVDvipijwDtEuwbkySWZ9SBm6VEubmJ/kLKEoLQV/POhxXFb66bfekfg== +axios@^0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.28.0.tgz#801a4d991d0404961bccef46800e1170f8278c89" + integrity sha512-Tu7NYoGY4Yoc7I+Npf9HhUMtEEpV7ZiLH9yndTCoNhcpBH0kwcvFbzYN9/u5QKI5A6uefjsNNWaz5olJVYS62Q== dependencies: - follow-redirects "^1.14.0" + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" babel-jest@^29.3.1: version "29.3.1" @@ -6114,10 +6116,10 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -follow-redirects@^1.0.0, follow-redirects@^1.14.0: - version "1.14.8" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" - integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== +follow-redirects@^1.0.0, follow-redirects@^1.15.0: + version "1.15.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" + integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== for-each@^0.3.3: version "0.3.3" @@ -8891,6 +8893,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" From 76bc352d7b337fff9006522b24c2ff930c6ec943 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 26 Feb 2024 13:28:45 +0100 Subject: [PATCH 30/92] update carrierwave --- Gemfile.lock | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index a5279cb17..40f2a0cfc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -72,7 +72,7 @@ GEM tzinfo (~> 2.0) acts_as_list (1.0.4) activerecord (>= 4.2) - addressable (2.8.1) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) aes_key_wrap (1.1.0) afm (0.2.2) @@ -102,13 +102,12 @@ GEM activesupport (>= 3.0.0) uniform_notifier (~> 1.11) camertron-eprun (1.1.1) - carrierwave (2.1.1) - activemodel (>= 5.0.0) - activesupport (>= 5.0.0) + carrierwave (3.0.5) + activemodel (>= 6.0.0) + activesupport (>= 6.0.0) addressable (~> 2.6) image_processing (~> 1.1) - mimemagic (>= 0.3.0) - mini_mime (>= 0.1.3) + marcel (~> 1.0.0) ssrf_filter (~> 1.0) caxlsx (3.0.4) htmlentities (~> 4.3, >= 4.3.4) @@ -177,7 +176,7 @@ GEM i18n (>= 1.6, < 2) faraday (0.17.3) multipart-post (>= 1.2, < 3) - ffi (1.15.5) + ffi (1.16.3) foreman (0.87.0) forgery (0.7.0) friendly_id (5.1.0) @@ -195,7 +194,7 @@ GEM mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) httpclient (2.8.3) - i18n (1.12.0) + i18n (1.14.1) concurrent-ruby (~> 1.0) icalendar (2.7.1) ice_cube (~> 0.16) @@ -249,9 +248,9 @@ GEM mimemagic (0.4.3) nokogiri (~> 1) rake - mini_magick (4.10.1) - mini_mime (1.1.2) - minitest (5.18.0) + mini_magick (4.12.0) + mini_mime (1.1.5) + minitest (5.22.2) minitest-reporters (1.4.2) ansi builder @@ -271,9 +270,9 @@ GEM net-smtp (0.3.3) net-protocol nio4r (2.7.0) - nokogiri (1.14.3-x86_64-darwin) + nokogiri (1.16.2-x86_64-darwin) racc (~> 1.4) - nokogiri (1.14.3-x86_64-linux) + nokogiri (1.16.2-x86_64-linux) racc (~> 1.4) oauth2 (1.4.4) faraday (>= 0.8, < 2.0) @@ -338,13 +337,13 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.1) + public_suffix (5.0.4) puma (6.4.2) nio4r (~> 2.0) pundit (2.1.0) activesupport (>= 3.0.0) raabro (1.4.0) - racc (1.6.2) + racc (1.7.3) rack (2.2.8.1) rack-oauth2 (1.21.3) activesupport @@ -386,7 +385,7 @@ GEM thor (~> 1.0) zeitwerk (~> 2.5) rainbow (3.0.0) - rake (13.0.6) + rake (13.1.0) rb-fsevent (0.10.3) rb-inotify (0.10.1) ffi (~> 1.0) @@ -428,7 +427,7 @@ GEM ruby-saml (1.16.0) nokogiri (>= 1.13.10) rexml - ruby-vips (2.1.4) + ruby-vips (2.2.1) ffi (~> 1.12) rubyXL (3.4.25) nokogiri (>= 1.10.8) @@ -477,7 +476,7 @@ GEM spring-watcher-listen (2.1.0) listen (>= 2.7, < 4.0) spring (>= 4) - ssrf_filter (1.0.7) + ssrf_filter (1.1.2) stripe (5.29.0) swd (1.3.0) activesupport (>= 3) From a2aa1f37d7f2da8d5d29796847a474444b341c76 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 26 Feb 2024 13:49:30 +0100 Subject: [PATCH 32/92] Version 6.3.14 --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04f7b1390..b2b1bb87a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,13 @@ ## Next release +## v6.3.14 2024 February 26 + - improvement: add idp_slo_service_url(logout requests url) to saml provider - Fix a bug: event canceled places error +- Updated puma to 6.4.2 +- Updated carrierwave to 3.0.4 +- Updated sidekiq-unique-jobs to 7.1.33 - [TODO DEPLOY] `rails fablab:setup:build_places_cache` ## v6.3.13 2024 February 19 diff --git a/package.json b/package.json index 7c59558b1..c6dce20d2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fab-manager", - "version": "6.3.13", + "version": "6.3.14", "description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.", "keywords": [ "fablab", From d4b5b3db239c57a310c314df65d3d5132d1ca58e Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 29 Feb 2024 19:29:47 +0100 Subject: [PATCH 33/92] (bug) unable to generate invoice for payment by check/transfer --- CHANGELOG.md | 2 ++ app/services/invoices/payment_details_service.rb | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2b1bb87a..0ad8db149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +- Fix a bug: unable to generate invoice for payment by check/transfer + ## v6.3.14 2024 February 26 - improvement: add idp_slo_service_url(logout requests url) to saml provider diff --git a/app/services/invoices/payment_details_service.rb b/app/services/invoices/payment_details_service.rb index 7d7ace7bd..d1177857b 100644 --- a/app/services/invoices/payment_details_service.rb +++ b/app/services/invoices/payment_details_service.rb @@ -62,9 +62,9 @@ class Invoices::PaymentDetailsService # else if invoice.paid_by_card? I18n.t('invoices.settlement_by_debit_card') - elsif paid_by_transfer? + elsif invoice.paid_by_transfer? I18n.t('invoices.settlement_by_transfer') - elsif paid_by_check? + elsif invoice.paid_by_check? I18n.t('invoices.settlement_by_check') else I18n.t('invoices.settlement_done_at_the_reception') From 58e3097da2a63ff4a8bfe10a3d7202130bf6c407 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 29 Feb 2024 19:33:49 +0100 Subject: [PATCH 34/92] Version 6.3.15 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ad8db149..28a52dff2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +## v6.3.15 2024 February 29 + - Fix a bug: unable to generate invoice for payment by check/transfer ## v6.3.14 2024 February 26 diff --git a/package.json b/package.json index c6dce20d2..e47588a54 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fab-manager", - "version": "6.3.14", + "version": "6.3.15", "description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.", "keywords": [ "fablab", From 0e554d22ff9ea562a1393cc4a4020a3b73f73a69 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Fri, 8 Mar 2024 18:09:53 +0100 Subject: [PATCH 35/92] (bug) set settlement by cash by default for local payment mean --- CHANGELOG.md | 2 ++ .../payment/local-payment/local-payment-form.tsx | 8 ++++---- app/frontend/src/javascript/models/payment.ts | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28a52dff2..824fd02fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +- Fix a bug: set settlement by cash by default for local payment mean + ## v6.3.15 2024 February 29 - Fix a bug: unable to generate invoice for payment by check/transfer diff --git a/app/frontend/src/javascript/components/payment/local-payment/local-payment-form.tsx b/app/frontend/src/javascript/components/payment/local-payment/local-payment-form.tsx index 54cb1d437..a25ab2d0e 100644 --- a/app/frontend/src/javascript/components/payment/local-payment/local-payment-form.tsx +++ b/app/frontend/src/javascript/components/payment/local-payment/local-payment-form.tsx @@ -13,7 +13,7 @@ import CheckoutAPI from '../../../api/checkout'; import { SelectOption } from '../../../models/select'; import { PaymentMethod } from '../../../models/payment'; -const ALL_SCHEDULE_METHODS = ['card', 'check', 'transfer'] as const; +const ALL_SCHEDULE_METHODS = ['card', 'check', 'transfer', 'cash'] as const; type scheduleMethod = typeof ALL_SCHEDULE_METHODS[number]; /** @@ -24,13 +24,13 @@ type scheduleMethod = typeof ALL_SCHEDULE_METHODS[number]; export const LocalPaymentForm: React.FC = ({ onSubmit, onSuccess, onError, children, className, paymentSchedule, cart, updateCart, customer, operator, formId, order }) => { const { t } = useTranslation('admin'); - const [method, setMethod] = useState('check'); + const [method, setMethod] = useState('cash'); const [onlinePaymentModal, setOnlinePaymentModal] = useState(false); useEffect(() => { - setMethod(cart.payment_method || 'check'); + setMethod(cart.payment_method || 'cash'); if (cart.payment_method === '') { - cart.payment_method = PaymentMethod.Check; + cart.payment_method = PaymentMethod.Cash; } }, [cart]); diff --git a/app/frontend/src/javascript/models/payment.ts b/app/frontend/src/javascript/models/payment.ts index fae604f8f..2909a569c 100644 --- a/app/frontend/src/javascript/models/payment.ts +++ b/app/frontend/src/javascript/models/payment.ts @@ -19,6 +19,7 @@ export enum PaymentMethod { Card = 'card', Check = 'check', Transfer = 'transfer', + Cash = 'cash', Other = '' } From 1d179e51a95988ba625fc896ff94b4cdabfdde78 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 11 Mar 2024 11:25:25 +0100 Subject: [PATCH 36/92] (bug) set cash for locale payment by default --- .../local-payment/local-payment-form.tsx | 20 +++++++++++-------- app/models/invoice.rb | 2 -- test/services/accounting_service_test.rb | 1 + 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/app/frontend/src/javascript/components/payment/local-payment/local-payment-form.tsx b/app/frontend/src/javascript/components/payment/local-payment/local-payment-form.tsx index a25ab2d0e..897d14ddf 100644 --- a/app/frontend/src/javascript/components/payment/local-payment/local-payment-form.tsx +++ b/app/frontend/src/javascript/components/payment/local-payment/local-payment-form.tsx @@ -13,8 +13,8 @@ import CheckoutAPI from '../../../api/checkout'; import { SelectOption } from '../../../models/select'; import { PaymentMethod } from '../../../models/payment'; -const ALL_SCHEDULE_METHODS = ['card', 'check', 'transfer', 'cash'] as const; -type scheduleMethod = typeof ALL_SCHEDULE_METHODS[number]; +const ALL_PAYMENT_METHODS = ['card', 'check', 'transfer', 'cash'] as const; +type paymentMethod = typeof ALL_PAYMENT_METHODS[number]; /** * A form component to ask for confirmation before cashing a payment directly at the FabLab's reception. @@ -24,7 +24,7 @@ type scheduleMethod = typeof ALL_SCHEDULE_METHODS[number]; export const LocalPaymentForm: React.FC = ({ onSubmit, onSuccess, onError, children, className, paymentSchedule, cart, updateCart, customer, operator, formId, order }) => { const { t } = useTranslation('admin'); - const [method, setMethod] = useState('cash'); + const [method, setMethod] = useState('cash'); const [onlinePaymentModal, setOnlinePaymentModal] = useState(false); useEffect(() => { @@ -44,15 +44,15 @@ export const LocalPaymentForm: React.FC = ({ onSubmit, onSucce /** * Convert all payement methods for schedules to the react-select format */ - const buildMethodOptions = (): Array> => { - return ALL_SCHEDULE_METHODS.map(i => methodToOption(i)); + const buildMethodOptions = (): Array> => { + return ALL_PAYMENT_METHODS.filter(p => p !== 'cash').map(i => methodToOption(i)); }; /** * Convert the given payment-method to the react-select format */ - const methodToOption = (value: scheduleMethod): SelectOption => { - if (!value) return { value, label: '' }; + const methodToOption = (value: paymentMethod): SelectOption => { + if (!value || value === 'cash') return { value, label: '' }; return { value, label: t(`app.admin.local_payment_form.method_${value}`) }; }; @@ -60,7 +60,7 @@ export const LocalPaymentForm: React.FC = ({ onSubmit, onSucce /** * Callback triggered when the user selects a payment method for the current payment schedule. */ - const handleUpdateMethod = (option: SelectOption) => { + const handleUpdateMethod = (option: SelectOption) => { updateCart(Object.assign({}, cart, { payment_method: option.value })); setMethod(option.value); }; @@ -69,6 +69,10 @@ export const LocalPaymentForm: React.FC = ({ onSubmit, onSucce * Handle the submission of the form. It will process the local payment. */ const handleSubmit = async (event: FormEvent): Promise => { + if (paymentSchedule && !ALL_PAYMENT_METHODS.filter(p => p !== 'cash').includes(method)) { + event.preventDefault(); + return; + } event.preventDefault(); onSubmit(); diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 454671423..097e68aa3 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -165,8 +165,6 @@ class Invoice < PaymentDocument if paid_by_card? res.push(means: :card, amount: amount_paid) - elsif paid_by_wallet? - res.push(means: :wallet, amount: amount_paid) elsif paid_by_transfer? res.push(means: :transfer, amount: amount_paid) elsif paid_by_check? diff --git a/test/services/accounting_service_test.rb b/test/services/accounting_service_test.rb index 00dbfb983..a3105c033 100644 --- a/test/services/accounting_service_test.rb +++ b/test/services/accounting_service_test.rb @@ -30,6 +30,7 @@ class AccountingServiceTest < ActionDispatch::IntegrationTest post '/api/local_payment/confirm_payment', params: { customer_id: @vlonchamp.id, coupon_code: 'GIME3EUR', + payment_method: 'cash', items: [ { reservation: { From 71d10b3436a4e8f566bc665185522e21aa5c0fdd Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 11 Mar 2024 11:26:50 +0100 Subject: [PATCH 37/92] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 824fd02fe..4793a3ddf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Next release - Fix a bug: set settlement by cash by default for local payment mean +- [TODO DEPLOY] `rails fablab:setup:build_accounting_lines` ## v6.3.15 2024 February 29 From cb8bea0ab888e327c9ba15b34f03a0609afe4ec2 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 11 Mar 2024 12:28:02 +0100 Subject: [PATCH 38/92] update translations --- config/locales/app.public.de.yml | 2 +- config/locales/app.public.en.yml | 2 +- config/locales/app.public.es-MX.yml | 2 +- config/locales/app.public.es.yml | 2 +- config/locales/app.public.it.yml | 2 +- config/locales/app.public.no.yml | 2 +- config/locales/app.public.pt.yml | 2 +- config/locales/app.public.sv.yml | 2 +- config/locales/app.public.zu.yml | 2 +- config/locales/de.yml | 2 +- config/locales/en.yml | 2 +- config/locales/es-MX.yml | 2 +- config/locales/es.yml | 2 +- config/locales/fr.yml | 2 +- config/locales/it.yml | 2 +- config/locales/no.yml | 2 +- config/locales/pt.yml | 2 +- config/locales/sv.yml | 2 +- config/locales/zu.yml | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/config/locales/app.public.de.yml b/config/locales/app.public.de.yml index 32b50eeca..8355b5b13 100644 --- a/config/locales/app.public.de.yml +++ b/config/locales/app.public.de.yml @@ -155,7 +155,7 @@ de: discover_members: "Mitglieder entdecken" #next events summary on the home page fablab_s_next_events: "Next events" - every_events: "Alle Veranstaltungen" + every_events: "All events" event_card: on_the_date: "Am {DATE}" from_date_to_date: "Von {START} bis {END}" diff --git a/config/locales/app.public.en.yml b/config/locales/app.public.en.yml index 3e51f5d1f..c33cc4591 100644 --- a/config/locales/app.public.en.yml +++ b/config/locales/app.public.en.yml @@ -155,7 +155,7 @@ en: discover_members: "Discover members" #next events summary on the home page fablab_s_next_events: "Next events" - every_events: "Every events" + every_events: "All events" event_card: on_the_date: "On the {DATE}" from_date_to_date: "From {START} to {END}" diff --git a/config/locales/app.public.es-MX.yml b/config/locales/app.public.es-MX.yml index 869801790..211f97201 100644 --- a/config/locales/app.public.es-MX.yml +++ b/config/locales/app.public.es-MX.yml @@ -155,7 +155,7 @@ es-MX: discover_members: "Descubrir miembros" #next events summary on the home page fablab_s_next_events: "Próximos eventos" - every_events: "Todos los eventos" + every_events: "All events" event_card: on_the_date: "El {DATE}" from_date_to_date: "Desde {START} hasta {END}" diff --git a/config/locales/app.public.es.yml b/config/locales/app.public.es.yml index a342dcfb3..14b53a815 100644 --- a/config/locales/app.public.es.yml +++ b/config/locales/app.public.es.yml @@ -155,7 +155,7 @@ es: discover_members: "Descubrir miembros" #next events summary on the home page fablab_s_next_events: "Próximos eventos" - every_events: "Todos los eventos" + every_events: "All events" event_card: on_the_date: "El {DATE}" from_date_to_date: "Desde {START} hasta {END}" diff --git a/config/locales/app.public.it.yml b/config/locales/app.public.it.yml index 0819a81b6..14b43853e 100644 --- a/config/locales/app.public.it.yml +++ b/config/locales/app.public.it.yml @@ -155,7 +155,7 @@ it: discover_members: "Cerca i membri" #next events summary on the home page fablab_s_next_events: "Prossimi eventi" - every_events: "Tutti gli eventi" + every_events: "All events" event_card: on_the_date: "Il {DATE}" from_date_to_date: "Da {START} a {END}" diff --git a/config/locales/app.public.no.yml b/config/locales/app.public.no.yml index cc699f54e..a984e0794 100644 --- a/config/locales/app.public.no.yml +++ b/config/locales/app.public.no.yml @@ -155,7 +155,7 @@ discover_members: "Oppdag medlemmer" #next events summary on the home page fablab_s_next_events: "Next events" - every_events: "Alle arrangementer" + every_events: "All events" event_card: on_the_date: "På {DATE}" from_date_to_date: "Fra {START} til {END}" diff --git a/config/locales/app.public.pt.yml b/config/locales/app.public.pt.yml index af16a480c..c9284bc89 100644 --- a/config/locales/app.public.pt.yml +++ b/config/locales/app.public.pt.yml @@ -155,7 +155,7 @@ pt: discover_members: "Ver membros" #next events summary on the home page fablab_s_next_events: "Próximos eventos" - every_events: "Todos Eventos" + every_events: "All events" event_card: on_the_date: "Em {DATE}" from_date_to_date: "De {START} até {END}" diff --git a/config/locales/app.public.sv.yml b/config/locales/app.public.sv.yml index 2f4082591..2af5eb44a 100644 --- a/config/locales/app.public.sv.yml +++ b/config/locales/app.public.sv.yml @@ -155,7 +155,7 @@ sv: discover_members: "Upptäck medlemmar" #next events summary on the home page fablab_s_next_events: "Nästa evenemang" - every_events: "Alla evenemang" + every_events: "All events" event_card: on_the_date: "Den {DATE}" from_date_to_date: "Från {START} till {END}" diff --git a/config/locales/app.public.zu.yml b/config/locales/app.public.zu.yml index f12efd294..e4816ad3a 100644 --- a/config/locales/app.public.zu.yml +++ b/config/locales/app.public.zu.yml @@ -155,7 +155,7 @@ zu: discover_members: "crwdns28036:0crwdne28036:0" #next events summary on the home page fablab_s_next_events: "crwdns36235:0crwdne36235:0" - every_events: "crwdns28040:0crwdne28040:0" + every_events: "crwdns38182:0crwdne38182:0" event_card: on_the_date: "crwdns28042:0{DATE}crwdne28042:0" from_date_to_date: "crwdns28044:0{START}crwdnd28044:0{END}crwdne28044:0" diff --git a/config/locales/de.yml b/config/locales/de.yml index 1ec779b13..94b13f3bc 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -127,7 +127,7 @@ de: no_refund: "Keine Rückerstattung" settlement_by_debit_card: "Abrechnung per Debitkarte" settlement_by_transfer: "Settlement by transfer" - settlement_by_check: "Settlement by check" + settlement_by_check: "Settlement done at the reception" settlement_done_at_the_reception: "Abrechnung an der Rezeption durchgeführt" settlement_by_wallet: "Abrechnung per Guthaben" on_DATE_at_TIME: "am %{DATE} um %{TIME}," diff --git a/config/locales/en.yml b/config/locales/en.yml index 9252146be..b719e20ee 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -127,7 +127,7 @@ en: no_refund: "No refund" settlement_by_debit_card: "Settlement by debit card" settlement_by_transfer: "Settlement by transfer" - settlement_by_check: "Settlement by check" + settlement_by_check: "Settlement done at the reception" settlement_done_at_the_reception: "Settlement done at the reception" settlement_by_wallet: "Settlement by wallet" on_DATE_at_TIME: "on %{DATE} at %{TIME}," diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 97b9f76ff..6b417c5f1 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -127,7 +127,7 @@ es-MX: no_refund: "Sin devolución" settlement_by_debit_card: "Liquidación por tarjeta de débito" settlement_by_transfer: "Settlement by transfer" - settlement_by_check: "Settlement by check" + settlement_by_check: "Settlement done at the reception" settlement_done_at_the_reception: "Liquidación realizada en la recepción" settlement_by_wallet: "Liquidación con cartera" on_DATE_at_TIME: "el %{DATE} a las %{TIME}," diff --git a/config/locales/es.yml b/config/locales/es.yml index 699dd8d36..60d8ca15c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -127,7 +127,7 @@ es: no_refund: "Sin devolución" settlement_by_debit_card: "Liquidación por tarjeta de débito" settlement_by_transfer: "Settlement by transfer" - settlement_by_check: "Settlement by check" + settlement_by_check: "Settlement done at the reception" settlement_done_at_the_reception: "Liquidación realizada en la recepción" settlement_by_wallet: "Liquidación con cartera" on_DATE_at_TIME: "el %{DATE} a las %{TIME}," diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 53dd1d4f0..f217b6a3e 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -127,7 +127,7 @@ fr: no_refund: "Pas de remboursement" settlement_by_debit_card: "Règlement effectué par carte bancaire" settlement_by_transfer: "Règlement effectué par virement" - settlement_by_check: "Règlement effectué par chèque" + settlement_by_check: "Règlement effectué à l'accueil" settlement_done_at_the_reception: "Règlement effectué à l'accueil" settlement_by_wallet: "Règlement effectué par porte-monnaie" on_DATE_at_TIME: "le %{DATE} à %{TIME}," diff --git a/config/locales/it.yml b/config/locales/it.yml index 2bd2c07e1..f4602aba9 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -127,7 +127,7 @@ it: no_refund: "Nessun rimborso" settlement_by_debit_card: "Pagamento con carta di debito" settlement_by_transfer: "Settlement by transfer" - settlement_by_check: "Settlement by check" + settlement_by_check: "Settlement done at the reception" settlement_done_at_the_reception: "Pagamento effettuato al banco" settlement_by_wallet: "Pagamento effettuato tramite il portafoglio" on_DATE_at_TIME: "il %{DATE} alle %{TIME}," diff --git a/config/locales/no.yml b/config/locales/no.yml index 799d07c45..dfc29664c 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -127,7 +127,7 @@ no_refund: "Ingen refusjon" settlement_by_debit_card: "Oppgjør med betalingskort" settlement_by_transfer: "Settlement by transfer" - settlement_by_check: "Settlement by check" + settlement_by_check: "Settlement done at the reception" settlement_done_at_the_reception: "Oppgjør i resepsjonen" settlement_by_wallet: "Oppgjør via lommebok" on_DATE_at_TIME: "på %{DATE} kl. %{TIME}," diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 487ec3225..05f4cc791 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -127,7 +127,7 @@ pt: no_refund: "Sem reembolso" settlement_by_debit_card: "Liquidação por cartão de débito" settlement_by_transfer: "Settlement by transfer" - settlement_by_check: "Settlement by check" + settlement_by_check: "Settlement done at the reception" settlement_done_at_the_reception: "Liquidação feita na recepção" settlement_by_wallet: "Liquidação por carteira" on_DATE_at_TIME: "em %{DATE} ás %{TIME}," diff --git a/config/locales/sv.yml b/config/locales/sv.yml index da6871229..b16de2733 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -127,7 +127,7 @@ sv: no_refund: "Ingen återbetalning" settlement_by_debit_card: "Betalning med betalkort" settlement_by_transfer: "Settlement by transfer" - settlement_by_check: "Settlement by check" + settlement_by_check: "Settlement done at the reception" settlement_done_at_the_reception: "Betalning görs i receptionen" settlement_by_wallet: "Betalning med plånbok" on_DATE_at_TIME: "den %{DATE} kl %{TIME}," diff --git a/config/locales/zu.yml b/config/locales/zu.yml index bb8a72616..73300c282 100644 --- a/config/locales/zu.yml +++ b/config/locales/zu.yml @@ -127,7 +127,7 @@ zu: no_refund: "crwdns3355:0crwdne3355:0" settlement_by_debit_card: "crwdns3357:0crwdne3357:0" settlement_by_transfer: "crwdns38172:0crwdne38172:0" - settlement_by_check: "crwdns38174:0crwdne38174:0" + settlement_by_check: "crwdns38180:0crwdne38180:0" settlement_done_at_the_reception: "crwdns3359:0crwdne3359:0" settlement_by_wallet: "crwdns3361:0crwdne3361:0" on_DATE_at_TIME: "crwdns3363:0%{DATE}crwdnd3363:0%{TIME}crwdne3363:0" From f07164afb27fd764097b3b400416b404957d41ae Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 11 Mar 2024 12:28:29 +0100 Subject: [PATCH 39/92] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4793a3ddf..3eefdc415 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Next release - Fix a bug: set settlement by cash by default for local payment mean +- updates translations - [TODO DEPLOY] `rails fablab:setup:build_accounting_lines` ## v6.3.15 2024 February 29 From 523de4f3f760c79061a747329d150f81a1499efb Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 11 Mar 2024 12:46:39 +0100 Subject: [PATCH 40/92] (bug) #content_type_whitelist is instead by #content_type_allowlist --- CHANGELOG.md | 2 ++ app/uploaders/custom_assets_uploader.rb | 4 ++-- app/uploaders/event_file_uploader.rb | 4 ++-- app/uploaders/event_image_uploader.rb | 4 ++-- app/uploaders/import_uploader.rb | 4 ++-- app/uploaders/machine_file_uploader.rb | 4 ++-- app/uploaders/machine_image_uploader.rb | 4 ++-- app/uploaders/plan_file_uploader.rb | 4 ++-- app/uploaders/product_file_uploader.rb | 4 ++-- app/uploaders/product_image_uploader.rb | 4 ++-- app/uploaders/project_cao_uploader.rb | 4 ++-- app/uploaders/project_image_uploader.rb | 4 ++-- app/uploaders/space_file_uploader.rb | 4 ++-- app/uploaders/space_image_uploader.rb | 4 ++-- app/uploaders/supporting_document_file_uploader.rb | 4 ++-- app/uploaders/training_image_uploader.rb | 4 ++-- app/uploaders/user_avatar_uploader.rb | 4 ++-- 17 files changed, 34 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eefdc415..f74c134c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - Fix a bug: set settlement by cash by default for local payment mean - updates translations +- #content_type_whitelist is instead by #content_type_allowlist +- #extension_whitelist is instead by #extension_allowlist - [TODO DEPLOY] `rails fablab:setup:build_accounting_lines` ## v6.3.15 2024 February 29 diff --git a/app/uploaders/custom_assets_uploader.rb b/app/uploaders/custom_assets_uploader.rb index 3fc789cd7..ad783434a 100644 --- a/app/uploaders/custom_assets_uploader.rb +++ b/app/uploaders/custom_assets_uploader.rb @@ -48,11 +48,11 @@ class CustomAssetsUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[pdf png jpeg jpg ico] end - def content_type_whitelist + def content_type_allowlist [%r{image/}, 'application/pdf'] end diff --git a/app/uploaders/event_file_uploader.rb b/app/uploaders/event_file_uploader.rb index 43752a117..35e2419d8 100644 --- a/app/uploaders/event_file_uploader.rb +++ b/app/uploaders/event_file_uploader.rb @@ -41,11 +41,11 @@ class EventFileUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[pdf] end - def content_type_whitelist + def content_type_allowlist %w[application/pdf] end diff --git a/app/uploaders/event_image_uploader.rb b/app/uploaders/event_image_uploader.rb index 90d8c965a..57a2ced7d 100644 --- a/app/uploaders/event_image_uploader.rb +++ b/app/uploaders/event_image_uploader.rb @@ -59,11 +59,11 @@ class EventImageUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[jpg jpeg gif png] end - def content_type_whitelist + def content_type_allowlist [%r{image/}] end diff --git a/app/uploaders/import_uploader.rb b/app/uploaders/import_uploader.rb index 34a7cbd73..486c3d062 100644 --- a/app/uploaders/import_uploader.rb +++ b/app/uploaders/import_uploader.rb @@ -22,11 +22,11 @@ class ImportUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[csv] end - def content_type_whitelist + def content_type_allowlist %w[text/csv] end diff --git a/app/uploaders/machine_file_uploader.rb b/app/uploaders/machine_file_uploader.rb index a7d212831..1b06ea4d5 100644 --- a/app/uploaders/machine_file_uploader.rb +++ b/app/uploaders/machine_file_uploader.rb @@ -41,11 +41,11 @@ class MachineFileUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[pdf] end - def content_type_whitelist + def content_type_allowlist %w[application/pdf] end diff --git a/app/uploaders/machine_image_uploader.rb b/app/uploaders/machine_image_uploader.rb index 0141731e1..4dcd0f5ea 100644 --- a/app/uploaders/machine_image_uploader.rb +++ b/app/uploaders/machine_image_uploader.rb @@ -51,11 +51,11 @@ class MachineImageUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[jpg jpeg gif png] end - def content_type_whitelist + def content_type_allowlist [%r{image/}] end diff --git a/app/uploaders/plan_file_uploader.rb b/app/uploaders/plan_file_uploader.rb index 680ef86af..983322e02 100644 --- a/app/uploaders/plan_file_uploader.rb +++ b/app/uploaders/plan_file_uploader.rb @@ -41,11 +41,11 @@ class PlanFileUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[pdf png jpeg jpg] end - def content_type_whitelist + def content_type_allowlist [%r{image/}, 'application/pdf'] end diff --git a/app/uploaders/product_file_uploader.rb b/app/uploaders/product_file_uploader.rb index 1cee5d75c..316a8d9eb 100644 --- a/app/uploaders/product_file_uploader.rb +++ b/app/uploaders/product_file_uploader.rb @@ -46,11 +46,11 @@ class ProductFileUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[pdf] end - def content_type_whitelist + def content_type_allowlist ['application/pdf'] end diff --git a/app/uploaders/product_image_uploader.rb b/app/uploaders/product_image_uploader.rb index caaa61799..90a522c36 100644 --- a/app/uploaders/product_image_uploader.rb +++ b/app/uploaders/product_image_uploader.rb @@ -39,11 +39,11 @@ class ProductImageUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[jpg jpeg gif png webp] end - def content_type_whitelist + def content_type_allowlist [%r{image/}] end diff --git a/app/uploaders/project_cao_uploader.rb b/app/uploaders/project_cao_uploader.rb index 0b060198f..25ba2f0ce 100644 --- a/app/uploaders/project_cao_uploader.rb +++ b/app/uploaders/project_cao_uploader.rb @@ -23,11 +23,11 @@ class ProjectCaoUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist Setting.get('allowed_cad_extensions').split(' ') end - def content_type_whitelist + def content_type_allowlist Setting.get('allowed_cad_mime_types').split(' ') end end diff --git a/app/uploaders/project_image_uploader.rb b/app/uploaders/project_image_uploader.rb index 96e9d5bf6..aed3ffb8e 100644 --- a/app/uploaders/project_image_uploader.rb +++ b/app/uploaders/project_image_uploader.rb @@ -29,11 +29,11 @@ class ProjectImageUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[jpg jpeg gif png] end - def content_type_whitelist + def content_type_allowlist [%r{image/}] end diff --git a/app/uploaders/space_file_uploader.rb b/app/uploaders/space_file_uploader.rb index 1cdf2cf20..ccd30427c 100644 --- a/app/uploaders/space_file_uploader.rb +++ b/app/uploaders/space_file_uploader.rb @@ -41,11 +41,11 @@ class SpaceFileUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[pdf] end - def content_type_whitelist + def content_type_allowlist %w[application/pdf] end diff --git a/app/uploaders/space_image_uploader.rb b/app/uploaders/space_image_uploader.rb index 4c5b57a29..ad9759f10 100644 --- a/app/uploaders/space_image_uploader.rb +++ b/app/uploaders/space_image_uploader.rb @@ -51,11 +51,11 @@ class SpaceImageUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[jpg jpeg gif png] end - def content_type_whitelist + def content_type_allowlist [%r{image/}] end diff --git a/app/uploaders/supporting_document_file_uploader.rb b/app/uploaders/supporting_document_file_uploader.rb index 9cc533a2d..a94dfbf00 100644 --- a/app/uploaders/supporting_document_file_uploader.rb +++ b/app/uploaders/supporting_document_file_uploader.rb @@ -47,11 +47,11 @@ class SupportingDocumentFileUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[pdf png jpeg jpg] end - def content_type_whitelist + def content_type_allowlist [%r{image/}, 'application/pdf'] end diff --git a/app/uploaders/training_image_uploader.rb b/app/uploaders/training_image_uploader.rb index 8d87b4025..8d6e4206d 100644 --- a/app/uploaders/training_image_uploader.rb +++ b/app/uploaders/training_image_uploader.rb @@ -51,11 +51,11 @@ class TrainingImageUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[jpg jpeg gif png] end - def content_type_whitelist + def content_type_allowlist [%r{image/}] end diff --git a/app/uploaders/user_avatar_uploader.rb b/app/uploaders/user_avatar_uploader.rb index 6c9f40ced..9841a0e69 100644 --- a/app/uploaders/user_avatar_uploader.rb +++ b/app/uploaders/user_avatar_uploader.rb @@ -55,11 +55,11 @@ class UserAvatarUploader < CarrierWave::Uploader::Base # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: - def extension_whitelist + def extension_allowlist %w[jpg jpeg gif png] end - def content_type_whitelist + def content_type_allowlist %w[image/jpeg image/gif image/png] end From d5d3e6153863fb931c9923f56f3d1a5c8244cb6d Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 11 Mar 2024 12:48:20 +0100 Subject: [PATCH 41/92] Version 6.3.16 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f74c134c2..b3f5b7fca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +## v6.3.16 2024 March 11 + - Fix a bug: set settlement by cash by default for local payment mean - updates translations - #content_type_whitelist is instead by #content_type_allowlist diff --git a/package.json b/package.json index e47588a54..8b7ea0300 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fab-manager", - "version": "6.3.15", + "version": "6.3.16", "description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.", "keywords": [ "fablab", From 8a2a9085be40f4530e080be25b0b51db4ba9d3f8 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Tue, 12 Mar 2024 18:58:27 +0100 Subject: [PATCH 42/92] (impv) add loader for create/delete availability slot --- .../src/javascript/controllers/admin/calendar.js | 14 +++++++++++++- .../src/javascript/controllers/events.js.erb | 5 +++++ .../templates/admin/calendar/deleteRecurrent.html | 2 +- .../templates/admin/calendar/eventModal.html | 2 +- app/frontend/templates/events/deleteRecurrent.html | 2 +- 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/frontend/src/javascript/controllers/admin/calendar.js b/app/frontend/src/javascript/controllers/admin/calendar.js index 3e59d6b76..77b132488 100644 --- a/app/frontend/src/javascript/controllers/admin/calendar.js +++ b/app/frontend/src/javascript/controllers/admin/calendar.js @@ -789,6 +789,8 @@ Application.Controllers.controller('CreateEventModalController', ['$scope', '$ui // number of slots for this availability $scope.slots_nb = slots; + $scope.saving = false; + /** * Adds or removes the provided machine from the current slot * @param machine {Object} @@ -867,9 +869,14 @@ Application.Controllers.controller('CreateEventModalController', ['$scope', '$ui if ($scope.isOnlySubscriptions && $scope.selectedPlans.length > 0) { $scope.availability.plan_ids = $scope.selectedPlans.map(function (p) { return p.id; }); } + $scope.saving = true; return Availability.save( { availability: $scope.availability }, - function (availability) { $uibModalInstance.close(availability); } + function (availability) { $uibModalInstance.close(availability); }, + function (error) { + console.error(error); + $scope.saving = false; + } ); }; @@ -1158,15 +1165,19 @@ Application.Controllers.controller('DeleteRecurrentAvailabilityController', ['$s // with recurrent slots: how many slots should we delete? $scope.deleteMode = 'single'; + $scope.deleting = false; + /** * Confirmation callback */ $scope.ok = function () { const { id, start_at, end_at } = availabilityPromise; + $scope.deleting = true; // the admin has confirmed, delete the slot Availability.delete( { id, mode: $scope.deleteMode }, function (res) { + $scope.deleting = false; // delete success if (res.deleted > 1) { growl.success(_t( @@ -1185,6 +1196,7 @@ Application.Controllers.controller('DeleteRecurrentAvailabilityController', ['$s }); }, function (res) { + $scope.deleting = false; // not everything was deleted const { data } = res; if (data.total > 1) { diff --git a/app/frontend/src/javascript/controllers/events.js.erb b/app/frontend/src/javascript/controllers/events.js.erb index 376a6378e..04aaead75 100644 --- a/app/frontend/src/javascript/controllers/events.js.erb +++ b/app/frontend/src/javascript/controllers/events.js.erb @@ -1096,15 +1096,19 @@ Application.Controllers.controller('DeleteRecurrentEventController', ['$scope', // with recurrent slots: how many slots should we delete? $scope.deleteMode = 'single'; + $scope.deleting = false; + /** * Confirmation callback */ $scope.ok = function () { + $scope.deleting = true; const { id, start_at, end_at } = eventPromise; // the admin has confirmed, delete the slot Event.delete( { id, mode: $scope.deleteMode }, function (res) { + $scope.deleting = false; // delete success if (res.deleted > 1) { growl.success(_t( @@ -1122,6 +1126,7 @@ Application.Controllers.controller('DeleteRecurrentEventController', ['$scope', }); }, function (res) { + $scope.deleting = false; // not everything was deleted const { data } = res; if (data.total > 1) { diff --git a/app/frontend/templates/admin/calendar/deleteRecurrent.html b/app/frontend/templates/admin/calendar/deleteRecurrent.html index 6d26fe67a..cce63be6e 100644 --- a/app/frontend/templates/admin/calendar/deleteRecurrent.html +++ b/app/frontend/templates/admin/calendar/deleteRecurrent.html @@ -21,6 +21,6 @@ diff --git a/app/frontend/templates/admin/calendar/eventModal.html b/app/frontend/templates/admin/calendar/eventModal.html index 0f7d3c551..077d3986c 100644 --- a/app/frontend/templates/admin/calendar/eventModal.html +++ b/app/frontend/templates/admin/calendar/eventModal.html @@ -252,6 +252,6 @@ diff --git a/app/frontend/templates/events/deleteRecurrent.html b/app/frontend/templates/events/deleteRecurrent.html index 90acecbf8..a6ae798b3 100644 --- a/app/frontend/templates/events/deleteRecurrent.html +++ b/app/frontend/templates/events/deleteRecurrent.html @@ -22,6 +22,6 @@ From 1b6f43361cd07460b2109c18bbfec340e06a6481 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Tue, 12 Mar 2024 18:58:46 +0100 Subject: [PATCH 43/92] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3f5b7fca..df078dc9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +- improvement: add loader for create/delete availability slot + ## v6.3.16 2024 March 11 - Fix a bug: set settlement by cash by default for local payment mean From 0b085104736feaee3ae5d0587eaeff7cac2c5dd5 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 18 Mar 2024 18:36:10 +0100 Subject: [PATCH 44/92] (bug) unable to update a space with a deleted machine --- CHANGELOG.md | 1 + app/frontend/src/javascript/lib/api.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df078dc9d..cee1a7843 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Next release - improvement: add loader for create/delete availability slot +- Fix a bug: unable to update a space with a deleted machine ## v6.3.16 2024 March 11 diff --git a/app/frontend/src/javascript/lib/api.ts b/app/frontend/src/javascript/lib/api.ts index 76e99d6fc..1de9110df 100644 --- a/app/frontend/src/javascript/lib/api.ts +++ b/app/frontend/src/javascript/lib/api.ts @@ -18,7 +18,7 @@ export default class ApiLib { ...object, ...attachmentAttributes.reduce((a, name) => { return { ...a, [name]: null }; }, {}) } - }, { dateWithTimezone: true }); + }, { dateWithTimezone: true, allowEmptyArrays: true }); attachmentAttributes.forEach((attr) => { data.delete(`${name}[${attr}]`); if (Array.isArray(object[attr])) { From 6db25324d2ce9ea38977830662c12f1d8e6e2e22 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Wed, 20 Mar 2024 14:59:02 +0100 Subject: [PATCH 45/92] (bug) unable to get invoice payment details if the account code is same for card/transfer payment method --- CHANGELOG.md | 1 + app/views/open_api/v1/accounting/index.json.jbuilder | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cee1a7843..11277b0b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - improvement: add loader for create/delete availability slot - Fix a bug: unable to update a space with a deleted machine +- Fix a bug: unable to get invoice payment details if the account code is same for card/transfer payment method ## v6.3.16 2024 March 11 diff --git a/app/views/open_api/v1/accounting/index.json.jbuilder b/app/views/open_api/v1/accounting/index.json.jbuilder index 44b161f0b..fca21c588 100644 --- a/app/views/open_api/v1/accounting/index.json.jbuilder +++ b/app/views/open_api/v1/accounting/index.json.jbuilder @@ -11,7 +11,7 @@ json.lines @lines do |line| json.url download_open_api_v1_invoice_path(line.invoice) json.payment_method line.invoice_payment_method if @codes.values.include?(line.account_code) # if this is a 'payment' line - mean = @codes.select { |_key, value| value == line.account_code } + mean = @codes.select { |_key, value| value == line.account_code && _key == line.invoice_payment_method.to_sym } json.payment_details line.invoice.payment_details(mean.keys[0]) end end From e8b59bbdcd64f98d33d07c5814c4e394bfd782e8 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 21 Mar 2024 18:21:11 +0100 Subject: [PATCH 46/92] (feat) allow admin configure memeber's profile gender/birthday as required --- CHANGELOG.md | 1 + .../components/user/user-profile-form.tsx | 6 ++--- .../javascript/controllers/admin/members.js | 24 +++++++++++++++++ .../src/javascript/controllers/application.js | 6 +++++ app/frontend/src/javascript/models/setting.ts | 4 ++- app/frontend/src/javascript/router.js | 14 +++++----- .../templates/admin/settings/compte.html | 26 +++++++++++++++++++ .../templates/shared/_admin_form.html | 9 ++++--- .../templates/shared/_manager_form.html | 8 +++--- .../templates/shared/signupModal.html | 8 +++--- app/helpers/excel_helper.rb | 2 +- app/helpers/settings_helper.rb | 2 ++ app/models/statistic_profile.rb | 2 ++ app/models/user.rb | 6 +++-- app/policies/setting_policy.rb | 3 ++- app/views/exports/users_members.xlsx.axlsx | 2 +- config/locales/app.admin.en.yml | 6 +++++ db/seeds/settings.rb | 5 ++++ .../exports/statistics_export_test.rb | 3 ++- 19 files changed, 110 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11277b0b4..8396dda38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Next release - improvement: add loader for create/delete availability slot +- improvement: allow admin configure memeber's profile gender/birthday as required - Fix a bug: unable to update a space with a deleted machine - Fix a bug: unable to get invoice payment details if the account code is same for card/transfer payment method diff --git a/app/frontend/src/javascript/components/user/user-profile-form.tsx b/app/frontend/src/javascript/components/user/user-profile-form.tsx index eb7911b93..a2f5f2c9e 100644 --- a/app/frontend/src/javascript/components/user/user-profile-form.tsx +++ b/app/frontend/src/javascript/components/user/user-profile-form.tsx @@ -93,7 +93,7 @@ export const UserProfileForm: React.FC = ({ action, size, }); setValue('invoicing_profile_attributes.user_profile_custom_fields_attributes', userProfileCustomFields); }).catch(error => onError(error)); - SettingAPI.query(['phone_required', 'address_required', 'external_id']) + SettingAPI.query(['phone_required', 'address_required', 'external_id', 'gender_required', 'birthday_required']) .then(settings => setFieldsSettings(settings)) .catch(error => onError(error)); }, []); @@ -185,7 +185,7 @@ export const UserProfileForm: React.FC = ({ action, size,

{t('app.shared.user_profile_form.personal_data')}

- +
= ({ action, size, register={register} label={t('app.shared.user_profile_form.date_of_birth')} disabled={isDisabled} - rules={{ required: true }} + rules={{ required: fieldsSettings.get('birthday_required') === 'true' }} formState={formState} type="date" nullable /> diff --git a/app/frontend/src/javascript/controllers/admin/members.js b/app/frontend/src/javascript/controllers/admin/members.js index 860cb71aa..cf72738f8 100644 --- a/app/frontend/src/javascript/controllers/admin/members.js +++ b/app/frontend/src/javascript/controllers/admin/members.js @@ -720,6 +720,12 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state', // is the address required in _member_form? $scope.addressRequired = (settingsPromise.address_required === 'true'); + // is the gender number required in _member_form? + $scope.genderRequired = (settingsPromise.gender_required === 'true'); + + // is the birthday required in _member_form? + $scope.birthdayRequired = (settingsPromise.birthday_required === 'true'); + // is user validation required $scope.enableUserValidationRequired = (settingsPromise.user_validation_required === 'true'); @@ -1060,6 +1066,12 @@ Application.Controllers.controller('NewMemberController', ['$scope', '$state', ' // is the address required to sign-up? $scope.addressRequired = (settingsPromise.address_required === 'true'); + // is the gender number required in _member_form? + $scope.genderRequired = (settingsPromise.gender_required === 'true'); + + // is the birthday required in _member_form? + $scope.birthdayRequired = (settingsPromise.birthday_required === 'true'); + // Default member's profile parameters $scope.user = { plan_interval: '', @@ -1205,6 +1217,12 @@ Application.Controllers.controller('NewAdminController', ['$state', '$scope', 'A // is the address required in _admin_form? $scope.addressRequired = (settingsPromise.address_required === 'true'); + // is the gender number required in _admin_form? + $scope.genderRequired = (settingsPromise.gender_required === 'true'); + + // is the birthday required in _admin_form? + $scope.birthdayRequired = (settingsPromise.birthday_required === 'true'); + // all available groups $scope.groups = groupsPromise; @@ -1276,6 +1294,12 @@ Application.Controllers.controller('NewManagerController', ['$state', '$scope', // is the address required in _admin_form? $scope.addressRequired = (settingsPromise.address_required === 'true'); + // is the gender number required in _admin_form? + $scope.genderRequired = (settingsPromise.gender_required === 'true'); + + // is the birthday required in _admin_form? + $scope.birthdayRequired = (settingsPromise.birthday_required === 'true'); + // list of all groups $scope.groups = groupsPromise.filter(function (g) { return !g.disabled; }); diff --git a/app/frontend/src/javascript/controllers/application.js b/app/frontend/src/javascript/controllers/application.js index 846c5eb40..c081a7bd3 100644 --- a/app/frontend/src/javascript/controllers/application.js +++ b/app/frontend/src/javascript/controllers/application.js @@ -103,6 +103,12 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco // is the address required to sign-up? $scope.addressRequired = (settingsPromise.address_required === 'true'); + // is the gender required to sign-up? + $scope.genderRequired = (settingsPromise.gender_required === 'true'); + + // is the birthday required to sign-up? + $scope.birthdayRequired = (settingsPromise.birthday_required === 'true'); + // reCaptcha v2 site key (or undefined) $scope.recaptchaSiteKey = settingsPromise.recaptcha_site_key; diff --git a/app/frontend/src/javascript/models/setting.ts b/app/frontend/src/javascript/models/setting.ts index 604a58a28..315e74d2e 100644 --- a/app/frontend/src/javascript/models/setting.ts +++ b/app/frontend/src/javascript/models/setting.ts @@ -186,7 +186,9 @@ export const accountSettings = [ 'user_change_group', 'user_validation_required', 'user_validation_required_list', - 'family_account' + 'family_account', + 'gender_required', + 'birthday_required' ] as const; export const analyticsSettings = [ diff --git a/app/frontend/src/javascript/router.js b/app/frontend/src/javascript/router.js index 74d83f59e..610758d88 100644 --- a/app/frontend/src/javascript/router.js +++ b/app/frontend/src/javascript/router.js @@ -127,7 +127,7 @@ angular.module('application.router', ['ui.router']) } }, resolve: { - settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['fablab_name', 'name_genre', 'phone_required', 'address_required']" }).$promise; }], + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['fablab_name', 'name_genre', 'phone_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }], activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }], groupsPromise: ['Group', function (Group) { return Group.query().$promise; }], cguFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'cgu-file' }).$promise; }], @@ -174,7 +174,7 @@ angular.module('application.router', ['ui.router']) resolve: { groups: ['Group', function (Group) { return Group.query().$promise; }], activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }], - settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }] } }) .state('app.logged.dashboard.supporting_document_files', { @@ -1049,7 +1049,7 @@ angular.module('application.router', ['ui.router']) } }, resolve: { - settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }] } }) .state('app.admin.members_import', { @@ -1090,7 +1090,7 @@ angular.module('application.router', ['ui.router']) walletPromise: ['Wallet', '$transition$', function (Wallet, $transition$) { return Wallet.getWalletByUser({ user_id: $transition$.params().id }).$promise; }], transactionsPromise: ['Wallet', 'walletPromise', function (Wallet, walletPromise) { return Wallet.transactions({ id: walletPromise.id }).$promise; }], tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }], - settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'user_validation_required']" }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'gender_required', 'birthday_required', 'user_validation_required']" }).$promise; }] } }) .state('app.admin.admins_new', { @@ -1102,7 +1102,7 @@ angular.module('application.router', ['ui.router']) } }, resolve: { - settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }], + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }], groupsPromise: ['Group', function (Group) { return Group.query({ disabled: false }).$promise; }] } }) @@ -1117,7 +1117,7 @@ angular.module('application.router', ['ui.router']) resolve: { groupsPromise: ['Group', function (Group) { return Group.query().$promise; }], tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }], - settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }] + settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }] } }) @@ -1200,7 +1200,7 @@ angular.module('application.router', ['ui.router']) "'extended_prices_in_same_day', 'recaptcha_site_key', 'recaptcha_secret_key', 'user_validation_required', " + "'user_validation_required_list', 'machines_module', 'user_change_group', " + "'store_module', 'machine_reservation_deadline', 'training_reservation_deadline', 'event_reservation_deadline', " + - "'space_reservation_deadline', 'reservation_context_feature']" + "'space_reservation_deadline', 'reservation_context_feature', 'gender_required', 'birthday_required']" }).$promise; }], privacyDraftsPromise: ['Setting', function (Setting) { return Setting.get({ name: 'privacy_draft', history: true }).$promise; }], diff --git a/app/frontend/templates/admin/settings/compte.html b/app/frontend/templates/admin/settings/compte.html index 44f0f14a9..536d5a627 100644 --- a/app/frontend/templates/admin/settings/compte.html +++ b/app/frontend/templates/admin/settings/compte.html @@ -110,6 +110,32 @@ {{ 'app.admin.settings.account.customize_account_settings' }}
+
+

{{ 'app.admin.settings.gender' }}

+

+ {{ 'app.admin.settings.gender_required_info' }} +

+
+ + +
+
+
+

{{ 'app.admin.settings.birthday' }}

+

+ {{ 'app.admin.settings.birthday_required_info' }} +

+
+ + +
+

{{ 'app.admin.settings.phone' }}

diff --git a/app/frontend/templates/shared/_admin_form.html b/app/frontend/templates/shared/_admin_form.html index 5f90dc4c6..2b33f38c7 100644 --- a/app/frontend/templates/shared/_admin_form.html +++ b/app/frontend/templates/shared/_admin_form.html @@ -6,7 +6,7 @@ name="admin[statistic_profile_attributes][gender]" ng-model="admin.statistic_profile_attributes.gender" ng-value="true" - required/> + ng-required="genderRequired"/> {{ 'app.admin.admins_new.man' | translate }} - +

@@ -76,7 +76,9 @@
- + + + + ng-required="genderRequired"/> {{ 'app.admin.manager_new.man' | translate }} - +
@@ -76,7 +76,9 @@
- + + + {{ 'app.public.common.man' | translate }} + ng-required="genderRequired"/> {{ 'app.public.common.man' | translate }}
- + {{ 'app.public.common.gender_is_required'}}
@@ -222,9 +222,9 @@ is-open="datePicker.opened" placeholder="{{ 'app.public.common.birth_date' | translate }}" ng-click="openDatePicker($event)" - required/> + ng-required="birthdayRequired"/>
- + {{ 'app.public.common.birth_date_is_required' }}
diff --git a/app/helpers/excel_helper.rb b/app/helpers/excel_helper.rb index 9693c9262..391dc8113 100644 --- a/app/helpers/excel_helper.rb +++ b/app/helpers/excel_helper.rb @@ -31,7 +31,7 @@ module ExcelHelper user&.profile&.full_name || t('export.deleted_user'), user&.email || '', user&.profile&.phone || '', - t("export.#{hit['_source']['gender']}"), + hit['_source']['gender'].present? ? t("export.#{hit['_source']['gender']}") : '', hit['_source']['age'], subtype.nil? ? '' : subtype.label ] diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index 79885b5b1..ec52ec881 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -208,6 +208,8 @@ module SettingsHelper project_categories_filter_placeholder project_categories_wording reservation_context_feature + gender_required + birthday_required ].freeze end # rubocop:enable Metrics/ModuleLength diff --git a/app/models/statistic_profile.rb b/app/models/statistic_profile.rb index e0120c65e..4bd910163 100644 --- a/app/models/statistic_profile.rb +++ b/app/models/statistic_profile.rb @@ -31,6 +31,8 @@ class StatisticProfile < ApplicationRecord validate :check_birthday_in_past def str_gender + return '' if gender.blank? + gender ? 'male' : 'female' end diff --git a/app/models/user.rb b/app/models/user.rb index e714b15d7..11edbf2f3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -115,8 +115,10 @@ class User < ApplicationRecord end def need_completion? - statistic_profile.gender.nil? || profile.first_name.blank? || profile.last_name.blank? || username.blank? || - email.blank? || encrypted_password.blank? || group_id.nil? || statistic_profile.birthday.blank? || + (Setting.get('gender_required') && statistic_profile.gender.blank?) || + profile.first_name.blank? || profile.last_name.blank? || username.blank? || + email.blank? || encrypted_password.blank? || group_id.nil? || + (Setting.get('birthday_required') && statistic_profile.birthday.blank?) || (Setting.get('phone_required') && profile.phone.blank?) || (Setting.get('address_required') && invoicing_profile&.address&.address&.blank?) end diff --git a/app/policies/setting_policy.rb b/app/policies/setting_policy.rb index 5e3a620b6..be9fb64dd 100644 --- a/app/policies/setting_policy.rb +++ b/app/policies/setting_policy.rb @@ -47,7 +47,8 @@ class SettingPolicy < ApplicationPolicy machines_banner_cta_url trainings_banner_active trainings_banner_text trainings_banner_cta_active trainings_banner_cta_label trainings_banner_cta_url events_banner_active events_banner_text events_banner_cta_active events_banner_cta_label events_banner_cta_url projects_list_member_filter_presence projects_list_date_filters_presence advanced_accounting - project_categories_filter_placeholder project_categories_wording reservation_context_feature family_account child_validation_required] + project_categories_filter_placeholder project_categories_wording reservation_context_feature family_account child_validation_required + gender_required birthday_required] end ## diff --git a/app/views/exports/users_members.xlsx.axlsx b/app/views/exports/users_members.xlsx.axlsx index f4866e267..e05916abe 100644 --- a/app/views/exports/users_members.xlsx.axlsx +++ b/app/views/exports/users_members.xlsx.axlsx @@ -49,7 +49,7 @@ wb.add_worksheet(name: ExcelService.name_safe(t('export_members.members'))) do | member.email, member.is_allow_newsletter, member.last_sign_in_at&.to_date, - member.statistic_profile.gender ? t('export_members.man') : t('export_members.woman'), + member.statistic_profile.gender.present? ? (member.statistic_profile.gender ? t('export_members.man') : t('export_members.woman')) : '', member.statistic_profile.age, member.invoicing_profile&.address&.address || '', member.profile.phone, diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index ed86a193e..9bf556b83 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -1839,6 +1839,12 @@ en: address: "Address" address_required_info_html: "You can define if the address should be required to register a new user on Fab-manager.
Please note that, depending on your country, the regulations may requires addresses for the invoices to be valid." address_is_required: "Address is required" + gender: "Gender" + gender_is_required: "Gender required" + gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager." + birthday: "Date of birth" + birthday_is_required: "Date of birth required" + birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager." external_id: "External identifier" external_id_info_html: "You can set up an external identifier for your users, which cannot be modified by the user himself." enable_external_id: "Enable the external ID" diff --git a/db/seeds/settings.rb b/db/seeds/settings.rb index 2b62e06a9..574f6ae57 100644 --- a/db/seeds/settings.rb +++ b/db/seeds/settings.rb @@ -742,3 +742,8 @@ Setting.set('reservation_context_feature', false) unless Setting.find_by(name: ' Setting.set('family_account', false) unless Setting.find_by(name: 'family_account').try(:value) Setting.set('child_validation_required', false) unless Setting.find_by(name: 'child_validation_required').try(:value) + +Setting.set('phone_required', false) unless Setting.find_by(name: 'phone_required').try(:value) +Setting.set('address_required', false) unless Setting.find_by(name: 'address_required').try(:value) +Setting.set('gender_required', true) unless Setting.find_by(name: 'gender_required').try(:value) +Setting.set('birthday_required', true) unless Setting.find_by(name: 'birthday_required').try(:value) diff --git a/test/integration/exports/statistics_export_test.rb b/test/integration/exports/statistics_export_test.rb index 0169aec0c..3ed494cb2 100644 --- a/test/integration/exports/statistics_export_test.rb +++ b/test/integration/exports/statistics_export_test.rb @@ -59,7 +59,8 @@ class Exports::StatisticsExportTest < ActionDispatch::IntegrationTest assert_equal reservation.user.profile.full_name, wb.sheet_data[5][1].value assert_equal reservation.user.email, wb.sheet_data[5][2].value assert_equal reservation.user.profile.phone, wb.sheet_data[5][3].value - assert_equal I18n.t("export.#{reservation.user.statistic_profile.str_gender}"), wb.sheet_data[5][4].value + assert_equal reservation.user.statistic_profile.str_gender.present? ? I18n.t("export.#{reservation.user.statistic_profile.str_gender}") : '', + wb.sheet_data[5][4].value assert_equal reservation.user.statistic_profile.age.to_i, wb.sheet_data[5][5].value assert_equal reservation.reservable.name, wb.sheet_data[5][6].value assert_equal reservation.invoice_items.first.invoice.total / 100.0, wb.sheet_data[5][7].value From 584f3bc4a86def06d708fc43916e10d5fe8595ca Mon Sep 17 00:00:00 2001 From: Du Peng Date: Thu, 21 Mar 2024 18:56:24 +0100 Subject: [PATCH 47/92] update translations --- CHANGELOG.md | 1 + config/locales/app.admin.de.yml | 8 ++++++++ config/locales/app.admin.en.yml | 2 ++ config/locales/app.admin.es-MX.yml | 8 ++++++++ config/locales/app.admin.es.yml | 8 ++++++++ config/locales/app.admin.fr.yml | 10 +++++++++- config/locales/app.admin.it.yml | 8 ++++++++ config/locales/app.admin.no.yml | 8 ++++++++ config/locales/app.admin.pt.yml | 8 ++++++++ config/locales/app.admin.sv.yml | 8 ++++++++ config/locales/app.admin.zu.yml | 8 ++++++++ 11 files changed, 76 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8396dda38..d08c05844 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - improvement: allow admin configure memeber's profile gender/birthday as required - Fix a bug: unable to update a space with a deleted machine - Fix a bug: unable to get invoice payment details if the account code is same for card/transfer payment method +- updates translations ## v6.3.16 2024 March 11 diff --git a/config/locales/app.admin.de.yml b/config/locales/app.admin.de.yml index 01e52ee4e..4dbe34465 100644 --- a/config/locales/app.admin.de.yml +++ b/config/locales/app.admin.de.yml @@ -1787,6 +1787,8 @@ de: fab_analytics: "Fab-Analytics" phone_required: "Telefonummer erforderlich" address_required: "Adresse erforderlich" + gender_required: "gender required" + birthday_required: "date of birth required" tracking_id: "Tracking-ID" facebook_app_id: "Facebook App-ID" twitter_analytics: "Twitter Analytics-Konto" @@ -1839,6 +1841,12 @@ de: address: "Adresse" address_required_info_html: "Sie können festlegen, ob eine Adresse für die Neuregistrierung eines Benutzers erforderlich sein soll.
Bitte beachten Sie dass in Abhängigkeit von Landesvorschriften Adressen für die Gültigkeit der Rechnungen erforderlich sein können." address_is_required: "Adresse ist erforderlich" + gender: "Gender" + gender_is_required: "Gender required" + gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager." + birthday: "Date of birth" + birthday_is_required: "Date of birth required" + birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager." external_id: "External identifier" external_id_info_html: "You can set up an external identifier for your users, which cannot be modified by the user himself." enable_external_id: "Enable the external ID" diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index 9bf556b83..f9b091480 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -1787,6 +1787,8 @@ en: fab_analytics: "Fab Analytics" phone_required: "phone required" address_required: "address required" + gender_required: "gender required" + birthday_required: "date of birth required" tracking_id: "tracking ID" facebook_app_id: "Facebook App ID" twitter_analytics: "Twitter analytics account" diff --git a/config/locales/app.admin.es-MX.yml b/config/locales/app.admin.es-MX.yml index 9c236e8ca..2e772a303 100644 --- a/config/locales/app.admin.es-MX.yml +++ b/config/locales/app.admin.es-MX.yml @@ -1787,6 +1787,8 @@ es-MX: fab_analytics: "Fab Analytics" phone_required: "teléfono requerido" address_required: "dirección requerida" + gender_required: "gender required" + birthday_required: "date of birth required" tracking_id: "ID de seguimiento" facebook_app_id: "ID de aplicación de Facebook" twitter_analytics: "Cuenta analítica de Twitter" @@ -1839,6 +1841,12 @@ es-MX: address: "Dirección" address_required_info_html: "Puede definir si la dirección debe ser necesaria para registrar un nuevo usuario en Fab-manager.
Tenga en cuenta que, dependiendo de su país, la normativa puede exigir direcciones para que los recibos sean válidos." address_is_required: "Dirección requerida" + gender: "Gender" + gender_is_required: "Gender required" + gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager." + birthday: "Date of birth" + birthday_is_required: "Date of birth required" + birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager." external_id: "Identificador externo" external_id_info_html: "Puede establecer un identificador externo para sus usuarios, que no podrá ser modificado por el propio usuario." enable_external_id: "Activar el ID externo" diff --git a/config/locales/app.admin.es.yml b/config/locales/app.admin.es.yml index c0367f6fa..d0cd55b50 100644 --- a/config/locales/app.admin.es.yml +++ b/config/locales/app.admin.es.yml @@ -1787,6 +1787,8 @@ es: fab_analytics: "Fab Analytics" phone_required: "teléfono requerido" address_required: "dirección requerida" + gender_required: "gender required" + birthday_required: "date of birth required" tracking_id: "ID de seguimiento" facebook_app_id: "ID de aplicación de Facebook" twitter_analytics: "Cuenta analítica de Twitter" @@ -1839,6 +1841,12 @@ es: address: "Dirección" address_required_info_html: "Puede definir si la dirección debe ser necesaria para registrar un nuevo usuario en Fab-manager.
Tenga en cuenta que, dependiendo de su país, la normativa puede exigir direcciones para que las facturas sean válidas." address_is_required: "Dirección requerida" + gender: "Gender" + gender_is_required: "Gender required" + gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager." + birthday: "Date of birth" + birthday_is_required: "Date of birth required" + birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager." external_id: "Identificador externo" external_id_info_html: "Puede establecer un identificador externo para sus usuarios, que no podrá ser modificado por el propio usuario." enable_external_id: "Activar el ID externo" diff --git a/config/locales/app.admin.fr.yml b/config/locales/app.admin.fr.yml index 1bf7f9d40..e0a1f6f4e 100644 --- a/config/locales/app.admin.fr.yml +++ b/config/locales/app.admin.fr.yml @@ -1383,7 +1383,7 @@ fr: to_credit: 'Créditer' cannot_credit_own_wallet: "Vous ne pouvez pas créditer votre propre porte-monnaie. Veuillez demander à un autre gestionnaire ou à un administrateur de créditer votre porte-monnaie." cannot_extend_own_subscription: "Vous ne pouvez pas prolonger votre propre abonnement. Veuillez demander à un autre gestionnaire ou à un administrateur de prolonger votre abonnement." - update_success: "Le profile du membre a bien été mis à jour" + update_success: "Le profil du membre a bien été mis à jour" my_documents: "Mes documents" save: "Enregistrer" confirm: "Valider" @@ -1787,6 +1787,8 @@ fr: fab_analytics: "Fab Analytics" phone_required: "téléphone requis" address_required: "adresse requise" + gender_required: "genre requis" + birthday_required: "date de naissance requise" tracking_id: "l'ID de suivi" facebook_app_id: "l'App ID Facebook" twitter_analytics: "compte Twitter analytics" @@ -1839,6 +1841,12 @@ fr: address: "Adresse" address_required_info_html: "Vous pouvez définir si l'adresse doit être requise, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager.
Veuillez noter que, selon votre pays, la réglementation peut exiger des adresses pour que les factures soient valides." address_is_required: "Adresse requise" + gender: "Genre" + gender_is_required: "Genre requis" + gender_required_info: "Vous pouvez définir si le genre doit être requis, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager." + birthday: "Date de naissance" + birthday_is_required: "Date de naissance requise" + birthday_required_info: "Vous pouvez définir si la date de naissance doit être requis, lors de l'enregistrement d'un nouvel utilisateur sur Fab-manager." external_id: "Identifiant externe" external_id_info_html: "Vous pouvez configurer un identifiant externe pour vos utilisateurs, qui ne pourra pas être modifié par l'utilisateur lui-même." enable_external_id: "Activer l'identifiant externe" diff --git a/config/locales/app.admin.it.yml b/config/locales/app.admin.it.yml index 51406d6a2..76b9d7feb 100644 --- a/config/locales/app.admin.it.yml +++ b/config/locales/app.admin.it.yml @@ -1787,6 +1787,8 @@ it: fab_analytics: "Fab Analytics" phone_required: "telefono richiesto" address_required: "indirizzo richiesto" + gender_required: "gender required" + birthday_required: "date of birth required" tracking_id: "tracking ID" facebook_app_id: "Facebook App ID" twitter_analytics: "Account analytics Twitter" @@ -1839,6 +1841,12 @@ it: address: "Indirizzo" address_required_info_html: "È possibile definire se l'indirizzo deve essere richiesto per registrare un nuovo utente su Fab-manager.
Si prega di notare che, a seconda del tuo paese, la normativa potrebbe richiedere indirizzi per la validità delle fatture." address_is_required: "L'indirizzo è obbligatorio" + gender: "Gender" + gender_is_required: "Gender required" + gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager." + birthday: "Date of birth" + birthday_is_required: "Date of birth required" + birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager." external_id: "Identificatore esterno" external_id_info_html: "È possibile impostare un identificatore esterno per i propri utenti, che non può essere modificato dall'utente stesso." enable_external_id: "Abilita l'ID esterno" diff --git a/config/locales/app.admin.no.yml b/config/locales/app.admin.no.yml index 126778db2..dab311ed5 100644 --- a/config/locales/app.admin.no.yml +++ b/config/locales/app.admin.no.yml @@ -1787,6 +1787,8 @@ fab_analytics: "Fab Analytics" phone_required: "phone required" address_required: "address required" + gender_required: "gender required" + birthday_required: "date of birth required" tracking_id: "tracking ID" facebook_app_id: "Facebook App ID" twitter_analytics: "Twitter analytics account" @@ -1839,6 +1841,12 @@ address: "Address" address_required_info_html: "You can define if the address should be required to register a new user on Fab-manager.
Please note that, depending on your country, the regulations may requires addresses for the invoices to be valid." address_is_required: "Adresse er påkrevd" + gender: "Gender" + gender_is_required: "Gender required" + gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager." + birthday: "Date of birth" + birthday_is_required: "Date of birth required" + birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager." external_id: "External identifier" external_id_info_html: "You can set up an external identifier for your users, which cannot be modified by the user himself." enable_external_id: "Enable the external ID" diff --git a/config/locales/app.admin.pt.yml b/config/locales/app.admin.pt.yml index f14aa3805..390135ae7 100644 --- a/config/locales/app.admin.pt.yml +++ b/config/locales/app.admin.pt.yml @@ -1787,6 +1787,8 @@ pt: fab_analytics: "Fab Analytics" phone_required: "telefone é obrigatório" address_required: "o endereço é obrigatório" + gender_required: "gender required" + birthday_required: "date of birth required" tracking_id: "tracking ID" facebook_app_id: "ID de Utilizador do Facebook" twitter_analytics: "Analisador de conta Twitter" @@ -1839,6 +1841,12 @@ pt: address: "Endereço" address_required_info_html: "Você pode definir se o endereço deve ser necessário para registrar um novo usuário no Fab-manager.
Por favor, note que, dependendo do seu país, as regulamentações podem exigir endereços para que as faturas sejam válidas." address_is_required: "Endereço é obrigatório" + gender: "Gender" + gender_is_required: "Gender required" + gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager." + birthday: "Date of birth" + birthday_is_required: "Date of birth required" + birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager." external_id: "External identifier" external_id_info_html: "You can set up an external identifier for your users, which cannot be modified by the user himself." enable_external_id: "Enable the external ID" diff --git a/config/locales/app.admin.sv.yml b/config/locales/app.admin.sv.yml index 2c2af9633..9e906aedc 100644 --- a/config/locales/app.admin.sv.yml +++ b/config/locales/app.admin.sv.yml @@ -1787,6 +1787,8 @@ sv: fab_analytics: "Fab Analys" phone_required: "telefon krävs" address_required: "adress krävs" + gender_required: "gender required" + birthday_required: "date of birth required" tracking_id: "spårnings-ID" facebook_app_id: "ID för Facebook-app" twitter_analytics: "Twitter analytics-konto" @@ -1839,6 +1841,12 @@ sv: address: "Adress" address_required_info_html: "Du kan definiera om adress krävs för att registrera en ny användare.
OBS: beroende på landstillhörighet kan lagen kräva att giltiga fakturor har en faktureringsadress." address_is_required: "Adress måste fyllas i" + gender: "Gender" + gender_is_required: "Gender required" + gender_required_info: "You can define if the gender should be required to register a new user on Fab-manager." + birthday: "Date of birth" + birthday_is_required: "Date of birth required" + birthday_required_info: "You can define if the date of birth number should be required to register a new user on Fab-manager." external_id: "Extern identifierare" external_id_info_html: "Du kan ställa in en extern identifierare för dina användare, som inte kan ändras av användaren själv." enable_external_id: "Aktivera externt ID" diff --git a/config/locales/app.admin.zu.yml b/config/locales/app.admin.zu.yml index 771983579..54b7b2132 100644 --- a/config/locales/app.admin.zu.yml +++ b/config/locales/app.admin.zu.yml @@ -1787,6 +1787,8 @@ zu: fab_analytics: "crwdns26580:0crwdne26580:0" phone_required: "crwdns26582:0crwdne26582:0" address_required: "crwdns26584:0crwdne26584:0" + gender_required: "crwdns38196:0crwdne38196:0" + birthday_required: "crwdns38198:0crwdne38198:0" tracking_id: "crwdns26586:0crwdne26586:0" facebook_app_id: "crwdns26588:0crwdne26588:0" twitter_analytics: "crwdns26590:0crwdne26590:0" @@ -1839,6 +1841,12 @@ zu: address: "crwdns26676:0crwdne26676:0" address_required_info_html: "crwdns26678:0crwdne26678:0" address_is_required: "crwdns26680:0crwdne26680:0" + gender: "crwdns38184:0crwdne38184:0" + gender_is_required: "crwdns38186:0crwdne38186:0" + gender_required_info: "crwdns38188:0crwdne38188:0" + birthday: "crwdns38190:0crwdne38190:0" + birthday_is_required: "crwdns38192:0crwdne38192:0" + birthday_required_info: "crwdns38194:0crwdne38194:0" external_id: "crwdns32051:0crwdne32051:0" external_id_info_html: "crwdns36043:0crwdne36043:0" enable_external_id: "crwdns32055:0crwdne32055:0" From 407c0173aba63732038fc0d5d1f53a1555f4adb1 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Wed, 27 Mar 2024 14:41:30 +0100 Subject: [PATCH 48/92] (feat) add sp certificate for saml provider --- CHANGELOG.md | 1 + .../api/auth_providers_controller.rb | 3 +- .../authentication-provider/provider-form.tsx | 2 +- .../authentication-provider/saml-form.tsx | 30 ++++++++++++++----- .../models/authentication-provider.ts | 4 +++ .../api/auth_providers/show.json.jbuilder | 6 ++-- .../auth_provider/provider.json.jbuilder | 3 +- config/initializers/devise.rb | 6 ++++ config/locales/app.admin.de.yml | 4 +++ config/locales/app.admin.en.yml | 4 +++ config/locales/app.admin.es-MX.yml | 4 +++ config/locales/app.admin.es.yml | 4 +++ config/locales/app.admin.fr.yml | 4 +++ config/locales/app.admin.it.yml | 4 +++ config/locales/app.admin.no.yml | 4 +++ config/locales/app.admin.pt.yml | 4 +++ config/locales/app.admin.sv.yml | 4 +++ config/locales/app.admin.zu.yml | 4 +++ ...614_add_sp_certificate_to_saml_provider.rb | 10 +++++++ db/structure.sql | 9 ++++-- 20 files changed, 100 insertions(+), 14 deletions(-) create mode 100644 db/migrate/20240327095614_add_sp_certificate_to_saml_provider.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index d08c05844..79d13df4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - improvement: add loader for create/delete availability slot - improvement: allow admin configure memeber's profile gender/birthday as required +- improvement: add sp certificate for saml provider - Fix a bug: unable to update a space with a deleted machine - Fix a bug: unable to get invoice payment details if the account code is same for card/transfer payment method - updates translations diff --git a/app/controllers/api/auth_providers_controller.rb b/app/controllers/api/auth_providers_controller.rb index 642236355..907e41e8b 100644 --- a/app/controllers/api/auth_providers_controller.rb +++ b/app/controllers/api/auth_providers_controller.rb @@ -108,7 +108,8 @@ class API::AuthProvidersController < API::APIController elsif params['auth_provider']['providable_type'] == SamlProvider.name params.require(:auth_provider) .permit(:id, :name, :providable_type, - providable_attributes: [:id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url], + providable_attributes: %i[id sp_entity_id idp_sso_service_url profile_url idp_cert_fingerprint idp_cert + idp_slo_service_url authn_requests_signed want_assertions_signed sp_certificate sp_private_key], auth_provider_mappings_attributes: [:id, :local_model, :local_field, :api_field, :api_endpoint, :api_data_type, :_destroy, { transformation: [:type, :format, :true_value, :false_value, { mapping: %i[from to] }] }]) diff --git a/app/frontend/src/javascript/components/authentication-provider/provider-form.tsx b/app/frontend/src/javascript/components/authentication-provider/provider-form.tsx index 5eb8227b6..8ae761d6f 100644 --- a/app/frontend/src/javascript/components/authentication-provider/provider-form.tsx +++ b/app/frontend/src/javascript/components/authentication-provider/provider-form.tsx @@ -118,7 +118,7 @@ export const ProviderForm: React.FC = ({ action, provider, on currentFormValues={output.providable_attributes as OpenIdConnectProvider} formState={formState} setValue={setValue} />} - {providableType === 'SamlProvider' && } + {providableType === 'SamlProvider' && } {providableType && providableType !== 'DatabaseProvider' && { +interface SamlFormProps { register: UseFormRegister, + control: Control, formState: FormState, strategyName?: string, } @@ -14,7 +15,7 @@ interface SamlFormProps { /** * Partial form to fill the OAuth2 settings for a new/existing authentication provider. */ -export const SamlForm = ({ register, strategyName, formState }: SamlFormProps) => { +export const SamlForm = ({ register, strategyName, formState, control }: SamlFormProps) => { const { t } = useTranslation('admin'); /** @@ -39,7 +40,7 @@ export const SamlForm = ({ register, strategyN placeholder="https://sso.example.net..." label={t('app.admin.authentication.saml_form.idp_sso_service_url')} tooltip={t('app.admin.authentication.saml_form.idp_sso_service_url_help')} - rules={{ required: true, pattern: ValidationLib.urlRegex }} + rules={{ required: true }} formState={formState} /> ({ register, strategyN placeholder="https://exemple.net/user..." label={t('app.admin.authentication.saml_form.profile_edition_url')} tooltip={t('app.admin.authentication.saml_form.profile_edition_url_help')} - rules={{ required: true, pattern: ValidationLib.urlRegex }} + rules={{ required: true }} formState={formState} /> + + + +
); diff --git a/app/frontend/src/javascript/models/authentication-provider.ts b/app/frontend/src/javascript/models/authentication-provider.ts index f56c94bf8..3e406185c 100644 --- a/app/frontend/src/javascript/models/authentication-provider.ts +++ b/app/frontend/src/javascript/models/authentication-provider.ts @@ -73,6 +73,10 @@ export interface SamlProvider { idp_cert: string, profile_url: string, idp_slo_service_url: string, + sp_certificate: string, + sp_private_key: string, + authn_requests_signed: boolean, + want_assertions_signed: boolean } export interface MappingFields { diff --git a/app/views/api/auth_providers/show.json.jbuilder b/app/views/api/auth_providers/show.json.jbuilder index 18a2ab3e0..9a5f48295 100644 --- a/app/views/api/auth_providers/show.json.jbuilder +++ b/app/views/api/auth_providers/show.json.jbuilder @@ -6,7 +6,8 @@ json.partial! 'api/auth_providers/auth_provider', auth_provider: @provider if @provider.providable_type == OAuth2Provider.name json.providable_attributes do - json.extract! @provider.providable, :id, :base_url, :token_endpoint, :authorization_endpoint, :profile_url, :client_id, :client_secret, :scopes + json.extract! @provider.providable, :id, :base_url, :token_endpoint, :authorization_endpoint, :profile_url, :client_id, :client_secret, + :scopes end end @@ -22,6 +23,7 @@ end if @provider.providable_type == SamlProvider.name json.providable_attributes do - json.extract! @provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url + json.extract! @provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url, + :authn_requests_signed, :want_assertions_signed, :sp_certificate, :sp_private_key end end diff --git a/app/views/auth_provider/provider.json.jbuilder b/app/views/auth_provider/provider.json.jbuilder index dda5a9a72..149f91f89 100644 --- a/app/views/auth_provider/provider.json.jbuilder +++ b/app/views/auth_provider/provider.json.jbuilder @@ -23,6 +23,7 @@ end if provider.providable_type == 'SamlProvider' json.providable_attributes do - json.extract! provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url + json.extract! provider.providable, :id, :sp_entity_id, :idp_sso_service_url, :profile_url, :idp_cert_fingerprint, :idp_cert, :idp_slo_service_url, + :authn_requests_signed, :want_assertions_signed, :sp_certificate, :sp_private_key end end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 716ff45ca..4b334e06c 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -253,6 +253,12 @@ Devise.setup do |config| idp_slo_service_url: active_provider.providable.idp_slo_service_url, idp_cert: active_provider.providable.idp_cert, idp_cert_fingerprint: active_provider.providable.idp_cert_fingerprint, + certificate: active_provider.providable.sp_certificate, + private_key: active_provider.providable.sp_private_key, + security: OneLogin::RubySaml::Settings::DEFAULTS[:security].merge({ + authn_requests_signed: active_provider.providable.authn_requests_signed, + want_assertions_signed: active_provider.providable.want_assertions_signed + }), strategy_class: OmniAuth::Strategies::SsoSamlProvider end end diff --git a/config/locales/app.admin.de.yml b/config/locales/app.admin.de.yml index 4dbe34465..1ff86dfe4 100644 --- a/config/locales/app.admin.de.yml +++ b/config/locales/app.admin.de.yml @@ -1571,6 +1571,10 @@ de: profile_edition_url_help: "The URL of the page where the user can edit his profile." idp_slo_service_url: "Single logout request URL" idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." + authn_requests_signed: "Authentification requests signed" + want_assertions_signed: "Want assertions signed" + sp_certificate: "Service provider certificate" + sp_private_key: "Service provider private key" provider_form: name: "Name" authentication_type: "Authentifizierungsart" diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index f9b091480..638870a94 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -1571,6 +1571,10 @@ en: profile_edition_url_help: "The URL of the page where the user can edit his profile." idp_slo_service_url: "Single logout request URL" idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." + authn_requests_signed: "Authentification requests signed" + want_assertions_signed: "Want assertions signed" + sp_certificate: "Service provider certificate" + sp_private_key: "Service provider private key" provider_form: name: "Name" authentication_type: "Authentication type" diff --git a/config/locales/app.admin.es-MX.yml b/config/locales/app.admin.es-MX.yml index 2e772a303..c65a77ac8 100644 --- a/config/locales/app.admin.es-MX.yml +++ b/config/locales/app.admin.es-MX.yml @@ -1571,6 +1571,10 @@ es-MX: profile_edition_url_help: "The URL of the page where the user can edit his profile." idp_slo_service_url: "Single logout request URL" idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." + authn_requests_signed: "Authentification requests signed" + want_assertions_signed: "Want assertions signed" + sp_certificate: "Service provider certificate" + sp_private_key: "Service provider private key" provider_form: name: "Nombre" authentication_type: "Tipo de autenticación" diff --git a/config/locales/app.admin.es.yml b/config/locales/app.admin.es.yml index d0cd55b50..e92699ac9 100644 --- a/config/locales/app.admin.es.yml +++ b/config/locales/app.admin.es.yml @@ -1571,6 +1571,10 @@ es: profile_edition_url_help: "The URL of the page where the user can edit his profile." idp_slo_service_url: "Single logout request URL" idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." + authn_requests_signed: "Authentification requests signed" + want_assertions_signed: "Want assertions signed" + sp_certificate: "Service provider certificate" + sp_private_key: "Service provider private key" provider_form: name: "Nombre" authentication_type: "Tipo de autenticación" diff --git a/config/locales/app.admin.fr.yml b/config/locales/app.admin.fr.yml index e0a1f6f4e..a702c40f9 100644 --- a/config/locales/app.admin.fr.yml +++ b/config/locales/app.admin.fr.yml @@ -1571,6 +1571,10 @@ fr: profile_edition_url_help: "L'URL de la page où l'utilisateur peut modifier son profil." idp_slo_service_url: "URL de demande de déconnexion" idp_slo_service_url_help: "L'URL à laquelle la requête d'authentification doit être envoyée. Cela serait sur le fournisseur d'identité." + authn_requests_signed: "Demandes d'authentification signées" + want_assertions_signed: "Exiger des Assertions signées" + sp_certificate: "Certificat du SP" + sp_private_key: "Clé privée du SP" provider_form: name: "Nom" authentication_type: "Type d'authentification" diff --git a/config/locales/app.admin.it.yml b/config/locales/app.admin.it.yml index 76b9d7feb..3ed8cb14b 100644 --- a/config/locales/app.admin.it.yml +++ b/config/locales/app.admin.it.yml @@ -1571,6 +1571,10 @@ it: profile_edition_url_help: "The URL of the page where the user can edit his profile." idp_slo_service_url: "Single logout request URL" idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." + authn_requests_signed: "Authentification requests signed" + want_assertions_signed: "Want assertions signed" + sp_certificate: "Service provider certificate" + sp_private_key: "Service provider private key" provider_form: name: "Nome" authentication_type: "Tipo di autenticazione" diff --git a/config/locales/app.admin.no.yml b/config/locales/app.admin.no.yml index dab311ed5..82b568749 100644 --- a/config/locales/app.admin.no.yml +++ b/config/locales/app.admin.no.yml @@ -1571,6 +1571,10 @@ profile_edition_url_help: "The URL of the page where the user can edit his profile." idp_slo_service_url: "Single logout request URL" idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." + authn_requests_signed: "Authentification requests signed" + want_assertions_signed: "Want assertions signed" + sp_certificate: "Service provider certificate" + sp_private_key: "Service provider private key" provider_form: name: "Name" authentication_type: "Authentication type" diff --git a/config/locales/app.admin.pt.yml b/config/locales/app.admin.pt.yml index 390135ae7..815fa3f8c 100644 --- a/config/locales/app.admin.pt.yml +++ b/config/locales/app.admin.pt.yml @@ -1571,6 +1571,10 @@ pt: profile_edition_url_help: "The URL of the page where the user can edit his profile." idp_slo_service_url: "Single logout request URL" idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." + authn_requests_signed: "Authentification requests signed" + want_assertions_signed: "Want assertions signed" + sp_certificate: "Service provider certificate" + sp_private_key: "Service provider private key" provider_form: name: "Nome" authentication_type: "Tipo de autenticação" diff --git a/config/locales/app.admin.sv.yml b/config/locales/app.admin.sv.yml index 9e906aedc..5387a3d0d 100644 --- a/config/locales/app.admin.sv.yml +++ b/config/locales/app.admin.sv.yml @@ -1571,6 +1571,10 @@ sv: profile_edition_url_help: "URL till sidan där användaren kan redigera sin profil." idp_slo_service_url: "Single logout request URL" idp_slo_service_url_help: "The URL to which the single logout request and response should be sent. This would be on the identity provider." + authn_requests_signed: "Authentification requests signed" + want_assertions_signed: "Want assertions signed" + sp_certificate: "Service provider certificate" + sp_private_key: "Service provider private key" provider_form: name: "Namn" authentication_type: "Autentiseringstyp" diff --git a/config/locales/app.admin.zu.yml b/config/locales/app.admin.zu.yml index 54b7b2132..bd8568d13 100644 --- a/config/locales/app.admin.zu.yml +++ b/config/locales/app.admin.zu.yml @@ -1571,6 +1571,10 @@ zu: profile_edition_url_help: "crwdns38162:0crwdne38162:0" idp_slo_service_url: "crwdns38176:0crwdne38176:0" idp_slo_service_url_help: "crwdns38178:0crwdne38178:0" + authn_requests_signed: "crwdns38200:0crwdne38200:0" + want_assertions_signed: "crwdns38202:0crwdne38202:0" + sp_certificate: "crwdns38204:0crwdne38204:0" + sp_private_key: "crwdns38206:0crwdne38206:0" provider_form: name: "crwdns26204:0crwdne26204:0" authentication_type: "crwdns26206:0crwdne26206:0" diff --git a/db/migrate/20240327095614_add_sp_certificate_to_saml_provider.rb b/db/migrate/20240327095614_add_sp_certificate_to_saml_provider.rb new file mode 100644 index 000000000..a77330de5 --- /dev/null +++ b/db/migrate/20240327095614_add_sp_certificate_to_saml_provider.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class AddSpCertificateToSamlProvider < ActiveRecord::Migration[7.0] + def change + add_column :saml_providers, :sp_certificate, :string + add_column :saml_providers, :sp_private_key, :string + add_column :saml_providers, :authn_requests_signed, :boolean, default: false + add_column :saml_providers, :want_assertions_signed, :boolean, default: false + end +end diff --git a/db/structure.sql b/db/structure.sql index edf633649..0caddd176 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -3279,7 +3279,11 @@ CREATE TABLE public.saml_providers ( profile_url character varying, idp_cert character varying, idp_cert_fingerprint character varying, - idp_slo_service_url character varying + idp_slo_service_url character varying, + sp_certificate character varying, + sp_private_key character varying, + authn_requests_signed boolean DEFAULT false, + want_assertions_signed boolean DEFAULT false ); @@ -9326,6 +9330,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240116163703'), ('20240126145351'), ('20240126192110'), -('20240220140225'); +('20240220140225'), +('20240327095614'); From 61dfa141cc69325b2e0d0e025579948f69aa8570 Mon Sep 17 00:00:00 2001 From: Du Peng Date: Fri, 29 Mar 2024 18:28:42 +0100 Subject: [PATCH 49/92] (bug) unable to show machine/training picture --- CHANGELOG.md | 1 + .../src/javascript/components/machines/machine-card.tsx | 3 ++- app/frontend/templates/home/projects.html | 2 +- app/frontend/templates/spaces/index.html | 2 +- app/frontend/templates/trainings/index.html | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79d13df4e..e7087140b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - improvement: add sp certificate for saml provider - Fix a bug: unable to update a space with a deleted machine - Fix a bug: unable to get invoice payment details if the account code is same for card/transfer payment method +- Fix a bug: unable to show machine/training picture - updates translations ## v6.3.16 2024 March 11 diff --git a/app/frontend/src/javascript/components/machines/machine-card.tsx b/app/frontend/src/javascript/components/machines/machine-card.tsx index 7c0a2770a..108190c4b 100644 --- a/app/frontend/src/javascript/components/machines/machine-card.tsx +++ b/app/frontend/src/javascript/components/machines/machine-card.tsx @@ -49,9 +49,10 @@ const MachineCard: React.FC = ({ user, machine, onShowMachine, if (!machine.machine_image_attributes?.attachment_url) { return
; } + console.log(machine.machine_image_attributes.attachment_url); return ( -
+
); }; diff --git a/app/frontend/templates/home/projects.html b/app/frontend/templates/home/projects.html index 1dce03281..e215c7377 100644 --- a/app/frontend/templates/home/projects.html +++ b/app/frontend/templates/home/projects.html @@ -2,7 +2,7 @@

{{ 'app.public.home.latest_documented_projects' }}

- +
diff --git a/app/frontend/templates/spaces/index.html b/app/frontend/templates/spaces/index.html index 79c4414c1..09c5dec9f 100644 --- a/app/frontend/templates/spaces/index.html +++ b/app/frontend/templates/spaces/index.html @@ -52,7 +52,7 @@
-
+

{{space.name}}

diff --git a/app/frontend/templates/trainings/index.html b/app/frontend/templates/trainings/index.html index 06203604c..c370ac126 100644 --- a/app/frontend/templates/trainings/index.html +++ b/app/frontend/templates/trainings/index.html @@ -25,7 +25,7 @@
-
+

{{training.name}}

From b4c535149e87063fc673bbd5cc6c29f30279f98e Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 8 Apr 2024 09:26:17 +0200 Subject: [PATCH 50/92] (fix) remove unused table in structure.sal --- db/structure.sql | 78 ++++++------------------------------------------ 1 file changed, 9 insertions(+), 69 deletions(-) diff --git a/db/structure.sql b/db/structure.sql index 0caddd176..d29e99787 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2242,41 +2242,6 @@ CREATE SEQUENCE public.payment_gateway_objects_id_seq ALTER SEQUENCE public.payment_gateway_objects_id_seq OWNED BY public.payment_gateway_objects.id; --- --- Name: payment_infos; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.payment_infos ( - id bigint NOT NULL, - data jsonb, - state character varying, - payment_for character varying, - service character varying, - statistic_profile_id bigint, - created_at timestamp(6) without time zone NOT NULL, - updated_at timestamp(6) without time zone NOT NULL -); - - --- --- Name: payment_infos_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public.payment_infos_id_seq - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: payment_infos_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.payment_infos_id_seq OWNED BY public.payment_infos.id; - - -- -- Name: payment_schedule_items; Type: TABLE; Schema: public; Owner: - -- @@ -4398,8 +4363,8 @@ CREATE TABLE public.users ( is_allow_newsletter boolean, current_sign_in_ip inet, last_sign_in_ip inet, - validated_at timestamp without time zone, mapped_from_sso character varying, + validated_at timestamp without time zone, supporting_documents_reminder_sent_at timestamp(6) without time zone ); @@ -4952,13 +4917,6 @@ ALTER TABLE ONLY public.organizations ALTER COLUMN id SET DEFAULT nextval('publi ALTER TABLE ONLY public.payment_gateway_objects ALTER COLUMN id SET DEFAULT nextval('public.payment_gateway_objects_id_seq'::regclass); --- --- Name: payment_infos id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.payment_infos ALTER COLUMN id SET DEFAULT nextval('public.payment_infos_id_seq'::regclass); - - -- -- Name: payment_schedule_items id; Type: DEFAULT; Schema: public; Owner: - -- @@ -5895,14 +5853,6 @@ ALTER TABLE ONLY public.payment_gateway_objects ADD CONSTRAINT payment_gateway_objects_pkey PRIMARY KEY (id); --- --- Name: payment_infos payment_infos_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.payment_infos - ADD CONSTRAINT payment_infos_pkey PRIMARY KEY (id); - - -- -- Name: payment_schedule_items payment_schedule_items_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -7116,13 +7066,6 @@ CREATE INDEX index_payment_gateway_objects_on_item_type_and_item_id ON public.pa CREATE INDEX index_payment_gateway_objects_on_payment_gateway_object_id ON public.payment_gateway_objects USING btree (payment_gateway_object_id); --- --- Name: index_payment_infos_on_statistic_profile_id; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_payment_infos_on_statistic_profile_id ON public.payment_infos USING btree (statistic_profile_id); - - -- -- Name: index_payment_schedule_items_on_invoice_id; Type: INDEX; Schema: public; Owner: - -- @@ -7914,6 +7857,14 @@ CREATE INDEX proof_of_identity_type_id_and_proof_of_identity_refusal_id ON publi CREATE UNIQUE INDEX unique_not_null_external_id ON public.invoicing_profiles USING btree (external_id) WHERE (external_id IS NOT NULL); +-- +-- Name: accounting_periods accounting_periods_del_protect; Type: RULE; Schema: public; Owner: - +-- + +CREATE RULE accounting_periods_del_protect AS + ON DELETE TO public.accounting_periods DO INSTEAD NOTHING; + + -- -- Name: accounting_periods accounting_periods_upd_protect; Type: RULE; Schema: public; Owner: - -- @@ -7947,14 +7898,6 @@ ALTER TABLE ONLY public.payment_schedules ADD CONSTRAINT fk_rails_00308dc223 FOREIGN KEY (wallet_transaction_id) REFERENCES public.wallet_transactions(id); --- --- Name: payment_infos fk_rails_0308366a58; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.payment_infos - ADD CONSTRAINT fk_rails_0308366a58 FOREIGN KEY (statistic_profile_id) REFERENCES public.statistic_profiles(id); - - -- -- Name: cart_item_event_reservation_booking_users fk_rails_0964335a37; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -9301,10 +9244,8 @@ INSERT INTO "schema_migrations" (version) VALUES ('20230328094808'), ('20230328094809'), ('20230331132506'), -('20230509121907'), ('20230509161557'), ('20230510141305'), -('20230511080650'), ('20230511081018'), ('20230524080448'), ('20230524083558'), @@ -9320,7 +9261,6 @@ INSERT INTO "schema_migrations" (version) VALUES ('20230720085857'), ('20230728072726'), ('20230728090257'), -('20230825101952'), ('20230828073428'), ('20230831103208'), ('20230901090637'), From 930670312d443bcd0461ce3b4f130cb370462b9d Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 8 Apr 2024 09:36:33 +0200 Subject: [PATCH 51/92] Version 6.3.17 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7087140b..1c09fadb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +## v6.3.17 2024 Avril 8 + - improvement: add loader for create/delete availability slot - improvement: allow admin configure memeber's profile gender/birthday as required - improvement: add sp certificate for saml provider diff --git a/package.json b/package.json index 8b7ea0300..6794e6fac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fab-manager", - "version": "6.3.16", + "version": "6.3.17", "description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.", "keywords": [ "fablab", From 6cb6974a93bd198a03a140110411c6b70507989e Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 8 Apr 2024 10:40:06 +0200 Subject: [PATCH 52/92] (feat) hide gender in signup form if not required --- CHANGELOG.md | 2 ++ app/frontend/src/javascript/controllers/application.js | 2 +- app/frontend/templates/shared/signupModal.html | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c09fadb3..274cf4b9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next release +- improvement: hide gender in signup form if not required + ## v6.3.17 2024 Avril 8 - improvement: add loader for create/delete availability slot diff --git a/app/frontend/src/javascript/controllers/application.js b/app/frontend/src/javascript/controllers/application.js index c081a7bd3..854697e80 100644 --- a/app/frontend/src/javascript/controllers/application.js +++ b/app/frontend/src/javascript/controllers/application.js @@ -81,7 +81,7 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco size: 'md', resolve: { settingsPromise: ['Setting', function (Setting) { - return Setting.query({ names: "['phone_required', 'recaptcha_site_key', 'confirmation_required', 'address_required']" }).$promise; + return Setting.query({ names: "['phone_required', 'recaptcha_site_key', 'confirmation_required', 'address_required', 'gender_required', 'birthday_required']" }).$promise; }], profileCustomFieldsPromise: ['ProfileCustomField', function (ProfileCustomField) { return ProfileCustomField.query({}).$promise; }], proofOfIdentityTypesPromise: ['SupportingDocumentType', function (SupportingDocumentType) { return SupportingDocumentType.query({}).$promise; }] diff --git a/app/frontend/templates/shared/signupModal.html b/app/frontend/templates/shared/signupModal.html index 44ac77736..bb57d2d70 100644 --- a/app/frontend/templates/shared/signupModal.html +++ b/app/frontend/templates/shared/signupModal.html @@ -8,7 +8,7 @@