mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-17 06:52:27 +01:00
Merge branch 'monthly-payment' into staging
This commit is contained in:
commit
b4dc4fca83
20
CHANGELOG.md
20
CHANGELOG.md
@ -4,6 +4,8 @@
|
||||
- Refactored theme builder to use scss files
|
||||
- Updated stripe gem to 5.21.0
|
||||
- Architecture documentation
|
||||
- Improved coupon creation/deletion workflow
|
||||
- Default texts for the login modal
|
||||
- Fix a bug: unable to access embedded plan views
|
||||
- Fix a bug: warning message overflow in credit wallet modal
|
||||
- Fix a bug: when using a cash coupon, the amount shown in the statistics is invalid
|
||||
@ -16,6 +18,18 @@
|
||||
- [TODO DEPLOY] add the `INTL_CURRENCY` environment variable (see [doc/environment.md](doc/environment.md#INTL_CURRENCY) for configuration details)
|
||||
- [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/mount-payment-schedules.sh | bash`
|
||||
|
||||
## v4.6.6 2021 February 02
|
||||
- Full German translation (thanks to [@korrupt](https://crowdin.com/profile/korrupt))
|
||||
- OpenAPI endpoints to create/update/show/delete machines
|
||||
- Updated environment documentation
|
||||
- Removed useless locales' configuration files
|
||||
- OpenAPI's endpoints will now return more detailed error messages when something wrong occurs
|
||||
- Fix a bug: when an event is modified, the member's reservations does not reflect the new event date
|
||||
- Fix a security issue: updated ini to 1.3.8 to fix [CVE-2020-7788](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7788)
|
||||
- Fix a security issue: updated nokogiri to 1.11.1 to fix [CVE-2020-26247](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-26247)
|
||||
- Updated caxlsx to 3.0.4, and the dependencies of caxlsx_rail
|
||||
- [TODO DEPLOY] -> (only dev) `bundle install`
|
||||
|
||||
## v4.6.5 2020 December 07
|
||||
- Fix a bug: unable to run the upgrade script with docker-compose >= v1.19
|
||||
|
||||
@ -36,7 +50,7 @@
|
||||
- Removed fab-manager email address from the seeds
|
||||
- Initialize new plans with default prices for machines & spaces
|
||||
- Display a message when no plans are available
|
||||
- Fix a bug: in the settings area, boolean switches are always shown as false
|
||||
- Fix a bug: in the settings' area, boolean switches are always shown as false
|
||||
- Fix a bug: public cards presenting the plans in the public area, have bogus style
|
||||
- Fix a bug: theme primary color is ignored on links
|
||||
- [TODO DEPLOY] `rails fablab:maintenance:rebuild_stylesheet`
|
||||
@ -45,7 +59,7 @@
|
||||
|
||||
- Add intermediate step version for upgrades: v4.4.6. This will prevent issues with FootprintDebug if a regeneration is needed
|
||||
- Check postgreSQL status before compiling assets
|
||||
- Improved documentation about the upgrade process
|
||||
- Improved the documentation about the upgrade process
|
||||
- Fix a bug: unable to set libraries locales to their default values (en-us)
|
||||
- Fix a bug: unable to display details about a closed period
|
||||
- Fix a bug: members cannot view available trainings slots
|
||||
@ -53,7 +67,7 @@
|
||||
|
||||
## v4.6.1 2020 October 21
|
||||
|
||||
- Reduced down time during upgrades
|
||||
- Reduced downtime during upgrades
|
||||
- Architecture changes to allow including React.js components into the application
|
||||
- Allow running upgrade scripts from dev ranch
|
||||
- Fix a bug: script mount-webpack.sh was not updating the docker-compose.yml file
|
||||
|
24
Gemfile.lock
24
Gemfile.lock
@ -75,7 +75,7 @@ GEM
|
||||
image_processing (~> 1.1)
|
||||
mimemagic (>= 0.3.0)
|
||||
mini_mime (>= 0.1.3)
|
||||
caxlsx (3.0.1)
|
||||
caxlsx (3.0.4)
|
||||
htmlentities (~> 4.3, >= 4.3.4)
|
||||
mimemagic (~> 0.3)
|
||||
nokogiri (~> 1.10, >= 1.10.4)
|
||||
@ -87,7 +87,7 @@ GEM
|
||||
cldr-plurals-runtime-rb (1.0.1)
|
||||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
concurrent-ruby (1.1.7)
|
||||
concurrent-ruby (1.1.8)
|
||||
connection_pool (2.2.3)
|
||||
coveralls_reborn (0.18.0)
|
||||
simplecov (>= 0.18.1, < 0.20.0)
|
||||
@ -132,7 +132,7 @@ GEM
|
||||
faraday
|
||||
multi_json
|
||||
equalizer (0.0.11)
|
||||
erubi (1.9.0)
|
||||
erubi (1.10.0)
|
||||
et-orbi (1.2.1)
|
||||
tzinfo
|
||||
faker (2.10.2)
|
||||
@ -156,7 +156,7 @@ GEM
|
||||
httparty (0.18.0)
|
||||
mime-types (~> 3.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (1.8.5)
|
||||
i18n (1.8.7)
|
||||
concurrent-ruby (~> 1.0)
|
||||
icalendar (2.5.3)
|
||||
ice_cube (~> 0.16)
|
||||
@ -187,7 +187,7 @@ GEM
|
||||
listen (3.0.8)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
loofah (2.7.0)
|
||||
loofah (2.9.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.1)
|
||||
@ -203,8 +203,8 @@ GEM
|
||||
mimemagic (0.3.5)
|
||||
mini_magick (4.10.1)
|
||||
mini_mime (1.0.2)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.14.2)
|
||||
mini_portile2 (2.5.0)
|
||||
minitest (5.14.3)
|
||||
minitest-reporters (1.4.2)
|
||||
ansi
|
||||
builder
|
||||
@ -215,8 +215,9 @@ GEM
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.1.1)
|
||||
nio4r (2.5.4)
|
||||
nokogiri (1.10.10)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
nokogiri (1.11.1)
|
||||
mini_portile2 (~> 2.5.0)
|
||||
racc (~> 1.4)
|
||||
notify_with (0.0.2)
|
||||
jbuilder (~> 2.0)
|
||||
rails (>= 4.2.0)
|
||||
@ -265,6 +266,7 @@ GEM
|
||||
pundit (2.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
raabro (1.1.6)
|
||||
racc (1.5.2)
|
||||
rack (2.2.3)
|
||||
rack-protection (2.0.8.1)
|
||||
rack
|
||||
@ -334,7 +336,7 @@ GEM
|
||||
rubyXL (3.4.14)
|
||||
nokogiri (>= 1.10.8)
|
||||
rubyzip (>= 1.3.0)
|
||||
rubyzip (1.3.0)
|
||||
rubyzip (2.3.0)
|
||||
safe_yaml (1.0.5)
|
||||
sassc (2.2.1)
|
||||
ffi (~> 1.9)
|
||||
@ -386,7 +388,7 @@ GEM
|
||||
camertron-eprun
|
||||
cldr-plurals-runtime-rb (~> 1.0)
|
||||
tzinfo
|
||||
tzinfo (1.2.7)
|
||||
tzinfo (1.2.9)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2020.4)
|
||||
tzinfo (>= 1.0.0)
|
||||
|
2
Procfile
2
Procfile
@ -1,4 +1,4 @@
|
||||
#web: bundle exec rails server puma -p $PORT
|
||||
web: bundle exec rails server puma -p $PORT
|
||||
worker: bundle exec sidekiq -C ./config/sidekiq.yml
|
||||
wp-client: bin/webpack-dev-server
|
||||
wp-server: SERVER_BUNDLE_ONLY=yes bin/webpack --watch
|
||||
|
@ -23,7 +23,6 @@ class API::InvoicesController < API::ApiController
|
||||
p = params.require(:query).permit(:number, :customer, :date, :order_by, :page, :size)
|
||||
|
||||
render json: { error: 'page must be an integer' }, status: :unprocessable_entity and return unless p[:page].is_a? Integer
|
||||
|
||||
render json: { error: 'size must be an integer' }, status: :unprocessable_entity and return unless p[:size].is_a? Integer
|
||||
|
||||
order = InvoicesService.parse_order(p[:order_by])
|
||||
|
@ -5,6 +5,21 @@ class API::PaymentSchedulesController < API::ApiController
|
||||
before_action :authenticate_user!
|
||||
before_action :set_payment_schedule, only: %i[download]
|
||||
|
||||
def list
|
||||
authorize PaymentSchedule
|
||||
|
||||
p = params.require(:query).permit(:reference, :customer, :date, :page, :size)
|
||||
|
||||
render json: { error: 'page must be an integer' }, status: :unprocessable_entity and return unless p[:page].is_a? Integer
|
||||
render json: { error: 'size must be an integer' }, status: :unprocessable_entity and return unless p[:size].is_a? Integer
|
||||
|
||||
@payment_schedules = PaymentScheduleService.list(
|
||||
p[:page],
|
||||
p[:size],
|
||||
reference: p[:reference], customer: p[:customer], date: p[:date]
|
||||
)
|
||||
end
|
||||
|
||||
def download
|
||||
authorize @payment_schedule
|
||||
send_file File.join(Rails.root, @payment_schedule.file), type: 'application/pdf', disposition: 'attachment'
|
||||
|
@ -97,6 +97,7 @@ class API::PaymentsController < API::ApiController
|
||||
|
||||
def on_reservation_success(intent, details)
|
||||
@reservation = Reservation.new(reservation_params)
|
||||
payment_method = params[:cart_items][:reservation][:payment_method] || 'stripe'
|
||||
user_id = if current_user.admin? || current_user.manager?
|
||||
params[:cart_items][:reservation][:user_id]
|
||||
else
|
||||
@ -107,7 +108,7 @@ class API::PaymentsController < API::ApiController
|
||||
payment_details: details,
|
||||
intent_id: intent.id,
|
||||
schedule: params[:cart_items][:reservation][:payment_schedule],
|
||||
payment_method: params[:cart_items][:reservation][:payment_method])
|
||||
payment_method: payment_method)
|
||||
if intent.class == Stripe::PaymentIntent
|
||||
Stripe::PaymentIntent.update(
|
||||
intent.id,
|
||||
|
@ -1,5 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Parameters for OpenAPI endpoints
|
||||
class OpenAPI::V1::BaseController < ActionController::Base
|
||||
protect_from_forgery with: :null_session
|
||||
skip_before_action :verify_authenticity_token
|
||||
before_action :authenticate
|
||||
before_action :increment_calls_count
|
||||
|
||||
@ -7,37 +11,47 @@ class OpenAPI::V1::BaseController < ActionController::Base
|
||||
rescue_from OpenAPI::ParameterError, with: :bad_request
|
||||
rescue_from ActionController::ParameterMissing, with: :bad_request
|
||||
|
||||
rescue_from TypeError, with: :server_error
|
||||
rescue_from NoMethodError, with: :server_error
|
||||
rescue_from ArgumentError, with: :server_error
|
||||
|
||||
helper_method :current_api_client
|
||||
|
||||
protected
|
||||
def not_found
|
||||
render json: { errors: ["Not found"] }, status: :not_found
|
||||
end
|
||||
|
||||
def bad_request
|
||||
render json: { errors: ["Bad request"] }, status: :bad_request
|
||||
end
|
||||
def not_found(exception)
|
||||
render json: { errors: ['Not found', exception] }, status: :not_found
|
||||
end
|
||||
|
||||
def authenticate
|
||||
authenticate_token || render_unauthorized
|
||||
end
|
||||
def bad_request(exception)
|
||||
render json: { errors: ['Bad request', exception] }, status: :bad_request
|
||||
end
|
||||
|
||||
def authenticate_token
|
||||
authenticate_with_http_token do |token, options|
|
||||
@open_api_client = OpenAPI::Client.find_by(token: token)
|
||||
end
|
||||
end
|
||||
def server_error(exception)
|
||||
render json: { error: ['Server error', exception] }, status: :internal_server_error
|
||||
end
|
||||
|
||||
def current_api_client
|
||||
@open_api_client
|
||||
end
|
||||
def authenticate
|
||||
authenticate_token || render_unauthorized
|
||||
end
|
||||
|
||||
def render_unauthorized
|
||||
render json: { errors: ['Bad credentials'] }, status: 401
|
||||
def authenticate_token
|
||||
authenticate_with_http_token do |token, _options|
|
||||
@open_api_client = OpenAPI::Client.find_by(token: token)
|
||||
end
|
||||
end
|
||||
|
||||
def current_api_client
|
||||
@open_api_client
|
||||
end
|
||||
|
||||
def render_unauthorized
|
||||
render json: { errors: ['Bad credentials'] }, status: 401
|
||||
end
|
||||
|
||||
private
|
||||
def increment_calls_count
|
||||
@open_api_client.increment_calls_count
|
||||
end
|
||||
|
||||
def increment_calls_count
|
||||
@open_api_client.increment_calls_count
|
||||
end
|
||||
end
|
||||
|
@ -1,3 +1,4 @@
|
||||
# OpenAPI controller for the invoices
|
||||
class OpenAPI::V1::InvoicesController < OpenAPI::V1::BaseController
|
||||
extend OpenAPI::ApiDoc
|
||||
expose_doc
|
||||
@ -5,14 +6,12 @@ class OpenAPI::V1::InvoicesController < OpenAPI::V1::BaseController
|
||||
def index
|
||||
@invoices = Invoice.order(created_at: :desc)
|
||||
|
||||
if params[:user_id].present?
|
||||
@invoices = @invoices.where(user_id: params[:user_id])
|
||||
end
|
||||
@invoices = @invoices.where(user_id: params[:user_id]) if params[:user_id].present?
|
||||
|
||||
if params[:page].present?
|
||||
@invoices = @invoices.page(params[:page]).per(per_page)
|
||||
paginate @invoices, per_page: per_page
|
||||
end
|
||||
return unless params[:page].present?
|
||||
|
||||
@invoices = @invoices.page(params[:page]).per(per_page)
|
||||
paginate @invoices, per_page: per_page
|
||||
end
|
||||
|
||||
def download
|
||||
|
@ -1,8 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# authorized 3rd party softwares can manage the machines through the OpenAPI
|
||||
class OpenAPI::V1::MachinesController < OpenAPI::V1::BaseController
|
||||
extend OpenAPI::ApiDoc
|
||||
expose_doc
|
||||
|
||||
before_action :set_machine, only: %i[show update destroy]
|
||||
|
||||
def index
|
||||
@machines = Machine.order(:created_at)
|
||||
end
|
||||
|
||||
def create
|
||||
@machine = Machine.new(machine_params)
|
||||
if @machine.save
|
||||
render :show, status: :created, location: @machine
|
||||
else
|
||||
render json: @machine.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @machine.update(machine_params)
|
||||
render :show, status: :ok, location: @machine
|
||||
else
|
||||
render json: @machine.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def show; end
|
||||
|
||||
def destroy
|
||||
if @machine.destroyable?
|
||||
@machine.destroy
|
||||
head :no_content
|
||||
else
|
||||
render json: { error: 'has existing reservations' }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def machine_params
|
||||
params.require(:machine).permit(:name, :description, :spec, :disabled,
|
||||
machine_image_attributes: [:attachment])
|
||||
end
|
||||
|
||||
def set_machine
|
||||
@machine = Machine.friendly.find(params[:id])
|
||||
end
|
||||
end
|
||||
|
@ -83,4 +83,100 @@ class OpenAPI::V1::MachinesDoc < OpenAPI::V1::BaseDoc
|
||||
}
|
||||
MACHINES
|
||||
end
|
||||
|
||||
doc_for :create do
|
||||
api :POST, "/#{API_VERSION}/machines", 'Create a machine'
|
||||
formats %w[json multipart/form-data]
|
||||
description 'Create a new machine.'
|
||||
returns code: 201, desc: 'The machine was successfully created'
|
||||
param :machine, Hash, required: true do
|
||||
param :name, String, desc: 'The name of the machine.', required: true
|
||||
param :description, String, desc: 'A long textual description of the machine. HTML is supported.', required: true
|
||||
param :spec, String, desc: 'A long textual description of the technical specifications of the machine. HTML is supported.'
|
||||
param :disabled, [TrueClass, FalseClass], desc: "Should the machine be disabled? If yes, the machine won't be reservable and will be shown apart."
|
||||
param :machine_image_attributes, Hash do
|
||||
param :attachment, ActionDispatch::Http::UploadedFile, required: true, desc: 'Upload a picture for the machine.'
|
||||
end
|
||||
end
|
||||
example <<-MACHINE
|
||||
curl -X POST
|
||||
-H "Authorization:Token token=xxx"
|
||||
-H "Content-Type:multipart/form-data"
|
||||
-H "Accept: application/json"
|
||||
-F machine[name]="Epilog laser"
|
||||
-F machine[description]="La découpeuse laser vous permet de découper ou graver des matériaux."
|
||||
-F machine[machine_image_attributes[attachment]]=@epilog.jpeg
|
||||
/open_api/v1/machines
|
||||
|
||||
curl -X POST
|
||||
-H "Authorization:Token token=xxx"
|
||||
-H "Content-Type:application/json"
|
||||
-H "Accept: application/json"
|
||||
-d '{"machine": { "name": "DMP Flex 100", "description": "Cette imprimante 3D peut imprimer des métaux." }}'
|
||||
/open_api/v1/machines
|
||||
MACHINE
|
||||
end
|
||||
|
||||
doc_for :update do
|
||||
api :PATCH, "/#{API_VERSION}/machines/:id", 'Update a machine'
|
||||
formats %w[json multipart/form-data]
|
||||
description 'Update an existing machine.'
|
||||
returns code: 200, desc: 'The machine was successfully updated'
|
||||
param :machine, Hash, required: true do
|
||||
param :name, String, desc: 'The name of the machine.', required: true
|
||||
param :description, String, desc: 'A long textual description of the machine. HTML is supported.', required: true
|
||||
param :spec, String, desc: 'A long textual description of the technical specifications of the machine. HTML is supported.'
|
||||
param :disabled, [TrueClass, FalseClass], desc: "Should the machine be disabled? If yes, the machine won't be reservable and will be shown apart."
|
||||
param :machine_image_attributes, Hash do
|
||||
param :attachment, ActionDispatch::Http::UploadedFile, required: true, desc: 'Upload a picture for the machine.'
|
||||
end
|
||||
end
|
||||
example <<-MACHINE
|
||||
curl -X PATCH
|
||||
-H "Authorization:Token token=xxx"
|
||||
-H "Content-Type:multipart/form-data"
|
||||
-H "Accept: application/json"
|
||||
-F machine[spec]="Laser CO2 de 60W<br>Surface de travail de 812 x 508 mm"
|
||||
-F machine[machine_image_attributes[attachment]]=@epilog2.jpg
|
||||
/open_api/v1/machines/10
|
||||
|
||||
curl -X PATCH
|
||||
-H "Authorization:Token token=xxx"
|
||||
-H "Content-Type:application/json"
|
||||
-H "Accept: application/json"
|
||||
-d '{"machine": { "disabled": true }}'
|
||||
/open_api/v1/machines/10
|
||||
MACHINE
|
||||
end
|
||||
|
||||
doc_for :show do
|
||||
api :GET, "/#{API_VERSION}/machines/:id", 'Show a machine'
|
||||
description 'Show all the details of single machine.'
|
||||
example <<-MACHINES
|
||||
# /open_api/v1/machines/1
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Epilog EXT36 Laser",
|
||||
"slug": "decoupeuse-laser",
|
||||
"disabled": false,
|
||||
"updated_at": "2015-02-17T11:06:00.495+01:00",
|
||||
"created_at": "2014-06-30T03:32:31.972+02:00",
|
||||
"description": "La découpeuse Laser, EPILOG Legend 36EXT\r\n\r\nInformations générales :\r\nLa découpeuse laser vous permet de découper ou graver des matériaux. \r\n\r\nPour la découpe, il suffit d'apporter votre fichier vectorisé type illustrator, svg ou dxf avec des \"lignes de coupe\" d'une épaisseur inférieure à 0,01 mm et la machine s'occupera du reste!\r\n\r\nLa gravure est basée sur le spectre noir et blanc. Les nuances sont obtenues par différentes profondeurs de gravure correspondant aux niveaux de gris de votre image. Il suffit pour cela d'apporter une image scannée ou un fichier photo en noir et blanc pour pouvoir reproduire celle-ci sur votre support.\r\n\r\nTypes de matériaux gravables/découpeables ?\r\nDu bois au tissu, du plexiglass au cuir, cette machine permet de découper et graver la plupart des matériaux sauf les métaux. La gravure est néanmoins possible sur les métaux recouverts d'une couche de peinture ou les aluminiums anodisés. \r\nConcernant l'épaisseur des matériaux découpés, il est préférable de ne pas dépasser 5 mm pour le bois et 6 mm pour le plexiglass.\r\n",
|
||||
"spec": "Puissance : 40W\r\nSurface de travail : 914x609 mm \r\nEpaisseur maximale de la matière : 305mm\r\nSource laser : tube laser type CO2\r\nContrôles de vitesse et de puissance : ces deux paramètres sont ajustables en fonction du matériau (de 1% à 100%) .\r\n",
|
||||
"image": "/uploads/machine_image/2514/machine_image.jpg"
|
||||
}
|
||||
MACHINES
|
||||
end
|
||||
|
||||
doc_for :destroy do
|
||||
api :DELETE, "/#{API_VERSION}/machines/:id", 'Delete a machine'
|
||||
description 'Delete an existing machine that does not have any existing reservations.'
|
||||
returns code: 204, desc: 'The machine was successfully deleted'
|
||||
example <<-MACHINE
|
||||
curl -X DELETE
|
||||
-H "Authorization:Token token=xxx"
|
||||
-H "Accept: application/json"
|
||||
/open_api/v1/machines/10
|
||||
MACHINE
|
||||
end
|
||||
end
|
||||
|
5
app/exceptions/invalid_subscription_error.rb
Normal file
5
app/exceptions/invalid_subscription_error.rb
Normal file
@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Raised when trying to create something based on a subscription but it does not exists or is expired
|
||||
class InvalidSubscriptionError < StandardError
|
||||
end
|
17
app/frontend/src/javascript/api/payment-schedule.ts
Normal file
17
app/frontend/src/javascript/api/payment-schedule.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import apiClient from './api-client';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { PaymentSchedule, PaymentScheduleIndexRequest } from '../models/payment-schedule';
|
||||
import wrapPromise, { IWrapPromise } from '../lib/wrap-promise';
|
||||
|
||||
export default class PaymentScheduleAPI {
|
||||
async list (query: PaymentScheduleIndexRequest): Promise<Array<PaymentSchedule>> {
|
||||
const res: AxiosResponse = await apiClient.post(`/api/payment_schedules/list`, query);
|
||||
return res?.data;
|
||||
}
|
||||
|
||||
static list (query: PaymentScheduleIndexRequest): IWrapPromise<Array<PaymentSchedule>> {
|
||||
const api = new PaymentScheduleAPI();
|
||||
return wrapPromise(api.list(query));
|
||||
}
|
||||
}
|
||||
|
57
app/frontend/src/javascript/components/document-filters.tsx
Normal file
57
app/frontend/src/javascript/components/document-filters.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* This component shows 3 input fields for filtering invoices/payment-schedules by reference, customer name and date
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { LabelledInput } from './labelled-input';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface DocumentFiltersProps {
|
||||
onFilterChange: (value: { reference: string, customer: string, date: Date }) => void
|
||||
}
|
||||
|
||||
export const DocumentFilters: React.FC<DocumentFiltersProps> = ({ onFilterChange }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const [referenceFilter, setReferenceFilter] = useState('');
|
||||
const [customerFilter, setCustomerFilter] = useState('');
|
||||
const [dateFilter, setDateFilter] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
onFilterChange({ reference: referenceFilter, customer: customerFilter, date: dateFilter });
|
||||
}, [referenceFilter, customerFilter, dateFilter])
|
||||
|
||||
const handleReferenceUpdate = (e) => {
|
||||
setReferenceFilter(e.target.value);
|
||||
}
|
||||
|
||||
const handleCustomerUpdate = (e) => {
|
||||
setCustomerFilter(e.target.value);
|
||||
}
|
||||
|
||||
const handleDateUpdate = (e) => {
|
||||
let date = e.target.value;
|
||||
if (e.target.value === '') date = null;
|
||||
setDateFilter(date);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="document-filters">
|
||||
<LabelledInput id="reference"
|
||||
label={t('app.admin.invoices.document_filters.reference')}
|
||||
type="text"
|
||||
onChange={handleReferenceUpdate}
|
||||
value={referenceFilter} />
|
||||
<LabelledInput id="customer"
|
||||
label={t('app.admin.invoices.document_filters.customer')}
|
||||
type="text"
|
||||
onChange={handleCustomerUpdate}
|
||||
value={customerFilter} />
|
||||
<LabelledInput id="reference"
|
||||
label={t('app.admin.invoices.document_filters.date')}
|
||||
type="date"
|
||||
onChange={handleDateUpdate}
|
||||
value={dateFilter ? dateFilter : ''} />
|
||||
</div>
|
||||
);
|
||||
}
|
22
app/frontend/src/javascript/components/labelled-input.tsx
Normal file
22
app/frontend/src/javascript/components/labelled-input.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* This component shows input field with its label, styled
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
interface LabelledInputProps {
|
||||
id: string,
|
||||
type: string,
|
||||
label: string,
|
||||
value: any,
|
||||
onChange: (value: any) => void
|
||||
}
|
||||
|
||||
export const LabelledInput: React.FC<LabelledInputProps> = ({ id, type, label, value, onChange }) => {
|
||||
return (
|
||||
<div className="input-with-label">
|
||||
<label className="label" htmlFor={id}>{label}</label>
|
||||
<input className="input" id={id} type={type} value={value} onChange={onChange} />
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* This component shows a list of all payment schedules with their associated deadlines (aka. PaymentScheduleItem) and invoices
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { IApplication } from '../models/application';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Loader } from './loader';
|
||||
import { react2angular } from 'react2angular';
|
||||
import PaymentScheduleAPI from '../api/payment-schedule';
|
||||
import { DocumentFilters } from './document-filters';
|
||||
import { PaymentSchedulesTable } from './payment-schedules-table';
|
||||
|
||||
declare var Application: IApplication;
|
||||
|
||||
const paymentSchedulesList = PaymentScheduleAPI.list({ query: { page: 1, size: 20 } });
|
||||
|
||||
const PaymentSchedulesList: React.FC = () => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const [paymentSchedules, setPaymentSchedules] = useState(paymentSchedulesList.read());
|
||||
|
||||
const handleFiltersChange = ({ reference, customer, date }): void => {
|
||||
const api = new PaymentScheduleAPI();
|
||||
api.list({ query: { reference, customer, date, page: 1, size: 20 }}).then((res) => {
|
||||
setPaymentSchedules(res);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="payment-schedules-list">
|
||||
<h3>
|
||||
<i className="fas fa-filter" />
|
||||
{t('app.admin.invoices.payment_schedules.filter_schedules')}
|
||||
</h3>
|
||||
<div className="schedules-filters">
|
||||
<DocumentFilters onFilterChange={handleFiltersChange} />
|
||||
</div>
|
||||
<PaymentSchedulesTable paymentSchedules={paymentSchedules} showCustomer={true} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const PaymentSchedulesListWrapper: React.FC = () => {
|
||||
return (
|
||||
<Loader>
|
||||
<PaymentSchedulesList />
|
||||
</Loader>
|
||||
);
|
||||
}
|
||||
|
||||
Application.Components.component('paymentSchedulesList', react2angular(PaymentSchedulesListWrapper));
|
@ -0,0 +1,253 @@
|
||||
/**
|
||||
* This component shows a list of all payment schedules with their associated deadlines (aka. PaymentScheduleItem) and invoices
|
||||
*/
|
||||
|
||||
import React, { ReactEventHandler, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Loader } from './loader';
|
||||
import moment from 'moment';
|
||||
import { IFablab } from '../models/fablab';
|
||||
import _ from 'lodash';
|
||||
import { PaymentSchedule, PaymentScheduleItem, PaymentScheduleItemState } from '../models/payment-schedule';
|
||||
|
||||
declare var Fablab: IFablab;
|
||||
|
||||
interface PaymentSchedulesTableProps {
|
||||
paymentSchedules: Array<PaymentSchedule>,
|
||||
showCustomer?: boolean
|
||||
}
|
||||
|
||||
const PaymentSchedulesTableComponent: React.FC<PaymentSchedulesTableProps> = ({ paymentSchedules, showCustomer }) => {
|
||||
const { t } = useTranslation('admin');
|
||||
|
||||
const [showExpanded, setShowExpanded] = useState({});
|
||||
|
||||
/**
|
||||
* Check if the requested payment schedule is displayed with its deadlines (PaymentScheduleItem) or without them
|
||||
*/
|
||||
const isExpanded = (paymentScheduleId: number): boolean => {
|
||||
return showExpanded[paymentScheduleId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the formatted localized date for the given date
|
||||
*/
|
||||
const formatDate = (date: Date): string => {
|
||||
return Intl.DateTimeFormat().format(moment(date).toDate());
|
||||
}
|
||||
/**
|
||||
* Return the formatted localized amount for the given price (eg. 20.5 => "20,50 €")
|
||||
*/
|
||||
const formatPrice = (price: number): string => {
|
||||
return new Intl.NumberFormat(Fablab.intl_locale, {style: 'currency', currency: Fablab.intl_currency}).format(price);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value for the CSS property 'display', for the payment schedule deadlines
|
||||
*/
|
||||
const statusDisplay = (paymentScheduleId: number): string => {
|
||||
if (isExpanded(paymentScheduleId)) {
|
||||
return 'table-row'
|
||||
} else {
|
||||
return 'none';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the action icon for showing/hiding the deadlines
|
||||
*/
|
||||
const expandCollapseIcon = (paymentScheduleId: number): JSX.Element => {
|
||||
if (isExpanded(paymentScheduleId)) {
|
||||
return <i className="fas fa-minus-square" />;
|
||||
} else {
|
||||
return <i className="fas fa-plus-square" />
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show or hide the deadlines for the provided payment schedule, inverting their current status
|
||||
*/
|
||||
const togglePaymentScheduleDetails = (paymentScheduleId: number): ReactEventHandler => {
|
||||
return (): void => {
|
||||
if (isExpanded(paymentScheduleId)) {
|
||||
setShowExpanded(Object.assign({}, showExpanded, { [paymentScheduleId]: false }));
|
||||
} else {
|
||||
setShowExpanded(Object.assign({}, showExpanded, { [paymentScheduleId]: true }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For use with downloadButton()
|
||||
*/
|
||||
enum TargetType {
|
||||
Invoice = 'invoices',
|
||||
PaymentSchedule = 'payment_schedules'
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a button to download a PDF file, may be an invoice, or a payment schedule, depending or the provided parameters
|
||||
*/
|
||||
const downloadButton = (target: TargetType, id: number): JSX.Element => {
|
||||
const link = `api/${target}/${id}/download`;
|
||||
return (
|
||||
<a href={link} target="_blank" className="download-button">
|
||||
<i className="fas fa-download" />
|
||||
{t('app.admin.invoices.schedules_table.download')}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the human-readable string for the status of the provided deadline.
|
||||
*/
|
||||
const formatState = (item: PaymentScheduleItem): JSX.Element => {
|
||||
let res = t(`app.admin.invoices.schedules_table.state_${item.state}`);
|
||||
if (item.state === PaymentScheduleItemState.Paid) {
|
||||
const key = `app.admin.invoices.schedules_table.method_${item.payment_method}`
|
||||
res += ` (${t(key)})`;
|
||||
}
|
||||
return <span className={`state-${item.state}`}>{res}</span>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the action button(s) for the given deadline
|
||||
*/
|
||||
const itemButtons = (item: PaymentScheduleItem): JSX.Element => {
|
||||
switch (item.state) {
|
||||
case PaymentScheduleItemState.Paid:
|
||||
return downloadButton(TargetType.Invoice, item.invoice_id);
|
||||
case PaymentScheduleItemState.Pending:
|
||||
return (
|
||||
<button className="action-button" onClick={handleConfirmCheckPayment(item)}>
|
||||
<i className="fas fa-money-check" />
|
||||
{t('app.admin.invoices.schedules_table.confirm_payment')}
|
||||
</button>
|
||||
);
|
||||
case PaymentScheduleItemState.RequireAction:
|
||||
return (
|
||||
<button className="action-button" onClick={handleSolveAction(item)}>
|
||||
<i className="fas fa-wrench" />
|
||||
{t('app.admin.invoices.schedules_table.solve')}
|
||||
</button>
|
||||
);
|
||||
case PaymentScheduleItemState.RequirePaymentMethod:
|
||||
return (
|
||||
<button className="action-button" onClick={handleUpdateCard(item)}>
|
||||
<i className="fas fa-credit-card" />
|
||||
{t('app.admin.invoices.schedules_table.update_card')}
|
||||
</button>
|
||||
);
|
||||
default:
|
||||
return <span />
|
||||
}
|
||||
}
|
||||
|
||||
const handleConfirmCheckPayment = (item: PaymentScheduleItem): ReactEventHandler => {
|
||||
return (): void => {
|
||||
/*
|
||||
TODO
|
||||
- display confirmation modal
|
||||
- create /api/payment_schedule/item/confirm_check endpoint and post to it
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
const handleSolveAction = (item: PaymentScheduleItem): ReactEventHandler => {
|
||||
return (): void => {
|
||||
/*
|
||||
TODO
|
||||
- create component wrapped with <StripeElements>
|
||||
- stripe.confirmCardSetup(item.client_secret).then(function(result) {
|
||||
if (result.error) {
|
||||
// Display error.message in your UI.
|
||||
} else {
|
||||
// The setup has succeeded. Display a success message.
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
const handleUpdateCard = (item: PaymentScheduleItem): ReactEventHandler => {
|
||||
return (): void => {
|
||||
/*
|
||||
TODO
|
||||
- Notify the customer, collect new payment information, and create a new payment method
|
||||
- Attach the payment method to the customer
|
||||
- Update the default payment method
|
||||
- Pay the invoice using the new payment method
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<table className="schedules-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="w-35" />
|
||||
<th className="w-200">{t('app.admin.invoices.schedules_table.schedule_num')}</th>
|
||||
<th className="w-200">{t('app.admin.invoices.schedules_table.date')}</th>
|
||||
<th className="w-120">{t('app.admin.invoices.schedules_table.price')}</th>
|
||||
{showCustomer && <th className="w-200">{t('app.admin.invoices.schedules_table.customer')}</th>}
|
||||
<th className="w-200"/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{paymentSchedules.map(p => <tr key={p.id}>
|
||||
<td colSpan={6}>
|
||||
<table className="schedules-table-body">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="w-35 row-header" onClick={togglePaymentScheduleDetails(p.id)}>{expandCollapseIcon(p.id)}</td>
|
||||
<td className="w-200">{p.reference}</td>
|
||||
<td className="w-200">{formatDate(p.created_at)}</td>
|
||||
<td className="w-120">{formatPrice(p.total)}</td>
|
||||
{showCustomer && <td className="w-200">{p.user.name}</td>}
|
||||
<td className="w-200">{downloadButton(TargetType.PaymentSchedule, p.id)}</td>
|
||||
</tr>
|
||||
<tr style={{ display: statusDisplay(p.id) }}>
|
||||
<td className="w-35" />
|
||||
<td colSpan={5}>
|
||||
<div>
|
||||
<table className="schedule-items-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="w-120">{t('app.admin.invoices.schedules_table.deadline')}</th>
|
||||
<th className="w-120">{t('app.admin.invoices.schedules_table.amount')}</th>
|
||||
<th className="w-200">{t('app.admin.invoices.schedules_table.state')}</th>
|
||||
<th className="w-200" />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{_.orderBy(p.items, 'due_date').map(item => <tr key={item.id}>
|
||||
<td>{formatDate(item.due_date)}</td>
|
||||
<td>{formatPrice(item.amount)}</td>
|
||||
<td>{formatState(item)}</td>
|
||||
<td>{itemButtons(item)}</td>
|
||||
</tr>)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
PaymentSchedulesTableComponent.defaultProps = { showCustomer: false };
|
||||
|
||||
|
||||
export const PaymentSchedulesTable: React.FC<PaymentSchedulesTableProps> = ({ paymentSchedules, showCustomer }) => {
|
||||
return (
|
||||
<Loader>
|
||||
<PaymentSchedulesTableComponent paymentSchedules={paymentSchedules} showCustomer={showCustomer} />
|
||||
</Loader>
|
||||
);
|
||||
}
|
@ -7,7 +7,6 @@ import { Elements } from '@stripe/react-stripe-js';
|
||||
import { loadStripe } from "@stripe/stripe-js";
|
||||
import SettingAPI from '../api/setting';
|
||||
import { SettingName } from '../models/setting';
|
||||
import { Loader } from './loader';
|
||||
|
||||
const stripePublicKey = SettingAPI.get(SettingName.StripePublicKey);
|
||||
|
||||
|
@ -174,7 +174,7 @@ const StripeModal: React.FC<StripeModalProps> = ({ isOpen, toggleModal, afterSuc
|
||||
customFooter={logoFooter()}
|
||||
className="stripe-modal">
|
||||
{ready && <StripeElements>
|
||||
<WalletInfo reservation={cartItems?.reservation} currentUser={currentUser} wallet={wallet} price={price?.price} />
|
||||
<WalletInfo cartItems={cartItems} currentUser={currentUser} wallet={wallet} price={price?.price} />
|
||||
<StripeForm onSubmit={handleSubmit}
|
||||
onSuccess={handleFormSuccess}
|
||||
onError={handleFormError}
|
||||
|
@ -8,23 +8,25 @@ import { react2angular } from 'react2angular';
|
||||
import { IApplication } from '../models/application';
|
||||
import '../lib/i18n';
|
||||
import { Loader } from './loader';
|
||||
import { Reservation } from '../models/reservation';
|
||||
import { User } from '../models/user';
|
||||
import { Wallet } from '../models/wallet';
|
||||
import { IFablab } from '../models/fablab';
|
||||
import WalletLib from '../lib/wallet';
|
||||
import { CartItems } from '../models/payment';
|
||||
import { Reservation } from '../models/reservation';
|
||||
import { SubscriptionRequest } from '../models/subscription';
|
||||
|
||||
declare var Application: IApplication;
|
||||
declare var Fablab: IFablab;
|
||||
|
||||
interface WalletInfoProps {
|
||||
reservation: Reservation,
|
||||
cartItems: CartItems,
|
||||
currentUser: User,
|
||||
wallet: Wallet,
|
||||
price: number,
|
||||
}
|
||||
|
||||
export const WalletInfo: React.FC<WalletInfoProps> = ({reservation, currentUser, wallet, price}) => {
|
||||
export const WalletInfo: React.FC<WalletInfoProps> = ({ cartItems, currentUser, wallet, price }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
const [remainingPrice, setRemainingPrice] = useState(0);
|
||||
|
||||
@ -34,20 +36,26 @@ export const WalletInfo: React.FC<WalletInfoProps> = ({reservation, currentUser,
|
||||
useEffect(() => {
|
||||
const wLib = new WalletLib(wallet);
|
||||
setRemainingPrice(wLib.computeRemainingPrice(price));
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* Return the formatted localized amount for the given price (eg. 20.5 => "20,50 €")
|
||||
* Return the formatted localized amount for the given price (e.g. 20.5 => "20,50 €")
|
||||
*/
|
||||
const formatPrice = (price: number): string => {
|
||||
return new Intl.NumberFormat(Fablab.intl_locale, {style: 'currency', currency: Fablab.intl_currency}).format(price);
|
||||
}
|
||||
/**
|
||||
* Check if the currently connected used is also the person making the reservation.
|
||||
* If the currently connected user (ie. the operator), is an admin or a manager, he may book the reservation for someone else.
|
||||
* If the currently connected user (i.e. the operator), is an admin or a manager, he may book the reservation for someone else.
|
||||
*/
|
||||
const isOperatorAndClient = (): boolean => {
|
||||
return currentUser.id == reservation.user_id;
|
||||
return currentUser.id == buyingItem().user_id;
|
||||
}
|
||||
/**
|
||||
* Return the item currently bought (reservation or subscription)
|
||||
*/
|
||||
const buyingItem = (): Reservation|SubscriptionRequest => {
|
||||
return cartItems.reservation || cartItems.subscription;
|
||||
}
|
||||
/**
|
||||
* If the client has some money in his wallet & the price is not zero, then we should display this component.
|
||||
@ -66,17 +74,17 @@ export const WalletInfo: React.FC<WalletInfoProps> = ({reservation, currentUser,
|
||||
* Does the current cart contains a payment schedule?
|
||||
*/
|
||||
const isPaymentSchedule = (): boolean => {
|
||||
return reservation.plan_id && reservation.payment_schedule;
|
||||
return buyingItem().plan_id && buyingItem().payment_schedule;
|
||||
}
|
||||
/**
|
||||
* Return the human-readable name of the item currently bought with the wallet
|
||||
*/
|
||||
const getPriceItem = (): string => {
|
||||
let item = 'other';
|
||||
if (reservation.slots_attributes.length > 0) {
|
||||
if (cartItems.reservation) {
|
||||
item = 'reservation';
|
||||
} else if (reservation.plan_id) {
|
||||
if (reservation.payment_schedule) {
|
||||
} else if (cartItems.subscription) {
|
||||
if (cartItems.subscription.payment_schedule) {
|
||||
item = 'first_deadline';
|
||||
} else item = 'subscription';
|
||||
}
|
||||
@ -120,12 +128,12 @@ export const WalletInfo: React.FC<WalletInfoProps> = ({reservation, currentUser,
|
||||
);
|
||||
}
|
||||
|
||||
const WalletInfoWrapper: React.FC<WalletInfoProps> = ({currentUser, reservation, price, wallet}) => {
|
||||
const WalletInfoWrapper: React.FC<WalletInfoProps> = ({ currentUser, cartItems, price, wallet }) => {
|
||||
return (
|
||||
<Loader>
|
||||
<WalletInfo currentUser={currentUser} reservation={reservation} price={price} wallet={wallet}/>
|
||||
<WalletInfo currentUser={currentUser} cartItems={cartItems} price={price} wallet={wallet}/>
|
||||
</Loader>
|
||||
);
|
||||
}
|
||||
|
||||
Application.Components.component('walletInfo', react2angular(WalletInfoWrapper, ['currentUser', 'price', 'reservation', 'wallet']));
|
||||
Application.Components.component('walletInfo', react2angular(WalletInfoWrapper, ['currentUser', 'price', 'cartItems', 'wallet']));
|
||||
|
@ -704,9 +704,12 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
controller: ['$scope', '$uibModalInstance', '$state', 'reservation', 'price', 'cgv', 'Auth', 'Reservation', 'growl', 'wallet', 'helpers', '$filter', 'coupon', 'cartItems', 'stripeKey',
|
||||
function ($scope, $uibModalInstance, $state, reservation, price, cgv, Auth, Reservation, growl, wallet, helpers, $filter, coupon, cartItems, stripeKey) {
|
||||
// User's wallet amount
|
||||
$scope.walletAmount = wallet.amount;
|
||||
$scope.wallet = wallet;
|
||||
|
||||
// Price
|
||||
$scope.price = price.price;
|
||||
|
||||
// Amount to pay
|
||||
$scope.amount = helpers.getAmountToPay(price.price, wallet.amount);
|
||||
|
||||
// Cart items
|
||||
@ -753,16 +756,22 @@ Application.Controllers.controller('ShowEventController', ['$scope', '$state', '
|
||||
},
|
||||
coupon () {
|
||||
return $scope.coupon.applied;
|
||||
}
|
||||
},
|
||||
cartItems () {
|
||||
return mkRequestParams(reservation, $scope.coupon.applied);
|
||||
},
|
||||
},
|
||||
controller: ['$scope', '$uibModalInstance', '$state', 'reservation', 'price', 'Auth', 'Reservation', 'wallet', 'helpers', '$filter', 'coupon',
|
||||
function ($scope, $uibModalInstance, $state, reservation, price, Auth, Reservation, wallet, helpers, $filter, coupon) {
|
||||
controller: ['$scope', '$uibModalInstance', '$state', 'reservation', 'price', 'Auth', 'Reservation', 'wallet', 'helpers', '$filter', 'coupon', 'cartItems',
|
||||
function ($scope, $uibModalInstance, $state, reservation, price, Auth, Reservation, wallet, helpers, $filter, coupon, cartItems) {
|
||||
// User's wallet amount
|
||||
$scope.walletAmount = wallet.amount;
|
||||
$scope.wallet = wallet;
|
||||
|
||||
// Price
|
||||
$scope.price = price.price;
|
||||
|
||||
// Cart items
|
||||
$scope.cartItems = cartItems;
|
||||
|
||||
// price to pay
|
||||
$scope.amount = helpers.getAmountToPay(price.price, wallet.amount);
|
||||
|
||||
|
@ -938,7 +938,7 @@ Application.Directives.directive('cart', ['$rootScope', '$uibModal', 'dialogs',
|
||||
|
||||
return Wallet.getWalletByUser({ user_id: $scope.user.id }, function (wallet) {
|
||||
const amountToPay = helpers.getAmountToPay($scope.amountTotal, wallet.amount);
|
||||
if ((AuthService.isAuthorized(['member']) && amountToPay > 0) ||
|
||||
if ((AuthService.isAuthorized(['member']) && (amountToPay > 0 || (amountToPay === 0 && hasOtherDeadlines()))) ||
|
||||
(AuthService.isAuthorized('manager') && $scope.user.id === $rootScope.currentUser.id && amountToPay > 0)) {
|
||||
return payByStripe(reservation);
|
||||
} else {
|
||||
|
@ -47,15 +47,18 @@ Application.Directives.directive('coupon', [ '$rootScope', 'Coupon', '_t', funct
|
||||
$scope.messages = [];
|
||||
if ($scope.couponCode === '') {
|
||||
$scope.status = 'pending';
|
||||
return $scope.coupon = null;
|
||||
$scope.coupon = null;
|
||||
} else {
|
||||
return Coupon.validate({ code: $scope.couponCode, user_id: $scope.userId, amount: $scope.total }, function (res) {
|
||||
Coupon.validate({ code: $scope.couponCode, user_id: $scope.userId, amount: $scope.total }, function (res) {
|
||||
$scope.status = 'valid';
|
||||
$scope.coupon = res;
|
||||
if (res.type === 'percent_off') {
|
||||
return $scope.messages.push({ type: 'success', message: _t('app.shared.coupon_input.the_coupon_has_been_applied_you_get_PERCENT_discount', { PERCENT: res.percent_off }) });
|
||||
$scope.messages.push({ type: 'success', message: _t('app.shared.coupon_input.the_coupon_has_been_applied_you_get_PERCENT_discount', { PERCENT: res.percent_off }) });
|
||||
} else {
|
||||
return $scope.messages.push({ type: 'success', message: _t('app.shared.coupon_input.the_coupon_has_been_applied_you_get_AMOUNT_CURRENCY', { AMOUNT: res.amount_off, CURRENCY: $rootScope.currencySymbol }) });
|
||||
$scope.messages.push({ type: 'success', message: _t('app.shared.coupon_input.the_coupon_has_been_applied_you_get_AMOUNT_CURRENCY', { AMOUNT: res.amount_off, CURRENCY: $rootScope.currencySymbol }) });
|
||||
}
|
||||
if (res.validity_per_user === 'once') {
|
||||
$scope.messages.push({ type: 'warning', message: _t('app.shared.coupon_input.coupon_validity_once') });
|
||||
}
|
||||
}
|
||||
, function (err) {
|
||||
|
@ -1,7 +1,24 @@
|
||||
export enum PaymentScheduleItemState {
|
||||
New = 'new',
|
||||
Pending = 'pending',
|
||||
RequirePaymentMethod = 'requires_payment_method',
|
||||
RequireAction = 'requires_action',
|
||||
Paid = 'paid',
|
||||
Error = 'error'
|
||||
}
|
||||
|
||||
export enum PaymentMethod {
|
||||
Stripe = 'stripe',
|
||||
Check = 'check'
|
||||
}
|
||||
export interface PaymentScheduleItem {
|
||||
id: number,
|
||||
amount: number,
|
||||
due_date: Date
|
||||
due_date: Date,
|
||||
state: PaymentScheduleItemState,
|
||||
invoice_id: number,
|
||||
payment_method: PaymentMethod,
|
||||
client_secret?: string,
|
||||
details: {
|
||||
recurring: number,
|
||||
adjustment: number,
|
||||
@ -18,5 +35,25 @@ export interface PaymentSchedule {
|
||||
reference: string,
|
||||
payment_method: string,
|
||||
wallet_amount: number,
|
||||
items: Array<PaymentScheduleItem>
|
||||
items: Array<PaymentScheduleItem>,
|
||||
created_at: Date,
|
||||
chained_footprint: boolean,
|
||||
user: {
|
||||
name: string
|
||||
},
|
||||
operator: {
|
||||
id: number,
|
||||
first_name: string,
|
||||
last_name: string,
|
||||
}
|
||||
}
|
||||
|
||||
export interface PaymentScheduleIndexRequest {
|
||||
query: {
|
||||
reference?: string,
|
||||
customer?: string,
|
||||
date?: Date,
|
||||
page: number,
|
||||
size: number
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Reservation } from './reservation';
|
||||
import { SubscriptionRequest } from './subscription';
|
||||
|
||||
export interface PaymentConfirmation {
|
||||
requires_action?: boolean,
|
||||
@ -20,11 +21,6 @@ export enum PaymentMethod {
|
||||
|
||||
export interface CartItems {
|
||||
reservation?: Reservation,
|
||||
subscription?: {
|
||||
plan_id: number,
|
||||
user_id: number,
|
||||
payment_schedule: boolean,
|
||||
payment_method: PaymentMethod
|
||||
},
|
||||
subscription?: SubscriptionRequest,
|
||||
coupon_code?: string
|
||||
}
|
||||
|
18
app/frontend/src/javascript/models/subscription.ts
Normal file
18
app/frontend/src/javascript/models/subscription.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { Plan } from './plan';
|
||||
import { PaymentMethod } from './payment';
|
||||
|
||||
export interface Subscription {
|
||||
id: number,
|
||||
plan_id: number,
|
||||
expired_at: Date,
|
||||
canceled_at?: Date,
|
||||
stripe: boolean,
|
||||
plan: Plan
|
||||
}
|
||||
|
||||
export interface SubscriptionRequest {
|
||||
plan_id: number,
|
||||
user_id: number,
|
||||
payment_schedule: boolean,
|
||||
payment_method: PaymentMethod
|
||||
}
|
@ -25,5 +25,9 @@
|
||||
@import "modules/payment-schedule-summary";
|
||||
@import "modules/wallet-info";
|
||||
@import "modules/stripe-modal";
|
||||
@import "modules/labelled-input";
|
||||
@import "modules/document-filters";
|
||||
@import "modules/payment-schedules-table";
|
||||
@import "modules/payment-schedules-list";
|
||||
|
||||
@import "app.responsive";
|
||||
|
@ -0,0 +1,8 @@
|
||||
.document-filters {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
& > * {
|
||||
width: 31%;
|
||||
}
|
||||
}
|
@ -17,6 +17,8 @@
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
animation: 0.15s linear fadeIn;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.fab-modal-sm { width: 340px; }
|
||||
|
48
app/frontend/src/stylesheets/modules/labelled-input.scss
Normal file
48
app/frontend/src/stylesheets/modules/labelled-input.scss
Normal file
@ -0,0 +1,48 @@
|
||||
.input-with-label {
|
||||
position: relative;
|
||||
display: inline-table;
|
||||
border-collapse: separate;
|
||||
box-sizing: border-box;
|
||||
|
||||
label.label {
|
||||
padding: 6px 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
color: #555555;
|
||||
text-align: center;
|
||||
background-color: #eeeeee;
|
||||
border: 1px solid #c4c4c4;
|
||||
border-radius: 4px 0 0 4px;
|
||||
width: 1%;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
display: table-cell;
|
||||
box-sizing: border-box;
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
input.input {
|
||||
padding: 6px 12px;
|
||||
height: 38px;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
border: 1px solid #c4c4c4;
|
||||
border-radius: 0 4px 4px 0;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||
display: table-cell;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:focus {
|
||||
border-color: #fdde3f;
|
||||
outline: 0;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(253, 222, 63, .6);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
.schedules-filters {
|
||||
margin-bottom: 2em;
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
.schedules-table {
|
||||
table-layout: fixed;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-top: 0;
|
||||
margin-bottom: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
background-color: transparent;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
|
||||
& > thead {
|
||||
border-top: 1px solid #e9e9e9;
|
||||
|
||||
& > tr > th {
|
||||
font-weight: 600;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
padding: 2rem 1rem;
|
||||
line-height: 1.5;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.w-35 { width: 35px; }
|
||||
.w-120 { width: 120px; }
|
||||
.w-200 { width: 200px; }
|
||||
|
||||
.schedules-table-body {
|
||||
table-layout: fixed;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-top: 0;
|
||||
margin-bottom: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
|
||||
& > tbody {
|
||||
background: #f7f7f9;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
line-height: 1.5;
|
||||
|
||||
& > tr > td {
|
||||
padding: 12px 10px;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-top: 0;
|
||||
vertical-align: middle;
|
||||
font-size: 1.4rem;
|
||||
line-height: 1.5;
|
||||
|
||||
&.row-header {
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.schedule-items-table {
|
||||
table-layout: fixed;
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin-bottom: 1rem;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-top: 0;
|
||||
|
||||
& > thead {
|
||||
border-top: 1px solid #e9e9e9;
|
||||
font-size: 1.4rem;
|
||||
line-height: 1.5;
|
||||
|
||||
& > tr > th {
|
||||
border: 1px solid #f0f0f0;
|
||||
border-top: 0;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
font-weight: 600;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
font-size: 1.1rem;
|
||||
padding: 2rem 1rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
& > tbody > tr > td {
|
||||
vertical-align: middle;
|
||||
border: 1px solid #f0f0f0;
|
||||
border-top: 0;
|
||||
padding: 12px 10px;
|
||||
font-size: 1.4rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.download-button,
|
||||
.action-button {
|
||||
color: black;
|
||||
background-color: #fbfbfb;
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
background-image: none;
|
||||
border: 1px solid #c9c9c9;
|
||||
padding: 6px 12px;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
border-radius: 4px;
|
||||
user-select: none;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
background-color: #f2f2f2;
|
||||
color: black;
|
||||
border-color: #aaaaaa;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: black;
|
||||
background-color: #f2f2f2;
|
||||
border-color: #aaaaaa;
|
||||
outline: 0;
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
}
|
||||
|
||||
& > i {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
// The color classes above are automatically generated from PaymentScheduleItem.state
|
||||
.state-new {
|
||||
color: #3a3a3a;
|
||||
}
|
||||
.state-pending,
|
||||
.state-requires_payment_method,
|
||||
.state-requires_action {
|
||||
color: #d43333;
|
||||
}
|
||||
.state-paid,
|
||||
.state-error {
|
||||
color: black;
|
||||
}
|
||||
}
|
@ -79,6 +79,8 @@
|
||||
</select>
|
||||
<span class="help-block error" ng-show="couponForm['coupon[validity_per_user]'].$dirty && couponForm['coupon[validity_per_user]'].$error.required" translate>{{ 'app.shared.coupon.validity_per_user_is_required' }}</span>
|
||||
</div>
|
||||
<p class="alert alert-warning" ng-show="coupon.validity_per_user == 'once'" translate>{{ 'app.shared.coupon.warn_validity_once' }}</p>
|
||||
<p class="alert alert-warning" ng-show="coupon.validity_per_user == 'forever'" translate>{{ 'app.shared.coupon.warn_validity_forever' }}</p>
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': errors['valid_until']}">
|
||||
<label for="coupon[valid_until]" translate>{{ 'app.shared.coupon.valid_until' }}</label>
|
||||
|
@ -34,6 +34,10 @@
|
||||
<ng-include src="'/admin/invoices/list.html'"></ng-include>
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'app.admin.invoices.payment_schedules_list' | translate }}" ng-show="$root.modules.invoicing" index="4">
|
||||
<payment-schedules-list />
|
||||
</uib-tab>
|
||||
|
||||
<uib-tab heading="{{ 'app.admin.invoices.invoicing_settings' | translate }}" index="1" class="invoices-settings">
|
||||
<ng-include src="'/admin/invoices/settings.html'"></ng-include>
|
||||
</uib-tab>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<div class="" id="loginModal">
|
||||
<div class="modal-header">
|
||||
<img ng-src="{{logoBlack.custom_asset_file_attributes.attachment_url}}" alt="{{logo.custom_asset_file_attributes.attachment}}" class="modal-logo"/>
|
||||
<h1 translate>
|
||||
<h1 translate translate-default="Login">
|
||||
{{ 'app.public.common.connection' }}
|
||||
</h1>
|
||||
</div>
|
||||
@ -24,7 +24,7 @@
|
||||
required="required"
|
||||
ng-blur="emailError = !!loginForm.email.$error.email"
|
||||
ng-focus="emailError = false"
|
||||
placeholder="{{ 'app.public.common.your_email_address' | translate }}" />
|
||||
translate-attr="{ placeholder: 'app.public.common.your_email_address' }" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -38,12 +38,12 @@
|
||||
class="form-control"
|
||||
ng-model="user.password"
|
||||
required="required"
|
||||
placeholder="{{ 'app.public.common.your_password' | translate }}"
|
||||
translate-attr="{ placeholder: 'app.public.common.your_password' }"
|
||||
ng-minlength="8"/>
|
||||
</div>
|
||||
<a href="#" ng-click="openResetPassword($event)" class="text-xs">{{ 'app.public.common.password_forgotten' | translate }}</a>
|
||||
<a href="#" ng-click="openResetPassword($event)" class="text-xs" translate translate-default="Forgotten password">{{ 'app.public.common.password_forgotten' }}</a>
|
||||
<span ng-if="confirmationRequired">
|
||||
<br><a href="#" ng-click="openConfirmationNewModal($event)" class="text-xs">{{ 'app.public.common.confirm_my_account' | translate }}</a>
|
||||
<br><a href="#" ng-click="openConfirmationNewModal($event)" class="text-xs" translate translate-default="Confirm account">{{ 'app.public.common.confirm_my_account' }}</a>
|
||||
</span>
|
||||
<div class="alert alert-warning m-t-sm m-b-none text-xs p-sm" ng-show='isCapsLockOn' role="alert">
|
||||
<i class="fa fa-warning"></i>
|
||||
@ -56,13 +56,13 @@
|
||||
|
||||
</div>
|
||||
<div class="panel-footer no-padder">
|
||||
<button class="btn btn-valid btn-warning btn-block p-l btn-lg text-u-c r-b" ng-click="login()" ng-disabled="loginForm.$invalid" translate>{{ 'app.shared.buttons.confirm' }}</button>
|
||||
<button class="btn btn-valid btn-warning btn-block p-l btn-lg text-u-c r-b" ng-click="login()" ng-disabled="loginForm.$invalid" translate translate-default="OK">{{ 'app.shared.buttons.confirm' }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-center font-sbold">
|
||||
<span translate>{{ 'app.public.common.not_registered_to_the_fablab' }}</span>
|
||||
<span translate translate-default="Not registered?">{{ 'app.public.common.not_registered_to_the_fablab' }}</span>
|
||||
<br/>
|
||||
<a href="#" ng-click="openSignup($event)" class="text-u-l" translate>{{ 'app.public.common.create_an_account' }}</a></br>
|
||||
<a href="#" ng-click="openSignup($event)" class="text-u-l" translate translate-default="Create an account">{{ 'app.public.common.create_an_account' }}</a></br>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<wallet-info current-user="currentUser"
|
||||
reservation="reservation"
|
||||
cart-items="cartItems"
|
||||
price="price"
|
||||
wallet="wallet"/>
|
||||
</div>
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
<div class="row">
|
||||
<wallet-info current-user="currentUser"
|
||||
reservation="reservation"
|
||||
cart-items="cartItems"
|
||||
price="price"
|
||||
wallet="wallet"/>
|
||||
</div>
|
||||
|
@ -17,6 +17,9 @@
|
||||
<a ng-href="api/invoices/{{t.invoice.id}}/download" target="_blank" ng-if="t.invoice.id">
|
||||
{{::t.invoice.reference}}
|
||||
</a>
|
||||
<a ng-href="api/payment_schedules/{{t.payment_schedule.id}}/download" target="_blank" ng-if="t.payment_schedule.id">
|
||||
{{::t.payment_schedule.reference}}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ ::t.user.full_name }}</td>
|
||||
<td ng-class="{'green':t.transaction_type == 'credit', 'red':t.transaction_type == 'debit'}">
|
||||
|
@ -43,4 +43,11 @@ class NotificationsMailer < NotifyWith::NotificationsMailer
|
||||
subject: t('notifications_mailer.notify_member_avoir_ready.subject'),
|
||||
template_name: 'notify_member_avoir_ready')
|
||||
end
|
||||
|
||||
def notify_user_when_payment_schedule_ready
|
||||
attachments[@attached_object.filename] = File.read(@attached_object.file)
|
||||
mail(to: @recipient.email,
|
||||
subject: t('notifications_mailer.notify_member_payment_schedule_ready.subject'),
|
||||
template_name: 'notify_member_payment_schedule_ready')
|
||||
end
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ class Coupon < ApplicationRecord
|
||||
has_many :invoices
|
||||
has_many :payment_schedule
|
||||
|
||||
after_commit :create_stripe_coupon, on: [:create]
|
||||
after_save :create_stripe_coupon, on: [:create]
|
||||
after_commit :delete_stripe_coupon, on: [:destroy]
|
||||
|
||||
validates :name, presence: true
|
||||
@ -32,13 +32,17 @@ class Coupon < ApplicationRecord
|
||||
}
|
||||
|
||||
def safe_destroy
|
||||
if invoices.size.zero?
|
||||
if usages.zero?
|
||||
destroy
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def usages
|
||||
invoices.count + payment_schedule.count
|
||||
end
|
||||
|
||||
##
|
||||
# Check the status of the current coupon. The coupon:
|
||||
# - may have been disabled by an admin,
|
||||
@ -94,7 +98,7 @@ class Coupon < ApplicationRecord
|
||||
private
|
||||
|
||||
def create_stripe_coupon
|
||||
StripeWorker.perform_async(:create_stripe_coupon, id)
|
||||
StripeService.create_stripe_coupon(id)
|
||||
end
|
||||
|
||||
def delete_stripe_coupon
|
||||
|
@ -54,6 +54,10 @@ class NotificationType
|
||||
notify_admins_role_update
|
||||
notify_user_role_update
|
||||
notify_admin_members_stripe_sync
|
||||
notify_user_when_payment_schedule_ready
|
||||
notify_admin_payment_schedule_failed
|
||||
notify_member_payment_schedule_failed
|
||||
notify_admin_payment_schedule_check_deadline
|
||||
]
|
||||
# deprecated:
|
||||
# - notify_member_subscribed_plan_is_changed
|
||||
|
@ -18,9 +18,9 @@ class PaymentDocument < Footprintable
|
||||
end
|
||||
|
||||
def set_wallet_transaction(amount, transaction_id)
|
||||
raise InvalidFootprintError unless check_footprint
|
||||
|
||||
update_columns(wallet_amount: amount, wallet_transaction_id: transaction_id)
|
||||
chain_record
|
||||
self.wallet_amount = amount
|
||||
self.wallet_transaction_id = transaction_id
|
||||
end
|
||||
|
||||
def post_save(arg); end
|
||||
end
|
||||
|
@ -9,6 +9,7 @@ class PaymentSchedule < PaymentDocument
|
||||
belongs_to :wallet_transaction
|
||||
belongs_to :coupon
|
||||
belongs_to :invoicing_profile
|
||||
belongs_to :statistic_profile
|
||||
belongs_to :operator_profile, foreign_key: :operator_profile_id, class_name: 'InvoicingProfile'
|
||||
|
||||
belongs_to :subscription, foreign_type: 'Subscription', foreign_key: 'scheduled_id'
|
||||
@ -19,6 +20,7 @@ class PaymentSchedule < PaymentDocument
|
||||
before_create :add_environment
|
||||
after_create :update_reference, :chain_record
|
||||
after_commit :generate_and_send_document, on: [:create], if: :persisted?
|
||||
after_commit :generate_initial_invoice, on: [:create], if: :persisted?
|
||||
|
||||
def file
|
||||
dir = "payment_schedules/#{invoicing_profile.id}"
|
||||
@ -45,10 +47,24 @@ class PaymentSchedule < PaymentDocument
|
||||
payment_schedule_items.order(due_date: :asc)
|
||||
end
|
||||
|
||||
def user
|
||||
invoicing_profile.user
|
||||
end
|
||||
|
||||
def check_footprint
|
||||
payment_schedule_items.map(&:check_footprint).all? && footprint == compute_footprint
|
||||
end
|
||||
|
||||
def post_save(setup_intent_id)
|
||||
return unless payment_method == 'stripe'
|
||||
|
||||
StripeService.create_stripe_subscription(self, setup_intent_id)
|
||||
end
|
||||
|
||||
def self.columns_out_of_footprint
|
||||
%w[stp_subscription_id]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_and_send_document
|
||||
@ -60,4 +76,8 @@ class PaymentSchedule < PaymentDocument
|
||||
end
|
||||
PaymentScheduleWorker.perform_async(id)
|
||||
end
|
||||
|
||||
def generate_initial_invoice
|
||||
PaymentScheduleItemWorker.perform_async
|
||||
end
|
||||
end
|
||||
|
@ -6,7 +6,19 @@ class PaymentScheduleItem < Footprintable
|
||||
belongs_to :invoice
|
||||
after_create :chain_record
|
||||
|
||||
def first?
|
||||
payment_schedule.ordered_items.first == self
|
||||
end
|
||||
|
||||
def payment_intent
|
||||
return unless stp_invoice_id
|
||||
|
||||
key = Setting.get('stripe_secret_key')
|
||||
stp_invoice = Stripe::Invoice.retrieve(stp_invoice_id, api_key: key)
|
||||
Stripe::PaymentIntent.retrieve(stp_invoice.payment_intent, api_key: key)
|
||||
end
|
||||
|
||||
def self.columns_out_of_footprint
|
||||
%w[invoice_id]
|
||||
%w[invoice_id stp_invoice_id state payment_method]
|
||||
end
|
||||
end
|
||||
|
@ -145,15 +145,13 @@ class Price < ApplicationRecord
|
||||
total_amount = cs.apply(total_amount, cp)
|
||||
|
||||
# == generate PaymentSchedule (if applicable) ===
|
||||
schedule = if options[:payment_schedule] && plan.monthly_payment
|
||||
PaymentScheduleService.new.compute(plan, _amount_no_coupon, cp)
|
||||
schedule = if options[:payment_schedule] && plan&.monthly_payment
|
||||
PaymentScheduleService.new.compute(plan, _amount_no_coupon, coupon: cp)
|
||||
else
|
||||
nil
|
||||
end
|
||||
if schedule
|
||||
total_amount -= schedule[:payment_schedule].total
|
||||
total_amount += schedule[:items][0].amount
|
||||
end
|
||||
|
||||
total_amount = schedule[:items][0].amount if schedule
|
||||
|
||||
# return result
|
||||
{
|
||||
|
@ -45,9 +45,7 @@ class Reservation < ApplicationRecord
|
||||
def generate_subscription
|
||||
return unless plan_id
|
||||
|
||||
self.subscription = Subscription.find_or_initialize_by(statistic_profile_id: statistic_profile_id)
|
||||
subscription.attributes = { plan_id: plan_id, statistic_profile_id: statistic_profile_id, expiration_date: nil }
|
||||
|
||||
self.subscription = Subscription.new(plan_id: plan_id, statistic_profile_id: statistic_profile_id, expiration_date: nil)
|
||||
subscription.init_save
|
||||
subscription
|
||||
end
|
||||
|
@ -148,7 +148,7 @@ class Setting < ApplicationRecord
|
||||
##
|
||||
# Return the value of the requested setting, if any.
|
||||
# Usage: Setting.get('my_setting')
|
||||
# @return {String}
|
||||
# @return {String|Boolean}
|
||||
##
|
||||
def self.get(name)
|
||||
res = find_by(name: name)&.value
|
||||
|
@ -38,6 +38,7 @@ class Subscription < ApplicationRecord
|
||||
end
|
||||
|
||||
def cancel
|
||||
# TODO, currently unused, refactor to use with PaymentSchedule
|
||||
update_columns(canceled_at: DateTime.current)
|
||||
end
|
||||
|
||||
@ -143,18 +144,4 @@ class Subscription < ApplicationRecord
|
||||
def of_partner_plan?
|
||||
plan.is_a?(PartnerPlan)
|
||||
end
|
||||
|
||||
def get_wallet_amount_debit
|
||||
total = plan.amount
|
||||
total = CouponService.new.apply(total, @coupon, user.id) if @coupon
|
||||
wallet_amount = (user.wallet.amount * 100).to_i
|
||||
wallet_amount >= total ? total : wallet_amount
|
||||
end
|
||||
|
||||
def debit_user_wallet
|
||||
return if !@wallet_amount_debit.present? || @wallet_amount_debit.zero?
|
||||
|
||||
amount = @wallet_amount_debit / 100.0
|
||||
WalletService.new(user: user, wallet: user.wallet).debit(amount, self)
|
||||
end
|
||||
end
|
||||
|
151
app/pdfs/pdf/payment_schedule.rb
Normal file
151
app/pdfs/pdf/payment_schedule.rb
Normal file
@ -0,0 +1,151 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Generate a downloadable PDF file for the recorded payment schedule
|
||||
class PDF::PaymentSchedule < Prawn::Document
|
||||
require 'stringio'
|
||||
include ActionView::Helpers::NumberHelper
|
||||
include ApplicationHelper
|
||||
|
||||
##
|
||||
# @param payment_schedule {PaymentSchedule}
|
||||
##
|
||||
def initialize(payment_schedule)
|
||||
super(margin: 70)
|
||||
|
||||
# fonts
|
||||
opensans = Rails.root.join('vendor/assets/fonts/OpenSans-Regular.ttf').to_s
|
||||
opensans_bold = Rails.root.join('vendor/assets/fonts/OpenSans-Bold.ttf').to_s
|
||||
opensans_bolditalic = Rails.root.join('vendor/assets/fonts/OpenSans-BoldItalic.ttf').to_s
|
||||
opensans_italic = Rails.root.join('vendor/assets/fonts/OpenSans-Italic.ttf').to_s
|
||||
|
||||
font_families.update(
|
||||
'Open-Sans' => {
|
||||
normal: { file: opensans, font: 'Open-Sans' },
|
||||
bold: { file: opensans_bold, font: 'Open-Sans-Bold' },
|
||||
italic: { file: opensans_italic, font: 'Open-Sans-Oblique' },
|
||||
bold_italic: { file: opensans_bolditalic, font: 'Open-Sans-BoldOblique' }
|
||||
}
|
||||
)
|
||||
|
||||
# logo
|
||||
img_b64 = Setting.find_by(name: 'invoice_logo')
|
||||
begin
|
||||
image StringIO.new(Base64.decode64(img_b64.value)), fit: [415, 40]
|
||||
rescue StandardError => e
|
||||
puts "Unable to decode invoice logo from base64: #{e}"
|
||||
end
|
||||
move_down 20
|
||||
font('Open-Sans', size: 10) do
|
||||
# general information
|
||||
text I18n.t('payment_schedules.schedule_reference', REF: payment_schedule.reference), leading: 3
|
||||
text I18n.t('payment_schedules.schedule_issued_on_DATE', DATE: I18n.l(payment_schedule.created_at.to_date))
|
||||
|
||||
# user/organization's information
|
||||
if payment_schedule.invoicing_profile&.organization
|
||||
name = payment_schedule.invoicing_profile.organization.name
|
||||
full_name = "#{name} (#{payment_schedule.invoicing_profile.full_name})"
|
||||
else
|
||||
name = payment_schedule.invoicing_profile.full_name
|
||||
full_name = name
|
||||
end
|
||||
|
||||
address = if payment_schedule.invoicing_profile&.organization&.address
|
||||
payment_schedule.invoicing_profile.organization.address.address
|
||||
elsif payment_schedule.invoicing_profile&.address
|
||||
payment_schedule.invoicing_profile.address.address
|
||||
else
|
||||
''
|
||||
end
|
||||
|
||||
text_box "<b>#{name}</b>\n#{payment_schedule.invoicing_profile.email}\n#{address}",
|
||||
at: [bounds.width - 130, bounds.top - 49],
|
||||
width: 130,
|
||||
align: :right,
|
||||
inline_format: true
|
||||
name = full_name
|
||||
subscription = Subscription.find(payment_schedule.payment_schedule_items.first.details['subscription_id'])
|
||||
|
||||
# object
|
||||
move_down 25
|
||||
text I18n.t('payment_schedules.object', ITEM: subscription_verbose(subscription, name))
|
||||
|
||||
# details table of the deadlines
|
||||
move_down 20
|
||||
text I18n.t('payment_schedules.deadlines'), leading: 4
|
||||
move_down 2
|
||||
data = [[I18n.t('payment_schedules.deadline_date'), I18n.t('payment_schedules.deadline_amount')]]
|
||||
|
||||
# going through the payment_schedule_items
|
||||
payment_schedule.payment_schedule_items.each do |item|
|
||||
|
||||
price = item.amount.to_i / 100.00
|
||||
date = I18n.l(item.due_date.to_date)
|
||||
|
||||
data += [[date, number_to_currency(price)]]
|
||||
end
|
||||
data += [[I18n.t('payment_schedules.total_amount'), number_to_currency(payment_schedule.total / 100.0)]]
|
||||
|
||||
# display table
|
||||
font_size(8) do
|
||||
table(data, header: true, column_widths: [400, 72], cell_style: { inline_format: true }) do
|
||||
row(0).font_style = :bold
|
||||
column(1).style align: :right
|
||||
row(-1).style align: :right
|
||||
row(-1).background_color = 'E4E4E4'
|
||||
row(-1).font_style = :bold
|
||||
end
|
||||
end
|
||||
|
||||
# payment method
|
||||
move_down 20
|
||||
payment_verbose = _t('payment_schedules.settlement_by_METHOD', METHOD: payment_schedule.payment_method)
|
||||
payment_verbose = I18n.t('payment_schedules.settlement_by_wallet', AMOUNT: payment_schedule.wallet_amount / 100.00) if payment_schedule.wallet_amount
|
||||
text payment_verbose
|
||||
|
||||
# important information
|
||||
move_down 40
|
||||
txt = parse_html(Setting.get('invoice_text'))
|
||||
txt.each_line do |line|
|
||||
text line, style: :bold, inline_format: true
|
||||
end
|
||||
|
||||
|
||||
# address and legals information
|
||||
move_down 40
|
||||
txt = parse_html(Setting.get('invoice_legals'))
|
||||
txt.each_line do |line|
|
||||
text line, align: :right, leading: 4, inline_format: true
|
||||
end
|
||||
end
|
||||
|
||||
# factice watermark
|
||||
return unless %w[staging test development].include?(payment_schedule.environment)
|
||||
|
||||
transparent(0.1) do
|
||||
rotate(45, origin: [0, 0]) do
|
||||
image "#{Rails.root}/app/pdfs/data/watermark-#{I18n.locale}.png", at: [90, 150]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def subscription_verbose(subscription, username)
|
||||
subscription_start_at = subscription.expired_at - subscription.plan.duration
|
||||
duration_verbose = I18n.t("duration.#{subscription.plan.interval}", count: subscription.plan.interval_count)
|
||||
I18n.t('payment_schedules.subscription_of_NAME_for_DURATION_starting_from_DATE',
|
||||
NAME: username,
|
||||
DURATION: duration_verbose,
|
||||
DATE: I18n.l(subscription_start_at.to_date))
|
||||
end
|
||||
|
||||
##
|
||||
# Remove every unsupported html tag from the given html text (like <p>, <span>, ...).
|
||||
# The supported tags are <b>, <u>, <i> and <br>.
|
||||
# @param html [String] single line html text
|
||||
# @return [String] multi line simplified html text
|
||||
##
|
||||
def parse_html(html)
|
||||
ActionController::Base.helpers.sanitize(html, tags: %w[b u i br])
|
||||
end
|
||||
end
|
12
app/policies/payment_schedule_policy.rb
Normal file
12
app/policies/payment_schedule_policy.rb
Normal file
@ -0,0 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Check the access policies for API::PaymentSchedulesController
|
||||
class PaymentSchedulePolicy < ApplicationPolicy
|
||||
def list?
|
||||
user.admin? || user.manager?
|
||||
end
|
||||
|
||||
def download?
|
||||
user.admin? || user.manager? || (record.invoicing_profile.user_id == user.id)
|
||||
end
|
||||
end
|
@ -2,172 +2,192 @@
|
||||
|
||||
# Provides helper methods for Events resources and properties
|
||||
class EventService
|
||||
def self.process_params(params)
|
||||
# handle dates & times (whole-day events or not, maybe during many days)
|
||||
range = EventService.date_range({ date: params[:start_date], time: params[:start_time] },
|
||||
{ date: params[:end_date], time: params[:end_time] },
|
||||
params[:all_day] == 'true')
|
||||
params.merge!(availability_attributes: { id: params[:availability_id],
|
||||
start_at: range[:start_at],
|
||||
end_at: range[:end_at],
|
||||
available_type: 'event' })
|
||||
.extract!(:start_date, :end_date, :start_time, :end_time, :all_day)
|
||||
# convert main price to centimes
|
||||
params[:amount] = (params[:amount].to_f * 100 if params[:amount].present?)
|
||||
# delete non-complete "other" prices and convert them to centimes
|
||||
unless params[:event_price_categories_attributes].nil?
|
||||
params[:event_price_categories_attributes].delete_if do |price_cat|
|
||||
price_cat[:price_category_id].empty? || price_cat[:amount].empty?
|
||||
end
|
||||
params[:event_price_categories_attributes].each do |price_cat|
|
||||
price_cat[:amount] = price_cat[:amount].to_f * 100
|
||||
end
|
||||
end
|
||||
# return the resulting params object
|
||||
params
|
||||
end
|
||||
|
||||
def self.date_range(starting, ending, all_day)
|
||||
start_date = Time.zone.parse(starting[:date])
|
||||
end_date = Time.zone.parse(ending[:date])
|
||||
start_time = Time.parse(starting[:time]) if starting[:time]
|
||||
end_time = Time.parse(ending[:time]) if ending[:time]
|
||||
if all_day
|
||||
start_at = DateTime.new(start_date.year, start_date.month, start_date.day, 0, 0, 0, start_date.zone)
|
||||
end_at = DateTime.new(end_date.year, end_date.month, end_date.day, 23, 59, 59, end_date.zone)
|
||||
else
|
||||
start_at = DateTime.new(start_date.year, start_date.month, start_date.day, start_time.hour, start_time.min, start_time.sec, start_date.zone)
|
||||
end_at = DateTime.new(end_date.year, end_date.month, end_date.day, end_time.hour, end_time.min, end_time.sec, end_date.zone)
|
||||
end
|
||||
{ start_at: start_at, end_at: end_at }
|
||||
end
|
||||
|
||||
# delete one or more events (if periodic)
|
||||
def self.delete(event_id, mode = 'single')
|
||||
results = []
|
||||
event = Event.find(event_id)
|
||||
events = case mode
|
||||
when 'single'
|
||||
[event]
|
||||
when 'next'
|
||||
Event.includes(:availability)
|
||||
.where(
|
||||
'availabilities.start_at >= ? AND events.recurrence_id = ?',
|
||||
event.availability.start_at,
|
||||
event.recurrence_id
|
||||
)
|
||||
.references(:availabilities, :events)
|
||||
when 'all'
|
||||
Event.where(
|
||||
'recurrence_id = ?',
|
||||
event.recurrence_id
|
||||
)
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
events.each do |e|
|
||||
# here we use double negation because safe_destroy can return either a boolean (false) or an Availability (in case of delete success)
|
||||
results.push status: !!e.safe_destroy, event: e # rubocop:disable Style/DoubleNegation
|
||||
end
|
||||
results
|
||||
end
|
||||
|
||||
# update one or more events (if periodic)
|
||||
def self.update(event, event_params, mode = 'single')
|
||||
results = []
|
||||
events = case mode
|
||||
when 'single'
|
||||
[event]
|
||||
when 'next'
|
||||
Event.includes(:availability, :event_price_categories, :event_files)
|
||||
.where(
|
||||
'availabilities.start_at >= ? AND events.recurrence_id = ?',
|
||||
event.availability.start_at,
|
||||
event.recurrence_id
|
||||
)
|
||||
.references(:availabilities, :events)
|
||||
when 'all'
|
||||
Event.includes(:availability, :event_price_categories, :event_files)
|
||||
.where(
|
||||
'recurrence_id = ?',
|
||||
event.recurrence_id
|
||||
)
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
events.each do |e|
|
||||
next unless e.id != event.id
|
||||
|
||||
start_at = event_params['availability_attributes']['start_at']
|
||||
end_at = event_params['availability_attributes']['end_at']
|
||||
event_price_categories_attributes = event_params['event_price_categories_attributes']
|
||||
event_files_attributes = event_params['event_files_attributes']
|
||||
e_params = event_params.merge(
|
||||
availability_id: e.availability_id,
|
||||
availability_attributes: {
|
||||
id: e.availability_id,
|
||||
start_at: e.availability.start_at.change(hour: start_at.hour, min: start_at.min),
|
||||
end_at: e.availability.end_at.change(hour: end_at.hour, min: end_at.min),
|
||||
available_type: e.availability.available_type
|
||||
}
|
||||
)
|
||||
epc_attributes = []
|
||||
event_price_categories_attributes&.each do |epca|
|
||||
epc = e.event_price_categories.find_by(price_category_id: epca['price_category_id'])
|
||||
if epc
|
||||
epc_attributes.push(
|
||||
id: epc.id,
|
||||
price_category_id: epc.price_category_id,
|
||||
amount: epca['amount'],
|
||||
_destroy: epca['_destroy']
|
||||
)
|
||||
elsif epca['id'].present?
|
||||
event_price = event.event_price_categories.find(epca['id'])
|
||||
epc_attributes.push(
|
||||
price_category_id: epca['price_category_id'],
|
||||
amount: event_price.amount,
|
||||
_destroy: ''
|
||||
)
|
||||
class << self
|
||||
def process_params(params)
|
||||
# handle dates & times (whole-day events or not, maybe during many days)
|
||||
range = EventService.date_range({ date: params[:start_date], time: params[:start_time] },
|
||||
{ date: params[:end_date], time: params[:end_time] },
|
||||
params[:all_day] == 'true')
|
||||
params.merge!(availability_attributes: { id: params[:availability_id],
|
||||
start_at: range[:start_at],
|
||||
end_at: range[:end_at],
|
||||
available_type: 'event' })
|
||||
.extract!(:start_date, :end_date, :start_time, :end_time, :all_day)
|
||||
# convert main price to centimes
|
||||
params[:amount] = (params[:amount].to_f * 100 if params[:amount].present?)
|
||||
# delete non-complete "other" prices and convert them to centimes
|
||||
unless params[:event_price_categories_attributes].nil?
|
||||
params[:event_price_categories_attributes].delete_if do |price_cat|
|
||||
price_cat[:price_category_id].empty? || price_cat[:amount].empty?
|
||||
end
|
||||
params[:event_price_categories_attributes].each do |price_cat|
|
||||
price_cat[:amount] = price_cat[:amount].to_f * 100
|
||||
end
|
||||
end
|
||||
unless epc_attributes.empty?
|
||||
e_params = e_params.merge(
|
||||
event_price_categories_attributes: epc_attributes
|
||||
)
|
||||
end
|
||||
# return the resulting params object
|
||||
params
|
||||
end
|
||||
|
||||
ef_attributes = []
|
||||
event_files_attributes&.each do |efa|
|
||||
if efa['id'].present?
|
||||
event_file = event.event_files.find(efa['id'])
|
||||
ef = e.event_files.find_by(attachment: event_file.attachment.file.filename)
|
||||
if ef
|
||||
ef_attributes.push(
|
||||
id: ef.id,
|
||||
attachment: efa['attachment'],
|
||||
_destroy: efa['_destroy']
|
||||
def date_range(starting, ending, all_day)
|
||||
start_date = Time.zone.parse(starting[:date])
|
||||
end_date = Time.zone.parse(ending[:date])
|
||||
start_time = Time.parse(starting[:time]) if starting[:time]
|
||||
end_time = Time.parse(ending[:time]) if ending[:time]
|
||||
if all_day
|
||||
start_at = DateTime.new(start_date.year, start_date.month, start_date.day, 0, 0, 0, start_date.zone)
|
||||
end_at = DateTime.new(end_date.year, end_date.month, end_date.day, 23, 59, 59, end_date.zone)
|
||||
else
|
||||
start_at = DateTime.new(start_date.year, start_date.month, start_date.day, start_time.hour, start_time.min, start_time.sec, start_date.zone)
|
||||
end_at = DateTime.new(end_date.year, end_date.month, end_date.day, end_time.hour, end_time.min, end_time.sec, end_date.zone)
|
||||
end
|
||||
{ start_at: start_at, end_at: end_at }
|
||||
end
|
||||
|
||||
# delete one or more events (if periodic)
|
||||
def delete(event_id, mode = 'single')
|
||||
results = []
|
||||
event = Event.find(event_id)
|
||||
events = case mode
|
||||
when 'single'
|
||||
[event]
|
||||
when 'next'
|
||||
Event.includes(:availability)
|
||||
.where(
|
||||
'availabilities.start_at >= ? AND events.recurrence_id = ?',
|
||||
event.availability.start_at,
|
||||
event.recurrence_id
|
||||
)
|
||||
.references(:availabilities, :events)
|
||||
when 'all'
|
||||
Event.where(
|
||||
'recurrence_id = ?',
|
||||
event.recurrence_id
|
||||
)
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
events.each do |e|
|
||||
# here we use double negation because safe_destroy can return either a boolean (false) or an Availability (in case of delete success)
|
||||
results.push status: !!e.safe_destroy, event: e # rubocop:disable Style/DoubleNegation
|
||||
end
|
||||
results
|
||||
end
|
||||
|
||||
# update one or more events (if periodic)
|
||||
def update(event, event_params, mode = 'single')
|
||||
events = case mode
|
||||
when 'single'
|
||||
[event]
|
||||
when 'next'
|
||||
Event.includes(:availability, :event_price_categories, :event_files)
|
||||
.where(
|
||||
'availabilities.start_at >= ? AND events.recurrence_id = ?',
|
||||
event.availability.start_at,
|
||||
event.recurrence_id
|
||||
)
|
||||
.references(:availabilities, :events)
|
||||
when 'all'
|
||||
Event.includes(:availability, :event_price_categories, :event_files)
|
||||
.where(
|
||||
'recurrence_id = ?',
|
||||
event.recurrence_id
|
||||
)
|
||||
else
|
||||
[]
|
||||
end
|
||||
update_events(event, events, event_params)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_events(event, events, event_params)
|
||||
results = []
|
||||
events.each do |e|
|
||||
next unless e.id != event.id
|
||||
|
||||
start_at = event_params['availability_attributes']['start_at']
|
||||
end_at = event_params['availability_attributes']['end_at']
|
||||
event_price_categories_attributes = event_params['event_price_categories_attributes']
|
||||
event_files_attributes = event_params['event_files_attributes']
|
||||
e_params = event_params.merge(
|
||||
availability_id: e.availability_id,
|
||||
availability_attributes: {
|
||||
id: e.availability_id,
|
||||
start_at: e.availability.start_at.change(hour: start_at.hour, min: start_at.min),
|
||||
end_at: e.availability.end_at.change(hour: end_at.hour, min: end_at.min),
|
||||
available_type: e.availability.available_type
|
||||
}
|
||||
)
|
||||
epc_attributes = []
|
||||
event_price_categories_attributes&.each do |epca|
|
||||
epc = e.event_price_categories.find_by(price_category_id: epca['price_category_id'])
|
||||
if epc
|
||||
epc_attributes.push(
|
||||
id: epc.id,
|
||||
price_category_id: epc.price_category_id,
|
||||
amount: epca['amount'],
|
||||
_destroy: epca['_destroy']
|
||||
)
|
||||
elsif epca['id'].present?
|
||||
event_price = event.event_price_categories.find(epca['id'])
|
||||
epc_attributes.push(
|
||||
price_category_id: epca['price_category_id'],
|
||||
amount: event_price.amount,
|
||||
_destroy: ''
|
||||
)
|
||||
end
|
||||
else
|
||||
ef_attributes.push(efa)
|
||||
end
|
||||
unless epc_attributes.empty?
|
||||
e_params = e_params.merge(
|
||||
event_price_categories_attributes: epc_attributes
|
||||
)
|
||||
end
|
||||
|
||||
ef_attributes = []
|
||||
event_files_attributes&.each do |efa|
|
||||
if efa['id'].present?
|
||||
event_file = event.event_files.find(efa['id'])
|
||||
ef = e.event_files.find_by(attachment: event_file.attachment.file.filename)
|
||||
if ef
|
||||
ef_attributes.push(
|
||||
id: ef.id,
|
||||
attachment: efa['attachment'],
|
||||
_destroy: efa['_destroy']
|
||||
)
|
||||
end
|
||||
else
|
||||
ef_attributes.push(efa)
|
||||
end
|
||||
end
|
||||
e_params = e_params.merge(
|
||||
event_files_attributes: ef_attributes
|
||||
)
|
||||
begin
|
||||
results.push status: !!e.update(e_params.permit!), event: e # rubocop:disable Style/DoubleNegation
|
||||
rescue StandardError => err
|
||||
results.push status: false, event: e, error: err.try(:record).try(:class).try(:name), message: err.message
|
||||
end
|
||||
results.concat(update_slots(e.availability_id))
|
||||
end
|
||||
e_params = e_params.merge(
|
||||
event_files_attributes: ef_attributes
|
||||
)
|
||||
begin
|
||||
results.push status: !!e.update(e_params.permit!), event: e # rubocop:disable Style/DoubleNegation
|
||||
results.push status: !!event.update(event_params), event: event # rubocop:disable Style/DoubleNegation
|
||||
rescue StandardError => err
|
||||
results.push status: false, event: e, error: err.try(:record).try(:class).try(:name), message: err.message
|
||||
results.push status: false, event: event, error: err.try(:record).try(:class).try(:name), message: err.message
|
||||
end
|
||||
results.concat(update_slots(event.availability_id))
|
||||
results
|
||||
end
|
||||
begin
|
||||
results.push status: !!event.update(event_params), event: event # rubocop:disable Style/DoubleNegation
|
||||
rescue StandardError => err
|
||||
results.push status: false, event: event, error: err.try(:record).try(:class).try(:name), message: err.message
|
||||
|
||||
def update_slots(availability_id)
|
||||
results = []
|
||||
avail = Availability.find(availability_id)
|
||||
avail.slots.each do |s|
|
||||
results.push(status: !!s.update_attributes(start_at: avail.start_at, end_at: avail.end_at), slot: s) # rubocop:disable Style/DoubleNegation
|
||||
rescue StandardError => err
|
||||
results.push status: false, slot: s, error: err.try(:record).try(:class).try(:name), message: err.message
|
||||
end
|
||||
results
|
||||
end
|
||||
results
|
||||
end
|
||||
end
|
||||
|
@ -87,9 +87,10 @@ class PaymentDocumentService
|
||||
else
|
||||
return get_max_id(Invoice) + get_max_id(PaymentSchedule)
|
||||
end
|
||||
return Invoice.count unless defined? start && defined? ending
|
||||
return Invoice.count + PaymentSchedule.count unless defined? start && defined? ending
|
||||
|
||||
Invoice.where('created_at >= :start_date AND created_at < :end_date', start_date: start, end_date: ending).length
|
||||
Invoice.where('created_at >= :start_date AND created_at < :end_date', start_date: start, end_date: ending).length +
|
||||
PaymentSchedule.where('created_at >= :start_date AND created_at < :end_date', start_date: start, end_date: ending).length
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -8,34 +8,36 @@ class PaymentScheduleService
|
||||
# @param total {Number} Total amount of the current shopping cart (which includes this plan) - without coupon
|
||||
# @param coupon {Coupon} apply this coupon, if any
|
||||
##
|
||||
def compute(plan, total, coupon = nil)
|
||||
def compute(plan, total, coupon: nil, subscription: nil)
|
||||
other_items = total - plan.amount
|
||||
price = if coupon
|
||||
cs = CouponService.new
|
||||
other_items = cs.ventilate(total, other_items, coupon)
|
||||
cs.ventilate(total, plan.amount, coupon)
|
||||
else
|
||||
plan.amount
|
||||
end
|
||||
# base monthly price of the plan
|
||||
price = plan.amount
|
||||
ps = PaymentSchedule.new(scheduled: plan, total: price + other_items, coupon: coupon)
|
||||
deadlines = plan.duration / 1.month
|
||||
per_month = (price / deadlines).truncate
|
||||
adjustment = if per_month * deadlines != price
|
||||
price - (per_month * deadlines)
|
||||
adjustment = if per_month * deadlines + other_items.truncate != ps.total
|
||||
ps.total - (per_month * deadlines + other_items.truncate)
|
||||
else
|
||||
0
|
||||
end
|
||||
items = []
|
||||
(0..deadlines - 1).each do |i|
|
||||
date = DateTime.current + i.months
|
||||
details = { recurring: per_month }
|
||||
details = { recurring: per_month, subscription_id: subscription&.id }
|
||||
amount = if i.zero?
|
||||
details[:adjustment] = adjustment
|
||||
details[:other_items] = other_items
|
||||
per_month + adjustment + other_items
|
||||
details[:adjustment] = adjustment.truncate
|
||||
details[:other_items] = other_items.truncate
|
||||
per_month + adjustment.truncate + other_items.truncate
|
||||
else
|
||||
per_month
|
||||
end
|
||||
if coupon
|
||||
cs = CouponService.new
|
||||
if (coupon.validity_per_user == 'once' && i.zero?) || coupon.validity_per_user == 'forever'
|
||||
details[:without_coupon] = amount
|
||||
amount = cs.apply(amount, coupon)
|
||||
end
|
||||
end
|
||||
items.push PaymentScheduleItem.new(
|
||||
amount: amount,
|
||||
due_date: date,
|
||||
@ -43,13 +45,15 @@ class PaymentScheduleService
|
||||
details: details
|
||||
)
|
||||
end
|
||||
ps.total = items.map(&:amount).reduce(:+)
|
||||
{ payment_schedule: ps, items: items }
|
||||
end
|
||||
|
||||
def create(subscription, total, coupon: nil, operator: nil, payment_method: nil, reservation: nil, user: nil, setup_intent_id: nil)
|
||||
subscription = reservation.generate_subscription if !subscription && reservation.plan_id
|
||||
subscription = reservation.generate_subscription if !subscription && reservation&.plan_id
|
||||
raise InvalidSubscriptionError unless subscription&.persisted?
|
||||
|
||||
schedule = compute(subscription.plan, total, coupon)
|
||||
schedule = compute(subscription.plan, total, coupon: coupon, subscription: subscription)
|
||||
ps = schedule[:payment_schedule]
|
||||
items = schedule[:items]
|
||||
|
||||
@ -58,13 +62,178 @@ class PaymentScheduleService
|
||||
ps.stp_setup_intent_id = setup_intent_id
|
||||
ps.operator_profile = operator.invoicing_profile
|
||||
ps.invoicing_profile = user.invoicing_profile
|
||||
ps.save!
|
||||
ps.statistic_profile = user.statistic_profile
|
||||
ps.payment_schedule_items = items
|
||||
items.each do |item|
|
||||
item.payment_schedule = ps
|
||||
item.save!
|
||||
end
|
||||
|
||||
StripeService.create_stripe_subscription(ps.id, subscription, reservation&.reservable&.stp_product_id, setup_intent_id) if payment_method == 'stripe'
|
||||
ps
|
||||
end
|
||||
|
||||
##
|
||||
# Generate the invoice associated with the given PaymentScheduleItem, with the children elements (InvoiceItems).
|
||||
# @param stp_invoice is used to determine if the invoice was paid using stripe
|
||||
##
|
||||
def generate_invoice(payment_schedule_item, stp_invoice = nil)
|
||||
# build the base invoice
|
||||
invoice = Invoice.new(
|
||||
invoiced: payment_schedule_item.payment_schedule.scheduled,
|
||||
invoicing_profile: payment_schedule_item.payment_schedule.invoicing_profile,
|
||||
statistic_profile: payment_schedule_item.payment_schedule.statistic_profile,
|
||||
operator_profile_id: payment_schedule_item.payment_schedule.operator_profile_id,
|
||||
stp_payment_intent_id: stp_invoice&.payment_intent,
|
||||
payment_method: stp_invoice ? 'stripe' : nil
|
||||
)
|
||||
# complete the invoice with some InvoiceItem
|
||||
if payment_schedule_item.first?
|
||||
complete_first_invoice(payment_schedule_item, invoice)
|
||||
else
|
||||
complete_next_invoice(payment_schedule_item, invoice)
|
||||
end
|
||||
|
||||
# set the total and apply any coupon
|
||||
user = payment_schedule_item.payment_schedule.user
|
||||
coupon = payment_schedule_item.payment_schedule.coupon
|
||||
set_total_and_coupon(payment_schedule_item, invoice, user, coupon)
|
||||
|
||||
# save the results
|
||||
invoice.save
|
||||
payment_schedule_item.update_attributes(invoice_id: invoice.id)
|
||||
end
|
||||
|
||||
##
|
||||
# return a paginated list of PaymentSchedule, optionally filtered, with their associated PaymentScheduleItem
|
||||
# @param page {number} page number, used to paginate results
|
||||
# @param size {number} number of items per page
|
||||
# @param filters {Hash} allowed filters: reference, customer, date.
|
||||
##
|
||||
def self.list(page, size, filters = {})
|
||||
ps = PaymentSchedule.includes(:invoicing_profile, :payment_schedule_items, :subscription)
|
||||
.joins(:invoicing_profile)
|
||||
.order('payment_schedules.created_at DESC')
|
||||
.page(page)
|
||||
.per(size)
|
||||
|
||||
|
||||
unless filters[:reference].nil?
|
||||
ps = ps.where(
|
||||
'payment_schedules.reference LIKE :search',
|
||||
search: "#{filters[:reference]}%"
|
||||
)
|
||||
end
|
||||
unless filters[:customer].nil?
|
||||
# ILIKE => PostgreSQL case-insensitive LIKE
|
||||
ps = ps.where(
|
||||
'invoicing_profiles.first_name ILIKE :search OR invoicing_profiles.last_name ILIKE :search',
|
||||
search: "%#{filters[:customer]}%"
|
||||
)
|
||||
end
|
||||
unless filters[:date].nil?
|
||||
ps = ps.where(
|
||||
"date_trunc('day', payment_schedules.created_at) = :search OR date_trunc('day', payment_schedule_items.due_date) = :search",
|
||||
search: "%#{DateTime.iso8601(filters[:date]).to_time.to_date}%"
|
||||
)
|
||||
end
|
||||
|
||||
ps
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
##
|
||||
# The first PaymentScheduleItem contains references to the reservation price (if any) and to the adjustement price
|
||||
# for the subscription (if any)
|
||||
##
|
||||
def complete_first_invoice(payment_schedule_item, invoice)
|
||||
# sub-prices for the subscription and the reservation
|
||||
details = {
|
||||
subscription: payment_schedule_item.details['recurring'] + payment_schedule_item.details['adjustment']
|
||||
}
|
||||
|
||||
# the subscription and reservation items
|
||||
subscription = Subscription.find(payment_schedule_item.details['subscription_id'])
|
||||
if payment_schedule_item.payment_schedule.scheduled_type == Reservation.name
|
||||
details[:reservation] = payment_schedule_item.details['other_items']
|
||||
reservation = payment_schedule_item.payment_schedule.scheduled
|
||||
end
|
||||
|
||||
# build the invoice items
|
||||
generate_invoice_items(invoice, details, subscription: subscription, reservation: reservation)
|
||||
end
|
||||
|
||||
##
|
||||
# The later PaymentScheduleItems only contain references to the subscription (which is recurring)
|
||||
##
|
||||
def complete_next_invoice(payment_schedule_item, invoice)
|
||||
# the subscription item
|
||||
subscription = Subscription.find(payment_schedule_item.details['subscription_id'])
|
||||
|
||||
# sub-price for the subscription
|
||||
details = { subscription: payment_schedule_item.details['recurring'] }
|
||||
|
||||
# build the invoice item
|
||||
generate_invoice_items(invoice, details, subscription: subscription)
|
||||
end
|
||||
|
||||
##
|
||||
# Generate an array of InvoiceItem according to the provided parameters and saves them in invoice.invoice_items
|
||||
##
|
||||
def generate_invoice_items(invoice, payment_details, reservation: nil, subscription: nil)
|
||||
generate_reservation_item(invoice, reservation, payment_details) if reservation
|
||||
|
||||
return unless subscription
|
||||
|
||||
generate_subscription_item(invoice, subscription, payment_details)
|
||||
end
|
||||
|
||||
##
|
||||
# Generate a single InvoiceItem for the given reservation and save it in invoice.invoice_items.
|
||||
# This method must be called only with a valid reservation
|
||||
##
|
||||
def generate_reservation_item(invoice, reservation, payment_details)
|
||||
raise TypeError unless [Space, Machine, Training].include? reservation.reservable.class
|
||||
|
||||
description = "#{reservation.reservable.name}\n"
|
||||
reservation.slots.each do |slot|
|
||||
description += " #{I18n.l slot.start_at, format: :long} - #{I18n.l slot.end_at, format: :hour_minute}\n"
|
||||
end
|
||||
|
||||
invoice.invoice_items.push InvoiceItem.new(
|
||||
amount: payment_details[:reservation],
|
||||
description: description
|
||||
)
|
||||
end
|
||||
|
||||
##
|
||||
# Generate an InvoiceItem for the given subscription and save it in invoice.invoice_items.
|
||||
# This method must be called only with a valid subscription
|
||||
##
|
||||
def generate_subscription_item(invoice, subscription, payment_details)
|
||||
raise TypeError unless subscription
|
||||
|
||||
invoice.invoice_items.push InvoiceItem.new(
|
||||
amount: payment_details[:subscription],
|
||||
description: subscription.plan.name,
|
||||
subscription_id: subscription.id
|
||||
)
|
||||
end
|
||||
|
||||
##
|
||||
# Set the total price to the invoice, summing all sub-items.
|
||||
# Additionally a coupon may be applied to this invoice to make a discount on the total price
|
||||
##
|
||||
def set_total_and_coupon(payment_schedule_item, invoice, user, coupon = nil)
|
||||
return unless invoice
|
||||
|
||||
total = invoice.invoice_items.map(&:amount).map(&:to_i).reduce(:+)
|
||||
|
||||
unless coupon.nil?
|
||||
if (coupon.validity_per_user == 'once' && payment_schedule_item.first?) || coupon.validity_per_user == 'forever'
|
||||
total = CouponService.new.apply(total, coupon, user.id)
|
||||
invoice.coupon_id = coupon.id
|
||||
end
|
||||
end
|
||||
|
||||
invoice.total = total
|
||||
end
|
||||
end
|
||||
|
@ -25,15 +25,16 @@ class Reservations::Reserve
|
||||
operator_profile_id: operator_profile_id,
|
||||
user: user,
|
||||
payment_method: payment_method,
|
||||
coupon_code: payment_details[:coupon],
|
||||
coupon: payment_details[:coupon],
|
||||
setup_intent_id: intent_id)
|
||||
else
|
||||
generate_invoice(reservation, operator_profile_id, payment_details, intent_id)
|
||||
end
|
||||
payment.save
|
||||
reservation.save
|
||||
WalletService.debit_user_wallet(payment, user, reservation)
|
||||
reservation.save
|
||||
reservation.post_save
|
||||
payment.save
|
||||
payment.post_save(intent_id)
|
||||
end
|
||||
true
|
||||
end
|
||||
@ -43,10 +44,9 @@ class Reservations::Reserve
|
||||
##
|
||||
# Generate the invoice for the given reservation+subscription
|
||||
##
|
||||
def generate_schedule(reservation: nil, total: nil, operator_profile_id: nil, user: nil, payment_method: nil, coupon_code: nil,
|
||||
def generate_schedule(reservation: nil, total: nil, operator_profile_id: nil, user: nil, payment_method: nil, coupon: nil,
|
||||
setup_intent_id: nil)
|
||||
operator = InvoicingProfile.find(operator_profile_id)&.user
|
||||
coupon = Coupon.find_by(code: coupon_code) unless coupon_code.nil?
|
||||
|
||||
PaymentScheduleService.new.create(
|
||||
nil,
|
||||
|
@ -5,11 +5,23 @@ class StripeService
|
||||
class << self
|
||||
|
||||
# Create the provided PaymentSchedule on Stripe, using the Subscription API
|
||||
def create_stripe_subscription(payment_schedule_id, subscription, reservable_stp_id, setup_intent_id)
|
||||
def create_stripe_subscription(payment_schedule, setup_intent_id)
|
||||
stripe_key = Setting.get('stripe_secret_key')
|
||||
payment_schedule = PaymentSchedule.find(payment_schedule_id)
|
||||
first_item = payment_schedule.ordered_items.first
|
||||
|
||||
case payment_schedule.scheduled_type
|
||||
when Reservation.name
|
||||
subscription = payment_schedule.scheduled.subscription
|
||||
reservable_stp_id = payment_schedule.scheduled.reservable&.stp_product_id
|
||||
when Subscription.name
|
||||
subscription = payment_schedule.scheduled
|
||||
reservable_stp_id = nil
|
||||
else
|
||||
raise InvalidSubscriptionError
|
||||
end
|
||||
|
||||
handle_wallet_transaction(payment_schedule)
|
||||
|
||||
# setup intent (associates the customer and the payment method)
|
||||
intent = Stripe::SetupIntent.retrieve(setup_intent_id, api_key: stripe_key)
|
||||
# subscription (recurring price)
|
||||
@ -22,8 +34,8 @@ class StripeService
|
||||
stp_subscription = Stripe::Subscription.create({
|
||||
customer: payment_schedule.invoicing_profile.user.stp_customer_id,
|
||||
cancel_at: subscription.expiration_date.to_i,
|
||||
promotion_code: payment_schedule.coupon&.code,
|
||||
add_invoice_items: items,
|
||||
coupon: payment_schedule.coupon&.code,
|
||||
items: [
|
||||
{ price: price[:id] }
|
||||
],
|
||||
@ -32,6 +44,23 @@ class StripeService
|
||||
payment_schedule.update_attributes(stp_subscription_id: stp_subscription.id)
|
||||
end
|
||||
|
||||
def create_stripe_coupon(coupon_id)
|
||||
coupon = Coupon.find(coupon_id)
|
||||
stp_coupon = { id: coupon.code }
|
||||
if coupon.type == 'percent_off'
|
||||
stp_coupon[:percent_off] = coupon.percent_off
|
||||
elsif coupon.type == 'amount_off'
|
||||
stp_coupon[:amount_off] = coupon.amount_off
|
||||
stp_coupon[:currency] = Setting.get('stripe_currency')
|
||||
end
|
||||
|
||||
stp_coupon[:duration] = coupon.validity_per_user == 'always' ? 'forever' : 'once'
|
||||
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?
|
||||
|
||||
Stripe::Coupon.create(stp_coupon, api_key: Setting.get('stripe_secret_key'))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def subscription_invoice_items(payment_schedule, subscription, first_item, reservable_stp_id)
|
||||
@ -71,5 +100,12 @@ class StripeService
|
||||
|
||||
Stripe::Price.create(params, api_key: Setting.get('stripe_secret_key'))
|
||||
end
|
||||
|
||||
def handle_wallet_transaction(payment_schedule)
|
||||
return unless payment_schedule.wallet_amount
|
||||
|
||||
customer_id = payment_schedule.invoicing_profile.user.stp_customer_id
|
||||
Stripe::Customer.update(customer_id, { balance: -payment_schedule.wallet_amount }, { api_key: Setting.get('stripe_secret_key') })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -24,19 +24,22 @@ class Subscriptions::Subscribe
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
subscription.init_save
|
||||
raise InvalidSubscriptionError unless subscription&.persisted?
|
||||
|
||||
payment = if schedule
|
||||
generate_schedule(subscription: subscription,
|
||||
total: payment_details[:before_coupon],
|
||||
operator_profile_id: operator_profile_id,
|
||||
user: user,
|
||||
payment_method: payment_method,
|
||||
coupon_code: payment_details[:coupon],
|
||||
coupon: payment_details[:coupon],
|
||||
setup_intent_id: intent_id)
|
||||
else
|
||||
generate_invoice(subscription, operator_profile_id, payment_details, intent_id)
|
||||
end
|
||||
payment.save
|
||||
WalletService.debit_user_wallet(payment, user, subscription)
|
||||
payment.save
|
||||
payment.post_save(intent_id)
|
||||
end
|
||||
true
|
||||
end
|
||||
@ -74,10 +77,9 @@ class Subscriptions::Subscribe
|
||||
##
|
||||
# Generate the invoice for the given subscription
|
||||
##
|
||||
def generate_schedule(subscription: nil, total: nil, operator_profile_id: nil, user: nil, payment_method: nil, coupon_code: nil,
|
||||
def generate_schedule(subscription: nil, total: nil, operator_profile_id: nil, user: nil, payment_method: nil, coupon: nil,
|
||||
setup_intent_id: nil)
|
||||
operator = InvoicingProfile.find(operator_profile_id)&.user
|
||||
coupon = Coupon.find_by(code: coupon_code) unless coupon_code.nil?
|
||||
|
||||
PaymentScheduleService.new.create(
|
||||
subscription,
|
||||
|
@ -80,7 +80,11 @@ class WalletService
|
||||
# @param coupon {Coupon|String} Coupon object or code
|
||||
##
|
||||
def self.wallet_amount_debit(payment, user, coupon = nil)
|
||||
total = payment.total
|
||||
total = if payment.class == PaymentSchedule
|
||||
payment.payment_schedule_items.first.amount
|
||||
else
|
||||
payment.total
|
||||
end
|
||||
total = CouponService.new.apply(total, coupon, user.id) if coupon
|
||||
|
||||
wallet_amount = (user.wallet.amount * 100).to_i
|
||||
|
@ -1,4 +1,4 @@
|
||||
json.extract! coupon, :id, :name, :code, :type, :percent_off, :valid_until, :validity_per_user, :max_usages, :active, :created_at
|
||||
json.amount_off (coupon.amount_off / 100.00) unless coupon.amount_off.nil?
|
||||
json.usages coupon.invoices.count
|
||||
json.usages coupon.usages
|
||||
json.status coupon.status
|
@ -1,2 +1,4 @@
|
||||
json.extract! @coupon, :id, :code, :type, :percent_off
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.extract! @coupon, :id, :code, :type, :percent_off, :validity_per_user
|
||||
json.amount_off (@coupon.amount_off / 100.00) unless @coupon.amount_off.nil?
|
@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.title notification.notification_type
|
||||
json.description t('.schedule_deadline', DATE: I18n.l(notification.attached_object.due_date.to_date),
|
||||
REFERENCE: notification.attached_object.payment_schedule.reference)
|
@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.title notification.notification_type
|
||||
json.description t('.schedule_failed', DATE: I18n.l(notification.attached_object.due_date.to_date),
|
||||
REFERENCE: notification.attached_object.payment_schedule.reference)
|
@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.title notification.notification_type
|
||||
json.description t('.schedule_failed', DATE: I18n.l(notification.attached_object.due_date.to_date),
|
||||
REFERENCE: notification.attached_object.payment_schedule.reference)
|
@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.title notification.notification_type
|
||||
amount = notification.attached_object.total / 100.0
|
||||
json.description t('.your_schedule_is_ready_html',
|
||||
REFERENCE: notification.attached_object.reference,
|
||||
AMOUNT: number_to_currency(amount),
|
||||
SCHEDULE_ID: notification.attached_object.id)
|
||||
|
21
app/views/api/payment_schedules/list.json.jbuilder
Normal file
21
app/views/api/payment_schedules/list.json.jbuilder
Normal file
@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.array! @payment_schedules do |ps|
|
||||
json.extract! ps, :id, :reference, :created_at, :payment_method
|
||||
json.total ps.total / 100.00
|
||||
json.chained_footprint ps.check_footprint
|
||||
json.user do
|
||||
json.name ps.invoicing_profile.full_name
|
||||
end
|
||||
if ps.operator_profile
|
||||
json.operator do
|
||||
json.id ps.operator_profile.user_id
|
||||
json.extract! ps.operator_profile, :first_name, :last_name
|
||||
end
|
||||
end
|
||||
json.items ps.payment_schedule_items do |item|
|
||||
json.extract! item, :id, :due_date, :state, :invoice_id, :payment_method
|
||||
json.amount item.amount / 100.00
|
||||
json.client_secret item.payment_intent.client_secret if item.stp_invoice_id && item.state == 'requires_action'
|
||||
end
|
||||
end
|
@ -10,4 +10,10 @@ json.array!(@wallet_transactions) do |t|
|
||||
json.reference t.invoice.reference
|
||||
end
|
||||
end
|
||||
if t.payment_schedule
|
||||
json.payment_schedule do
|
||||
json.id t.payment_schedule.id
|
||||
json.reference t.payment_schedule.reference
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -0,0 +1,10 @@
|
||||
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||
|
||||
<p>
|
||||
<%= t('.body.remember',
|
||||
REFERENCE: @attached_object.payment_schedule.reference,
|
||||
AMOUNT: number_to_currency(@attached_object.amount),
|
||||
DATE: I18n.l @attached_object.due_date, format: :long) %>
|
||||
<%= t('.body.date') %>
|
||||
</p>
|
||||
<p><%= t('.body.confirm') %></p>
|
@ -0,0 +1,10 @@
|
||||
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||
|
||||
<p>
|
||||
<%= t('.body.remember',
|
||||
REFERENCE: @attached_object.payment_schedule.reference,
|
||||
AMOUNT: number_to_currency(@attached_object.amount),
|
||||
DATE: I18n.l @attached_object.due_date, format: :long) %>
|
||||
<%= t('.body.error') %>
|
||||
</p>
|
||||
<p><%= t('.body.action') %></p>
|
@ -1,4 +1,4 @@
|
||||
<%# this is a mail template of notifcation notify_admin_user_wallet_is_credited %>
|
||||
<%# this is a mail template of notification notify_admin_user_wallet_is_credited %>
|
||||
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||
<p>
|
||||
<%= t('.body.wallet_credit_html',
|
||||
|
@ -0,0 +1,10 @@
|
||||
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||
|
||||
<p>
|
||||
<%= t('.body.remember',
|
||||
REFERENCE: @attached_object.payment_schedule.reference,
|
||||
AMOUNT: number_to_currency(@attached_object.amount),
|
||||
DATE: I18n.l @attached_object.due_date, format: :long) %>
|
||||
<%= t('.body.error') %>
|
||||
</p>
|
||||
<p><%= t('.body.action') %></p>
|
@ -0,0 +1,20 @@
|
||||
<%= render 'notifications_mailer/shared/hello', recipient: @recipient %>
|
||||
|
||||
<p>
|
||||
<%= _t('.body.please_find_attached_html',
|
||||
{
|
||||
DATE: I18n.l(@attached_object.created_at.to_date),
|
||||
AMOUNT: number_to_currency(@attached_object.total / 100.0),
|
||||
TYPE: @attached_object.scheduled_type
|
||||
})
|
||||
# messageFormat
|
||||
%>
|
||||
</p>
|
||||
|
||||
<p><%= t('.body.schedule_in_your_dashboard_html',
|
||||
DASHBOARD: link_to(
|
||||
t('.body.your_dashboard'),
|
||||
"#{root_url}#!/dashboard/invoices"
|
||||
)
|
||||
) %>
|
||||
</p>
|
@ -1 +1,3 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.extract! machine, :id, :name, :slug, :disabled, :updated_at, :created_at
|
||||
|
3
app/views/open_api/v1/machines/create.json.jbuilder
Normal file
3
app/views/open_api/v1/machines/create.json.jbuilder
Normal file
@ -0,0 +1,3 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.partial! 'open_api/v1/machines/machine', machine: @machine
|
@ -1,3 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.machines @machines do |machine|
|
||||
json.partial! 'open_api/v1/machines/machine', machine: machine
|
||||
json.extract! machine, :description, :spec
|
||||
|
5
app/views/open_api/v1/machines/show.json.jbuilder
Normal file
5
app/views/open_api/v1/machines/show.json.jbuilder
Normal file
@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.partial! 'open_api/v1/machines/machine', machine: @machine
|
||||
json.extract! @machine, :description, :spec
|
||||
json.image URI.join(root_url, @machine.machine_image.attachment.url) if @machine.machine_image
|
3
app/views/open_api/v1/machines/update.json.jbuilder
Normal file
3
app/views/open_api/v1/machines/update.json.jbuilder
Normal file
@ -0,0 +1,3 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.partial! 'open_api/v1/machines/machine', machine: @machine
|
@ -6,19 +6,37 @@ class PaymentScheduleItemWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
def perform
|
||||
PaymentScheduleItem.where(due_date: [DateTime.current.at_beginning_of_day, DateTime.current.end_of_day], state: 'new').each do |psi|
|
||||
PaymentScheduleItem.where(state: 'new').where('due_date < ?', DateTime.current.end_of_day).each do |psi|
|
||||
# the following depends on the payment method (stripe/check)
|
||||
if psi.payment_schedule.payment_method == 'stripe'
|
||||
# TODO, if stripe:
|
||||
# - verify the payment was successful
|
||||
# - if not, alert the admins
|
||||
# - if succeeded, generate the invoice
|
||||
### Stripe
|
||||
stripe_key = Setting.get('stripe_secret_key')
|
||||
stp_suscription = Stripe::Subscription.retrieve(psi.payment_schedule.stp_subscription_id, api_key: stripe_key)
|
||||
stp_invoice = Stripe::Invoice.retrieve(stp_suscription.latest_invoice, api_key: stripe_key)
|
||||
if stp_invoice.status == 'paid'
|
||||
##### Stripe / Successfully paid
|
||||
PaymentScheduleService.new.generate_invoice(psi, stp_invoice)
|
||||
psi.update_attributes(state: 'paid', payment_method: 'stripe', stp_invoice_id: stp_invoice.id)
|
||||
elsif stp_suscription.status == 'past_due'
|
||||
##### Stripe / Payment error
|
||||
NotificationCenter.call type: 'notify_admin_payment_schedule_failed',
|
||||
receiver: User.admins_and_managers,
|
||||
attached_object: psi
|
||||
NotificationCenter.call type: 'notify_member_payment_schedule_failed',
|
||||
receiver: psi.payment_schedule.user,
|
||||
attached_object: psi
|
||||
stp_payment_intent = Stripe::PaymentIntent.retrieve(stp_invoice.payment_intent, api_key: stripe_key)
|
||||
psi.update_attributes(state: stp_payment_intent.status, stp_invoice_id: stp_invoice.id)
|
||||
else
|
||||
psi.update_attributes(state: 'error')
|
||||
end
|
||||
else
|
||||
# TODO, if check:
|
||||
# - alert the admins and the user that it is time to bank the check
|
||||
# - generate the invoice
|
||||
### Check
|
||||
NotificationCenter.call type: 'notify_admin_payment_schedule_check_deadline',
|
||||
receiver: User.admins_and_managers,
|
||||
attached_object: psi
|
||||
psi.update_attributes(state: 'pending')
|
||||
end
|
||||
# TODO, finally, in any cases, update the psi.state field according to the new status
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -8,13 +8,13 @@ class PaymentScheduleWorker
|
||||
def perform(payment_schedule_id)
|
||||
# generate a payment schedule document
|
||||
ps = PaymentSchedule.find(payment_schedule_id)
|
||||
pdf = ::PDF::PaymentSchedule.new(ps).render # TODO, create ::PDF::PaymentSchedule
|
||||
pdf = ::PDF::PaymentSchedule.new(ps).render
|
||||
|
||||
# save the file on the disk
|
||||
File.binwrite(ps.file, pdf)
|
||||
|
||||
# notify user, send schedule document by email
|
||||
NotificationCenter.call type: 'notify_user_when_invoice_ready', # TODO, create a more appropriate notification type
|
||||
NotificationCenter.call type: 'notify_user_when_payment_schedule_ready',
|
||||
receiver: ps.user,
|
||||
attached_object: ps
|
||||
end
|
||||
|
@ -21,28 +21,11 @@ class StripeWorker
|
||||
user.update_columns(stp_customer_id: customer.id)
|
||||
end
|
||||
|
||||
def create_stripe_coupon(coupon_id)
|
||||
coupon = Coupon.find(coupon_id)
|
||||
stp_coupon = {
|
||||
id: coupon.code,
|
||||
duration: coupon.validity_per_user
|
||||
}
|
||||
if coupon.type == 'percent_off'
|
||||
stp_coupon[:percent_off] = coupon.percent_off
|
||||
elsif coupon.type == 'amount_off'
|
||||
stp_coupon[:amount_off] = coupon.amount_off
|
||||
stp_coupon[:currency] = Setting.get('stripe_currency')
|
||||
end
|
||||
|
||||
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?
|
||||
|
||||
Stripe::Coupon.create(stp_coupon, api_key: Setting.get('stripe_secret_key'))
|
||||
end
|
||||
|
||||
def delete_stripe_coupon(coupon_code)
|
||||
cpn = Stripe::Coupon.retrieve(coupon_code, api_key: Setting.get('stripe_secret_key'))
|
||||
cpn.delete
|
||||
rescue Stripe::InvalidRequestError => e
|
||||
STDERR.puts "WARNING: Unable to delete the coupon on Stripe: #{e}"
|
||||
end
|
||||
|
||||
def create_or_update_stp_product(class_name, id)
|
||||
@ -66,5 +49,19 @@ class StripeWorker
|
||||
object.update_attributes(stp_product_id: product.id)
|
||||
puts "Stripe product was created for the #{class_name} \##{id}"
|
||||
end
|
||||
|
||||
rescue Stripe::InvalidRequestError
|
||||
STDERR.puts "WARNING: saved stp_product_id (#{object.stp_product_id}) does not match on Stripe, recreating..."
|
||||
product = Stripe::Product.create(
|
||||
{
|
||||
name: object.name,
|
||||
metadata: {
|
||||
id: object.id,
|
||||
type: class_name
|
||||
}
|
||||
}, { api_key: Setting.get('stripe_secret_key') }
|
||||
)
|
||||
object.update_attributes(stp_product_id: product.id)
|
||||
puts "Stripe product was created for the #{class_name} \##{id}"
|
||||
end
|
||||
end
|
||||
|
@ -42,11 +42,6 @@ module Fablab
|
||||
|
||||
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
||||
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
||||
#
|
||||
# /!\ ALL locales SHOULD be configured accordingly with this locale. /!\
|
||||
#
|
||||
config.i18n.default_locale = Rails.application.secrets.rails_locale
|
||||
config.i18n.fallbacks = [Rails.application.secrets.app_locale, :en]
|
||||
|
||||
config.to_prepare do
|
||||
Devise::Mailer.layout 'notifications_mailer'
|
||||
|
@ -5,3 +5,10 @@ I18n.config.available_locales += %i[en en-AU-CA en-GB en-IE en-IN en-NZ en-US en
|
||||
es-AR es-CL es-CO es-CR es-DO es-EC es-ES es-MX es-PA es-PE es-US es-VE pt pt-BR zu]
|
||||
# we allow the Zulu locale (zu) as it is used for In-Context translation
|
||||
# @see https://support.crowdin.com/in-context-localization/
|
||||
|
||||
|
||||
#
|
||||
# /!\ ALL locales SHOULD be configured accordingly with the default_locale. /!\
|
||||
#
|
||||
I18n.config.default_locale = Rails.application.secrets.rails_locale
|
||||
I18n.config.locale = Rails.application.secrets.rails_locale
|
||||
|
1441
config/locales/app.admin.de.yml
Normal file
1441
config/locales/app.admin.de.yml
Normal file
@ -0,0 +1,1441 @@
|
||||
de:
|
||||
app:
|
||||
admin:
|
||||
#add a new machine
|
||||
machines_new:
|
||||
declare_a_new_machine: "Neue Maschine angeben"
|
||||
watch_out_when_creating_a_new_machine_its_prices_are_initialized_at_0_for_all_subscriptions: "Achtung! Beim Erstellen einer neuen Maschine werden die Preise für alle Abonnements auf 0 initialisiert."
|
||||
consider_changing_them_before_creating_any_reservation_slot: "Denken Sie daran, sie zu ändern, bevor Sie einen Reservierungsplatz erstellen."
|
||||
#machine edition
|
||||
machines_edit:
|
||||
machine_edit: "Maschine bearbeiten"
|
||||
#manage the trainings & machines slots
|
||||
calendar:
|
||||
calendar_management: "Kalenderverwaltung"
|
||||
trainings: "Schulungen"
|
||||
machines: "Maschinen"
|
||||
spaces: "Räume"
|
||||
events: "Veranstaltungen"
|
||||
availabilities: "Verfügbarkeiten"
|
||||
availabilities_notice: "Export aller für Reservierungen verfügbaren Slots und ihrer Belegung in ein Excel-Arbeitsbuch."
|
||||
info: "Info"
|
||||
tags: "Tags"
|
||||
slot_duration: "Slot-Dauer: {DURATION} Minuten"
|
||||
ongoing_reservations: "Laufende Reservierungen"
|
||||
without_reservation: "Ohne Reservierung"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "Wollen Sie wirklich die Reservierung {RESERVATION} von {USER} am {DATE} um {TIME} stornieren?"
|
||||
reservation_was_successfully_cancelled: "Reservierung wurde erfolgreich storniert."
|
||||
reservation_cancellation_failed: "Stornierung der Reservierung fehlgeschlagen."
|
||||
unable_to_remove_the_last_machine_of_the_slot_delete_the_slot_rather: "Die letzte Maschine des Slots konnte nicht entfernt werden. Löschen Sie den Slot."
|
||||
do_you_really_want_to_remove_MACHINE_from_this_slot: "Wollen Sie {MACHINE} wirklich aus diesem Slot entfernen?"
|
||||
this_will_prevent_any_new_reservation_on_this_slot_but_wont_cancel_those_existing: "Dadurch wird jede neue Reservierung auf diesem Slot verhindert, aber die bestehenden werden nicht storniert."
|
||||
beware_this_cannot_be_reverted: "Vorsicht: Das kann nicht rückgängig gemacht werden."
|
||||
the_machine_was_successfully_removed_from_the_slot: "Die Maschine wurde erfolgreich aus dem Slot entfernt."
|
||||
deletion_failed: "Löschvorgang fehlgeschlagen."
|
||||
do_you_really_want_to_remove_PLAN_from_this_slot: "Wollen Sie {PLAN} wirklich aus diesem Slot entfernen?"
|
||||
the_plan_was_successfully_removed_from_the_slot: "Der Plan wurde erfolgreich aus dem Slot entfernt."
|
||||
DATE_slot: "{DATE} Slot:"
|
||||
what_kind_of_slot_do_you_want_to_create: "Was für einen Slot wollen Sie erstellen?"
|
||||
training: "Schulung"
|
||||
machine: "Maschine"
|
||||
space: "Raum"
|
||||
next: "Weiter >"
|
||||
previous: "< Zurück"
|
||||
select_some_machines: "Maschinen auswählen"
|
||||
select_all: "Alle"
|
||||
select_none: "Keine"
|
||||
manage_machines: "Klicken Sie hier, um Maschinen hinzuzufügen oder zu entfernen."
|
||||
manage_spaces: "Klicken Sie hier, um Räume hinzuzufügen oder zu entfernen."
|
||||
manage_trainings: "Klicke hier, um Schulungen hinzuzufügen oder zu entfernen."
|
||||
number_of_tickets: "Anzahl der Tickets: "
|
||||
adjust_the_opening_hours: "Öffnungszeiten anpassen"
|
||||
to_time: "bis" #eg. from 18:00 to 21:00
|
||||
restrict_options: "Einschränkungsoptionen"
|
||||
restrict_with_labels: "Diesen Slot mit Labels einschränken"
|
||||
restrict_for_subscriptions: "Diesen Slot auf Abonnenten einschränken"
|
||||
select_some_plans: "Wählen Sie einige Pläne"
|
||||
plans: "Plan/Pläne:"
|
||||
recurrence: "Wiederholung"
|
||||
enabled: "Aktiviert"
|
||||
period: "Zeitraum"
|
||||
week: "Woche"
|
||||
month: "Monat"
|
||||
number_of_periods: "Anzahl der Zeiträume"
|
||||
end_date: "Enddatum"
|
||||
summary: "Zusammenfassung"
|
||||
select_period: "Bitte wählen Sie einen Zeitraum für die Wiederholung"
|
||||
select_nb_period: "Bitte wählen Sie eine Anzahl von Zeiträumen für die Wiederholung"
|
||||
select_end_date: "Bitte wählen Sie das Datum des letzten Ereignisses"
|
||||
about_to_create: "Sie erstellen nun {TYPE, select, machines{Maschinen} training{Schulungs} space{Raum} other{andere}} {NUMBER, plural, one{Slot} other{Slots}}:"
|
||||
divided_in_slots: "{COUNT, plural, one {} =1{Dieser Slot wird} other{Diese Slots werden}} für die Buchung in {DURATION}-Minuten-Abschnitten verfügbar sein."
|
||||
reservable: "Reservierbar(e):"
|
||||
labels: "Label(s):"
|
||||
none: "Keine"
|
||||
slot_successfully_deleted: "Der Slot {START} - {END} wurde erfolgreich gelöscht"
|
||||
slots_deleted: "Der Slot beginnend mit {START}, und {COUNT, plural, =1{one other} ein weiterer Slot{{COUNT} weitere Slots}}} wurden gelöscht"
|
||||
unable_to_delete_the_slot: "Konnte den Slot {START} - {END} nicht löschen, wahrscheinlich weil er bereits von einem Mitglied reserviert ist"
|
||||
slots_not_deleted: "Von {TOTAL} Slots {COUNT, plural, one {} =1{wurde einer wurde nicht gelöscht} other{wurden {COUNT} nicht gelöscht}}. Möglicherweise {COUNT, plural, =1{ist er} other{sind sie}} bereits reserviert."
|
||||
you_should_select_at_least_a_machine: "Sie sollten mindestens eine Maschine auf diesem Slot auswählen."
|
||||
export_is_running_you_ll_be_notified_when_its_ready: "Export wird ausgeführt. Sie werden nach Fertigstellung benachrichtigt."
|
||||
actions: "Aktionen"
|
||||
block_reservations: "Reservierungen blockieren"
|
||||
do_you_really_want_to_block_this_slot: "Möchten Sie diesen Slot wirklich für neue Reservierungen sperren? Er wird dadurch für Benutzer unsichtbar."
|
||||
locking_success: "Slot erfolgreich gesperrt. Er wird nicht mehr im Benutzerkalender angezeigt"
|
||||
locking_failed: "Ein Fehler ist aufgetreten. Sperren des Slots fehlgeschlagen"
|
||||
allow_reservations: "Reservierungen erlauben"
|
||||
do_you_really_want_to_allow_reservations: "Wollen Sie wirklich diesen Slot wieder entsperren? Er wird dadurch für die Benutzer wieder sichtbar."
|
||||
unlocking_success: "Slot erfolgreich entsperrt, er wird wieder im Benutzerkalender angezeigt"
|
||||
unlocking_failed: "Ein Fehler ist aufgetreten. Entsperren des Slots fehlgeschlagen"
|
||||
reservations_locked: "Buchung ist gesperrt"
|
||||
unlockable_because_reservations: "Buchungen auf diesen Slot konnten nicht blockiert werden, da bereits Reservierungen auf ihn gebucht sind."
|
||||
delete_slot: "Diesen Slot löschen"
|
||||
do_you_really_want_to_delete_this_slot: "Möchten Sie diesen Slot wirklich löschen?"
|
||||
delete_recurring_slot: "Sie sind dabei, einen wiederkehrenden Slot zu löschen. Was möchten Sie tun?"
|
||||
delete_this_slot: "Nur diesen Slot"
|
||||
delete_this_and_next: "Diesen Slot und die folgenden"
|
||||
delete_all: "Alle Slots"
|
||||
event_in_the_past: "In der Vergangenheit kann kein Slot erstellt werden."
|
||||
edit_event: "Veranstaltung bearbeiten"
|
||||
view_reservations: "Reservierungen anzeigen"
|
||||
legend: "Legende"
|
||||
and: "und"
|
||||
external_sync: "Kalendersynchronisierung"
|
||||
divide_this_availability: "Diese Verfügbarkeit teilen in"
|
||||
slots: "Slots"
|
||||
slots_of: "von"
|
||||
minutes: "Minuten"
|
||||
#import external iCal calendar
|
||||
icalendar:
|
||||
icalendar_import: "iCalendar Import"
|
||||
intro: "Fab-manager erlaubt das automatische Importieren von Kalenderereignissen im RFC 5545 iCalendar Format aus einer externen URL. Diese URL wird stündlich synchronisiert und die Termine werden im öffentlichen Kalender angezeigt. Sie können auch eine Synchronisation auslösen, indem Sie auf den entsprechenden Button vor jedem Import klicken."
|
||||
new_import: "Neuer ICS-Import"
|
||||
color: "Farbe"
|
||||
text_color: "Textfarbe"
|
||||
url: "URL"
|
||||
name: "Name"
|
||||
example: "Beispiel"
|
||||
display: "Anzeigen"
|
||||
hide_text: "Text ausblenden"
|
||||
hidden: "Ausgeblendet"
|
||||
shown: "Angezeigt"
|
||||
create_error: "iCalendar Import konnte nicht erstellt werden. Bitte versuchen Sie es später erneut"
|
||||
delete_failed: "Der iCalendar Import konnte nicht gelöscht werden. Bitte versuchen Sie es später erneut"
|
||||
refresh: "Aktualisieren..."
|
||||
sync_failed: "Die URL konnte nicht synchronisiert werden. Bitte versuchen Sie es später erneut"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
confirm_delete_import: "Möchten Sie diesen iCalendar Import wirklich löschen?"
|
||||
delete_success: "iCalendar Import erfolgreich gelöscht"
|
||||
#management of the projects' components & settings
|
||||
projects:
|
||||
name: "Name"
|
||||
projects_settings: "Projekteinstellungen"
|
||||
materials: "Materialien"
|
||||
add_a_material: "Materialien hinfügen"
|
||||
themes: "Themen"
|
||||
add_a_new_theme: "Neues Thema hinzufügen"
|
||||
licences: "Lizenzen"
|
||||
description: "Beschreibung"
|
||||
add_a_new_licence: "Neue Lizenz hinzufügen"
|
||||
manage_abuses: "Berichte verwalten"
|
||||
settings:
|
||||
title: "Einstellungen"
|
||||
comments: "Kommentare"
|
||||
disqus: "Disqus"
|
||||
disqus_info: "Wenn Sie Ihren Mitgliedern und Besuchern die Möglichkeit geben möchten, Projekte zu kommentieren, können Sie die Disqus-Foren aktivieren, indem Sie den folgenden Parameter setzen. Besuchen Sie die <a href='https://help.disqus.com/customer/portal/articles/466208-what-s-a-shortname-' target='_blank'>Disqus-Website</a> für weitere Informationen."
|
||||
shortname: "Kurzname"
|
||||
cad_files: "CAD-Dateien"
|
||||
validation: "Validierung"
|
||||
validation_info: "Benutzer können CAD-Dateien (Computer Aided Design) mit der Dokumentation ihrer Projekte hochladen. Sie können festlegen, welche Dateitypen erlaubt sind. Verwenden Sie die Testeingabe unten, um den MIME-Typ einer Datei zu bestimmen."
|
||||
extensions: "Zulässige Dateiendungen"
|
||||
new_extension: "Neue Dateiendung"
|
||||
new_ext_info_html: "<p>Geben Sie eine neue Dateiendung an, um das Hochladen dieser Dateien zu ermöglichen.</p><p>Bitte beachten Sie, dass das Erlauben von Datei-Archiven (zB. ZIP) oder ausführbaren Programmen (z. EXE) zu einem <strong>gefährlichen Sicherheitsproblem</strong> führen kann und in jedem Fall vermieden werden muss.</p>"
|
||||
mime_types: "Erlaubte MIME-Typen"
|
||||
new_mime_type: "Neuer MIME-Typ"
|
||||
new_type_info_html: "<p>Geben Sie einen neuen MIME-Typen an, um das Hochladen dieser Dateien zu ermöglichen.</p><p>Bitte beachten Sie, dass das Erlauben von Datei-Archiven (z.B. application/zip) oder ausführbaren Programmen (z.B. application/exe) zu einem <strong>gefährlichen Sicherheitsproblem</strong> führen kann und in jedem Fall vermieden werden muss.</p>"
|
||||
test_file: "Datei testen"
|
||||
set_a_file: "Datei auswählen"
|
||||
file_is_TYPE: "Der MIME-Typ dieser Datei ist {TYPE}"
|
||||
projects_sharing: "Projekte teilen"
|
||||
open_lab_projects: "OpenLab Projekte"
|
||||
open_lab_info_html: "Aktivieren Sie OpenLab, um Ihre Projekte mit anderen Fab Labs zu teilen und eine Galerie gemeinsamer Projekte anzuzeigen. Bitte senden Sie eine E-Mail an <a href='mailto:contact@fab-manager.com'>contact@fab-manager.com</a>, um kostenlos Ihre Zugangsdaten zu erhalten."
|
||||
open_lab_app_id: "ID"
|
||||
open_lab_app_secret: "Geheimnis"
|
||||
openlab_default_info_html: "In der Projektgalerie können Besucher zwischen zwei Ansichten wechseln: alle gemeinsam geteilten Projekte des OpenLab-Netzwerkes oder nur die in Ihrem FabLab dokumentierten Projekte.<br/>Hier können Sie die standardmäßig angezeigte Ansicht auswählen."
|
||||
default_to_openlab: "OpenLab standardmäßig anzeigen"
|
||||
#track and monitor the trainings
|
||||
trainings:
|
||||
trainings_monitoring: "Schulungs-Überwachung"
|
||||
plan_session: "Neue Sitzung planen"
|
||||
trainings: "Schulungen"
|
||||
add_a_new_training: "Neue Schulung hinzufügen"
|
||||
name: "Name"
|
||||
associated_machines: "Verknüpfte Maschinen"
|
||||
number_of_tickets: "Anzahl der Tickets"
|
||||
select_a_training: "Schulung auswählen"
|
||||
training: "Schulung"
|
||||
date: "Datum"
|
||||
year_NUMBER: "Jahr {NUMBER}"
|
||||
month_of_NAME: "Monat von {NAME}"
|
||||
NUMBER_reservation: "{NUMBER} {NUMBER, plural, one{Reservierung} other{Reservierungen}}"
|
||||
none: "Keine"
|
||||
training_validation: "Schulungs-Validierung"
|
||||
training_of_the_DATE_TIME_html: "Schulung vom <strong>{DATE} - {TIME}</strong>"
|
||||
you_can_validate_the_training_of_the_following_members: "Sie können die Schulung der folgenden Mitglieder validieren:"
|
||||
deleted_user: "Gelöschter Nutzer"
|
||||
no_reservation: "Keine Reservierung"
|
||||
validate_the_trainings: "Schulungen validieren"
|
||||
edition_of_the_description_tooltip: "Bearbeitung des Beschreibungs-Tooltips"
|
||||
describe_the_training_in_a_few_words: "Beschreiben Sie die Schulung in wenigen Worten."
|
||||
description_is_limited_to_255_characters: "Die Beschreibung ist auf 255 Zeichen beschränkt."
|
||||
description_was_successfully_saved: "Beschreibung wurde erfolgreich gespeichert."
|
||||
training_successfully_deleted: "Schulung erfolgreich gelöscht."
|
||||
unable_to_delete_the_training_because_some_users_already_booked_it: "Die Schulung konnte nicht gelöscht werden, da sie bereits von einigen Nutzern gebucht wurde."
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_delete_this_training: "Möchten Sie diese Schulung wirklich löschen?"
|
||||
status_enabled: "Aktiviert"
|
||||
status_disabled: "Deaktiviert"
|
||||
status_all: "Alle"
|
||||
#create a new training
|
||||
trainings_new:
|
||||
add_a_new_training: "Neue Schulung hinzufügen"
|
||||
beware_when_creating_a_training_its_reservation_prices_are_initialized_to_zero: "Vorsicht bei der Erstellung eines Trainings, die Reservierungspreise stehen auf Null."
|
||||
dont_forget_to_change_them_before_creating_slots_for_this_training: "Vergesse nicht, sie anzupassen, bevor du das Training aktivierst."
|
||||
#events tracking and management
|
||||
events:
|
||||
events_monitoring: "Ereignisüberwachung"
|
||||
manage_filters: "Filter verwalten"
|
||||
fablab_events: "Fablab-Veranstaltungen"
|
||||
add_an_event: "Veranstaltung hinzufügen"
|
||||
all_events: "Alle Veranstaltungen"
|
||||
passed_events: "Vergangene Veranstaltungen"
|
||||
events_to_come: "Zukünftige Veranstaltungen"
|
||||
events_to_come_asc: "Zukünftige Veranstaltungen | chronologische Reihenfolge"
|
||||
on_DATE: "am {DATE}"
|
||||
from_DATE: "von {DATE}"
|
||||
from_TIME: "ab {TIME}"
|
||||
to_date: "bis" #eg: from 01/01 to 01/05
|
||||
to_time: "bis" #eg. from 18:00 to 21:00
|
||||
title: "Titel"
|
||||
dates: "Datum"
|
||||
booking: "Buchung"
|
||||
sold_out: "Ausverkauft"
|
||||
cancelled: "Storniert"
|
||||
without_reservation: "Ohne Reservierung"
|
||||
free_admission: "Freier Eintritt"
|
||||
view_reservations: "Reservierungen anzeigen"
|
||||
load_the_next_events: "Die nächsten Veranstaltungen laden..."
|
||||
categories: "Kategorien"
|
||||
add_a_category: "Kategorie hinzufügen"
|
||||
name: "Name"
|
||||
themes: "Thema"
|
||||
add_a_theme: "Thema hinzufügen"
|
||||
age_ranges: "Altersklassen"
|
||||
add_a_range: "Neue Spanne hinzufügen"
|
||||
do_you_really_want_to_delete_this_ELEMENT: "Wollen Sie {ELEMENT, select, category{die Kategorie} theme{das Thema} age_range{die Altersklasse} other{Element}} wirklich löschen?"
|
||||
unable_to_delete_ELEMENT_already_in_use_NUMBER_times: "{ELEMENT, select, category{Die Kategorie} theme{Das Thema} age_range{Die Altersklasse} other{Element}} kann nicht gelöscht werden, weil bereits eine Verbindung mit {NUMBER, plural, =0{keinem Ereignis} one{einem Ereignis} other{{NUMBER} Ereignissen}} besteht."
|
||||
at_least_one_category_is_required: "Mindestens eine Kategorie ist erforderlich."
|
||||
unable_to_delete_the_last_one: "Letzte Veranstaltung konnte nicht gelöscht werden."
|
||||
unable_to_delete_an_error_occured: "Löschen fehlgeschlagen: Ein Fehler ist aufgetreten."
|
||||
manage_prices_categories: "Preiskategorien verwalten"
|
||||
prices_categories: "Preiskategorien"
|
||||
add_a_price_category: "Preiskategorie hinzufügen"
|
||||
usages_count: "Anzahl der Nutzungen"
|
||||
price_category: "Preiskategorie"
|
||||
category_name: "Name der Kategorie"
|
||||
category_name_is_required: "Der Name der Kategorie ist erforderlich."
|
||||
enter_here_the_conditions_under_which_this_price_is_applicable: "Geben Sie hier die Bedingungen ein, unter denen dieser Preis anwendbar ist"
|
||||
conditions_are_required: "Bedingungen sind erforderlich."
|
||||
price_category_successfully_created: "Preiskategorie erfolgreich erstellt."
|
||||
unable_to_add_the_price_category_check_name_already_used: "Preiskategorie konnte nicht hinzugefügt werden. Überprüfen Sie, ob der Name nicht bereits verwendet wird."
|
||||
unexpected_error_occurred_please_refresh: "Ein unerwarteter Fehler ist aufgetreten, bitte aktualisieren Sie die Seite."
|
||||
price_category_successfully_updated: "Preiskategorie erfolgreich aktualisiert."
|
||||
unable_to_update_the_price_category: "Preiskategorie konnte nicht aktualisiert werden."
|
||||
unable_to_delete_this_price_category_because_it_is_already_used: "Diese Preiskategorie kann nicht gelöscht werden, da sie bereits verwendet wird."
|
||||
do_you_really_want_to_delete_this_price_category: "Möchten Sie diese Preiskategorie wirklich löschen?"
|
||||
price_category_successfully_deleted: "Preiskategorie erfolgreich gelöscht."
|
||||
price_category_deletion_failed: "Löschen der Preiskategorie fehlgeschlagen."
|
||||
#add a new event
|
||||
events_new:
|
||||
add_an_event: "Veranstaltung hinzufügen"
|
||||
none: "Keine"
|
||||
every_days: "Täglich"
|
||||
every_week: "Wöchentlich"
|
||||
every_month: "Monatlich"
|
||||
every_year: "Jährlich"
|
||||
#edit an existing event
|
||||
events_edit:
|
||||
edit_the_event: "Veranstaltung bearbeiten"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
edit_recurring_event: "Sie bearbeiten eine wiederkehrende Veranstaltung. Was möchten Sie ändern?"
|
||||
edit_this_event: "Nur diese Veranstaltung"
|
||||
edit_this_and_next: "Diese und die nächste Veranstaltung"
|
||||
edit_all: "Alle Veranstaltungen"
|
||||
date_wont_change: "Warnung: Sie haben das Veranstaltungsdatum geändert. Diese Änderung wird nicht für die weiteren Termine der wiederkehrenden Veranstaltung übernommen."
|
||||
event_successfully_updated: "Veranstaltung erfolgreich aktualisiert."
|
||||
events_updated: "Die Veranstaltung sowie {COUNT, plural, one {} =1{eine weitere} other{{COUNT} weitere}} wurden aktualisiert"
|
||||
unable_to_update_the_event: "Veranstaltung konnte nicht aktualisiert werden"
|
||||
events_not_updated: "Von {TOTAL} Veranstaltungen {COUNT, plural, one {} =1{ wurde eine nicht aktualisiert} other{wurden {COUNT} nicht gelöscht}}."
|
||||
error_deleting_reserved_price: "Der angeforderte Preis konnte nicht gelöscht werden, da er mit einigen Reservierungen verknüpft ist"
|
||||
other_error: "Beim Aktualisieren der Veranstaltung ist ein unerwarteter Fehler aufgetreten"
|
||||
#event reservations list
|
||||
event_reservations:
|
||||
the_reservations: "Reservierungen:"
|
||||
user: "Nutzer"
|
||||
payment_date: "Zahlungsdatum"
|
||||
full_price_: "Voller Preis:"
|
||||
reserved_tickets: "Reservierte Tickets"
|
||||
show_the_event: "Veranstaltung anzeigen"
|
||||
no_reservations_for_now: "Momentan keine Reservierung."
|
||||
back_to_monitoring: "Zurück zur Überwachung"
|
||||
canceled: "Storniert"
|
||||
#subscriptions, prices, credits and coupons management
|
||||
pricing:
|
||||
pricing_management: "Preisverwaltung"
|
||||
subscriptions: "Abonnements"
|
||||
trainings: "Schulungen"
|
||||
list_of_the_subscription_plans: "Liste der Abonnement-Pläne"
|
||||
disabled_plans_info_html: "<p><strong>Warnung:</strong> die Abonnements sind in dieser Anwendung deaktiviert.</p><p>Sie können Abonnements erstellen, aber sie werden erst mit der Aktivierung des Planungsmoduls im Abschnitt « Anpassen » verfügbar.</p>"
|
||||
add_a_new_subscription_plan: "Neues Abonnement hinzufügen"
|
||||
type: "Typ"
|
||||
partner: "Partner"
|
||||
standard: "Standard"
|
||||
name: "Name"
|
||||
duration: "Dauer"
|
||||
group: "Gruppe"
|
||||
prominence: "Hervorhebung"
|
||||
price: "Preis"
|
||||
machine_hours: "Maschinen-Slots"
|
||||
these_prices_match_machine_hours_rates_html: "Die unten aufgeführten Preise entsprechen einer Stunde Maschinengebrauch, <strong>ohne Abonnement</strong>."
|
||||
prices_calculated_on_hourly_rate_html: "Alle Preise werden automatisch nach dem hier definierten Stundensatz berechnet.<br/><em>Zum Beispiel</em> wird bei einem veranschlagten Stundensatz von {RATE} ein Slot von {DURATION} Minuten (Standard) zum Preis von <strong>{PRICE}</strong> berechnet."
|
||||
you_can_override: "Sie können diese Dauer für jede Verfügbarkeit überschreiben, die Sie in der Agenda erstellen. Der Preis wird dann entsprechend angepasst."
|
||||
machines: "Maschinen"
|
||||
credits: "Gutschriften"
|
||||
subscription: "Abonnement"
|
||||
related_trainings: "Zugehörige Schulungen"
|
||||
add_a_machine_credit: "Guthaben für die Maschine hinzufügen"
|
||||
machine: "Maschine"
|
||||
hours: "Slots (Standard {DURATION} Minuten)"
|
||||
related_subscriptions: "Zugehörige Abonnements"
|
||||
please_specify_a_number: "Bitte geben Sie eine Zahl an."
|
||||
none: "Keine" #grammar concordance with training.
|
||||
an_error_occurred_while_saving_the_number_of_credits: "Beim Speichern der Guthabenmenge ist ein Fehler aufgetreten."
|
||||
an_error_occurred_while_deleting_credit_with_the_TRAINING: "Beim Löschen des Guthabens mit {TRAINING} ist ein Fehler aufgetreten."
|
||||
an_error_occurred_unable_to_find_the_credit_to_revoke: "Ein Fehler ist aufgetreten: Das Guthaben konnte nicht gefunden werden."
|
||||
an_error_occurred_while_creating_credit_with_the_TRAINING: "Beim Erstellen des Guthabens mit {TRAINING} ist ein Fehler aufgetreten."
|
||||
not_set: "Nicht festgelegt"
|
||||
error_a_credit_linking_this_machine_with_that_subscription_already_exists: "Fehler: Ein Guthaben, das diese Maschine mit diesem Abonnement verbindet, existiert bereits."
|
||||
changes_have_been_successfully_saved: "Ihre Änderungen wurden erfolgreich gespeichert."
|
||||
credit_was_successfully_saved: "Guthaben wurde erfolgreich gespeichert."
|
||||
error_creating_credit: "Konnte Guthaben nicht erstellen, ein Fehler ist aufgetreten"
|
||||
do_you_really_want_to_delete_this_subscription_plan: "Möchten Sie diesen Abonnementplan wirklich löschen?"
|
||||
subscription_plan_was_successfully_deleted: "Abonnementplan wurde erfolgreich gelöscht."
|
||||
unable_to_delete_the_specified_subscription_an_error_occurred: "Das angegebene Abonnement konnte nicht gelöscht werden, ein Fehler ist aufgetreten."
|
||||
coupons: "Gutscheine"
|
||||
list_of_the_coupons: "Liste der Gutscheine"
|
||||
discount: "Rabatt"
|
||||
nb_of_usages: "Anzahl von Nutzungen"
|
||||
status: "Status"
|
||||
add_a_new_coupon: "Neuen Gutschein hinzufügen"
|
||||
display_more_coupons: "Die nächsten Gutscheine anzeigen"
|
||||
disabled: "Deaktiviert"
|
||||
expired: "Abgelaufen"
|
||||
sold_out: "Ausverkauft"
|
||||
active: "Aktiv"
|
||||
all: "Alle anzeigen"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_delete_this_coupon: "Möchten Sie diesen Gutschein wirklich löschen?"
|
||||
coupon_was_successfully_deleted: "Gutschein wurde erfolgreich gelöscht."
|
||||
unable_to_delete_the_specified_coupon_already_in_use: "Der angegebene Gutschein konnte nicht gelöscht werden: Er wird bereits bei einigen Rechnungen verwendet."
|
||||
unable_to_delete_the_specified_coupon_an_unexpected_error_occurred: "Der angegebene Gutschein konnte nicht gelöscht werden: Ein unerwarteter Fehler ist aufgetreten."
|
||||
send_a_coupon: "Gutschein senden"
|
||||
coupon: "Gutschein"
|
||||
usages: "Verwendungen"
|
||||
unlimited: "Unbegrenzt"
|
||||
coupon_successfully_sent_to_USER: "Gutschein erfolgreich an {USER} gesendet"
|
||||
an_error_occurred_unable_to_send_the_coupon: "Ein unerwarteter Fehler hat verhindert, dass der Gutschein gesendet wird."
|
||||
code: "Code"
|
||||
enabled: "Aktiviert"
|
||||
validity_per_user: "Gültigkeit pro Benutzer"
|
||||
once: "Nur einmal"
|
||||
forever: "Jede Nutzung"
|
||||
valid_until: "Gültig bis (inklusive)"
|
||||
spaces: "Räume"
|
||||
these_prices_match_space_hours_rates_html: "Die unten aufgeführten Preise entsprechen einer Stunde Raumbelegung <strong>ohne Abonnement</strong>."
|
||||
add_a_space_credit: "Guthaben für Raum hinzufügen"
|
||||
space: "Raum"
|
||||
error_a_credit_linking_this_space_with_that_subscription_already_exists: "Fehler: Ein Guthaben, das diesen Raum mit diesem Abonnement verbindet, existiert bereits."
|
||||
status_enabled: "Aktiviert"
|
||||
status_disabled: "Deaktiviert"
|
||||
status_all: "Alle"
|
||||
#ajouter un code promotionnel
|
||||
coupons_new:
|
||||
add_a_coupon: "Gutschein hinzufügen"
|
||||
unable_to_create_the_coupon_check_code_already_used: "Der Gutschein konnte nicht erstellt werden. Bitte überprüfen Sie, ob der Code nicht bereits verwendet wird."
|
||||
#mettre à jour un code promotionnel
|
||||
coupons_edit:
|
||||
coupon: "Gutschein:"
|
||||
unable_to_update_the_coupon_an_error_occurred: "Gutschein konnte nicht aktualisiert werden: Ein Fehler ist aufgetreten."
|
||||
plans:
|
||||
#add a subscription plan on the platform
|
||||
new:
|
||||
add_a_subscription_plan: "Abonnement hinzufügen"
|
||||
unable_to_create_the_subscription_please_try_again: "Das Abonnement konnte nicht erstellt werden. Bitte versuchen Sie es erneut."
|
||||
successfully_created_subscriptions_dont_forget_to_redefine_prices: "Abonnement(s) erfolgreich erstellt. Vergessen Sie nicht, die Preise neu zu definieren."
|
||||
unable_to_save_this_user_check_that_there_isnt_an_already_a_user_with_the_same_name: "Der Benutzer konnte nicht gespeichert werden. Überprüfen Sie, ob nicht bereits ein Benutzer mit diesem Namen vorhanden ist."
|
||||
#edit a subscription plan / machine slots prices
|
||||
edit:
|
||||
subscription_plan: "Abonnementplan:"
|
||||
prices: "Preise"
|
||||
copy_prices_from: "Preise kopieren von"
|
||||
machines: "Maschinen"
|
||||
machine: "Maschine"
|
||||
hourly_rate: "Stundensatz"
|
||||
spaces: "Räume"
|
||||
space: "Raum"
|
||||
unable_to_save_subscription_changes_please_try_again: "Abonnementänderungen konnten nicht gespeichert werden. Bitte versuchen Sie es erneut."
|
||||
subscription_successfully_changed: "Abonnement erfolgreich geändert."
|
||||
#list of all invoices & invoicing parameters
|
||||
invoices:
|
||||
invoices: "Rechnungen"
|
||||
accounting_periods: "Abrechnungszeiträume"
|
||||
invoices_list: "Rechnungsliste"
|
||||
filter_invoices: "Rechnungen filtern"
|
||||
operator_: "Betreiber:"
|
||||
invoice_num_: "Rechnung Nr:"
|
||||
customer_: "Kunde:"
|
||||
date_: "Datum:"
|
||||
invoice_num: "Rechnung Nr"
|
||||
date: "Datum"
|
||||
price: "Preis"
|
||||
customer: "Kunde"
|
||||
download_the_invoice: "Rechnung herunterladen"
|
||||
download_the_credit_note: "Gutschrift herunterladen"
|
||||
credit_note: "Gutschrift"
|
||||
display_more_invoices: "Weitere Rechnungen anzeigen..."
|
||||
no_invoices_for_now: "Momentan keine Rechnungen."
|
||||
invoicing_settings: "Rechnungs-Einstellungen"
|
||||
warning_invoices_disabled: "Warnung: Rechnungen sind nicht aktiviert. Es werden keine Rechnungen von Fab-Manager generiert. Trotzdem müssen Sie die unten angegebenen Informationen korrekt ausfüllen, insbesondere die Mehrwertsteuer."
|
||||
change_logo: "Logo ändern"
|
||||
john_smith: "Max Mustermann"
|
||||
john_smith_at_example_com: "max.mustermann@example.com"
|
||||
invoice_reference_: "Rechnungsbezug:"
|
||||
code_: "Code:"
|
||||
code_disabled: "Code deaktiviert"
|
||||
order_num: "Bestellung #:"
|
||||
invoice_issued_on_DATE_at_TIME: "Rechnung am {DATE} am {TIME} ausgestellt"
|
||||
object_reservation_of_john_smith_on_DATE_at_TIME: "Betreff: Reservierung von Max Mustermann am {DATE} um {TIME}"
|
||||
order_summary: "Bestellungsübersicht:"
|
||||
details: "Details"
|
||||
amount: "Betrag"
|
||||
machine_booking-3D_printer: "Maschinen-Buchung - 3D-Drucker"
|
||||
total_amount: "Gesamtbetrag"
|
||||
total_including_all_taxes: "Gesamtpreis inkl. Steuern"
|
||||
VAT_disabled: "MwSt. deaktiviert"
|
||||
VAT_enabled: "MwSt. aktiviert"
|
||||
including_VAT: "Inklusive MwSt."
|
||||
including_total_excluding_taxes: "Gesamtbetrag zzgl. Steuern"
|
||||
including_amount_payed_on_ordering: "Inklusive bei Bestellung bezahlter Betrag"
|
||||
settlement_by_debit_card_on_DATE_at_TIME_for_an_amount_of_AMOUNT: "Begleichung mit Debitkarte am {DATE} um {TIME}, über den Betrag von {AMOUNT}"
|
||||
important_notes: "Wichtige Hinweise"
|
||||
address_and_legal_information: "Adresse und rechtliche Informationen"
|
||||
invoice_reference: "Rechnungsbezug"
|
||||
year: "Jahr"
|
||||
month: "Monat"
|
||||
day: "Tag"
|
||||
num_of_invoice: "Rechnungsnummer"
|
||||
online_sales: "Online-Verkäufe"
|
||||
wallet: "Guthabenkonto"
|
||||
refund: "Erstattung"
|
||||
model: "Modell"
|
||||
documentation: "Dokumentation"
|
||||
2_digits_year: "Jahr (zwei Ziffern, z.B. 75)"
|
||||
4_digits_year: "Jahr (vier Ziffern, z.B. 1975)"
|
||||
month_number: "Monatsnummer (z.B. 1)"
|
||||
2_digits_month_number: "Monatsnummer (zwei Ziffern, z.B. 01)"
|
||||
3_characters_month_name: "Monatsname (3 Zeichen, z. B. JAN)"
|
||||
day_in_the_month: "Tag des Monats (z.B. 1)"
|
||||
2_digits_day_in_the_month: "Tag des Monats (2 Ziffern, z.B. 01)"
|
||||
n_digits_daily_count_of_invoices: "(n) Ziffern, tägliche Anzahl von Rechnungen (z. B. ddd => 002 : 2. Rechnung des Tages)"
|
||||
n_digits_monthly_count_of_invoices: "(n) Ziffern, monatliche Anzahl von Rechnungen (z.B. mmmm => 0012 : 12. Rechnung des Monats)"
|
||||
n_digits_annual_amount_of_invoices: "(n) Ziffern, jährliche Anzahl von Rechnungen (z.B. yyyyy => 000012 : 12. Rechnung des Monats)"
|
||||
beware_if_the_number_exceed_the_specified_length_it_will_be_truncated_by_the_left: "Achtung: Wenn die Zahl die angegebene Länge überschreitet, wird sie von links abgeschnitten."
|
||||
n_digits_count_of_orders: "(n) Ziffern, Anzahl der Bestellungen (z.B. nnnn => 0327 : 327. Bestellung)"
|
||||
n_digits_daily_count_of_orders: "(n) Ziffern, tägliche Anzahl von Bestellungen (z. B. ddd => 002 : 2. Bestellung des Tages)"
|
||||
n_digits_monthly_count_of_orders: "(n) Ziffern, monatliche Anzahl von Bestellungen (z. B. mmmm => 0012 : 12. Bestellung des Monats)"
|
||||
n_digits_annual_amount_of_orders: "(n) Ziffern, jährliche Anzahl von Bestellungen (z.B. yyyyy => 00012 : 12. Bestellung des Jahres"
|
||||
add_a_notice_regarding_the_online_sales_only_if_the_invoice_is_concerned: "Fügen Sie nur dann eine Mitteilung zu den Online-Verkäufen hinzu, wenn die Rechnung betroffen ist."
|
||||
this_will_never_be_added_when_a_refund_notice_is_present: "Dies wird nie hinzugefügt, wenn eine Rückerstattung vorhanden ist."
|
||||
eg_XVL_will_add_VL_to_the_invoices_settled_with_stripe: '(z.B. fügt W[/VL] jenen Rechnungen "/VL" hinzu, die mit Stripe bezahlt werden)'
|
||||
add_a_notice_regarding_refunds_only_if_the_invoice_is_concerned: "Fügen Sie nur dann eine Mitteilung zu Erstattungen hinzu, wenn die Rechnung betroffen ist."
|
||||
this_will_never_be_added_when_an_online_sales_notice_is_present: "Dies wird nie hinzugefügt, wenn eine Online-Verkaufsmitteilung vorhanden ist."
|
||||
eg_RA_will_add_A_to_the_refund_invoices: '(z.B. fügt R[/A] den Rückerstattungsrechnungen "/A" hinzu)'
|
||||
add_a_notice_regarding_the_wallet_only_if_the_invoice_is_concerned: "Fügen Sie eine Mitteilung zum Guthaben nur dann hinzu, wenn die Rechnung betroffen ist."
|
||||
eg_WPM_will_add_PM_to_the_invoices_settled_with_wallet: '(z.B. fügt W[/PM] jenen Rechnungen "/PM" hinzu, die mit Guthaben bezahlt werden)'
|
||||
code: "Code"
|
||||
enable_the_code: "Code aktivieren"
|
||||
enabled: "Aktiviert"
|
||||
disabled: "Deaktiviert"
|
||||
order_number: "Bestellnummer"
|
||||
elements: "Elemente"
|
||||
VAT: "Mwst."
|
||||
enable_VAT: "MwSt. aktivieren"
|
||||
VAT_rate: "MwSt.-Satz"
|
||||
VAT_history: "MwSt.-Sätze Historie"
|
||||
changed_at: "Geändert am"
|
||||
changed_by: "Von"
|
||||
deleted_user: "Gelöschter Nutzer"
|
||||
refund_invoice_successfully_created: "Rückerstattungsrechnung erfolgreich erstellt."
|
||||
create_a_refund_on_this_invoice: "Erstelle eine Rückerstattung mit dieser Rechnung"
|
||||
creation_date_for_the_refund: "Erstellungsdatum für die Erstattung"
|
||||
creation_date_is_required: "Erstellungsdatum ist erforderlich."
|
||||
refund_mode: "Erstattungsmodus:"
|
||||
do_you_want_to_disable_the_user_s_subscription: "Möchten Sie das Abonnement des Benutzers deaktivieren:"
|
||||
elements_to_refund: "Erstattungselemente"
|
||||
description: "Beschreibung"
|
||||
description_optional: "Beschreibung (optional):"
|
||||
will_appear_on_the_refund_invoice: "Wird auf der Rückerstattungsrechnung angezeigt."
|
||||
none: "Keine" #grammar concordance with payment mean
|
||||
by_cash: "In bar"
|
||||
by_cheque: "Per Scheck"
|
||||
by_transfer: "Per Banküberweisung"
|
||||
by_wallet: "Durch Guthaben"
|
||||
you_must_select_at_least_one_element_to_create_a_refund: "Sie müssen mindestens ein Element auswählen, um eine Rückerstattung zu erstellen."
|
||||
unable_to_create_the_refund: "Erstattung kann nicht erstellt werden"
|
||||
invoice_reference_successfully_saved: "Rechnungsreferenz erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_invoice_reference: "Beim Speichern der Rechnungsreferenz ist ein Fehler aufgetreten."
|
||||
invoicing_code_succesfully_saved: "Rechnungscode erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_the_invoicing_code: "Beim Speichern des Rechnungscodes ist ein Fehler aufgetreten."
|
||||
code_successfully_activated: "Code erfolgreich aktiviert."
|
||||
code_successfully_disabled: "Code erfolgreich deaktiviert."
|
||||
an_error_occurred_while_activating_the_invoicing_code: "Beim Aktivieren des Rechnungscodes ist ein Fehler aufgetreten."
|
||||
order_number_successfully_saved: "Bestellnummer erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_the_order_number: "Beim Speichern der Bestellnummer ist ein Fehler aufgetreten."
|
||||
VAT_rate_successfully_saved: "MwSt.-Satz erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_the_VAT_rate: "Beim Speichern des Mehrwertsteuersatzes ist ein Fehler aufgetreten."
|
||||
VAT_successfully_activated: "MwSt. erfolgreich aktiviert."
|
||||
VAT_successfully_disabled: "MwSt. erfolgreich deaktiviert."
|
||||
an_error_occurred_while_activating_the_VAT: "Beim Aktivieren der Mehrwertsteuer ist ein Fehler aufgetreten."
|
||||
text_successfully_saved: "Text erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_the_text: "Beim Speichern des Textes ist ein Fehler aufgetreten."
|
||||
address_and_legal_information_successfully_saved: "Adresse und rechtliche Informationen erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_the_address_and_the_legal_information: "Beim Speichern der Adresse und der rechtlichen Informationen ist ein Fehler aufgetreten."
|
||||
logo_successfully_saved: "Logo erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_the_logo: "Beim Speichern des Logos ist ein Fehler aufgetreten."
|
||||
filename: "Dateiname"
|
||||
prefix_info: "Die Rechnungen werden als PDF-Dateien generiert, die mit dem folgenden Präfix benannt sind."
|
||||
prefix: "Präfix"
|
||||
prefix_successfully_saved: "Dateipräfix erfolgreich gespeichert"
|
||||
an_error_occurred_while_saving_the_prefix: "Beim Speichern des Dateipräfix ist ein Fehler aufgetreten"
|
||||
online_payment: "Online-Bezahlung"
|
||||
close_accounting_period: "Abrechnungszeitraum schließen"
|
||||
close_from_date: "Schließen ab"
|
||||
start_date_is_required: "Startdatum ist erforderlich"
|
||||
close_until_date: "Schließen bis"
|
||||
end_date_is_required: "Enddatum ist erforderlich"
|
||||
previous_closings: "Vorherige Schließungen"
|
||||
start_date: "Von"
|
||||
end_date: "Bis"
|
||||
closed_at: "Geschlossen am"
|
||||
closed_by: "Von"
|
||||
period_total: "Zeitraum gesamt"
|
||||
perpetual_total: "Gesamt"
|
||||
integrity: "Integritätsprüfung"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
confirm_close_START_END: "Wollen Sie wirklich den Abrechnungszeitraum zwischen {START} und {END} schließen? Nachfolgende Änderungen sind nicht mehr möglich."
|
||||
period_must_match_fiscal_year: "Eine Schließung muss am Ende eines Mindestjahreszeitraums oder pro Geschäftsjahr erfolgen, wenn sie nicht kalenderbasiert ist."
|
||||
this_may_take_a_while: "Dieser Vorgang wird einige Zeit in Anspruch nehmen."
|
||||
period_START_END_closed_success: "Der Abrechnungszeitraum von {START} bis {END} wurde erfolgreich geschlossen. Die Archivgenerierung läuft, Sie werden nach Abschluss benachrichtigt."
|
||||
failed_to_close_period: "Ein Fehler ist aufgetreten, der Abrechnungszeitraum konnte nicht geschlossen werden"
|
||||
no_periods: "Momentan keine Schließungen"
|
||||
accounting_codes: "Abrechnungscodes"
|
||||
accounting_journal_code: "Journalcode"
|
||||
general_journal_code: "Allgemeiner Journalcode"
|
||||
accounting_card_client_code: "Kartenkunde Code"
|
||||
card_client_code: "Rechnungscode für Kunden, die mit Kreditkarte bezahlt haben"
|
||||
accounting_card_client_label: "Kreditkarten-Kunde Label"
|
||||
card_client_label: "Konto-Label für Kunden, die mit Kreditkarte bezahlt haben"
|
||||
accounting_wallet_client_code: "Guthabenkonto-Kunde Code"
|
||||
wallet_client_code: "Rechnungscode für Kunden, die mit dem Guthabenkonto bezahlen"
|
||||
accounting_wallet_client_label: "Guthabenkonto-Kunde Label"
|
||||
wallet_client_label: "Konto-Label für Kunden, die mit dem Guthabenkonto bezahlen"
|
||||
accounting_other_client_code: "Code für anders bezahlende Kunden"
|
||||
other_client_code: "Rechnungscode für Kunden, die mit einer anderen Zahlungsart bezahlen"
|
||||
accounting_other_client_label: "Label für anders bezahlende Kunden"
|
||||
other_client_label: "Rechnungs-Label für Kunden, die mit einer anderen Zahlungsart bezahlen"
|
||||
accounting_wallet_code: "Guthabenkonto-Code"
|
||||
general_wallet_code: "Rechnungscode für Guthabenkonto"
|
||||
accounting_wallet_label: "Guthabenkonto-Label"
|
||||
general_wallet_label: "Konten-Code für Guthabenkonto"
|
||||
accounting_vat_code: "MwSt.-Code"
|
||||
general_vat_code: "Rechnungscode für MwSt."
|
||||
accounting_vat_label: "MwSt.-Bezeichnung"
|
||||
general_vat_label: "MwSt.-Konto-Bezeichnung"
|
||||
accounting_subscription_code: "Abonnement-Code"
|
||||
general_subscription_code: "Abrechnungscode für alle Abonnements"
|
||||
accounting_subscription_label: "Abonnementbezeichung"
|
||||
general_subscription_label: "Abrechnungscode für alle Abonnements"
|
||||
accounting_Machine_code: "Maschinencode"
|
||||
general_machine_code: "Abrechnungscode für alle Maschinen"
|
||||
accounting_Machine_label: "Maschinenbezeichnug"
|
||||
general_machine_label: "Abrechnungscode für alle Maschinen"
|
||||
accounting_Training_code: "Trainings-Code"
|
||||
general_training_code: "Abrechnungscode für alle Schulungen"
|
||||
accounting_Training_label: "Schulungsbezeichnung"
|
||||
general_training_label: "Abrechnungs-Label für alle Schulungen"
|
||||
accounting_Event_code: "Veranstaltungs-Code"
|
||||
general_event_code: "Abrechnungscode für alle Veranstaltungen"
|
||||
accounting_Event_label: "Veranstaltungsbezeichnung"
|
||||
general_event_label: "Abrechnungs-Label für alle Veranstaltungen"
|
||||
accounting_Space_code: "Raum-Code"
|
||||
general_space_code: "Abrechnungscode für alle Räume"
|
||||
accounting_Space_label: "Raumbezeichnung"
|
||||
general_space_label: "Abrechnungs-Label für alle Räume"
|
||||
codes_customization_success: "Anpassung der Abrechnungscodes erfolgreich gespeichert."
|
||||
unexpected_error_occurred: "Beim Speichern der Codes ist ein unerwarteter Fehler aufgetreten. Bitte versuchen Sie es später erneut."
|
||||
export_accounting_data: "Abrechnungsdaten exportieren"
|
||||
export_to: "In die Buchhaltungssoftware exportieren"
|
||||
export_is_running: "Export wird ausgeführt. Sie werden nach Fertigstellung benachrichtigt."
|
||||
acd: "ACD"
|
||||
export_form_date: "Exportieren ab"
|
||||
export_to_date: "Exportieren bis"
|
||||
format: "Dateiformat"
|
||||
encoding: "Zeichenkodierung"
|
||||
separator: "Trennzeichen"
|
||||
dateFormat: "Datumsformat"
|
||||
labelMaxLength: "Label (max)"
|
||||
decimalSeparator: "Dezimaltrennzeichen"
|
||||
exportInvoicesAtZero: "Rechnungen in Höhe von 0 exportieren"
|
||||
columns: "Spalten"
|
||||
exportColumns:
|
||||
journal_code: "Journalcode"
|
||||
date: "Eintragsdatum"
|
||||
account_code: "Code des Kontos"
|
||||
account_label: "Kontobezeichnung"
|
||||
piece: "Dokument"
|
||||
line_label: "Eintragsbezeichnung"
|
||||
debit_origin: "Ursprungssoll"
|
||||
credit_origin: "Ursprungsguthaben"
|
||||
debit_euro: "Soll in Euro"
|
||||
credit_euro: "Guthaben in Euro"
|
||||
lettering: "Beschriftung"
|
||||
payment:
|
||||
payment_settings: "Bezahlungseinstellungen"
|
||||
online_payment: "Online-Bezahlung"
|
||||
online_payment_info_html: "Sie können Mitglieden gestatten, direkt online zu buchen und mit Kreditkarte zu bezahlen. Alternativ können Buchungs- und Zahlungsprozesse auf Administratoren und Manager beschränkt werden."
|
||||
enable_online_payment: "Online-Bezahlung aktivieren"
|
||||
stripe_keys: "Stripe-Schlüssel"
|
||||
stripe_keys_info_html: "<p>Um Online-Zahlungen annehmen zu können, müssen die <a href='https://stripe.com' target='_blank'>Stripe</a> API-Schlüssel konfiguriert sein.</p><p>Holen Sie sie von <a href='https://dashboard.stripe.com/account/apikeys' target='_blank'>Ihrem Dashboard</a>.</p><p>Das Aktualisieren dieser Schlüssel synchronisiert alle Stripe-Nutzer neu. Das kann einige Zeit dauern, Sie erhalten eine Benachrichtigung nach Abschluss.</p>"
|
||||
public_key: "Öffentlicher Schlüssel"
|
||||
secret_key: "Geheimer Schlüssel"
|
||||
error_check_keys: "Fehler: Bitte überprüfen Sie Ihre Stripe-Schlüssel."
|
||||
stripe_keys_saved: "Stripe-Schlüssel erfolgreich gespeichert."
|
||||
error_saving_stripe_keys: "Die Stripe-Schlüssel konnten nicht gespeichert werden. Bitte versuchen Sie es später erneut."
|
||||
edit_keys: "Schlüssel bearbeiten"
|
||||
currency: "Währung"
|
||||
currency_info_html: "Bitte geben Sie unten die Währung an, die für Online-Bezahlung verwendet wird. Sie sollten einen ISO-Code mit drei Buchstaben aus der Liste <a href='https://stripe.com/docs/currencies' target='_blank'>Stripe unterstützter Währungen eingeben</a>."
|
||||
currency_alert_html: "<strong>Warnung</strong>: Die Währung kann nicht mehr geändert werden, nachdem die erste Online-Zahlung eingegangen ist. Bitte nehmen Sie diese Einstellung sorgfältig vor, bevor Sie Fab-Manager für Mitglieder öffnen."
|
||||
stripe_currency: "Stripe-Währung"
|
||||
#management of users, labels, groups, and so on
|
||||
members:
|
||||
users_management: "Benutzer-Verwaltung"
|
||||
users: "Benutzer"
|
||||
members: "Mitglieder"
|
||||
subscriptions: "Abonnements"
|
||||
search_for_an_user: "Nach einem Benutzer suchen"
|
||||
add_a_new_member: "Neues Mitglied hinzufügen"
|
||||
reservations: "Reservierungen"
|
||||
surname: "Nachname"
|
||||
first_name: "Vorname"
|
||||
email: "E-Mail"
|
||||
phone: "Telefon"
|
||||
user_type: "Nutzertyp"
|
||||
subscription: "Abonnement"
|
||||
display_more_users: "Weitere Benutzer anzeigen..."
|
||||
administrators: "Administratoren"
|
||||
search_for_an_administrator: "Nach einem Administrator suchen"
|
||||
add_a_new_administrator: "Administrator hinzufügen"
|
||||
managers: "Manager"
|
||||
managers_info: "Ein Manager ist ein eingeschränkter Administrator, der die Einstellungen der Anwendung nicht ändern kann. Er kann aber für alle Mitglieder und Manager (inkl. sich selbst) Reservierungen vornehmen sowie Bezahlungen und Erstattungen durchführen."
|
||||
search_for_a_manager: "Nach einem Manager suchen"
|
||||
add_a_new_manager: "Neuen Manager hinzufügen"
|
||||
delete_this_manager: "Möchten Sie diesen Manager wirklich löschen? Dies kann nicht rückgängig gemacht werden."
|
||||
manager_successfully_deleted: "Manager erfolgreich gelöscht."
|
||||
unable_to_delete_the_manager: "Manager konnte nicht gelöscht werden."
|
||||
partners: "Partner"
|
||||
partners_info: "Ein Partner ist ein besonderer Benutzer, der mit den «Partner»-Plänen assoziiert werden kann. Diese Benutzer können sich nicht verbinden und erhalten nur Benachrichtigungen über Abonnements ihres zugehörigen Plans."
|
||||
search_for_a_partner: "Nach einem Partner suchen"
|
||||
add_a_new_partner: "Neuen Partner hinzufügen"
|
||||
delete_this_partner: "Möchten Sie diesen Partner wirklich löschen? Dies kann nicht rückgängig gemacht werden."
|
||||
partner_successfully_deleted: "Partner erfolgreich gelöscht."
|
||||
unable_to_delete_the_partner: "Partner konnte nicht gelöscht werden."
|
||||
associated_plan: "Zugehöriger Plan"
|
||||
groups: "Gruppen"
|
||||
tags: "Stichworte"
|
||||
authentication: "Authentifizierung"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
confirm_delete_member: "Möchten Sie dieses Mitglied wirklich löschen? Dies kann nicht rückgängig gemacht werden."
|
||||
member_successfully_deleted: "Mitglied erfolgreich gelöscht."
|
||||
unable_to_delete_the_member: "Mitglied kann nicht gelöscht werden."
|
||||
do_you_really_want_to_delete_this_administrator_this_cannot_be_undone: "Möchten Sie diesen Administrator wirklich löschen? Dies kann nicht rückgängig gemacht werden."
|
||||
this_may_take_a_while_please_wait: "Warnung: Dies kann eine Weile dauern, bitte haben Sie Geduld."
|
||||
administrator_successfully_deleted: "Administrator erfolgreich gelöscht."
|
||||
unable_to_delete_the_administrator: "Administrator konnte nicht gelöscht werden."
|
||||
changes_successfully_saved: "Änderungen erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_changes: "Beim Speichern der Änderungen ist ein Fehler aufgetreten."
|
||||
export_is_running_you_ll_be_notified_when_its_ready: "Export wird ausgeführt. Sie werden nach Fertigstellung benachrichtigt."
|
||||
tag_form:
|
||||
tags: "Tags"
|
||||
add_a_tag: "Tag hinzufügen"
|
||||
tag_name: "Tag-Name"
|
||||
new_tag_successfully_saved: "Neuer Tag erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_the_new_tag: "Beim Speichern des neuen Tags ist ein Fehler aufgetreten."
|
||||
confirmation_required: "Tag löschen?"
|
||||
confirm_delete_tag_html: "Möchten Sie dieses Tag wirklich löschen?<br>Benutzer und Slots, die diesem Tag zugeordnet sind, werden getrennt.<br><strong>Warnung: Dies kann nicht rückgängig gemacht werden!</strong>"
|
||||
tag_successfully_deleted: "Tag erfolgreich gelöscht."
|
||||
an_error_occurred_and_the_tag_deletion_failed: "Ein Fehler ist aufgetreten und der Tag konnte nicht gelöscht werden."
|
||||
authentication_form:
|
||||
search_for_an_authentication_provider: "Suche nach einem Authentifizierungsanbieter"
|
||||
add_a_new_authentication_provider: "Neuen Authentifizierungsanbieter hinzufügen"
|
||||
name: "Name"
|
||||
strategy_name: "Name der Strategie"
|
||||
type: "Typ"
|
||||
state: "Status"
|
||||
unknown: "Unbekannt: "
|
||||
active: "Aktiv"
|
||||
pending: "Ausstehend"
|
||||
previous_provider: "Vorheriger Anbieter"
|
||||
confirmation_required: "Anbieter löschen?"
|
||||
do_you_really_want_to_delete_the_TYPE_authentication_provider_NAME: "Möchten Sie wirklich den Authentifizierungsanbieter {TYPE} löschen: {NAME}?"
|
||||
authentication_provider_successfully_deleted: "Authentifizierungsanbieter erfolgreich gelöscht."
|
||||
an_error_occurred_unable_to_delete_the_specified_provider: "Ein Fehler ist aufgetreten: Der angegebene Anbieter konnte nicht gelöscht werden."
|
||||
local_database: "Lokale Datenbank"
|
||||
o_auth2: "OAuth 2.0"
|
||||
group_form:
|
||||
add_a_group: "Gruppe hinzufügen"
|
||||
group_name: "Gruppenname"
|
||||
disable: "Deaktivieren"
|
||||
enable: "Aktivieren"
|
||||
changes_successfully_saved: "Änderungen erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_changes: "Beim Speichern der Änderungen ist ein Fehler aufgetreten."
|
||||
new_group_successfully_saved: "Neue Gruppe erfolgreich gespeichert."
|
||||
an_error_occurred_when_saving_the_new_group: "Beim Speichern der neuen Gruppe ist ein Fehler aufgetreten."
|
||||
group_successfully_deleted: "Gruppe erfolgreich gelöscht."
|
||||
unable_to_delete_group_because_some_users_and_or_groups_are_still_linked_to_it: "Gruppe konnte nicht gelöscht werden, da einige Benutzer und/oder Gruppen noch mit ihr verknüpft sind."
|
||||
group_successfully_enabled_disabled: "Gruppe erfolgreich {STATUS, select, true{deaktiviert} other{aktiviert}}."
|
||||
unable_to_enable_disable_group: "Gruppe konnte nicht {STATUS, select, true{deaktiviert} other{aktiviert}} werden."
|
||||
unable_to_disable_group_with_users: "Die Gruppe konnte nicht deaktiviert werden, da sie noch {USERS} {USERS, plural, one {} =1{aktiven Benutzer} other{aktive Benutzer}} enthält."
|
||||
status_enabled: "Aktiviert"
|
||||
status_disabled: "Deaktiviert"
|
||||
status_all: "Alle"
|
||||
member_filter_all: "Alle"
|
||||
member_filter_not_confirmed: "Nicht bestätigt"
|
||||
member_filter_inactive_for_3_years: "Seit 3 Jahren inaktiv"
|
||||
#add a member
|
||||
members_new:
|
||||
add_a_member: "Mitglied hinzufügen"
|
||||
user_is_an_organization: "Benutzer ist eine Organisation"
|
||||
#members bulk import
|
||||
members_import:
|
||||
import_members: "Mitglieder importieren"
|
||||
info: "Sie können eine CSV-Datei hochladen, um neue Mitglieder zu erstellen oder bestehende zu aktualisieren. Ihre Datei muss die unten angegebenen Identifikatoren verwenden, um die Gruppe, die Schulungen und die Tags der Mitglieder festzulegen."
|
||||
required_fields: "Ihre Datei muss mindestens folgende Informationen enthalten, die für jeden Benutzer erstellt werden: E-Mail, Name, Vorname und Gruppe. Wenn das Passwort leer ist, wird es generiert. Bei Aktualisierungen werden leere Felder so beibehalten, wie sie sind."
|
||||
about_example: "Bitte nutzen Sie die angegebene Beispieldatei, um eine korrekte CSV-Datei zu generieren. Achten Sie auf die Verwendung des UTF-8-Encodings."
|
||||
groups: "Gruppen"
|
||||
group_name: "Gruppenname"
|
||||
group_identifier: "Zu verwendende Kennung"
|
||||
trainings: "Schulungen"
|
||||
training_name: "Schulungsbezeichnung"
|
||||
training_identifier: "Zu verwendende Kennung"
|
||||
plans: "Pläne"
|
||||
plan_name: "Planname"
|
||||
plan_identifier: "Zu verwendende Kennung"
|
||||
tags: "Tags"
|
||||
tag_name: "Tag-Name"
|
||||
tag_identifier: "Zu verwendende Kennung"
|
||||
download_example: "Beispieldatei"
|
||||
select_file: "Datei wählen"
|
||||
import: "Importieren"
|
||||
update_field: "Referenzfeld für zu aktualisierende Benutzer"
|
||||
update_on_id: "ID"
|
||||
update_on_username: "Benutzername"
|
||||
update_on_email: "E‐Mail‐Adresse"
|
||||
#import results
|
||||
members_import_result:
|
||||
import_results: "Import-Ergebnisse"
|
||||
import_details: "Import # {ID} von {DATE}, initiiert von {USER}"
|
||||
results: "Ergebnisse"
|
||||
pending: "Ausstehend..."
|
||||
status_create: "Neuen Benutzer anlegen"
|
||||
status_update: "Aktualisiere Benutzer {ID}"
|
||||
success: "Erfolgreich"
|
||||
failed: "Fehlgeschlagen"
|
||||
error_details: "Fehlerdetails:"
|
||||
#edit a member
|
||||
members_edit:
|
||||
change_role: "Rolle ändern"
|
||||
warning_role_change: "<p><strong>Warnung:</strong> das Ändern einer Benutzerrolle ist nicht harmlos. Aktuell ist es nicht möglich, einem Benutzer wieder eine weniger privilegierte Rolle zuzuzuweisen.</p><ul><li><strong>Mitglieder</strong> können nur für sich selbst reservieren und mit Kreditkarte oder Guthabenkonto bezahlen.</li><li><strong>Manager</strong> können für sich selbst Reservierungen buchen und per Kreditkarte oder Guthabenkonto bezahlen sowie auch für andere Mitglieder und Manager, indem sie beim Checkout die Zahlungen einbuchen.</li><li><strong>Administratoren</strong> können nur Reservierungen für Mitglieder und Manager buchen, indem sie indem sie beim Checkout die Zahlungen einbuchen. Außerdem können sie alle Einstellungen der Anwendung ändern.</li></ul>"
|
||||
admin: "Administrator"
|
||||
manager: "Manager"
|
||||
member: "Mitglied"
|
||||
role_changed: "Rolle erfolgreich von {OLD} auf {NEW} geändert."
|
||||
error_while_changing_role: "Beim Ändern der Rolle ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut."
|
||||
subscription: "Abonnement"
|
||||
duration: "Dauer:"
|
||||
expires_at: "Läuft ab am:"
|
||||
price_: "Preis:"
|
||||
offer_free_days: "Kostenlose Tage anbieten"
|
||||
extend_subscription: "Abonnement verlängern"
|
||||
user_has_no_current_subscription: "Benutzer hat kein aktuelles Abonnement."
|
||||
subscribe_to_a_plan: "Plan abonnieren"
|
||||
trainings: "Schulungen"
|
||||
no_trainings: "Keine Schulungen"
|
||||
next_trainings: "Nächste Schulungen"
|
||||
passed_trainings: "Absolvierte Schulungen"
|
||||
validated_trainings: "Validierte Schulungen"
|
||||
events: "Veranstaltungen"
|
||||
next_events: "Nächste Veranstaltungen"
|
||||
no_upcoming_events: "Keine anstehenden Veranstaltungen"
|
||||
NUMBER_full_price_tickets_reserved: "{NUMBER, plural, =0{} one{1 Vollpreis-Ticket reserviert} other{{NUMBER} Vollpreis-Tickets reserviert}}"
|
||||
NUMBER_NAME_tickets_reserved: "{NUMBER, plural, =0{} one{1 {NAME}-Ticket reserviert} other{{NUMBER} {NAME}-Tickets reserviert}}"
|
||||
passed_events: "Vergangene Veranstaltungen"
|
||||
no_passed_events: "Keine vergangenen Termine"
|
||||
invoices: "Rechnungen"
|
||||
invoice_num: "Rechnung Nr"
|
||||
date: "Datum"
|
||||
price: "Preis"
|
||||
download_the_invoice: "Rechnung herunterladen"
|
||||
download_the_refund_invoice: "Rückerstattungsrechnung herunterladen"
|
||||
no_invoices_for_now: "Momentan keine Rechnungen."
|
||||
expiration_date: "Ablaufdatum"
|
||||
you_intentionally_decide_to_extend_the_user_s_subscription_by_offering_him_free_days: "Sie entscheiden sich absichtlich dafür, das Abonnement des Benutzers zu verlängern, indem Sie ihm kostenlose Tage anbieten."
|
||||
credits_will_remain_unchanged: "Der Saldo der freien Gutschriften (Schulungen / Maschinen / Räume) des Nutzers bleibt unverändert."
|
||||
you_intentionally_decide_to_extend_the_user_s_subscription_by_charging_him_again_for_his_current_subscription: "Sie entscheiden sich absichtlich dafür, das Abonnement des Benutzers zu verlängern, indem Sie ihn für sein aktuelles Abonnement erneut belasten."
|
||||
credits_will_be_reset: "Das Inklusiv-Guthaben (für Schulungen / Maschinen / Räume) des Benutzers wird zurückgesetzt, nicht genutztes Guthaben geht verloren."
|
||||
until_expiration_date: "Bis (Ablaufdatum):"
|
||||
you_successfully_changed_the_expiration_date_of_the_user_s_subscription: "Sie haben das Ablaufdatum des Abonnements erfolgreich geändert"
|
||||
a_problem_occurred_while_saving_the_date: "Beim Speichern des Datums ist ein Problem aufgetreten."
|
||||
new_subscription: "Neues Abonnement"
|
||||
you_are_about_to_purchase_a_subscription_to_NAME: "Sie sind dabei, ein Abonnement für {NAME} zu kaufen."
|
||||
subscription_successfully_purchased: "Abonnement erfolgreich gekauft."
|
||||
a_problem_occurred_while_taking_the_subscription: "Bei der Übernahme des Abonnements ist ein Problem aufgetreten"
|
||||
wallet: "Guthabenkonto"
|
||||
to_credit: 'Guthaben'
|
||||
cannot_credit_own_wallet: "Sie können keine Gutschrift auf Ihr eigenes Guthaben einbuchen. Bitten Sie einen anderen Manager oder einen Administrator um die Gutschreibung."
|
||||
cannot_extend_own_subscription: "Sie können Ihr eigenes Abonnement nicht erweitern. Bitte fragen Sie einen anderen Manager oder einen Administrator."
|
||||
#add a new administrator to the platform
|
||||
admins_new:
|
||||
add_an_administrator: "Administrator hinzufügen"
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Administrator erfolgreich erstellt. {GENDER, select, female{Sie} other{Er}} erhält {GENDER, select, female{ihre} other{seine}} Verbindungsanweisungen per E-Mail."
|
||||
failed_to_create_admin: "Administrator konnte nicht erstellt werden:"
|
||||
man: "Männlich"
|
||||
woman: "Weiblich"
|
||||
pseudonym: "Pseudonym"
|
||||
pseudonym_is_required: "Pseudonym ist erforderlich."
|
||||
first_name: "Vorname"
|
||||
first_name_is_required: "Der Vorname ist erforderlich."
|
||||
surname: "Nachname"
|
||||
surname_is_required: "Der Nachname ist erforderlich."
|
||||
email_address: "E‐Mail‐Adresse"
|
||||
email_is_required: "Die E-Mail-Adresse ist erforderlich."
|
||||
birth_date: "Geburtsdatum"
|
||||
address: "Adresse"
|
||||
phone_number: "Telefonnummer"
|
||||
#add a new manager to the platform
|
||||
manager_new:
|
||||
add_a_manager: "Manager hinzufügen"
|
||||
manager_successfully_created: "Manager erfolgreich erstellt. {GENDER, select, female{Sie} other{Er}} erhält {GENDER, select, female{ihre} other{seine}} Verbindungsanweisungen per E-Mail."
|
||||
failed_to_create_manager: "Konnte den Manager nicht erstellen:"
|
||||
man: "Männlich"
|
||||
woman: "Weiblich"
|
||||
pseudonym: "Pseudonym"
|
||||
pseudonym_is_required: "Pseudonym ist erforderlich."
|
||||
first_name: "Vorname"
|
||||
first_name_is_required: "Der Vorname ist erforderlich."
|
||||
surname: "Nachname"
|
||||
surname_is_required: "Der Nachname ist erforderlich."
|
||||
email_address: "E‐Mail‐Adresse"
|
||||
email_is_required: "Die E-Mail-Adresse ist erforderlich."
|
||||
birth_date: "Geburtsdatum"
|
||||
address: "Adresse"
|
||||
phone_number: "Telefonnummer"
|
||||
#add a new authentication provider (SSO)
|
||||
authentication_new:
|
||||
local_database: "Lokale Datenbank"
|
||||
o_auth2: "OAuth 2.0"
|
||||
add_a_new_authentication_provider: "Neuen Authentifizierungsanbieter hinzufügen"
|
||||
a_local_database_provider_already_exists_unable_to_create_another: "Ein \"Lokale Datenbank\" Provider existiert bereits. Kann keinen anderen erstellen."
|
||||
local_provider_successfully_saved: "Lokaler Anbieter erfolgreich gespeichert."
|
||||
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "Um diesen Provider hinzuzufügen, muss die Übereinstimmung zwischen User.uid und der API festgelegt werden."
|
||||
security_issue_detected: "Sicherheitsproblem erkannt"
|
||||
beware_the_oauth2_authenticatoin_provider_you_are_about_to_add_isnt_using_HTTPS: "Vorsicht: Der OAuth 2 Provider, den Sie hinzufügen werden, verwendet kein HTTPS."
|
||||
this_is_a_serious_security_issue_on_internet_and_should_never_be_used_except_for_testing_purposes: "Dies ist ein ernstes Sicherheitsproblem im Internet und sollte nur für Testzwecke verwendet werden."
|
||||
do_you_really_want_to_continue: "Möchten Sie wirklich fortfahren?"
|
||||
unsecured_oauth2_provider_successfully_added: "Ungesicherter OAuth 2.0 Provider erfolgreich hinzugefügt."
|
||||
oauth2_provider_successfully_added: "OAuth 2.0 Provider erfolgreich hinzugefügt."
|
||||
#edit an authentication provider (SSO)
|
||||
authentication_edit:
|
||||
provider: "Provider:"
|
||||
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "Um diesen Provider hinzuzufügen, muss die Übereinstimmung zwischen User.uid und der API festgelegt werden."
|
||||
provider_successfully_updated: "Anbieter erfolgreich aktualisiert."
|
||||
an_error_occurred_unable_to_update_the_provider: "Ein Fehler ist aufgetreten: Der Anbieter konnte nicht aktualisiert werden."
|
||||
#statistics tables
|
||||
statistics:
|
||||
statistics: "Statistiken"
|
||||
evolution: "Entwicklung"
|
||||
age_filter: "Altersfilter"
|
||||
from_age: "Von" #eg. from 8 to 40 years old
|
||||
to_age: "bis" #eg. from 8 to 40 years old
|
||||
start: "Start:"
|
||||
end: "Ende:"
|
||||
custom_filter: "Benutzerderfinierter Filter"
|
||||
NO_: "NO"
|
||||
criterion: "Kriterium:"
|
||||
value: "Wert:"
|
||||
exclude: "Ausschließen"
|
||||
from_date: "Von" #eg: from 01/01 to 01/05
|
||||
to_date: "bis" #eg: from 01/01 to 01/05
|
||||
entries: "Einträge:"
|
||||
revenue_: "Umsatz:"
|
||||
average_age: "Durchschnittsalter:"
|
||||
years_old: "Jahre alt"
|
||||
total: "Gesamt"
|
||||
available_hours: "Öffnungszeiten für Buchung:"
|
||||
available_tickets: "Verfügbare Tickets zur Buchung:"
|
||||
date: "Datum"
|
||||
user: "Nutzer"
|
||||
gender: "Geschlecht"
|
||||
age: "Alter"
|
||||
type: "Typ"
|
||||
revenue: "Umsatz"
|
||||
unknown: "Unbekannt"
|
||||
user_id: "Nutzer-ID"
|
||||
display_more_results: "Weitere Ergebnisse anzeigen"
|
||||
export_statistics_to_excel: "Statistiken nach Excel exportieren"
|
||||
export_all_statistics: "Alle Statistiken exportieren"
|
||||
export_the_current_search_results: "Aktuelle Suchergebnisse exportieren"
|
||||
export: "Export"
|
||||
deleted_user: "Gelöschter Nutzer"
|
||||
man: "Männlich"
|
||||
woman: "Weiblich"
|
||||
export_is_running_you_ll_be_notified_when_its_ready: "Export wird ausgeführt. Sie werden nach Fertigstellung benachrichtigt."
|
||||
create_plans_to_start: "Beginnen Sie mit dem Erstellen neuer Abonnement-Pläne."
|
||||
click_here: "Klicken Sie hier, um die erste zu erstellen."
|
||||
#statistics graphs
|
||||
stats_graphs:
|
||||
statistics: "Statistiken"
|
||||
data: "Daten"
|
||||
day: "Tag"
|
||||
week: "Woche"
|
||||
from_date: "Ab" #eg: from 01/01 to 01/05
|
||||
to_date: "bis" #eg: from 01/01 to 01/05
|
||||
month: "Monat"
|
||||
start: "Start:"
|
||||
end: "Ende:"
|
||||
type: "Typ"
|
||||
revenue: "Umsatz"
|
||||
top_list_of: "Top-Liste von"
|
||||
number: "Zahl"
|
||||
week_short: "Woche"
|
||||
week_of_START_to_END: "Woche von {START} bis {END}"
|
||||
no_data_for_this_period: "Keine Daten in diesem Zeitraum"
|
||||
date: "Datum"
|
||||
#global application parameters and customization
|
||||
settings:
|
||||
customize_the_application: "Anwendung anpassen"
|
||||
fablab_name: "FabLab-Name"
|
||||
about: "Über"
|
||||
customize_information_messages: "Anpassung der Erklärungstexte"
|
||||
message_of_the_machine_booking_page: "Erklärungstext der Maschinen-Buchungsseite:"
|
||||
type_the_message_content: "Inhalt des Erklärungstexts eingeben"
|
||||
warning_message_of_the_training_booking_page: "Warnmeldung auf der Schulungs-Buchungsseite:"
|
||||
information_message_of_the_training_reservation_page: "Erklärungstext auf der Seite für die Schulungs-Reservierung:"
|
||||
message_of_the_subscriptions_page: "Erklärungstext der Abonnement-Seite:"
|
||||
message_of_the_events_page: "Erklärungstext der Veranstaltungs-Seite:"
|
||||
message_of_the_spaces_page: "Erklärungstext der Räume-Seite:"
|
||||
legal_documents: "Rechtliche Dokumente"
|
||||
if_these_documents_are_not_filled_no_consent_about_them_will_be_asked_to_the_user: "Werden diese Dokumente nicht ausgefüllt, wird keine Zustimmung erbeten."
|
||||
general_terms_and_conditions: "Allgemeine Geschäftsbedingungen (AGB)"
|
||||
terms_of_service: "Nutzungsbedingungen"
|
||||
customize_the_graphics: "Grafiken anpassen"
|
||||
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 eine optimale Darstellung muss das Logobild im PNG-Format mit transparenten Hintergrund vorliegen, Seitenverhältnis 3.5 mal breiter als die Höhe."
|
||||
concerning_the_favicon_it_must_be_at_ICO_format_with_a_size_of_16x16_pixels: "Das Favicon muss im ICO-Format mit einer Größe von 16x16 Pixel vorliegen."
|
||||
remember_to_refresh_the_page_for_the_changes_to_take_effect: "Die Seite muss neu geladen werden, damit die Änderungen wirksam werden."
|
||||
logo_white_background: "Logo (weißer Hintergrund)"
|
||||
change_the_logo: "Logo ändern"
|
||||
logo_black_background: "Logo (schwarzer Hintergrund)"
|
||||
favicon: "Favicon"
|
||||
change_the_favicon: "Favicon ändern"
|
||||
main_colour: "Hauptfarbe:"
|
||||
primary: "Primär"
|
||||
secondary_colour: "Sekundärfarbe:"
|
||||
secondary: "Sekundär"
|
||||
background_picture_of_the_profile_banner: "Hintergrundbild des Profil-Banners"
|
||||
change_the_profile_banner: "Profil-Banner ändern"
|
||||
home_page: "Homepage"
|
||||
news_of_the_home_page: "Neuigkeiten der Homepage:"
|
||||
type_your_news_here: "Gib hier deine News ein"
|
||||
leave_it_empty_to_not_bring_up_any_news_on_the_home_page: "Lassen Sie es leer, um keine Neuigkeiten auf der Startseite anzuzeigen"
|
||||
twitter_stream: "Twitter-Stream:"
|
||||
name_of_the_twitter_account: "Name des Twitter-Kontos"
|
||||
link: "Link"
|
||||
link_to_about: 'Link-Titel zur "Über" Seite'
|
||||
content: "Inhalt"
|
||||
title_of_the_about_page: "Titel der \"Über\"-Seite"
|
||||
shift_enter_to_force_carriage_return: "SHIFT + ENTER für Zeilenumbruch"
|
||||
input_the_main_content: "Hauptinhalt eingeben"
|
||||
drag_and_drop_to_insert_images: "Ziehen und Ablegen, um Bilder einzufügen"
|
||||
input_the_fablab_contacts: "FabLab Kontakte eingeben"
|
||||
reservations: "Reservierungen"
|
||||
reservations_parameters: "Reservierungsparameter"
|
||||
confine_the_booking_agenda: "Buchungsagenda festlegen"
|
||||
opening_time: "Öffnungszeiten"
|
||||
closing_time: "Schließzeit"
|
||||
max_visibility: "Maximale Sichtbarkeit (in Monaten)"
|
||||
visibility_for_yearly_members: "Für derzeit laufende Abonnements, mindestens 1 Jahr lang"
|
||||
visibility_for_other_members: "Für alle anderen Mitglieder"
|
||||
ability_for_the_users_to_move_their_reservations: "Möglichkeit für die Benutzer, ihre Reservierungen zu verschieben"
|
||||
reservations_shifting: "Verschiebung von Reservierungen"
|
||||
prior_period_hours: "Vorheriger Zeitraum (Stunden)"
|
||||
enabled: "Aktiviert"
|
||||
disabled: "Deaktiviert"
|
||||
ability_for_the_users_to_cancel_their_reservations: "Möglichkeit für Benutzer, ihre Reservierungen zu stornieren"
|
||||
reservations_cancelling: "Reservierungen stornieren"
|
||||
reservations_reminders: "Erinnerungen an Reservierungen"
|
||||
notification_sending_before_the_reservation_occurs: "Senden der Benachrichtigung vor dem Eintreten der Reservierung"
|
||||
customization_of_SETTING_successfully_saved: "Anpassung von {SETTING} erfolgreich gespeichert."
|
||||
file_successfully_updated: "Datei erfolgreich aktualisiert."
|
||||
name_genre: "Titel-Konkordanz"
|
||||
machine_explications_alert: "Erklärungstext auf der Seite für die Maschinen-Reservierung"
|
||||
training_explications_alert: "Erklärungstext auf der Seite für die Schulungs-Reservierung"
|
||||
training_information_message: "Informationstext auf der Seite für die Maschinen-Reservierung"
|
||||
subscription_explications_alert: "Erklärungstext auf der Seite für die Abonnements"
|
||||
event_explications_alert: "Erklärungstext auf der Seite für die Veranstaltungs-Reservierung"
|
||||
space_explications_alert: "Erklärungstext auf der Seite für die Raum-Reservierung"
|
||||
main_color: "Hauptfarbe"
|
||||
secondary_color: "Sekundärfarbe"
|
||||
customize_home_page: "Startseite anpassen"
|
||||
reset_home_page: "Die Startseite auf den ursprünglichen Zustand zurücksetzen"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
confirm_reset_home_page: "Möchten Sie die Startseite wirklich auf ihren Anfangszustand zurücksetzen?"
|
||||
home_items: "Homepage-Elemente"
|
||||
item_news: "Neuigkeiten"
|
||||
item_projects: "Letzte Projekte"
|
||||
item_twitter: "Letzter Tweet"
|
||||
item_members: "Neueste Mitglieder"
|
||||
item_events: "Nächste Veranstaltungen"
|
||||
home_content: "die Startseite"
|
||||
home_content_reset: "Die Startseite wurde erfolgreich auf die ursprüngliche Konfiguration zurückgesetzt."
|
||||
home_css: "das Stylesheet der Startseite"
|
||||
home_blogpost: "Homepage Kurzinfo"
|
||||
twitter_name: "Twitter-Benutzername"
|
||||
link_name: "Link-Titel zur \"Über\" Seite"
|
||||
about_title: "Seitentitel \"Über\""
|
||||
about_body: "Seiteninhalt \"Über\""
|
||||
about_contacts: "Kontakte auf der \"Über\"-Seite"
|
||||
privacy_draft: "Entwurf der Datenschutzrichtlinien"
|
||||
privacy_body: "Datenschutzrichtlinie"
|
||||
privacy_dpo: "Adresse des Datenschutzbeauftragten"
|
||||
booking_window_start: "Öffnungszeit Beginn"
|
||||
booking_window_end: "Öffnungszeit Ende"
|
||||
booking_move_enable: "Verschieben von Reservierungen aktivieren"
|
||||
booking_move_delay: "vorbeugende Verzögerung der Verschiebung"
|
||||
booking_cancel_enable: "Buchungsstornierung aktivieren"
|
||||
booking_cancel_delay: "vorbeugende Verzögerung der Stornierung"
|
||||
reminder_enable: "Reservierungs-Erinnerung aktivieren"
|
||||
reminder_delay: "Verzögerung vor dem Versand der Erinnerung"
|
||||
default_value_is_24_hours: "Wenn das Feld leer bleibt: 24 Stunden."
|
||||
visibility_yearly: "maximale Sichtbarkeit für jährliche Abonnenten"
|
||||
visibility_others: "maximale Sichtbarkeit für andere Mitglieder"
|
||||
display: "Anzeige"
|
||||
display_name_info_html: "Bei Aktivierung sehen Mitglieder und Besucher im Kalender oder bei der Maschinenbuchung die Namen der Mitglieder, die Slots gebucht haben. Bei Deaktivierung sehen nur Administratoren und Manager die Namen.<br/><strong>Warnung:</strong> wenn Sie dieses Feature aktivieren, müssen sie in Ihren Datenschutzrichtlinien darauf hinweisen."
|
||||
display_machine_reservation_user_name: "Den vollständigen Namen des Benutzers anzeigen, der einen Maschinenslot gebucht hat"
|
||||
display_name: "Namen anzeigen"
|
||||
display_name_enable: "Name anzeigen"
|
||||
events_in_the_calendar: "Veranstaltungen im Kalender anzeigen"
|
||||
events_in_calendar_info: "Bei Aktivierung zeigt der Admin-Kalender geplante Veranstaltungen schreibgeschützt an."
|
||||
show_event: "Veranstaltungen anzeigen"
|
||||
events_in_calendar: "Veranstaltungsanzeige im Kalender"
|
||||
machines_sort_by: "Anzeigereihenfolge der Maschinen"
|
||||
fab_analytics: "Fab-Analytics"
|
||||
phone_required: "Telefonummer erforderlich"
|
||||
tracking_id: "Tracking-ID"
|
||||
facebook_app_id: "Facebook App-ID"
|
||||
twitter_analytics: "Twitter Analytics-Konto"
|
||||
book_overlapping_slots: "überlappende Slots buchen"
|
||||
slot_duration: "Dauer der Slots"
|
||||
advanced: "Erweiterte Einstellungen"
|
||||
customize_home_page_css: "Das Stylesheet der Startseite anpassen"
|
||||
home_css_notice_html: "Sie können das Stylesheet anpassen, das auf die Startseite angewendet wird, indem Sie die <a href=\"https://sass-lang.com/documentation\" target=\"_blank\">SASS</a> Syntax verwenden. Diese Stile werden automatisch dem <code>Homepage</code> Selektor untergeordnet, um das Risiko von Applikationsfehlern zu minimieren. Vorsicht: Änderungen im Homepage-Editor oben auf der Seite können Ihre Stile zerstören, beziehen Sie sich immer auf den HTML-Code."
|
||||
error_SETTING_locked: "Die Einstellung konnte nicht aktualisiert werden: {SETTING} ist gesperrt. Bitte kontaktieren Sie Ihren Systemadministrator."
|
||||
an_error_occurred_saving_the_setting: "Beim Speichern der Einstellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut."
|
||||
book_overlapping_slots_info: "Erlauben / Verhindern der Reservierung von überlappenden Slots"
|
||||
allow_booking: "Buchungen erlauben"
|
||||
default_slot_duration: "Standarddauer für Slots"
|
||||
duration_minutes: "Dauer (in Minuten)"
|
||||
default_slot_duration_info: "Die Verfügbarkeit von Maschinen und Räumen ist in mehrere Slots dieser Dauer aufgeteilt. Dieser Wert kann je Verfügbarkeit überschrieben werden."
|
||||
modules: "Module"
|
||||
spaces: "Räume"
|
||||
spaces_info_html: "<p>Ein Raum kann zum Beispiel eine Holzwerkstatt oder ein Meetingraum sein. Die Besonderheit von Räumen ist, dass sie von mehreren Personen gleichzeitig gebucht werden können.</p><p><strong>Warnung:</strong> Es wird nicht empfohlen, Räume zu deaktivieren, wenn mindestens eine Raumreservierung auf dem System vorgenommen wurde.</p>"
|
||||
enable_spaces: "Räume aktivieren"
|
||||
spaces_module: "Raum-Modul"
|
||||
plans: "Pläne"
|
||||
plans_info_html: "<p>Abonnements bieten eine Möglichkeit, Ihre Preise zu segmentieren und Vorteile für reguläre Benutzer zu bieten.</p><p><strong>Warnung:</strong> Es wird nicht empfohlen, die Abonnements zu deaktivieren, wenn mindestens ein Abonnement auf dem System aktiv ist.</p>"
|
||||
enable_plans: "Pläne aktivieren"
|
||||
plans_module: "Plan-Modul"
|
||||
invoicing: "Rechnungsstellung"
|
||||
invoicing_info_html: "<p>Sie können das Rechnungsmodul komplett deaktivieren.</p><p>Das ist nützlich, wenn Sie über Ihr eigenes Rechnungssystem verfügen und nicht wollen, dass Fab-Manager Rechnungen generiert und an Mitglieder sendet.</p><p><strong>Warnung:</strong> Auch wenn Sie das Rechnungsmodul deaktivieren, müssen Sie die Mehrwertsteuer konfigurieren, um Fehler in Rechnungslegung und Preisen zu vermeiden. Die Konfiguration erfolgt in der Sektion « Rechnungen > Einstellungen ».</p>"
|
||||
enable_invoicing: "Rechnungsstellung aktivieren"
|
||||
invoicing_module: "Rechnungs-Modul"
|
||||
account_creation: "Account-Erstellung"
|
||||
phone: "Telefon"
|
||||
phone_is_required: "Telefonummer erforderlich"
|
||||
phone_required_info: "Sie können festlegen, ob die Telefonnummer erforderlich sein soll, um einen neuen Benutzer auf Fab-Manager zu registrieren."
|
||||
captcha: "Captcha"
|
||||
captcha_info_html: "Sie können einen Schutz gegen Roboter einrichten, um zu verhindern, dass diese Accounts erstellen. Dieser Schutz verwendet Google reCAPTCHA. Melden Sie sich für <a href='http://www.google.com/recaptcha/admin' target='_blank'>ein API-Schlüsselpaar</a> an, um reCaptcha zu verwenden."
|
||||
site_key: "Site-Schlüssel"
|
||||
secret_key: "Geheimer Schlüssel"
|
||||
recaptcha_site_key: "ReCAPTCHA Site-Key"
|
||||
recaptcha_secret_key: "reCAPTCHA Geheimschlüssel"
|
||||
feature_tour_display: "Anzeige der Tour zu den Features"
|
||||
email_from: "Mailadresse des Senders"
|
||||
disqus_shortname: "Disqus Kurzname"
|
||||
COUNT_items_removed: "{COUNT, plural, one {} =1{Ein Element} other{{COUNT} Elemente}} entfernt"
|
||||
item_added: "Ein Element hinzugefügt"
|
||||
openlab_app_id: "OpenLab-ID"
|
||||
openlab_app_secret: "OpenLab App-Geheimnis"
|
||||
openlab_default: "Standard-Galerieansicht"
|
||||
online_payment_module: "Online-Zahlungsmodul"
|
||||
stripe_currency: "Stripe-Währung"
|
||||
account_confirmation: "Kontobestätigung"
|
||||
confirmation_required_info: "Optional können Sie die Bestätigung der E-Mail-Adresse für Benutzer obligatorisch machen, bevor Sie Zugriff auf Fab-Manager bekommen."
|
||||
confirmation_is_required: "Bestätigung erforderlich"
|
||||
wallet_module: "Guthabenkonto-Modul"
|
||||
statistics_module: "Statistik-Modul"
|
||||
upcoming_events_shown: "Anzeigelimit für anstehende Termine"
|
||||
general:
|
||||
general: "Allgemein"
|
||||
title: "Titel"
|
||||
fablab_title: "FabLab Titel"
|
||||
title_concordance: "Titel-Konkordanz"
|
||||
male: "Männlich."
|
||||
female: "Weiblich."
|
||||
neutral: "Neutral."
|
||||
eg: "z.B.:"
|
||||
the_team: "Das Team von"
|
||||
male_preposition: "der"
|
||||
female_preposition: "die"
|
||||
neutral_preposition: ""
|
||||
elements_ordering: "Elemente sortieren"
|
||||
machines_order: "Maschinen-Reihenfolge"
|
||||
display_machines_sorted_by: "Maschinen anzeigen, sortiert nach"
|
||||
sort_by:
|
||||
default: "Standard"
|
||||
name: "Name"
|
||||
created_at: "Erstellungsdatum"
|
||||
updated_at: "Datum der letzten Aktualisierung"
|
||||
help: "Hilfe"
|
||||
feature_tour: "Feature-Tour"
|
||||
feature_tour_info_html: "<p>Wenn sich ein Administrator oder Manager anmeldet, wird beim jeweils ersten Besuch eines Abschnitts der Anwendung die Feature-Tour ausgelöst. Sie können dieses Verhalten auf einen der folgenden Werte ändern:</p><ul><li>« Einmal », um das Standardverhalten beizubehalten.</li><li>« Pro Sitzung », um die Tour jedes Mal anzuzeigen, wenn die Anwendung erneut geöffnet wird.</li><li>« Nur manuell », deaktiviert die automatische Anzeige der Touren. Es ist weiterhin möglich, sie durch Drücken der F1-Taste oder durch Klicken auf « Hilfe » im Benutzermenu zu starten.</li></ul>"
|
||||
feature_tour_display_mode: "Anzeigemodus der Feature Tour"
|
||||
display_mode:
|
||||
once: "Einmalig"
|
||||
session: "Pro Sitzung"
|
||||
manual: "Manuell"
|
||||
notifications: "Mitteilungen"
|
||||
email: "E-Mail"
|
||||
email_info: "Die E-Mail-Adresse, von der Benachrichtigungen gesendet werden. Sie können eine nicht vorhandene Adresse (wie noreply@...) verwenden oder eine bestehende Adresse, wenn Sie Ihren Mitgliedern erlauben möchten, auf Benachrichtigungen zu antworten."
|
||||
email_from: "Mailadresse des Senders"
|
||||
wallet: "Guthabenkonto"
|
||||
wallet_info_html: "<p>Mit dem Guthabenkonto können Sie Benutzern eine Geldsumme zuweisen. Diese können es nach Belieben im Fab-Manager ausgeben.</p><p>Mitglieder können ihr Guthabenkonto nicht selbst aufladen, das können nur Manager und Administratoren.</p>"
|
||||
enable_wallet: "Guthabenkonto aktivieren"
|
||||
statistics: "Statistiken"
|
||||
statistics_info_html: "<p>Aktivieren oder deaktivieren Sie das Statistik-Modul.</p><p>Wenn aktiviert, konsolidiert das Modul die Tagesdaten in der Datenbank einer leistungsstarken Analyse-Engine. Administratoren können im entsprechenden Abschnitt die erstellten Diagramme und Tabellen durchsuchen.</p>"
|
||||
enable_statistics: "Statistik-Modul aktivieren"
|
||||
home:
|
||||
show_upcoming_events: "Anstehende Veranstaltungen anzeigen"
|
||||
upcoming_events:
|
||||
until_start: "Bis sie beginnen"
|
||||
2h_before_end: "Bis 2 Stunden vor ihrem Ende"
|
||||
until_end: "Bis sie enden"
|
||||
privacy:
|
||||
title: "Datenschutz"
|
||||
privacy_policy: "Datenschutzerklärung"
|
||||
input_the_dpo: "Datenschutzbeauftragter"
|
||||
current_policy: "Aktuelle Richtlinie"
|
||||
draft_from_USER_DATE: "Entwurf gespeichert von {USER} am {DATE}"
|
||||
save_or_publish: "Speichern oder veröffentlichen?"
|
||||
save_or_publish_body: "Möchten Sie eine neue Version der Datenschutzrichtlinie veröffentlichen oder sie als Entwurf speichern?"
|
||||
publish_will_notify: "Veröffentlichen der neuen Version sendet eine Benachrichtigung an alle Benutzer."
|
||||
publish: "Veröffentlichen"
|
||||
users_notified: "Plattform-Nutzer werden über das Update benachrichtigt."
|
||||
about_analytics: "Ich stimme zu, anonyme Daten mit dem Entwicklerteam zu teilen, um Fab-Manager zu verbessern."
|
||||
read_more: "Welche Daten werden von uns erfasst?"
|
||||
statistics: "Statistiken"
|
||||
google_analytics: "Google Analytics"
|
||||
facebook: "Facebook"
|
||||
facebook_info_html: "Um die statistische Verfolgung der Aktien im sozialen Netzwerk Facebook zu aktivieren, legen Sie hier Ihre App-ID fest. <a href='https://developers.facebook.com/docs/apps#register' target='_blank'>Diese Anleitung</a> erklärt, wie Sie eine App-ID erhalten."
|
||||
app_id: "App-ID"
|
||||
twitter: "Twitter"
|
||||
twitter_info_html: "Um Statistiken im sozialen Netzwerk Twitter via <a href='https://analytics.twitter.com/' target='_blank'>Twitter Analytics</a> zu aktivieren, können Sie hier den Namen Ihres Twitter-Kontos eingeben."
|
||||
twitter_analytics: "Twitter-Konto"
|
||||
analytics:
|
||||
title: "Anwendungsverbesserung"
|
||||
intro_analytics_html: "Sie finden unten eine detaillierte Ansicht der Daten, die Fab-Manager sammelt, <strong>wenn die Erlaubnis erteilt wurde.</strong>"
|
||||
version: "Anwendungsversion"
|
||||
members: "Mitgliederanzahl"
|
||||
admins: "Anzahl der Administratoren"
|
||||
availabilities: "Anzahl der Verfügbarkeiten der letzten 7 Tage"
|
||||
reservations: "Anzahl der Reservierungen in den letzten 7 Tagen"
|
||||
plans: "Ist das Abonnement-Modul aktiv?"
|
||||
spaces: "Ist das Raum-Management-Modul aktiv?"
|
||||
online_payment: "Ist das Online-Zahlungsmodul aktiv?"
|
||||
invoices: "Ist das Rechnungsmodul aktiv?"
|
||||
openlab: "Ist das Projektteilungsmodul (OpenLab) aktiv?"
|
||||
tracking_id_info_html: "<p>Um die statistische Analyse der Besuche mithilfe von Google Analytics zu ermöglichen, tragen Sie hier Ihre Tracking-ID in der Form UA-000000-0 ein. Besuchen Sie <a href='https://analytics.google.com/analytics/web/' target='_blank'>die Google Analytics Website</a>, um eine Tracking-ID zu erstellen.<br/><strong>Warnung:</strong> wenn Sie dieses Feature aktivieren, muss in Ihrer Datenschutzrichtlinie darauf hingewiesen werden.</p><p> Um Google Analytics verwenden zu können, benötigen Sie auch den Hostnamen. Klicken Sie auf die angrenzende Schaltfläche. Dieser letzte Parameter wird auch an anderen Stellen verwendet, bitte verwenden Sie ihn vorsichtig.</p>"
|
||||
tracking_id: "Tracking-ID"
|
||||
open_api_clients:
|
||||
add_new_client: "Neuen API-Client erstellen"
|
||||
api_documentation: "API-Dokumentation"
|
||||
open_api_clients: "OpenAPI-Clients"
|
||||
name: "Name"
|
||||
calls_count: "Anrufanzahl"
|
||||
token: "Token"
|
||||
created_at: "Erstellungsdatum"
|
||||
reset_token: "Zugriff widerrufen"
|
||||
client_name: "Kundenname"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_delete_this_open_api_client: "Möchten Sie diesen OpenAPI-Client wirklich löschen?"
|
||||
do_you_really_want_to_revoke_this_open_api_access: "Möchten Sie diesen Zugriff wirklich widerrufen ? Er wird das aktuelle Token löschen und ersetzen."
|
||||
client_successfully_created: "Client erfolgreich erstellt."
|
||||
client_successfully_updated: "Client erfolgreich aktualisiert."
|
||||
client_successfully_deleted: "Client erfolgreich gelöscht."
|
||||
access_successfully_revoked: "Zugriff erfolgreich widerrufen."
|
||||
#create a new space
|
||||
space_new:
|
||||
add_a_new_space: "Neuen Raum erstellen"
|
||||
watch_out_when_creating_a_new_space_its_prices_are_initialized_at_0_for_all_subscriptions: "Achtung! Beim Erstellen eines neuen Raums wird sein Preis für alle Abonnements mit 0 angelegt."
|
||||
consider_changing_its_prices_before_creating_any_reservation_slot: "Ändern Sie ggf. die Preise, bevor Sie Reservierungs-Slots erstellen."
|
||||
add_this_space: "Diesen Raum hinzufügen"
|
||||
#modify an exiting space
|
||||
space_edit:
|
||||
edit_the_space_NAME: "Bearbeite den Raum: {NAME}"
|
||||
validate_the_changes: "Änderungen validieren"
|
||||
#process and delete abuses reports
|
||||
manage_abuses:
|
||||
abuses_list: "Berichtsliste"
|
||||
no_reports: "Momentan keine Berichte"
|
||||
published_by: "verfasst von"
|
||||
at_date: "am"
|
||||
has_reported: "hat folgenden Bericht erstellt:"
|
||||
confirmation_required: "Bestätigen Sie die Bearbeitung des Berichts"
|
||||
report_will_be_destroyed: "Sobald der Bericht verarbeitet wurde, wird er gelöscht. Dies kann nicht rückgängig gemacht werden. Fortfahren?"
|
||||
report_removed: "Der Bericht wurde gelöscht"
|
||||
failed_to_remove: "Ein Fehler ist aufgetreten, der Bericht konnte nicht gelöscht werden"
|
||||
#feature tour
|
||||
tour:
|
||||
conclusion:
|
||||
title: "Vielen Dank für Ihre Aufmerksamkeit"
|
||||
content: "<p>Um diese kontextabhängige Hilfe neu zu starten, können Sie jederzeit <strong>F1</strong> drücken oder klicken Sie im Benutzermenu auf [? Hilfe].</p><p>Zusätzliche Hilfe finden Sie in der <a href='https://github.com/sleede/fab-manager/raw/master/doc/fr/guide_utilisation_fab_manager_v4.5.pdf' target='_blank'>Benutzeranleitung</a> (nur auf Französisch).</p><p>Das Fab-Manager-Team bietet auch personalisierten Support (Hilfe beim Einstieg, Hilfe bei der Installation, Anpassung etc.), <a href='mailto:contact@fab-manager.com'>kontaktieren Sie uns</a> für weitere Informationen.</p>"
|
||||
trainings:
|
||||
welcome:
|
||||
title: "Schulungen"
|
||||
content: "Hier können Sie Schuluigen erstellen, ändern und löschen. Ebenso können Sie hier die Schulungen validieren, die von Mitgliedern absolviert wurden."
|
||||
welcome_manager:
|
||||
title: "Schulungen"
|
||||
content: "Hier sehen Sie die Schulungen und ihre jeweiligen Maschinenzuordnungen. Ebenso können Sie hier Schulungen validieren, die von Mitgliedern absolviert wurden."
|
||||
trainings:
|
||||
title: "Schulungen verwalten"
|
||||
content: "<p>Jeder Schulung ist eine Standardanzahl von Räumen zugeordnet. Die Anzahl der tatsächlichen Räume kann für jede Einzelschulung geändert werden.</p><p>Schulungen werden über den Administrations-Tab « Kalender » geplant.</p><p>Einer Schulung können eine oder mehrere Maschinen zugeordnet werden. Dadurch wird es zur Voraussetzung zur Reservierung dieser Maschinen.</p>"
|
||||
filter:
|
||||
title: "Filter"
|
||||
content: "Standardmäßig werden hier nur aktive Kurse angezeigt. Um andere anzuzeigen, können Sie einen anderen Filter auswählen."
|
||||
tracking:
|
||||
title: "Schulungs-Überwachung"
|
||||
content: "Sobald eine Schulung abgeschlossen ist, kann sie hier für die anwesenden Mitglieder validiert werden. Die Validierung ist unerlässlich, um mit der Schulung assoziierte Maschinen benutzen zu dürfen."
|
||||
calendar:
|
||||
welcome:
|
||||
title: "Kalender"
|
||||
content: "Hier können die Slots geplant werden, in denen Mitglieder Schulungen, Maschinen und Räume buchen können."
|
||||
agenda:
|
||||
title: "Der Kalender"
|
||||
content: "Klicken Sie in den Kalender, um einen neuen Verfügbarkeits-Zeitraum zu erstellen. Sie können den Zeitraum durch Klicken und Halten direkt auswählen."
|
||||
export:
|
||||
title: "Export"
|
||||
content: "Erstellen Sie eine Excel-Datei, die alle im Kalender erstellten Verfügbarkeits-Slots auflistet."
|
||||
import:
|
||||
title: "Externe Kalender importieren"
|
||||
content: "Erlaubt den Import von Kalendern im iCal-Format aus einer externen Quelle."
|
||||
members:
|
||||
welcome:
|
||||
title: "Nutzer"
|
||||
content: "Hier können Sie Mitglieder und Administratoren erstellen, ändern und löschen. Sie verwalten hier auch Gruppen, Labels, Import/Export mit Spreadsheets und können SSO-Software anschließen."
|
||||
list:
|
||||
title: "Mitgliederliste"
|
||||
content: "Standardmäßig listet diese Tabelle alle Mitglieder des Fab-Managers auf. Sie können die Listensortierung per Klick auf die verschiedenen Spaltenheader ändern."
|
||||
search:
|
||||
title: "Benutzer suchen"
|
||||
content: "Über dieses Eingabefeld können Sie eine Freitextsuche über alle Spalten der Tabelle unten starten."
|
||||
filter:
|
||||
title: "Liste filtern"
|
||||
content: "<p>Filtern Sie die Liste unten, um nur Benutzer mit unbestätigter E-Mail-Adresse oder mehr als 3 Jahren Inaktivität anzuzeigen.</p><p>Bitte beachten Sie, dass aus Datenschutzgründen Konten gelöscht werden müssen, die länger als 3 Jahre inaktiv sind.</p>"
|
||||
actions:
|
||||
title: "Mitglieder-Aktionen"
|
||||
content: "<p>Mit den Schaltflächen in dieser Spalte können Sie alle Parameter des Mitglieds anzeigen, ändern oder unwiderruflich löschen.</p><p>Im Falle einer Löschung werden die Abrechnungsinformationen noch für 10 Jahre aufbewahrt. Anonymisierte statistische Daten werden ebenfalls erhalten.</p>"
|
||||
exports:
|
||||
title: "Export"
|
||||
content: "Jeder Button generiert ein Excel-Datei, die jeweils alle Mitglieder, Abonnements oder Reservierungen enthält, mit sowohl aktuellen wie historischen Daten."
|
||||
import:
|
||||
title: "Mitglieder importieren"
|
||||
content: "Importiert eine Liste von Mitgliedern aus einer CSV-Datei, die im Fab-Manager angelegt werden."
|
||||
admins:
|
||||
title: "Administratoren verwalten"
|
||||
content: "Administratoren werden hier analog zu den Mitgliedern verwaltet.<br>Administratoren können Reservierungen für jedes Mitglied vornehmen und alle Parameter der Software ändern."
|
||||
groups:
|
||||
title: "Gruppen verwalten"
|
||||
content: "<p>Gruppen ermöglichen die bessere Segmentierung der Preisliste.</p><p>Wenn Sie Fab-Manager zum ersten Mal einrichten, wird der Einstieg mit der Gruppendefinition empfohlen.</p>"
|
||||
labels:
|
||||
title: "Tags verwalten"
|
||||
content: "Mit Labeln können Sie bestimmte Slots für Benutzer reservieren, die diesen Labels zugeordnet sind."
|
||||
sso:
|
||||
title: "Single-Sign-On"
|
||||
content: "Hier können Sie ein Single-Sign-On-Authentifizierungssystem (SSO) einrichten und verwalten."
|
||||
invoices:
|
||||
welcome:
|
||||
title: "Rechnungen"
|
||||
content: "<p>Hier können Sie Rechnungen und Gutschriften herunterladen, sowie alles rund um Abrechnung und Rechnungsstellung verwalten.</p><p>Wenn Sie Ihre Rechnungen mit einer anderen Software verwalten, kann das Abrechnungsmodul deaktiviert werden. Kontaktieren Sie dazu Ihren Systemadministrator.</p>"
|
||||
welcome_manager:
|
||||
title: "Rechnungen"
|
||||
content: "Hier können Sie Rechnungen herunterladen und Gutschriften erstellen."
|
||||
list:
|
||||
title: "Rechnungsliste"
|
||||
content: "Diese Tabelle listet standardmäßig alle Rechnungen und Kreditnoten von Fab-Manager auf. Sie können die Liste in einer anderen Reihenfolge sortieren, indem Sie auf den Header jeder Spalte klicken."
|
||||
chained:
|
||||
title: "Verkettungs-Anzeiger"
|
||||
content: "<p>Dieses Icon stellt die Unänderbarkeit der Rechnungsdaten der Rechnung in dieser Zeile sicher in Übereinstimmung mit dem französischen Finanzgesetz von 2018 gegen Mehrwertsteuerbetrug.</p><p>Wenn anstelle dieses Symbol ein rotes Symbol erscheint, wenden Sie sich bitte sofort an den technischen Support.</p>"
|
||||
download:
|
||||
title: "Herunterladen"
|
||||
content: "Klicken Sie hier, um die Rechnung im PDF-Format herunterzuladen."
|
||||
refund:
|
||||
title: "Gutschrift"
|
||||
content: "Ermöglicht die Erstellung einer Gutschrift für die Rechnung in dieser Zeile oder für ihre Unterelemente. <strong>Warnung:</strong> Nur das Rechnungsdokument wird generiert, die tatsächliche Gutschrift für den Benutzer wird immer in Ihrer Verantwortung liegen."
|
||||
settings:
|
||||
title: "Einstellungen"
|
||||
content: "<p>Hier können Sie die Parameter für die Rechnungserstellung ändern. Klicken Sie auf das Element, das Sie bearbeiten wollen.</p><p>Insbesondere legen Sie hier fest, ob Sie der Mehrwertsteuer unterliegen und zu welchem Satz.</p>"
|
||||
codes:
|
||||
title: "Abrechnungscodes"
|
||||
content: "Legen Sie hier die Abrechnungscodes für alle Arten von Einträgen fest, die von der Software generiert werden. Diese Einstellung ist nur erforderlich, wenn Sie den Abrechnungsexport verwenden."
|
||||
export:
|
||||
title: "Abrechnungsexport"
|
||||
content: "Sobald die Codes konfiguriert sind, klicken Sie hier, um die Einträge in eine externe Buchhaltungssoftware zu exportieren."
|
||||
payment:
|
||||
title: "Zahlungseinstellungen"
|
||||
content: "Wenn Sie Ihren Mitgliedern die Möglichkeit geben, direkt online per Kreditkartenzahlung zu buchen, wird die Funktion von dieser Seite aus aktiviert und konfiguriert."
|
||||
periods:
|
||||
title: "Abrechnungszeiträume schließen"
|
||||
content: "<p>Die Bestimmungen IhresLandes können es erfordern, dass Sie Konten regelmäßig schließen müssen. Über diese Schaltfläche können Sie auf die Einstellungsmöglichkeiten zugreifen.</p> <p><strong>In Frankreich</strong> ist diese Schließung mindestens einmal im Jahr verpflichtend, wenn Sie dem MwSt.-Antibetrugsgesetz nach <a href='https://bofip.impots.gouv.fr/bofip/10691-PGP.html' target='_blank'>BOI-TVA-DECLA-30-10-30-20160803</a> unterworfen sind.</p><p>Zur Erinnerung: wenn Sie eine zertifizierte Software verwenden müssen (<a href='https://www.impots.gouv.fr/portail/suis-je-oblige-davoir-un-logiciel-de-caisse-securise' target='_blank'>Test hier</a>), sind Sie sind gesetzlich zur Vorlage eines Zertifikats der Einhaltung durch die Software verpflichtet. <a href='mailto:contact@fab-manager.com'>Kontaktieren Sie uns<a/>, um es zu erhalten.</p>"
|
||||
pricing:
|
||||
welcome:
|
||||
title: "Abonnements und Preise"
|
||||
content: "Verwalten Sie Abonnements und Preise für die Dienste, die Sie Ihren Mitgliedern anbieten."
|
||||
new_plan:
|
||||
title: "Neuer Abonnementplan"
|
||||
content: "Erstellen Sie Abonnementpläne, um regulären Benutzern ermäßigte Preise auf Maschinen und Räume anzubieten."
|
||||
trainings:
|
||||
title: "Schulungen"
|
||||
content: "Definieren Sie Preise der Schulungen nach Benutzergruppe."
|
||||
machines:
|
||||
title: "Maschinen"
|
||||
content: "Legen Sie hier die Preise für die Maschinenslots nach Benutzergruppe fest. Diese Preise gelten für Benutzer ohne Abonnements."
|
||||
spaces:
|
||||
title: "Räume"
|
||||
content: "Ebenso legen Sie hier die Preise der Raum-Slots für Benutzer ohne Abonnements fest."
|
||||
credits:
|
||||
title: "Gutschriften"
|
||||
content: "<p>Über Gutschriften können Benutzer mit Abonnements bestimmte Dienste kostenlos nutzen.</p><p>Sie können beispielsweise 2 Stunden 3D-Drucker für alle Jahresabonnementen anbieten oder eine Schulung Ihrer Wahl für Studierende etc.</p>"
|
||||
coupons:
|
||||
title: "Gutscheine"
|
||||
content: "Erstellen und verwalten Sie Gutscheine, um ihren Inhabern einzelne Rabatte zu bieten."
|
||||
events:
|
||||
welcome:
|
||||
title: "Veranstaltungen"
|
||||
content: "Hier erstellen und organisieren Sie Veranstaltungen und überwachen den Reservierungsverlauf."
|
||||
list:
|
||||
title: "Die Veranstaltungen"
|
||||
content: "Diese Liste zeigt vergangene oder zukünftige Veranstaltungen sowie die jeweilige Anzahl der Reservierungen."
|
||||
filter:
|
||||
title: "Veranstaltungen filtern"
|
||||
content: "Wahlweise nur zukünftige oder nur vergangene Veranstaltungen in der folgenden Liste anzeigen."
|
||||
categories:
|
||||
title: "Kategorien"
|
||||
content: "Mit Kategorien informieren Sie Ihre Nutzer über die jeweilige Veranstaltungsart. Neu erstellten Veranstaltungen muss eine Kategorie zugewiesen werden."
|
||||
themes:
|
||||
title: "Themen"
|
||||
content: "<p>Themen sind eine zusätzliche (optionale) Kategorisierung von Veranstaltungen. Sie können Veranstaltungen unterschiedlicher Formen gruppieren.</p><p>Ein zweitägiger Kurs zu Einlegearbeiten und ein Abendworkshop zum Umgang mit der Abrichte können z.B. unter dem Thema « Tischlerei » gruppiert werden.</p>"
|
||||
ages:
|
||||
title: "Altersgruppen"
|
||||
content: "Ein (optionaler) Filter, der Nutzern helfen kann, für sie geeignete Veranstaltungen zu finden."
|
||||
prices:
|
||||
title: "Preiskategorien"
|
||||
content: "Der Preis einer Veranstaltung hängt nicht von Gruppen oder Abonnements ab, sondern von den Kategorien, die Sie auf dieser Seite definieren."
|
||||
projects:
|
||||
welcome:
|
||||
title: "Projekte"
|
||||
content: "Hier können Sie alle Elemente definieren, die Mitgliedern für die Dokumentation ihrer Projekte zur Verfügung stehen. Ebenso können weitere Projekt-Parameter definiert werden."
|
||||
abuses:
|
||||
title: "Meldungen verwalten"
|
||||
content: "<p>Zugriff auf die Meldungsverwaltung.</p><p>Besucher können Projekte melden, beispielsweise wegen Urheberrechtsverletzungen oder Hetze.</p><p>Datenschutzrechtlich sind Sie zur Löschung dieser Meldungen verpflichtet, sobald die erforderlichen Maßnahmen durchgeführt wurden.</p>"
|
||||
settings:
|
||||
title: "Einstellungen"
|
||||
content: "<p>Kommentare, CAD-Dateien ... Verwalten Sie hier Projektparameter.</p><p>Sie können auch die OpenLab-Projekte aktivieren, um von anderen FabLabs geteilte Projekte in Ihrer Galerie anzuzeigen.</p>"
|
||||
statistics:
|
||||
welcome:
|
||||
title: "Statistiken"
|
||||
content: "<p>Zugriff auf Daten und Statistiken über die Mitglieder und deren Verwendungszwecke im FabLab.</p><p>Gemäß der Datenschutzverordnung werden Benutzer, die ihr Konto gelöscht haben, zwar weiter in den Statistiken aufgeführt, die Daten aber anonymisiert.</p>"
|
||||
export:
|
||||
title: "Daten exportieren"
|
||||
content: "Sie können wahlweise alle oder einen Teil der statistischen Daten in eine Excel-Datei exportieren."
|
||||
trending:
|
||||
title: "Entwicklung"
|
||||
content: "Visualisieren Sie mit Grafiken und Kurven die Entwicklung der FabLab-Nutzung über die Zeit."
|
||||
settings:
|
||||
welcome:
|
||||
title: "Anpassung der Applikation"
|
||||
content: "Von hier aus konfigurieren Sie allgemeine Einstellungen von Fab-Manager, können optionale Module aktiviert und deaktiviert sowie die Benutzeroberfläche angepasst werden."
|
||||
general:
|
||||
title: "Allgemeine Einstellungen"
|
||||
content: "Viele Einstellungen können von hier aus vorgenommen werden. Nehmen Sie sich für diese Seite Zeit: hier können Nachrichten, Dokumente, optionale Module, Registrierungen, das Erscheinungsbild von Fab-Manager und vieles mehr angepasst werden."
|
||||
home:
|
||||
title: "Startseite anpassen"
|
||||
content: "<p>Mit diesem WYSIWYG-Editor können Sie das Aussehen der Startseite anpassen, indem Sie verschiedene Komponenten verwenden (letzter Tweet, Kurzinformation etc.).</p><p><strong>Warnung:</strong> Beachten Sie, dass unbedachte Änderungen das Aussehen der Startseite beschädigen können.</p>"
|
||||
components:
|
||||
title: "Komponente einfügen"
|
||||
content: "Hier klicken, um eine bestehende Komponente in die Startseite einzufügen."
|
||||
codeview:
|
||||
title: "HTML-Code anzeigen"
|
||||
content: "Über diese Schaltfläche kann der HTML-Code der Startseite direkt angezeigt und bearbeitet werden. Diese Vorgehensweise wird empfohlen, HTML-Kenntnisse sind vorausgesetzt."
|
||||
reset:
|
||||
title: "Rückgängig"
|
||||
content: "Sie können jederzeit die Originalseite wiederherstellen, indem Sie hier klicken."
|
||||
css:
|
||||
title: "Stylesheet anpassen"
|
||||
content: "Fortgeschrittene Benutzer können ein benutzerdefiniertes Stylesheet (CSS) für die Startseite erstellen."
|
||||
about:
|
||||
title: "Über"
|
||||
content: "Passen Sie diese Seite vollständig an, um Ihre Aktivitäten vorzustellen."
|
||||
privacy:
|
||||
title: "Datenschutzerklärung"
|
||||
content: "<p>Erklären Sie hier, wie die gesammelten Daten der Nutzer verwendet werden.</p><p>Die Datenschutzbestimmungen sehen eine Datenschutzerklärung vor sowie die Bestimmung eines Datenschutzbeauftragten.</p>"
|
||||
draft:
|
||||
title: "Entwurf"
|
||||
content: "Klicken Sie hier für die Vorlage einer Datenschutzerklärung, die Sie nur lesen und vervollständigen müssen."
|
||||
reservations:
|
||||
title: "Reservierungen"
|
||||
content: "Öffnungszeiten, Reservierungssstornierungen... Jedes Fablab hat seine eigenen Reservierungsregeln, die Sie auf dieser Seite festlegen können."
|
||||
open_api:
|
||||
welcome:
|
||||
title: "OpenAPI"
|
||||
content: "Fab-Manager bietet eine offene API an, über die externe Programme einfach auf Fab-Manager-Daten zugreifen können. Hier können Sie Zugriffe auf diese API gewähren."
|
||||
doc:
|
||||
title: "Dokumentation"
|
||||
content: "Klicken Sie hier, um die API Online-Dokumentation aufzurufen."
|
@ -346,7 +346,7 @@ en:
|
||||
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."
|
||||
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"
|
||||
@ -414,6 +414,7 @@ en:
|
||||
credit_note: "Credit note"
|
||||
display_more_invoices: "Display more invoices..."
|
||||
no_invoices_for_now: "No invoices for now."
|
||||
payment_schedules_list: "Payment schedules"
|
||||
invoicing_settings: "Invoicing settings"
|
||||
warning_invoices_disabled: "Warning : invoices are not enabled. No invoices will be generated by Fab-manager. Nevertheless, you must correctly fill the information below, especially VAT."
|
||||
change_logo: "Change logo"
|
||||
@ -639,6 +640,32 @@ en:
|
||||
currency_info_html: "Please specify below the currency used for online payment. You should provide a three-letter ISO code, from the list of <a href='https://stripe.com/docs/currencies' target='_blank'>Stripe supported currencies</a>."
|
||||
currency_alert_html: "<strong>Warning</strong>: 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"
|
||||
payment_schedules:
|
||||
filter_schedules: "Filter schedules"
|
||||
schedules_table:
|
||||
schedule_num: "Schedule #"
|
||||
date: "Date"
|
||||
price: "Price"
|
||||
customer: "Customer"
|
||||
deadline: "Deadline"
|
||||
amount: "Amount"
|
||||
state: "State"
|
||||
download: "Download"
|
||||
state_new: "Not yet due"
|
||||
state_pending: "Waiting for the cashing of the check"
|
||||
state_requires_payment_method: "The credit card must be updated"
|
||||
state_requires_action: "Action required"
|
||||
state_paid: "Paid"
|
||||
state_error: "Error"
|
||||
method_stripe: "by card"
|
||||
method_check: "by check"
|
||||
confirm_payment: "Confirm payment"
|
||||
solve: "Solve"
|
||||
update_card: "Update the card"
|
||||
document_filters:
|
||||
reference: "Reference"
|
||||
customer: "Customer"
|
||||
date: "Date"
|
||||
#management of users, labels, groups, and so on
|
||||
members:
|
||||
users_management: "Users management"
|
||||
|
@ -346,7 +346,7 @@ fr:
|
||||
confirmation_required: "Confirmation requise"
|
||||
do_you_really_want_to_delete_this_coupon: "Êtes-vous sûr(e) de vouloir supprimer ce code promotionnel ?"
|
||||
coupon_was_successfully_deleted: "Le code promotionnel a bien été supprimé."
|
||||
unable_to_delete_the_specified_coupon_already_in_use: "Impossible de supprimer le code promotionnel : il est utilisé dans des factures."
|
||||
unable_to_delete_the_specified_coupon_already_in_use: "Impossible de supprimer le code promotionnel : il est utilisé dans des factures et/ou des échéanciers."
|
||||
unable_to_delete_the_specified_coupon_an_unexpected_error_occurred: "Impossible de supprimer le code promotionnel : une erreur inattendue s'est produite."
|
||||
send_a_coupon: "Envoyer un code promo"
|
||||
coupon: "Code promo"
|
||||
@ -414,6 +414,7 @@ fr:
|
||||
credit_note: "Avoir"
|
||||
display_more_invoices: "Afficher plus de factures..."
|
||||
no_invoices_for_now: "Aucune facture pour le moment."
|
||||
payment_schedules_list: "Échéanciers de paiement"
|
||||
invoicing_settings: "Paramètres de facturation"
|
||||
warning_invoices_disabled: "Attention : les factures ne sont pas activées. Aucune facture ne sera générée par Fab-manager. Vous devez néanmoins remplir correctement les informations ci-dessous, particulièrement la TVA."
|
||||
change_logo: "Changer le logo"
|
||||
@ -639,6 +640,32 @@ fr:
|
||||
currency_info_html: "Veuillez indiquer la devise à utiliser lors des paiements en ligne. Vous devez fournir un code ISO à trois lettres, issu de la liste des <a href='https://stripe.com/docs/currencies' target='_blank'>devises supportées par Stripe</a>."
|
||||
currency_alert_html: "<strong>Attention</strong> : la devise ne peut pas être modifiée après que le premier paiement en ligne ait été effectué. Veuillez définir attentivement ce paramètre avant d'ouvrir Fab-manager à vos membres."
|
||||
stripe_currency: "Devise Stripe"
|
||||
payment_schedules:
|
||||
filter_schedules: "Filtrer les échéanciers"
|
||||
schedules_table:
|
||||
schedule_num: "Échéancier n°"
|
||||
date: "Date"
|
||||
price: "Prix"
|
||||
customer: "Client"
|
||||
deadline: "Échéance"
|
||||
amount: "Montant"
|
||||
state: "État"
|
||||
download: "Télécharger"
|
||||
state_new: "Pas encore à l'échéance"
|
||||
state_pending: "En attente de l'encaissement du chèque"
|
||||
state_requires_payment_method: "La carte bancaire doit être mise à jour"
|
||||
state_requires_action: "Action requise"
|
||||
state_paid: "Payée"
|
||||
state_error: "Erreur"
|
||||
method_stripe: "par carte"
|
||||
method_check: "par chèque"
|
||||
confirm_payment: "Confirmer l'encaissement"
|
||||
solve: "Résoudre"
|
||||
update_card: "Mettre à jour la carte"
|
||||
document_filters:
|
||||
reference: "Référence"
|
||||
customer: "Client"
|
||||
date: "Date"
|
||||
#management of users, labels, groups, and so on
|
||||
members:
|
||||
users_management: "Gestion des utilisateurs"
|
||||
|
183
config/locales/app.logged.de.yml
Normal file
183
config/locales/app.logged.de.yml
Normal file
@ -0,0 +1,183 @@
|
||||
de:
|
||||
app:
|
||||
logged:
|
||||
#user's profile completion page when logging from an SSO provider
|
||||
profile_completion:
|
||||
confirm_your_new_account: "Bestätigen Sie Ihr neues Konto"
|
||||
you_ve_just_created_a_new_account_on_the_fablab_by_logging_from: "Sie haben ein neues Konto auf {GENDER, select, neutral{} other{dem}} {NAME} erstellt, über Anmeldung von"
|
||||
we_need_some_more_details: "Um die Einrichtung der Plattform abzuschließen, benötigen wir weitere Details"
|
||||
your_email_is_already_used_by_another_account_on_the_platform: "Ihre E-Mail-Adresse scheint bereits von einem anderen Benutzer verwendet zu werden. Prüfen Sie bitte Ihr Postfach und geben Sie den Code ein, der Ihnen geschickt wurde."
|
||||
or: "oder"
|
||||
please_fill_the_following_form: "Bitte füllen Sie das folgende Formular aus"
|
||||
some_data_may_have_already_been_provided_by_provider_and_cannot_be_modified: "Einige Daten wurden möglicherweise bereits von {NAME} bereitgestellt und können nicht geändert werden"
|
||||
then_click_on_: "Dann klicken Sie auf"
|
||||
_to_start_using_the_application: "um die Anwendung zu verwenden"
|
||||
new_on_this_platform: "Neu auf dieser Plattform?"
|
||||
your_email_: "Ihre E-Mail-Adresse"
|
||||
_is_currently_associated_with_another_account_on_this_platform: "ist derzeit mit einem anderen Konto auf dieser Plattform verknüpft."
|
||||
please_click_to_change_email_associated_with_your_PROVIDER_account: "Wenn es nicht Ihre Mailadresse ist, klicken Sie bitte auf den folgenden Button, um die E-Mail zu ändern, die mit Ihrem {PROVIDER} -Konto verknüpft ist."
|
||||
do_you_already_have_an_account: "Haben Sie bereits ein Konto?"
|
||||
do_not_fill_the_form_beside_but_specify_here_the_code_you_ve_received_by_email_to_recover_your_access: "Füllen Sie nicht das Formular aus. Geben Sie stattdessen hier den Code an, den Sie per E-Mail erhalten haben, um Ihren Zugang wiederherzustellen."
|
||||
just_specify_code_here_to_recover_access: "Geben Sie hier den Code an, den Sie per E-Mail erhalten haben, um Ihren Zugriff wiederherzustellen."
|
||||
i_did_not_receive_the_code: "Ich habe den Code nicht erhalten"
|
||||
authentification_code: "Authentifizierungscode"
|
||||
confirm_my_code: "Meinen Authentifizierungscode bestätigen"
|
||||
an_unexpected_error_occurred_check_your_authentication_code: "Ein unerwarteter Fehler ist aufgetreten. Bitte überprüfen Sie Ihren Authentifizierungscode."
|
||||
send_code_again: "Code erneut senden"
|
||||
email_address_associated_with_your_account: "E-Mail-Adresse, die Ihrem Konto zugeordnet ist"
|
||||
email_is_required: "E-Mail-Adresse ist erforderlich"
|
||||
email_format_is_incorrect: "E-Mail-Format ist falsch"
|
||||
code_successfully_sent_again: "Code erfolgreich erneut gesendet"
|
||||
used_for_statistics: "Diese Daten werden für statistische Zwecke verwendet"
|
||||
your_user_s_profile: "Ihr Benutzerprofil"
|
||||
user_s_profile_is_required: "Benutzerprofil ist erforderlich."
|
||||
i_ve_read_and_i_accept_: "Ich habe gelesen und akzeptiere"
|
||||
_the_fablab_policy: "die FabLab Richtlinie"
|
||||
change_my_data: "Meine Daten ändern"
|
||||
sync_my_profile: "Mein Profil synchronisieren"
|
||||
once_your_data_are_up_to_date_: "Sobald Ihre Daten auf dem neuesten Stand sind,"
|
||||
_click_on_the_synchronization_button_opposite_: "klicken Sie auf den Synchronisation-Button gegenüber"
|
||||
_disconnect_then_reconnect_: "trennen und erneut verbinden"
|
||||
_for_your_changes_to_take_effect: "damit Ihre Änderungen wirksam werden."
|
||||
dashboard:
|
||||
#dashboard: public profile
|
||||
profile:
|
||||
empty: ''
|
||||
#dashboard: edit my profile
|
||||
settings:
|
||||
last_activity_on_: "Letzte Aktivität am {DATE}"
|
||||
i_want_to_change_group: "Ich möchte die Gruppe ändern!"
|
||||
your_subscription_expires_on_: "Ihr Abonnement endet am"
|
||||
no_subscriptions: "Keine Abonnements"
|
||||
i_want_to_subscribe: "Ich möchte mich anmelden!"
|
||||
to_come: "demnächst"
|
||||
approved: "bestätigt"
|
||||
projects: "Projekte"
|
||||
no_projects: "Keine Projekte"
|
||||
labels: "Labels"
|
||||
no_labels: "Keine Labels"
|
||||
cookies: "Cookies"
|
||||
cookies_accepted: "Sie haben Cookies akzeptiert"
|
||||
cookies_declined: "Sie haben Cookies abgelehnt"
|
||||
cookies_unset: "Sie haben noch keine Cookie-Auswahl getroffen"
|
||||
reset_cookies: "Meine Wahl ändern"
|
||||
delete_my_account: "Mein Konto löschen"
|
||||
edit_my_profile: "Mein Profil bearbeiten"
|
||||
your_group_has_been_successfully_changed: "Ihre Gruppe wurde erfolgreich geändert."
|
||||
an_unexpected_error_prevented_your_group_from_being_changed: "Ein unerwarteter Fehler verhinderte, dass Ihre Gruppe geändert wurde."
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
confirm_delete_your_account: "Wollen Sie wirklich Ihr Konto löschen?"
|
||||
all_data_will_be_lost: "Alle Ihre Daten werden gelöscht und können nicht wiederhergestellt werden."
|
||||
invoicing_data_kept: "Nach geltender Gesetzeslage werden alle rechnungsrelevanten Daten für 10 Jahre separat aufbewahrt."
|
||||
statistic_data_anonymized: "Einige Daten (Geschlecht, Geburtsdatum, Gruppe) werden anonymisiert und zu statistischen Zwecken gespeichert."
|
||||
no_further_access_to_projects: "Ihre veröffentlichten Projekte werden anonymisiert, Sie werden keine Bearbeitungsmöglichkeit mehr haben."
|
||||
your_user_account_has_been_successfully_deleted_goodbye: "Ihr Benutzerkonto wurde erfolgreich gelöscht. Auf Wiedersehen!"
|
||||
an_error_occured_preventing_your_account_from_being_deleted: "Ein Fehler hat das Löschen Ihres Kontos verhindert."
|
||||
used_for_statistics: "Diese Daten werden für statistische Zwecke verwendet"
|
||||
used_for_invoicing: "Diese Daten werden für Abrechnungszwecke verwendet"
|
||||
used_for_reservation: "Diese Daten werden im Fall einer Buchungsänderung verwendet"
|
||||
used_for_profile: "Diese Daten werden nur auf Ihrem Profil angezeigt"
|
||||
used_for_pricing_stats: "Diese Daten werden zur Bestimmung der Ihnen gewährten Preise und zu statistischen Zwecken verwendet"
|
||||
public_profile: "Sie werden über ein öffentliches Profil verfügen, andere Nutzer können Sie in ihren Projekten einbinden"
|
||||
trainings: "Schulungen"
|
||||
no_trainings: "Keine Schulungen"
|
||||
subscription: "Abonnement"
|
||||
group: "Gruppe"
|
||||
or: "oder"
|
||||
confirm_changes: "Änderungen bestätigen"
|
||||
change_my_data: "Meine Daten ändern"
|
||||
sync_my_profile: "Mein Profil synchronisieren"
|
||||
once_your_data_are_up_to_date_: "Sobald Ihre Daten auf dem neuesten Stand sind,"
|
||||
_click_on_the_synchronization_button_opposite_: "klicken Sie auf den Synchronisation-Button gegenüber"
|
||||
_disconnect_then_reconnect_: "trennen und erneut verbinden"
|
||||
_for_your_changes_to_take_effect: "damit Ihre Änderungen wirksam werden."
|
||||
#dashboard: my projects
|
||||
projects:
|
||||
you_dont_have_any_projects: "Sie haben keine Projekte."
|
||||
add_a_project: "Projekt hinzufügen"
|
||||
author: "Autor"
|
||||
collaborator: "Mitarbeitende"
|
||||
rough_draft: "Entwurf"
|
||||
description: "Beschreibung"
|
||||
machines_and_materials: "Maschinen und Materialien"
|
||||
machines: "Maschinen"
|
||||
materials: "Materialien"
|
||||
collaborators: "Mitarbeitende"
|
||||
#dashboard: my trainings
|
||||
trainings:
|
||||
your_next_trainings: "Ihre nächsten Schulungen"
|
||||
your_previous_trainings: "Ihre vorigen Schulungen"
|
||||
your_approved_trainings: "Ihre bestätigten Trainings"
|
||||
no_trainings: "Keine Schulungen"
|
||||
#dashboard: my events
|
||||
events:
|
||||
your_next_events: "Ihre nächsten Termine"
|
||||
no_events_to_come: "Keine anzuzeigenden Termine"
|
||||
your_previous_events: "Ihre vorherigen Termine"
|
||||
no_passed_events: "Keine vergangenen Termine"
|
||||
NUMBER_normal_places_reserved: "{NUMBER} {NUMBER, plural, one {} =0{} =1{normaler Platz reserviert} other{normale Plätze reserviert}}"
|
||||
NUMBER_of_NAME_places_reserved: "{NUMBER} {NUMBER, plural, one {} =0{} =1{{NAME}-Platz reserviert} other{{NAME}-Plätze reserviert}}"
|
||||
#dashboard: my invoices
|
||||
invoices:
|
||||
reference_number: "Referenznummer"
|
||||
date: "Datum"
|
||||
price: "Preis"
|
||||
download_the_invoice: "Rechnung herunterladen"
|
||||
download_the_credit_note: "Rückerstattungsrechnung herunterladen"
|
||||
no_invoices_for_now: "Momentan keine Rechnungen."
|
||||
#public profil of a member
|
||||
members_show:
|
||||
members_list: "Mitgliederliste"
|
||||
#list of members accepting to be contacted
|
||||
members:
|
||||
the_fablab_members: "Die FabLab-Mitglieder"
|
||||
display_more_members: "Weitere Mitglieder anzeigen..."
|
||||
no_members_for_now: "Keine Mitglieder im Moment"
|
||||
avatar: "Benutzerbild"
|
||||
user: "Nutzer"
|
||||
pseudonym: "Pseudonym"
|
||||
email_address: "E‐Mail‐Adresse"
|
||||
#add a new project
|
||||
projects_new:
|
||||
add_a_new_project: "Neues Projekt hinzufügen"
|
||||
#modify an existing project
|
||||
projects_edit:
|
||||
edit_the_project: "Projekt bearbeiten"
|
||||
rough_draft: "Entwurf"
|
||||
publish: "Veröffentlichen"
|
||||
#book a machine
|
||||
machines_reserve:
|
||||
machine_planning: "Belegungsplan"
|
||||
i_ve_reserved: "Ich habe reserviert"
|
||||
not_available: "Nicht verfügbar"
|
||||
i_reserve: "Ich reserviere"
|
||||
i_shift: "Ich verschiebe"
|
||||
i_change: "Ich ändere"
|
||||
do_you_really_want_to_cancel_this_reservation: "Diese Reservierung stornieren?"
|
||||
reservation_was_cancelled_successfully: "Die Reservierung wurde erfolgreich storniert."
|
||||
cancellation_failed: "Stornierung fehlgeschlagen."
|
||||
a_problem_occured_during_the_payment_process_please_try_again_later: "Während des Zahlungsvorgangs ist ein Problem aufgetreten. Bitte versuchen Sie es später erneut."
|
||||
#book a training
|
||||
trainings_reserve:
|
||||
trainings_planning: "Schulungsplanung"
|
||||
planning_of: "Planung von " #eg. Planning of 3d printer training
|
||||
all_trainings: "Alle Schulungen"
|
||||
cancel_my_selection: "Auswahl aufheben"
|
||||
i_change: "Ich ändere"
|
||||
i_shift: "Ich verschiebe"
|
||||
i_ve_reserved: "Ich reservierte"
|
||||
#book a space
|
||||
space_reserve:
|
||||
planning_of_space_NAME: "Planung des {NAME} Raumes"
|
||||
i_ve_reserved: "Ich reservierte"
|
||||
i_shift: "Ich verschiebe"
|
||||
i_change: "Ich ändere"
|
||||
notifications:
|
||||
notifications_center: "Mitteilungszentrale"
|
||||
mark_all_as_read: "Alle als gelesen markieren"
|
||||
date: "Datum"
|
||||
notif_title: "Titel"
|
||||
no_new_notifications: "Keine neuen Benachrichtigungen."
|
||||
archives: "Archiv"
|
||||
no_archived_notifications: "Keine archivierten Benachrichtigungen."
|
||||
load_the_next_notifications: "Lade die nächsten Benachrichtigungen..."
|
449
config/locales/app.public.de.yml
Normal file
449
config/locales/app.public.de.yml
Normal file
@ -0,0 +1,449 @@
|
||||
de:
|
||||
app:
|
||||
public:
|
||||
#header and "about" page
|
||||
common:
|
||||
about_the_fablab: "Über {GENDER, select, male{den} female{die} neutral{} other{das}} {NAME}"
|
||||
return: "Zurück"
|
||||
#cookies
|
||||
cookies:
|
||||
about_cookies: "Diese Website verwendet Cookies zur Reichweitenmessung."
|
||||
learn_more: "Mehr erfahren"
|
||||
accept: "Cookies akzeptieren"
|
||||
decline: "Ablehnen"
|
||||
#dashboard sections
|
||||
dashboard: "Dashboard"
|
||||
my_profile: "Mein Profil"
|
||||
my_settings: "Persönliche Einstellungen"
|
||||
my_projects: "Meine Projekte"
|
||||
my_trainings: "Meine Trainings"
|
||||
my_events: "Meine Veranstaltungen"
|
||||
my_invoices: "Meine Rechnungen"
|
||||
my_wallet: "Mein Guthaben"
|
||||
#contextual help
|
||||
help: "Hilfe"
|
||||
#login/logout
|
||||
sign_out: "Abmelden"
|
||||
sign_up: "Registrieren"
|
||||
sign_in: "Anmelden"
|
||||
#left menu
|
||||
notifications: "Mitteilungen"
|
||||
admin: "Admin"
|
||||
manager: "Manager"
|
||||
reduce_panel: "Navigatiion reduzieren"
|
||||
#left menu (public)
|
||||
home: "Start"
|
||||
reserve_a_machine: "Maschine reservieren"
|
||||
trainings_registrations: "Schulungen - Anmeldung"
|
||||
events_registrations: "Veranstaltungen - Anmeldung"
|
||||
reserve_a_space: "Platz reservieren"
|
||||
projects_gallery: "Projekt-Galerie"
|
||||
subscriptions: "Abonnements"
|
||||
public_calendar: "Kalender"
|
||||
#left menu (admin)
|
||||
trainings_monitoring: "Schulungen"
|
||||
manage_the_calendar: "Kalender"
|
||||
manage_the_users: "Benutzer"
|
||||
manage_the_invoices: "Rechnungen"
|
||||
subscriptions_and_prices: "Abonnements und Preise"
|
||||
manage_the_events: "Veranstaltungen"
|
||||
manage_the_machines: "Maschinen"
|
||||
manage_the_spaces: "Räume"
|
||||
projects: "Projekte"
|
||||
statistics: "Statistiken"
|
||||
customization: "Anpassung"
|
||||
open_api_clients: "OpenAPI-Clients"
|
||||
#account creation modal
|
||||
create_your_account: "Eigenen Account erstellen"
|
||||
man: "Männlich"
|
||||
woman: "Weiblich"
|
||||
gender_is_required: "Die Angabe des Geschlechts ist erforderlich."
|
||||
your_first_name: "Dein Vorname"
|
||||
first_name_is_required: "Der Vorname ist erforderlich."
|
||||
your_surname: "Dein Nachname"
|
||||
surname_is_required: "Nachname ist erforderlich."
|
||||
your_pseudonym: "Dein Pseudonym"
|
||||
pseudonym_is_required: "Pseudonym ist erforderlich."
|
||||
your_email_address: "Deine E-Mail-Adresse"
|
||||
email_is_required: "E-Mail-Adresse ist erforderlich."
|
||||
your_password: "Passwort"
|
||||
password_is_required: "Passwort ist erforderlich."
|
||||
password_is_too_short: "Paßwort ist zu kurz (mindestens 8 Zeichen)"
|
||||
type_your_password_again: "Passwort erneut eingeben"
|
||||
password_confirmation_is_required: "Passwortbestätigung ist erforderlich."
|
||||
password_does_not_match_with_confirmation: "Die beiden Passworteingaben sind nicht identisch."
|
||||
i_am_an_organization: "Ich bin eine Organisation"
|
||||
name_of_your_organization: "Geben Sie den Namen ihrer Organisation ein"
|
||||
organization_name_is_required: "Name der Organisation ist erforderlich."
|
||||
address_of_your_organization: "Adresse Ihrer Organisation"
|
||||
organization_address_is_required: "Adresse der Organisation ist erforderlich."
|
||||
your_user_s_profile: "Dein Benutzerprofil"
|
||||
user_s_profile_is_required: "Benutzerprofil ist erforderlich."
|
||||
birth_date: "Geburtsdatum"
|
||||
birth_date_is_required: "Geburtsdatum ist erforderlich."
|
||||
phone_number: "Telefonnummer"
|
||||
phone_number_is_required: "Die Angabe der Telefonnummer ist erforderlich."
|
||||
i_authorize_Fablab_users_registered_on_the_site_to_contact_me: "Angemeldete Benutzer dürfen mich kontaktieren"
|
||||
i_accept_to_receive_information_from_the_fablab: "Das Fablab darf mir Informationen schicken"
|
||||
i_ve_read_and_i_accept_: "Ich habe gelesen und akzeptiere"
|
||||
_the_fablab_policy: "die FabLab Richtlinie"
|
||||
field_required: "Erforderliche Felder"
|
||||
unexpected_error_occurred: "Ein unerwarteter Fehler ist aufgetreten. Bitte versuche es später erneut."
|
||||
used_for_statistics: "Diese Daten werden für statistische Zwecke verwendet"
|
||||
used_for_invoicing: "Diese Daten werden für Abrechnungszwecke verwendet"
|
||||
used_for_reservation: "Diese Daten werden im Fall einer Buchungsänderung verwendet"
|
||||
used_for_profile: "Diese Daten werden nur auf deinem Profil angezeigt"
|
||||
public_profile: "Sie werden über ein öffentliches Profil verfügen, andere Nutzer können Sie in ihren Projekten einbinden"
|
||||
you_will_receive_confirmation_instructions_by_email_detailed: "In wenigen Minuten wirst Du eine Email erhalten mit der du deine Anmeldung bestätigen kannst."
|
||||
#password modification modal
|
||||
change_your_password: "Passwort ändern"
|
||||
your_new_password: "Ihr neues Passwort"
|
||||
your_password_was_successfully_changed: "Ihr Passwort wurde erfolgreich geändert."
|
||||
#connection modal
|
||||
connection: "Anmelden"
|
||||
password_forgotten: "Passwort vergessen?"
|
||||
confirm_my_account: "E-mail bestätigen"
|
||||
not_registered_to_the_fablab: "Nicht bei FabLab registriert?"
|
||||
create_an_account: "Erstelle ein Konto"
|
||||
wrong_email_or_password: "Falsche E-Mail Adresse oder Passwort."
|
||||
caps_lock_is_on: "Feststelltaste ist aktiviert"
|
||||
#confirmation modal
|
||||
you_will_receive_confirmation_instructions_by_email: "Sie erhalten eine Bestätigungsanleitung per E-Mail."
|
||||
#forgotten password modal
|
||||
your_email_address_is_unknown: "Ihre E-Mail-Adresse ist unbekannt."
|
||||
you_will_receive_in_a_moment_an_email_with_instructions_to_reset_your_password: "Sie erhalten in Kürze eine E-Mail mit Anweisungen zum Zurücksetzen Ihres Passworts."
|
||||
#Fab-manager's version
|
||||
version: "Version:"
|
||||
upgrade_fabmanager: "Fab-Manager aktualisieren"
|
||||
current_version: "Sie verwenden derzeit Version {VERSION} von Fab-Manager."
|
||||
upgrade_to: "Eine neue Version ist verfügbar. Sie können bis zu Version {VERSION} upgraden."
|
||||
read_more: "Details dieser Version ansehen"
|
||||
security_version_html: "<strong>Ihre aktuelle Version ist unsicher!</strong><br> Eine neue Version mit Sicherheitsupdates ist verfügbar. Aktualisieren Sie so bald wie möglich!"
|
||||
how_to: "So können Sie upgraden"
|
||||
#Notifications
|
||||
and_NUMBER_other_notifications: "und {NUMBER, plural, one {} =0{keine weiteren Benachrichtigungen} =1{eine weitere Benachrichtigung} other{{NUMBER} weitere Benachrichtigungen}}..."
|
||||
#about page
|
||||
about:
|
||||
read_the_fablab_policy: "Lesen Sie die FabLab-Richtlinie"
|
||||
read_the_fablab_s_general_terms_and_conditions: "Lesen Sie die allgemeinen Geschäftsbedingungen des FabLabs"
|
||||
your_fablab_s_contacts: "Ihre FabLab-Kontakte"
|
||||
privacy_policy: "Datenschutzerklärung"
|
||||
#'privacy policy' page
|
||||
privacy:
|
||||
title: "Datenschutzerklärung"
|
||||
dpo: "Datenschutzbeauftragter"
|
||||
last_update: "Letztes Update,"
|
||||
#home page
|
||||
home:
|
||||
latest_documented_projects: "Die neuesten dokumentierten Projekte"
|
||||
follow_us: "Folge uns"
|
||||
latest_tweets: "Die neuesten Tweets"
|
||||
latest_registered_members: "Neueste registrierte Mitglieder"
|
||||
create_an_account: "Neues Konto einrichten"
|
||||
discover_members: "Mitglieder entdecken"
|
||||
#next events summary on the home page
|
||||
fablab_s_next_events: "Fablab´s nächste Veranstaltungen"
|
||||
every_events: "Alle Veranstaltungen"
|
||||
from_date_to_date: "Von {START} bis {END}"
|
||||
on_the_date: "Am {DATE}"
|
||||
from_time_to_time: "Von {START} bis {END}"
|
||||
without_reservation: "Ohne Reservierung"
|
||||
free_admission: "Freier Zugang"
|
||||
full_price: "Voller Preis: "
|
||||
event_full: "Event ausgebucht"
|
||||
still_available: "Verfügbare Plätze: "
|
||||
all_day: "Ganztägig"
|
||||
#projects gallery
|
||||
projects_list:
|
||||
the_fablab_projects: "Die Fab Lab-Projekte"
|
||||
add_a_project: "Projekt hinzufügen"
|
||||
search_over_the_whole_network: "Suche über das gesamte Fab-Manager-Netzwerk"
|
||||
tooltip_openlab_projects_switch: "Mit der Suche über das gesamte Netzwerk können Sie die Projekte aller Fab-Manager durchsuchen, die diese Funktion nutzen!"
|
||||
openlab_search_not_available_at_the_moment: "Suche über das gesamte Netzwerk ist derzeit nicht verfügbar. Sie können nach Projekten auf dieser Plattform suchen."
|
||||
project_search_result_is_empty: "Leider haben wir keine Ergebnisse gefunden, die Ihren Suchkriterien entsprechen."
|
||||
reset_all_filters: "Alle Filter zurücksetzen"
|
||||
search: "Suche"
|
||||
all_projects: "Alle Projekte"
|
||||
my_projects: "Meine Projekte"
|
||||
projects_to_whom_i_take_part_in: "Projekte, an denen ich beteiligt bin"
|
||||
all_machines: "Alle Maschinen"
|
||||
all_themes: "Alle Themen"
|
||||
all_materials: "Alle Materialien"
|
||||
load_next_projects: "Nächste Projekte laden"
|
||||
rough_draft: "Grober Entwurf"
|
||||
#details of a projet
|
||||
projects_show:
|
||||
rough_draft: "Entwurf"
|
||||
project_description: "Projektbeschreibung"
|
||||
by_name: "Von {NAME}"
|
||||
step_N: "Schritt {INDEX}"
|
||||
share_on_facebook: "Auf Facebook teilen"
|
||||
share_on_twitter: "Auf Twitter teilen"
|
||||
deleted_user: "Gelöschter Nutzer"
|
||||
posted_on_: "Gepostet am"
|
||||
CAD_file_to_download: "{COUNT, plural, one {} =0{Keine CAD-Dateien} =1{CAD-Datei zum Download} other{CAD-Dateien zum Download}}"
|
||||
machines_and_materials: "Maschinen und Materialien"
|
||||
collaborators: "Mitarbeitende"
|
||||
licence: "Lizenz"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
report_an_abuse: "Missbrauch melden"
|
||||
unauthorized_operation: "Unerlaubter Vorgang"
|
||||
your_report_was_successful_thanks: "Deine Meldung wurde verschickt - vielen Dank."
|
||||
an_error_occured_while_sending_your_report: "Beim Senden Ihrer Meldung trat ein Fehler auf."
|
||||
your_first_name: "Ihr Vorname"
|
||||
your_first_name_is_required: "Der Vorname ist erforderlich."
|
||||
your_surname: "Ihr Nachname"
|
||||
your_surname_is_required: "Der Nachname ist erforderlich."
|
||||
your_email_address: "Ihre E-Mail-Adresse"
|
||||
your_email_address_is_required: "Die E-Mail-Adresse ist erforderlich."
|
||||
tell_us_why_this_looks_abusive: "Erklären Sie, warum das beleidigend wirkt"
|
||||
message_is_required: "Nachricht erforderlich."
|
||||
report: "Melden"
|
||||
do_you_really_want_to_delete_this_project: "Wollen Sie dieses Projekt wirklich löschen?"
|
||||
#list of machines
|
||||
machines_list:
|
||||
the_fablab_s_machines: "Die Maschinen des FabLabs"
|
||||
add_a_machine: "Maschine hinzufügen"
|
||||
new_availability: "Verfügbare Reservierungen"
|
||||
book: "Buchen"
|
||||
_or_the_: " oder die "
|
||||
status_enabled: "Aktiviert"
|
||||
status_disabled: "Deaktiviert"
|
||||
status_all: "Alle"
|
||||
#details of a machine
|
||||
machines_show:
|
||||
book_this_machine: "Diese Maschine buchen"
|
||||
technical_specifications: "Technische Spezifikationen"
|
||||
files_to_download: "Dateien zum Herunterladen"
|
||||
projects_using_the_machine: "Projekte mit der Maschine"
|
||||
_or_the_: " oder die "
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_delete_this_machine: "Möchten Sie diese Maschine wirklich löschen?"
|
||||
unauthorized_operation: "Unerlaubter Vorgang"
|
||||
the_machine_cant_be_deleted_because_it_is_already_reserved_by_some_users: "Die Maschine kann nicht gelöscht werden, da sie bereits von einigen Benutzern reserviert ist."
|
||||
#list of trainings
|
||||
trainings_list:
|
||||
book: "Buchen"
|
||||
the_trainings: "Schulungen"
|
||||
#details of a training
|
||||
training_show:
|
||||
book_this_training: "Diese Schulung buchen"
|
||||
do_you_really_want_to_delete_this_training: "Möchten Sie diese Schulung wirklich löschen?"
|
||||
unauthorized_operation: "Unerlaubter Vorgang"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
the_training_cant_be_deleted_because_it_is_already_reserved_by_some_users: "Die Schulung kann nicht gelöscht werden, da sie bereits von einigen Benutzern gebucht ist."
|
||||
#summary of the subscriptions
|
||||
plans:
|
||||
subscriptions: "Abonnements"
|
||||
i_choose_that_plan: "Ich wähle dieses Abo"
|
||||
i_subscribe_online: "Ich abonniere online"
|
||||
i_already_subscribed: "Ich habe bereits abonniert"
|
||||
more_information: "Weitere Informationen"
|
||||
your_subscription_expires_on_the_DATE: "Ihr Abonnement läuft ab am {DATE}"
|
||||
no_plans: "Für Ihre Gruppe sind keine Pläne verfügbar"
|
||||
my_group: "Meine Gruppe"
|
||||
his_group: "{GENDER, select, male{Seine} female{Ihre} other{Seine}} Gruppe"
|
||||
he_wants_to_change_group: "{ROLE, select, member{Ich möchte} other{Der Benutzer möchte}} die Gruppe wechseln"
|
||||
change_my_group: "Ändere {ROLE, select, member{meine} other{{GENDER, select, male{seine} female{ihre} other{seine}}}} Gruppe"
|
||||
summary: "Zusammenfassung"
|
||||
your_subscription_has_expired_on_the_DATE: "Ihr Abonnement ist am {DATE} abgelaufen"
|
||||
subscription_price: "Abonnementspreis"
|
||||
you_ve_just_selected_a_subscription_html: "Sie haben ein <strong>Abonnement</strong> ausgewählt:"
|
||||
confirm_and_pay: "Bestätigen und bezahlen"
|
||||
you_ve_just_payed_the_subscription_html: "Sie bezahlten das <strong>Abonnement</strong>:"
|
||||
thank_you_your_subscription_is_successful: "Vielen Dank. Ihr Abonnement ist erfolgt!"
|
||||
your_invoice_will_be_available_soon_from_your_dashboard: "Ihre Rechnung wird bald in Ihrem Dashboard verfügbar sein"
|
||||
your_group_was_successfully_changed: "Ihre Gruppe wurde erfolgreich geändert."
|
||||
the_user_s_group_was_successfully_changed: "Die Gruppe des Nutzers wurde erfolgreich geändert."
|
||||
an_error_prevented_your_group_from_being_changed: "Ein Fehler verhinderte das Ändern Ihrer Gruppe."
|
||||
an_error_prevented_to_change_the_user_s_group: "Fehler beim Ändern der Benutzergruppe."
|
||||
an_error_occured_during_the_payment_process_please_try_again_later: "Beim Zahlungsvorgang ist ein Problem aufgetreten. Bitte versuchen Sie es später erneut."
|
||||
subscription_confirmation: "Abonnementbestätigung"
|
||||
here_is_the_NAME_subscription_summary: "Hier ist die Zusammenfassung des {NAME}-Abonnements:"
|
||||
confirm_payment_of_html: "{ROLE, select, admin{Bezahlung vor Ort} other{Bezahlen}}: {AMOUNT}" #(contexte : validate a payment of $20,00)
|
||||
online_payment_disabled: "Zahlung per Kreditkarte ist nicht möglich. Bitte kontaktieren Sie die FabLab Rezeption direkt."
|
||||
#Fablab's events list
|
||||
events_list:
|
||||
the_fablab_s_events: "Veranstaltungen des Fablabs"
|
||||
all_categories: "Alle Kategorien"
|
||||
for_all: "Für alle"
|
||||
sold_out: "Ausverkauft"
|
||||
cancelled: "Storniert"
|
||||
free_admission: "Freier Zugang"
|
||||
still_available: "verfügbare Plätze"
|
||||
without_reservation: "Ohne Reservierung"
|
||||
add_an_event: "Veranstaltung hinzufügen"
|
||||
load_the_next_events: "Die nächsten Events laden..."
|
||||
full_price_: "Voller Preis:"
|
||||
to_date: "bis" #eg. from 01/01 to 01/05
|
||||
all_themes: "Alle Themen"
|
||||
#details and booking of an event
|
||||
events_show:
|
||||
event_description: "Beschreibung"
|
||||
downloadable_documents: "Herunterladbare Dokumente"
|
||||
information_and_booking: "Information und Buchung"
|
||||
dates: "Datum"
|
||||
beginning: "Beginn:"
|
||||
ending: "Endet:"
|
||||
opening_hours: "Öffnungszeiten:"
|
||||
all_day: "Ganztägig"
|
||||
from_time: "Von" #eg. from 18:00 to 21:00
|
||||
to_time: "bis" #eg. from 18:00 to 21:00
|
||||
full_price_: "Voller Preis:"
|
||||
tickets_still_availables: "noch verfügbare Tickets:"
|
||||
sold_out: "Ausverkauft."
|
||||
without_reservation: "Ohne Reservierung"
|
||||
cancelled: "Storniert"
|
||||
ticket: "{NUMBER, plural, one{Ticket} other{Tickets}}"
|
||||
make_a_gift_of_this_reservation: "Diese Reservierung verschenken"
|
||||
thank_you_your_payment_has_been_successfully_registered: "Vielen Dank. Ihre Zahlung wurde erfolgreich gebucht!"
|
||||
you_can_find_your_reservation_s_details_on_your_: "Sie finden die Reservierungsdetails in Ihrem"
|
||||
dashboard: "Dashboard"
|
||||
you_booked_DATE: "Sie haben gebucht ({DATE}):"
|
||||
canceled_reservation_SEATS: "Reservierung storniert ({SEATS} Plätze)"
|
||||
book: "Buchen"
|
||||
confirm_and_pay: "Bestätigen und bezahlen"
|
||||
confirm_payment_of_html: "{ROLE, select, admin{Bezahlung vor Ort} other{Bezahlen}}: {AMOUNT}" #(contexte : validate a payment of $20,00)
|
||||
online_payment_disabled: "Zahlung per Kreditkarte ist nicht möglich. Bitte kontaktieren Sie die FabLab Rezeption direkt."
|
||||
please_select_a_member_first: "Bitte wählen Sie zuerst ein Mitglied"
|
||||
change_the_reservation: "Reservierung ändern"
|
||||
you_can_shift_this_reservation_on_the_following_slots: "Sie können diese Reservierung auf die folgenden Slots verschieben:"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_delete_this_event: "Möchten Sie diese Veranstaltung wirklich löschen?"
|
||||
delete_recurring_event: "Sie sind dabei, eine wiederkehrende Veranstaltung zu löschen. Was möchten Sie tun?"
|
||||
delete_this_event: "Nur diese Veranstaltung"
|
||||
delete_this_and_next: "Diese Veranstaltung sowie die folgenden"
|
||||
delete_all: "Alle Veranstaltungen"
|
||||
event_successfully_deleted: "Veranstaltung erfolgreich gelöscht."
|
||||
events_deleted: "Die Veranstaltung sowie {COUNT, plural, one {} =1{eine weitere} other{{COUNT} weitere}} wurden gelöscht"
|
||||
unable_to_delete_the_event: "Das Ereignis kann nicht gelöscht werden, es wurde möglicherweise von einem Mitglied gebucht"
|
||||
events_not_deleted: "Von {TOTAL} Veranstaltungen {COUNT, plural, one {} =1{wurde eine nicht gelöscht} other{wurden {COUNT} nicht gelöscht}}. Möglicherweise {COUNT, plural, =1{ist sie} other{sind sie}} bereits reserviert."
|
||||
cancel_the_reservation: "Reservierung stornieren"
|
||||
do_you_really_want_to_cancel_this_reservation_this_apply_to_all_booked_tickets: "Möchten Sie diese Reservierung wirklich stornieren? Dies gilt für alle gebuchten Tickets."
|
||||
reservation_was_successfully_cancelled: "Reservierung wurde erfolgreich storniert."
|
||||
cancellation_failed: "Stornierung fehlgeschlagen."
|
||||
event_is_over: "Die Veranstaltung ist vorbei."
|
||||
thanks_for_coming: "Vielen Dank für Ihr Kommen!"
|
||||
view_event_list: "Kommende Veranstaltungen anzeigen"
|
||||
share_on_facebook: "Auf Facebook teilen"
|
||||
share_on_twitter: "Auf Twitter teilen"
|
||||
#public calendar
|
||||
calendar:
|
||||
calendar: "Kalender"
|
||||
show_unavailables: "Nicht verfügbare Slots anzeigen"
|
||||
filter_calendar: "Kalender filtern"
|
||||
trainings: "Schulungen"
|
||||
machines: "Maschinen"
|
||||
spaces: "Räume"
|
||||
events: "Veranstaltungen"
|
||||
externals: "Andere Kalender"
|
||||
#list of spaces
|
||||
spaces_list:
|
||||
the_spaces: "Die Räume"
|
||||
new_availability: "Verfügbare Reservierungen"
|
||||
add_a_space: "Raum hinzufügen"
|
||||
status_enabled: "Aktiviert"
|
||||
status_disabled: "Deaktiviert"
|
||||
status_all: "Alle"
|
||||
book: "Buchen"
|
||||
#display the details of a space
|
||||
space_show:
|
||||
book_this_space: "Diesen Platz buchen"
|
||||
unauthorized_operation: "Unerlaubter Vorgang"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_delete_this_space: "Wollen Sie diesen Raum wirklich löschen?"
|
||||
the_space_cant_be_deleted_because_it_is_already_reserved_by_some_users: "Der Raum konnte nicht gelöscht werden, da er bereits von Nutzern reserviert wurde."
|
||||
characteristics: "Eigenschaften"
|
||||
files_to_download: "Dateien zum Herunterladen"
|
||||
projects_using_the_space: "Projekte, die den Raum nutzen"
|
||||
tour:
|
||||
conclusion:
|
||||
title: "Vielen Dank für Ihre Aufmerksamkeit"
|
||||
content: "<p>Um diese kontextabhängige Hilfe neu zu starten, können Sie jederzeit <strong>F1</strong> drücken oder klicken Sie im Benutzermenu auf [? Hilfe].</p><p>Zusätzliche Hilfe finden Sie in der <a href='https://github.com/sleede/fab-manager/raw/master/doc/fr/guide_utilisation_fab_manager_v4.5.pdf' target='_blank'>Benutzeranleitung</a> (nur auf Französisch).</p><p>Das Fab-Manager-Team bietet auch personalisierten Support (Hilfe beim Einstieg, Hilfe bei der Installation, Anpassung etc.), <a href='mailto:contact@fab-manager.com'>kontaktieren Sie uns</a> für weitere Informationen.</p>"
|
||||
welcome:
|
||||
welcome:
|
||||
title: "Willkommen bei Fab-Manager"
|
||||
content: "Zum leichteren Einstieg in die Anwendung bieten wir eine schnelle Tour über die Funktionen."
|
||||
home:
|
||||
title: "Startseite"
|
||||
content: "Wenn Du hier klickst, kommst du zurück zur Homepage, auf der du dich gerade befindest."
|
||||
machines:
|
||||
title: "Maschinen"
|
||||
content: "<p>Auf dieser Seite können Sie die Liste aller Maschinen einsehen und einen Slot im Namen eines Mitglieds reservieren.</p><p>Eine Maschine kann zum Beispiel ein 3D-Drucker sein.</p><p>Mitglieder können auch auf diese Seite zugreifen und eine Maschine selbst reservieren wenn Kreditkartenzahlung aktiviert ist, oder wenn einige Preise gleich 0 sind.</p>"
|
||||
trainings:
|
||||
title: "Schulungen"
|
||||
content: "<p>Auf dieser Seite können Sie die Liste aller Schulungen einsehen und ein Mitglied für eine Schulung registrieren.</p><p>Trainings können als Voraussetzungen gesetzt werden, bevor die Reservierung bestimmter Maschinen erlaubt wird.</p><p>Mitglieder können auch auf diese Seite zugreifen und sich für eine Schulung registrieren wenn Kreditkartenzahlung aktiviert ist, oder wenn einige Preise gleich 0 sind.</p>"
|
||||
spaces:
|
||||
title: "Räume"
|
||||
content: "<p>Auf dieser Seite können Sie die Liste aller verfügbaren Räume einsehen und einen Slot im Namen eines Mitglieds reservieren.</p><p>Ein Raum kann beispielsweise ein Meetingraum oder eine Holzwerkstatt sein.</p><p>Die Besonderheit von Räumen ist, dass sie von mehreren Mitgliedern gleichzeitig gebucht werden können. </p><p>Mitglieder können auf diese Seite zugreifen und selbst eine Maschine reservieren, wenn Kreditkartenzahlung aktiviert ist oder wenn einige Preise gleich 0 sind.</p>"
|
||||
events:
|
||||
title: "Veranstaltungen"
|
||||
content: "<p>Ein Tag der offenen Tür oder ein Kurzworkshop zum Schreibtischlampenbau? Hier drüben!</p><p>Veranstaltungen können gratis oder kostenpflichtig (mit Möglichkeit zur Preisstaffelung) sein, frei zugänglich oder reservierungspflichtig.</p><p>Auch hier haben Mitglieder Seitenzugriff und können Plätze für kostenlose Veranstaltungen buchen bzw. auch für eintrittspflichtige, wenn Kreditkartenzahlung aktiviert ist.</p>"
|
||||
calendar:
|
||||
title: "Terminübersicht"
|
||||
content: "Visualisieren Sie auf einen Blick alles, was für die nächsten Wochen geplant ist (Veranstaltungen, Schulungen, Maschinen etc.)."
|
||||
projects:
|
||||
title: "Projekte"
|
||||
content: "<p>Dokumentieren und teilen Sie Projekte mit der Community.</p><p>Wenn Sie OpenLab nutzen, haben SIe Zugriff auf die Projekte des gesamten Fab-Manager-Netzwerks. <a href='mailto:contact@fab-manager.com'>Kontaktieren Sie uns</a> für den kostenlosen Zugang!</p>"
|
||||
plans:
|
||||
title: "Abonnements"
|
||||
content: "Abonnements bieten eine Möglichkeit, Ihre Preise zu segmentieren und Vorteile für regelmäßige Nutzer zu bieten."
|
||||
admin:
|
||||
title: "{ROLE} -Abschnitt"
|
||||
content: "<p>Alle Elemente unterhalb sind nur für Administratoren und Manager zugänglich. Mit ihnen wird Fab-Manager verwaltet und konfiguriert.</p><p>Anklicken, um jeweils mehr zu erfahren.</p>"
|
||||
about:
|
||||
title: "Über"
|
||||
content: "Eine Seite, die Sie vollständig anpassen können, um Aktivitäten und Struktur Ihres Fablabs darzustellen."
|
||||
notifications:
|
||||
title: "Mitteilungszentrale"
|
||||
content: "<p>Jedes Mal, wenn etwas Wichtiges passiert (Reservierungen, Kontoerstellung, Aktivitäten der Mitglieder usw.), werden Sie hier benachrichtigt.</p><p>Auch Ihre Mitglieder erhalten dort Benachrichtigungen.</p>"
|
||||
profile:
|
||||
title: "Benutzermenü"
|
||||
content: "<p>zugriff auf Ihre persönlichen Informationen sowie Ihre Aktivitäten auf Fab-Manager.</p><p>Dieser Bereich ist auch jeweils für die Mitglieder verfügbar.</p>"
|
||||
news:
|
||||
title: "Neuigkeiten"
|
||||
content: "<p>In diesem Bereich können Sie Neuigkeiten anzeigen lassen.</p><p>Inhalte können Sie leicht unter « Anpassen », « Startseite » ändern.</p>"
|
||||
last_projects:
|
||||
title: "Letzte Projekte"
|
||||
content: "<p>Dieses Karussell scrollt durch die neuesten von Ihren Mitgliedern dokumentierten Projekte.</p>"
|
||||
last_tweet:
|
||||
title: "Letzter Tweet"
|
||||
content: "<p>Der letzte Tweet Ihres Tweeter-Feeds kann hier angezeigt werden.</p><p>Konfigurieren Sie ihn unter « Anpassen », « Startseite ».</p>"
|
||||
last_members:
|
||||
title: "Neueste Mitglieder"
|
||||
content: "Hier werden die letzten registrierten Mitglieder angezeigt, die ihre Adresse validiert und dem Kontaktieren zugestimmt haben."
|
||||
next_events:
|
||||
title: "Kommende Veranstaltungen"
|
||||
content: "Die nächsten drei geplanten Veranstaltungen werden in diesem Bereich angezeigt."
|
||||
customize:
|
||||
title: "Startseite anpassen"
|
||||
content: "<p>Diese Seite kann vollständig personalisiert werden.</p><p>Sie können <a href='mailto:contact@fab-manager.com'>uns kontaktieren</a> um eine maßgeschneiderte Anpassung der Startseite vorzunehmen.</p>"
|
||||
version:
|
||||
title: "Programmversion"
|
||||
content: "Bewegen Sie den Cursor über dieses Symbol, um die Version von Fab-Manager anzuzeigen. Wenn Sie nicht die aktuellste Version verwenden, wird das hier angezeigt. Per Klick erhalten Sie weitere Informationen."
|
||||
machines:
|
||||
welcome:
|
||||
title: "Maschinen"
|
||||
content: "<p>Maschinen sind die Werkzeuge, die Ihren Nutzern zur Verfügung stehen. Maschinen, die von den Mitgliedern reserviert werden können, müssen hier erstellt werden.</p><p>Sie können auch nicht buchbare oder frei verfügbare Maschinen anlegen, diesen sollten keine Verfügbarkeits-Slots zugewiesen werden.</p>"
|
||||
welcome_manager:
|
||||
title: "Maschinen"
|
||||
content: "Maschinen sind die Werkzeuge, die von Nutzern reserviert werden können."
|
||||
view:
|
||||
title: "Ansicht"
|
||||
content: "Um eine Maschine zu ändern oder zu löschen, klicken Sie bitte zuerst hier. Maschinen mit verknüpften Verfügbarkeits-Slots können nicht gelöscht, aber deaktiviert werden."
|
||||
reserve:
|
||||
title: "Reservieren"
|
||||
content: "Klicken Sie hier, um zu einer Übersicht der freien Slots zu gelangen. Dort können Sie diese Maschine für einen Benutzer buchen und bestehende Reservierungen verwalten."
|
||||
spaces:
|
||||
welcome:
|
||||
title: "Räume"
|
||||
content: "<p>Räume sind Orte für deine Nutzer, beispielsweise ein Meetingraum oder eine Holzwerkstatt. Räume, die von Nutzern reserviert werden können, müssen hier angelegt werden.</p><p>Das Besondere an Räumen ist, dass sie von mehreren Benutzern gleichzeitig reserviert werden können.</p>"
|
||||
welcome_manager:
|
||||
title: "Räume"
|
||||
content: "<p>Räume sind Orte, die von Nutzern reserviert werden können, beispielsweise ein Meetingraum oder eine Holzwerkstatt. </p><p>Das Besondere an Räumen ist, dass sie von mehreren Benutzern gleichzeitig reserviert werden können.</p>"
|
||||
view:
|
||||
title: "Ansicht"
|
||||
content: "Um einer Raum zu ändern oder zu löschen, klicken Sie bitte zuerst hier. Räume mit verknüpften Verfügbarkeits-Slots können nicht gelöscht, aber deaktiviert werden."
|
||||
reserve:
|
||||
title: "Reservieren"
|
||||
content: "Klicken Sie hier, um zu einer Übersicht der freien Slots zu gelangen. Dort können Sie diesen Raum für einen Benutzer buchen und bestehende Reservierungen verwalten."
|
446
config/locales/app.shared.de.yml
Normal file
446
config/locales/app.shared.de.yml
Normal file
@ -0,0 +1,446 @@
|
||||
de:
|
||||
app:
|
||||
shared:
|
||||
#translations of common buttons
|
||||
buttons:
|
||||
confirm_changes: "Änderungen bestätigen"
|
||||
consult: "Beschreibung"
|
||||
edit: "Bearbeiten"
|
||||
change: "Ändern"
|
||||
delete: "Löschen"
|
||||
browse: "Durchsuchen"
|
||||
cancel: "Abbrechen"
|
||||
close: "Schließen"
|
||||
clear: "Leeren"
|
||||
today: "Heute"
|
||||
confirm: "Bestätigen"
|
||||
save: "Speichern"
|
||||
"yes": "Ja"
|
||||
"no": "Nein"
|
||||
apply: "Anwenden"
|
||||
messages:
|
||||
you_will_lose_any_unsaved_modification_if_you_quit_this_page: "Sie verlieren jede ungespeicherte Änderung, wenn Sie diese Seite verlassen"
|
||||
you_will_lose_any_unsaved_modification_if_you_reload_this_page: "Ungespeicherte Änderungen gehen verloren, wenn Sie die Seite neu laden"
|
||||
payment_card_error: "Mit Ihrer Kreditkarte ist ein Problem aufgetreten:"
|
||||
#user edition form
|
||||
user:
|
||||
man: "Männlich"
|
||||
woman: "Weiblich"
|
||||
add_an_avatar: "Avatar hinzufügen"
|
||||
pseudonym: "Pseudonym"
|
||||
pseudonym_is_required: "Pseudonym ist erforderlich."
|
||||
first_name: "Ihr Vorname"
|
||||
first_name_is_required: "Der Vorname ist erforderlich."
|
||||
surname: "Ihr Nachname"
|
||||
surname_is_required: "Der Nachname ist erforderlich."
|
||||
email_address: "E‐Mail‐Adresse"
|
||||
email_address_is_required: "Die E-Mail-Adresse ist erforderlich."
|
||||
change_password: "Passwort ändern"
|
||||
new_password: "Neues Passwort"
|
||||
password_is_required: "Passwort ist erforderlich."
|
||||
password_is_too_short: "Passwort ist zu kurz (mindestens 8 Zeichen erforderlich)"
|
||||
confirmation_of_new_password: "Neues Passwort bestätigen"
|
||||
confirmation_of_password_is_required: "Passwortbestätigung ist erforderlich."
|
||||
confirmation_of_password_is_too_short: "Die Passwortbestätigung ist zu kurz (mindestens 8 Zeichen)."
|
||||
confirmation_mismatch_with_password: "Bestätigung stimmt nicht mit Passwort überein."
|
||||
organization_name: "Name der Organisation"
|
||||
organization_address: "Adresse der Organisation"
|
||||
date_of_birth: "Geburtsdatum"
|
||||
date_of_birth_is_required: "Geburtsdatum ist erforderlich."
|
||||
website: "Website"
|
||||
job: "Beruf/Tätigkeit"
|
||||
interests: "Interessen"
|
||||
CAD_softwares_mastered: "Kenntnisse in CAD-Software"
|
||||
birthday: "Geburtsdatum"
|
||||
birthday_is_required: "Das Geburtsdatum ist erforderlich."
|
||||
address: "Adresse"
|
||||
phone_number: "Telefonnummer"
|
||||
phone_number_is_required: "Die Angabe der Telefonnummer ist erforderlich."
|
||||
i_authorize_Fablab_users_registered_on_the_site_to_contact_me: "Angemeldete Benutzer dürfen mich kontaktieren"
|
||||
i_accept_to_receive_information_from_the_fablab: "I accept to receive information from the FabLab"
|
||||
used_for_statistics: "Diese Daten werden für statistische Zwecke verwendet"
|
||||
used_for_invoicing: "Diese Daten werden für Abrechnungszwecke verwendet"
|
||||
used_for_reservation: "Diese Daten werden im Fall einer Buchungsänderung verwendet"
|
||||
used_for_profile: "Diese Daten werden nur auf Ihrem Profil angezeigt"
|
||||
#project edition form
|
||||
project:
|
||||
name: "Name"
|
||||
name_is_required: "Name ist erforderlich."
|
||||
illustration: "Ansicht"
|
||||
add_an_illustration: "Illustration hinzufügen"
|
||||
CAD_file: "CAD-Datei"
|
||||
allowed_extensions: "Zugelassene Dateitypen:"
|
||||
add_a_new_file: "Neue Datei hinzufügen"
|
||||
description: "Beschreibung"
|
||||
description_is_required: "Beschreibung ist erforderlich."
|
||||
steps: "Schritte"
|
||||
step_N: "Schritt {INDEX}"
|
||||
step_title: "Titel des Schrits"
|
||||
add_a_picture: "Ein Bild hinzufügen"
|
||||
change_the_picture: "Bild ändern"
|
||||
delete_the_step: "Diesen Schritt löschen"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_delete_this_step: "Möchten Sie diesen Schritt wirklich löschen?"
|
||||
add_a_new_step: "Neuen Schritt hinzufügen"
|
||||
publish_your_project: "Projekt veröffentlichen"
|
||||
or: "oder"
|
||||
employed_materials: "Verwendetes Material"
|
||||
employed_machines: "Verwendete Maschinen"
|
||||
collaborators: "Mitarbeitende"
|
||||
creative_commons_licences: "Creative Commons-Lizenzen"
|
||||
themes: "Themen"
|
||||
tags: "Stichwörter"
|
||||
save_as_draft: "Als Entwurf speichern"
|
||||
#machine edition form
|
||||
machine:
|
||||
name: "Name"
|
||||
name_is_required: "Name ist erforderlich."
|
||||
illustration: "Ansicht"
|
||||
add_an_illustration: "Foto hinzufügen"
|
||||
description: "Beschreibung"
|
||||
description_is_required: "Beschreibung ist erforderlich."
|
||||
technical_specifications: "Techische Daten"
|
||||
technical_specifications_are_required: "Technische Spezifikationen sind erforderlich."
|
||||
attached_files_pdf: "Dateianhänge (pdf)"
|
||||
attach_a_file: "Eine Datei anfügen"
|
||||
add_an_attachment: "Anhang hinzufügen"
|
||||
disable_machine: "Maschine deaktivieren"
|
||||
validate_your_machine: "Bestätigen Sie Ihr Gerät"
|
||||
#frame to select a plan to subscribe
|
||||
plan_subscribe:
|
||||
subscribe_online: "online abonnieren"
|
||||
do_not_subscribe: "nicht abonnieren"
|
||||
#admin: choose a member to interact with
|
||||
member_select:
|
||||
select_a_member: "Ein Mitglied auswählen"
|
||||
start_typing: "Tippe ein..."
|
||||
#stripe payment modal
|
||||
stripe:
|
||||
online_payment: "Online-Bezahlung"
|
||||
i_have_read_and_accept_: "Ich habe gelesen und akzeptiere"
|
||||
_the_general_terms_and_conditions: "die allgemeinen Nutzungs- und Geschäftsbedingungen."
|
||||
credit_amount_for_pay_reservation: "{amount} {currency} muss noch bezahlt werden, um Ihre Reservierung zu bestätigen"
|
||||
client_credit_amount_for_pay_reservation: "{amount} {currency} muss noch bezahlt werden, um die Reservierung des Kunden zu bestätigen"
|
||||
confirm_payment_of_: "Bezahlen: {AMOUNT}"
|
||||
#dialog of on site payment for reservations
|
||||
valid_reservation_modal:
|
||||
booking_confirmation: "Buchungsbestätigung"
|
||||
here_is_the_summary_of_the_slots_to_book_for_the_current_user: "Hier ist die Zusammenfassung der zu buchenden Slots für den aktuellen Benutzer:"
|
||||
#event edition form
|
||||
event:
|
||||
title: "Titel"
|
||||
title_is_required: "Titel ist erforderlich."
|
||||
matching_visual: "Passendes Bild"
|
||||
choose_a_picture: "Bild auswählen"
|
||||
description: "Beschreibung"
|
||||
description_is_required: "Beschreibung ist erforderlich."
|
||||
attachments: "Dateianhänge"
|
||||
add_a_new_file: "Neue Datei hinzufügen"
|
||||
event_type: "Art der Veranstaltung"
|
||||
dates_and_opening_hours: "Termine und Öffnungszeiten"
|
||||
all_day: "Ganztägig"
|
||||
start_date: "Startdatum"
|
||||
end_date: "Enddatum"
|
||||
start_time: "Startzeit"
|
||||
end_time: "Ende"
|
||||
recurrence: "Wiederholung"
|
||||
_and_ends_on: "und endet am"
|
||||
prices_and_availabilities: "Preise und Verfügbarkeiten"
|
||||
standard_rate: "Standardpreis"
|
||||
0_equal_free: "0 = kostenlos"
|
||||
tickets_available: "Tickets verfügbar"
|
||||
event_theme: "Veranstaltungsthema"
|
||||
age_range: "Altersklasse"
|
||||
#subscription plan edition form
|
||||
plan:
|
||||
general_information: "Allgemeine Informationen"
|
||||
name: "Name"
|
||||
name_is_required: "Name ist erforderlich"
|
||||
name_length_must_be_less_than_24_characters: "Der Name muss weniger als 24 Zeichen lang sein."
|
||||
type: "Typ"
|
||||
partner: "Partner"
|
||||
standard: "Standard"
|
||||
type_is_required: "Typ ist erforderlich."
|
||||
group: "Gruppe"
|
||||
groups: "Gruppen"
|
||||
all: "Alle"
|
||||
transversal_all_groups: "Transversal (alle Gruppen)"
|
||||
group_is_required: "Gruppe ist erforderlich."
|
||||
number_of_periods: "Anzahl der Zeiträume"
|
||||
number_of_periods_is_required: "Anzahl der Zeiträume ist erforderlich."
|
||||
period: "Zeitraum"
|
||||
year: "Jahr"
|
||||
month: "Monat"
|
||||
week: "Woche"
|
||||
period_is_required: "Zeitraum ist erforderlich."
|
||||
subscription_price: "Abonnementspreis"
|
||||
price_is_required: "Preis ist erforderlich."
|
||||
visual_prominence_of_the_subscription: "Sichtbarkeit des Abonnements"
|
||||
on_the_subscriptions_page_the_most_prominent_subscriptions_will_be_placed_at_the_top_of_the_list: "Auf der Abonnement-Seite werden die prominentesten Abonnements ganz oben auf der Liste platziert."
|
||||
an_evelated_number_means_a_higher_prominence: "Eine höhere Zahl bedeutet einen höheren Stellenwert."
|
||||
rolling_subscription: "Rollendes Abonnement?"
|
||||
a_rolling_subscription_will_begin_the_day_of_the_first_training: "Ein rollendes Abonnement beginnt mit dem Tag der ersten Schulung."
|
||||
otherwise_it_will_begin_as_soon_as_it_is_bought: "Andernfalls beginnt es ab Kaufdatum."
|
||||
information_sheet: "Informationsblatt"
|
||||
attach_an_information_sheet: "Ein Informationsblatt anhängen"
|
||||
notified_partner: "Benachrichtigter Partner"
|
||||
new_user: "Neuer Nutzer..."
|
||||
as_part_of_a_partner_subscription_some_notifications_may_be_sent_to_this_user: "Als Teil eines Partnerabonnements können einige Benachrichtigungen an diesen Benutzer gesendet werden."
|
||||
new_partner: "Neuer Partner"
|
||||
first_name: "Vorname"
|
||||
first_name_is_required: "Der Vorname ist erforderlich."
|
||||
surname: "Nachname"
|
||||
surname_is_required: "Der Nachname ist erforderlich."
|
||||
email_address: "E‐Mail‐Adresse"
|
||||
email_address_is_required: "Die E-Mail-Adresse ist erforderlich."
|
||||
disabled: "Abonnement deaktivieren"
|
||||
disable_plan_will_not_unsubscribe_users: "Achtung: Das Deaktivieren dieses Pakets wird Benutzer mit aktiven Abonnements nicht abbestellen."
|
||||
#training edition form
|
||||
trainings:
|
||||
name: "Name"
|
||||
name_is_required: "Name ist erforderlich."
|
||||
illustration: "Abbildung"
|
||||
add_an_illustration: "Bild hinzufügen"
|
||||
description: "Beschreibung"
|
||||
description_is_required: "Beschreibung ist erforderlich."
|
||||
add_a_new_training: "Neue Schulung hinzufügen"
|
||||
validate_your_training: "Schulung bestätigen"
|
||||
associated_machines: "Verknüpfte Maschinen"
|
||||
number_of_tickets: "Anzahl der Tickets"
|
||||
public_page: "In Schulungslisten anzeigen"
|
||||
disable_training: "Training deaktivieren"
|
||||
#partial form to edit/create an user (admin view)
|
||||
user_admin:
|
||||
user: "Nutzer"
|
||||
incomplete_profile: "Unvollständiges Profil"
|
||||
user_profile: "Nutzerprofil"
|
||||
warning_incomplete_user_profile_probably_imported_from_sso: "Warnung: Das Profil dieses Benutzers ist unvollständig. Da \"Single Sign-on\" (SSO) Authentifizierung derzeit aktiviert ist, kann es sich wahrscheinlich um ein importiertes, aber nicht zusammengeführtes Konto handeln. Ändern Sie es nicht, es sei denn, Sie wissen, was Sie tun."
|
||||
group: "Gruppe"
|
||||
group_is_required: "Gruppe ist erforderlich."
|
||||
trainings: "Schulungen"
|
||||
tags: "Stichwörter"
|
||||
#partial form to edit/create an authentication provider (SSO)
|
||||
authentication:
|
||||
name: "Name"
|
||||
provider_name_is_required: "Sie müssen einen Providernamen eingeben."
|
||||
authentication_type: "Authentifizierungsart"
|
||||
local_database: "Lokale Datenbank"
|
||||
o_auth2: "OAuth 2.0"
|
||||
authentication_type_is_required: "Authentifizierungstyp ist erforderlich."
|
||||
data_mapping: "Datenzuordnung"
|
||||
expected_data_type: "Erwarteter Datentyp"
|
||||
input_format: "Eingabeformat"
|
||||
mappings: "Zuordnungen"
|
||||
#edition/creation form of an OAuth2 authentication provider
|
||||
oauth2:
|
||||
common_url: "Gemeinsame URL"
|
||||
common_url_is_required: "Gemeinsame URL ist erforderlich."
|
||||
provided_url_is_not_a_valid_url: "Die angegebene URL ist keine gültige URL."
|
||||
authorization_endpoint: "Authentifizierungs-Endpunkt"
|
||||
oauth2_authorization_endpoint_is_required: "OAuth 2.0 Autorisierungs-Endpunkt ist erforderlich."
|
||||
provided_endpoint_is_not_valid: "Angegebener Endpunkt ist ungültig."
|
||||
token_acquisition_endpoint: "Endpunkt der Token-Akquisition"
|
||||
oauth2_token_acquisition_endpoint_is_required: "Endpunkt des OAuth 2.0-Tokens ist erforderlich."
|
||||
profil_edition_url: "Profil-Editierungs-URL"
|
||||
profile_edition_url_is_required: "URL zur Profil-Editierung ist erforderlich."
|
||||
client_identifier: "Client-Identifier"
|
||||
oauth2_client_identifier_is_required: "OAuth 2.0 Client-Identifier ist erforderlich."
|
||||
obtain_it_when_registering_with_your_provider: "Wird während der Registrierung bei Ihrem Provider erhalten."
|
||||
client_secret: "Client-Geheimnis"
|
||||
oauth2_client_secret_is_required: "OAuth 2.0 Client-Geheimnis ist erforderlich."
|
||||
define_the_fields_mapping: "Definieren Sie die Zuordnung der Felder"
|
||||
add_a_match: "Fügen Sie eine Zuordnung hinzu"
|
||||
model: "Modell"
|
||||
field: "Felder"
|
||||
api_endpoint_url: "URL des API-Endpunkts"
|
||||
api_type: "API-Typ"
|
||||
api_fields: "API-Felder"
|
||||
#machine/training slot modification modal
|
||||
confirm_modify_slot_modal:
|
||||
change_the_slot: "Slot ändern"
|
||||
do_you_want_to_change_your_booking_slot_initially_planned_at: "Möchten Sie Ihren Buchungsslot ändern? Ursprünglich geplant um:"
|
||||
do_you_want_to_change_NAME_s_booking_slot_initially_planned_at: "Möchten Sie den {NAME}-Buchungsplatz ändern? Ursprünglich geplant um:"
|
||||
cancel_this_reservation: "Reservierung stornieren"
|
||||
i_want_to_change_date: "Ich möchte das Datum ändern"
|
||||
#modal introducing that a training is requested before booking a machine
|
||||
request_training_modal:
|
||||
to_book_the_MACHINE_you_must_have_completed_the_TRAINING: "Um \"{MACHINE}\" zu buchen, müssen Sie {TRAINING} abgeschlossen haben."
|
||||
register_for_the_training: "Zur Schulung anmelden"
|
||||
i_dont_want_to_register_now: "Ich möchte mich jetzt nicht anmelden"
|
||||
#modal introducing that a user must wait for his training being validated before booking a machine
|
||||
training_reservation_modal:
|
||||
machine_reservation: "Maschinenreservierung"
|
||||
you_must_wait_for_your_training_is_being_validated_by_the_fablab_team_to_book_this_machine: "Sie müssen bis zur Schulungsbestätigung warten, um diese Maschine buchen zu können."
|
||||
your_training_will_occur_: "Ihre Schulung wird stattfinden"
|
||||
#user public profile
|
||||
public_profile:
|
||||
last_activity_html: "Letzte Aktivität <br><strong>am {DATE}</strong>"
|
||||
to_come: "kommend"
|
||||
approved: "bestätigt"
|
||||
projects: "Projekte"
|
||||
no_projects: "Keine Projekte"
|
||||
author: "Autor"
|
||||
collaborator: "Mitarbeitende"
|
||||
private_profile: "Privates Profil"
|
||||
interests: "Interessen"
|
||||
CAD_softwares_mastered: "Kenntnisse in CAD-Software"
|
||||
email_address: "E‐Mail‐Adresse"
|
||||
trainings: "Schulungen"
|
||||
no_trainings: "Keine Schulungen"
|
||||
#wallet
|
||||
wallet:
|
||||
wallet: 'Guthabenkonto'
|
||||
your_wallet_amount: 'verfügbares Guthaben'
|
||||
wallet_amount: 'Verfügbares Guthaben'
|
||||
no_transactions_for_now: 'Momentan keine Transaktionen'
|
||||
date: "Datum"
|
||||
operation: 'Vorgang'
|
||||
operator: 'Operator'
|
||||
amount: 'Betrag'
|
||||
credit: 'Guthaben'
|
||||
debit: 'Lastschrift'
|
||||
credit_title: 'Guthabenkonto'
|
||||
credit_label: 'Legen Sie den Betrag der Gutschrift fest'
|
||||
confirm_credit_label: 'Bestätigen Sie den Betrag der Gutschrift'
|
||||
generate_a_refund_invoice: "Erstelle eine Rückerstattungs-Rechnung"
|
||||
creation_date_for_the_refund: "Erstellungsdatum für die Erstattung"
|
||||
creation_date_is_required: "Erstellungsdatum ist erforderlich."
|
||||
description_optional: "Beschreibung (optional):"
|
||||
will_appear_on_the_refund_invoice: "Wird auf der Rückerstattungsrechnung angezeigt."
|
||||
to_credit: 'Guthaben'
|
||||
wallet_credit_successfully: "Gutschrift wurde erfolgreich dem Guthaben des Benutzers gutgeschrieben."
|
||||
a_problem_occurred_for_wallet_credit: "Ein Problem ist aufgetreten, als dem Benutzer die Gutschrift gutgeschrieben wurde."
|
||||
amount_is_required: "Betrag ist erforderlich."
|
||||
amount_minimum_1: "Der Mindestbetrag ist 1"
|
||||
amount_confirm_is_required: "Die Bestätigung des Betrags ist erforderlich."
|
||||
amount_confirm_does_not_match: "Betrag und Betragsbestätigung stimmen nicht überein."
|
||||
you_have_amount_in_wallet: "Ihr Gutgaben beträgt {amount} {currency}"
|
||||
client_have_amount_in_wallet: "Das guthaben des Kunden beträgt {amount} {currency}"
|
||||
wallet_pay_reservation: "Sie können Ihre Reservierung direkt bezahlen"
|
||||
client_wallet_pay_reservation: "Das Mitglied kann seine Reservierung direkt bezahlen"
|
||||
debit_subscription: "Bezahlen für ein Abonnement"
|
||||
debit_reservation_training: "Für eine Schulungsreservierung bezahlen"
|
||||
debit_reservation_machine: "Für eine Maschinenreservierung bezahlen"
|
||||
debit_reservation_event: "Für eine Veranstaltungsreservierung bezahlen"
|
||||
warning_uneditable_credit: "Warnung: Nach der Bestätigung kann der gutgeschriebene Betrag nicht mehr bearbeitet werden."
|
||||
#promotional coupon (creation/edition form)
|
||||
coupon:
|
||||
name: "Name"
|
||||
name_is_required: "Name ist erforderlich."
|
||||
code: "Code"
|
||||
code_is_required: "Code ist erforderlich."
|
||||
code_must_be_composed_of_capital_letters_digits_and_or_dashes: "Der Code muss aus Großbuchstaben, Ziffern und/oder Bindestrichen bestehen."
|
||||
kind_of_coupon: "Art des Gutscheins"
|
||||
percentage: "Prozentsatz"
|
||||
amount: "Betrag"
|
||||
amount_off: "Vergünstigter Betrag"
|
||||
percent_off: "Vergünstigter Prozentsatz"
|
||||
percent_off_is_required: "Vergünstigter Prozentsatz ist erforderlich."
|
||||
percentage_must_be_between_0_and_100: "Prozentsatz muss zwischen 0 und 100 liegen."
|
||||
validity_per_user: "Gültigkeit pro Benutzer"
|
||||
once: "Nur einmal"
|
||||
forever: "Jede Nutzung"
|
||||
validity_per_user_is_required: "Validität pro Benutzer ist erforderlich."
|
||||
valid_until: "Gültig bis (inklusive)"
|
||||
leave_empty_for_no_limit: "Geben Sie keine Befristung an, indem Sie das Feld leer lassen."
|
||||
max_usages: "Maximal zulässige Nutzungen"
|
||||
max_usages_must_be_equal_or_greater_than_0: "Die Zahl der maximal zulässigen Verwendungen muss größer als 0 sein."
|
||||
enabled: "Aktiv"
|
||||
#coupon (input zone for users)
|
||||
coupon_input:
|
||||
i_have_a_coupon: "Ich habe einen Gutschein!"
|
||||
code_: "Code:"
|
||||
the_coupon_has_been_applied_you_get_PERCENT_discount: "Der Gutschein wurde angewendet. Sie erhalten einen Rabatt von {PERCENT}%."
|
||||
the_coupon_has_been_applied_you_get_AMOUNT_CURRENCY: "Der Gutschein wurde angewendet. Sie erhalten einen Rabatt von {AMOUNT} {CURRENCY}."
|
||||
unable_to_apply_the_coupon_because_disabled: "Der Gutschein konnte nicht angewendet werden: Dieser Code wurde deaktiviert."
|
||||
unable_to_apply_the_coupon_because_expired: "Der Gutschein konnte nicht angewendet werden: Dieser Code ist abgelaufen."
|
||||
unable_to_apply_the_coupon_because_sold_out: "Der Gutschein kann nicht angewendet werden: Dieser Code hat sein Kontingent erreicht."
|
||||
unable_to_apply_the_coupon_because_already_used: "Der Gutschein konnte nicht angewendet werden: Sie haben diesen Code bereits einmal verwendet."
|
||||
unable_to_apply_the_coupon_because_amount_exceeded: "Der Gutschein kann nicht eingelöst werden: Der Rabatt überschreitet den Gesamtbetrag dieses Kaufs."
|
||||
unable_to_apply_the_coupon_because_undefined: "Der Gutschein konnte nicht eingelöst werden: Ein unerwarteter Fehler ist aufgetreten, bitte kontaktieren Sie den Fablab-Manager."
|
||||
unable_to_apply_the_coupon_because_rejected: "Dieser Code existiert nicht."
|
||||
#form to create/edit a space
|
||||
space:
|
||||
name: "Name"
|
||||
name_is_required: "Name ist erforderlich."
|
||||
illustration: "Abbildung"
|
||||
add_an_illustration: "Abbildung hinzufügen"
|
||||
description: "Beschreibung"
|
||||
description_is_required: "Beschreibung ist erforderlich."
|
||||
characteristics: "Eigenschaften"
|
||||
characteristics_are_required: "Eigenschaften sind erforderlich."
|
||||
attached_files_pdf: "Dateianhänge (pdf)"
|
||||
attach_a_file: "Datei anhängen"
|
||||
add_an_attachment: "Anhang hinzufügen"
|
||||
default_places: "Maximale Anzahl von Tickets"
|
||||
default_places_is_required: "Maximale Anzahl an Tickets ist erforderlich."
|
||||
disable_space: "Raum deaktivieren"
|
||||
#shopping cart module for reservations
|
||||
cart:
|
||||
summary: "Zusammenfassung"
|
||||
select_one_or_more_slots_in_the_calendar: "Wähle einen {SINGLE, select, true{Slot} other{oder mehrere Slots}} im Kalender"
|
||||
you_ve_just_selected_the_slot: "Sie haben gerade den Slot ausgewählt:"
|
||||
datetime_to_time: "{START_DATETIME} bis {END_TIME}" #eg: Thursday, September 4 1986 8:30 PM to 10:00 PM
|
||||
cost_of_TYPE: "Kosten für den {TYPE, select, Machine{Maschinenslot} Training{Schulungsslot} Space{Raum-Slot} other{anderes Element}}"
|
||||
offer_this_slot: "Diesen Slot anbieten"
|
||||
confirm_this_slot: "Diesen Slot bestätigen"
|
||||
remove_this_slot: "Diesen Slot entfernen"
|
||||
to_benefit_from_attractive_prices: "Um von günstigen Ageboten zu profitieren"
|
||||
view_our_subscriptions: "Lassen Sie sich unsere Abonnements vorstellen"
|
||||
or: "oder"
|
||||
you_ve_just_selected_a_: "Sie wählten gerade ein"
|
||||
_subscription: "Abonnement"
|
||||
cost_of_the_subscription: "Kosten des Abonnements"
|
||||
confirm_and_pay: "Bestätigen und bezahlen"
|
||||
you_have_settled_the_following_TYPE: "Sie haben die folgenden {TYPE, select, Machine{Maschinenslots} Training{Schulungen} other{Elemente}} beglichen:"
|
||||
you_have_settled_a_: "Sie haben beglichen"
|
||||
total_: "GESAMT :"
|
||||
thank_you_your_payment_has_been_successfully_registered: "Vielen Dank. Ihre Zahlung wurde erfolgreich registriert!"
|
||||
your_invoice_will_be_available_soon_from_your_: "Ihre Rechnung wird in Kürze verfügbar sein via"
|
||||
dashboard: "Dashboard"
|
||||
i_want_to_change_the_following_reservation: "Ich möchte folgende Reservierung ändern:"
|
||||
cancel_my_modification: "Änderung abbrechen"
|
||||
select_a_new_slot_in_the_calendar: "Wählen Sie einen neuen Slot im Kalender"
|
||||
cancel_my_selection: "Auswahl aufheben"
|
||||
tags_of_the_original_slot: "Tags des ursprünglichen Slots:"
|
||||
tags_of_the_destination_slot: "Tags des Ziel-Slots:"
|
||||
confirm_my_modification: "Meine Änderung bestätigen"
|
||||
your_booking_slot_was_successfully_moved_from_: "Ihr Buchungs-Slot wurde erfolgreich verschoben von"
|
||||
to_date: "zu" #eg. from 01/01 to 01/05
|
||||
please_select_a_member_first: "Bitte wählen Sie zuerst ein Mitglied"
|
||||
unable_to_select_plan_if_slots_in_the_past: "Es kann kein Plan ausgewählt werden, wenn einer der ausgewählten Slots in der Vergangenheit liegt"
|
||||
unable_to_change_the_reservation: "Die Reservierung konnte nicht geändert werden"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_cancel_this_reservation_html: "<p>Möchten Sie diese Reservierung wirklich stornieren?</p><p>Achtung: wenn diese Reservierung kostenlos, als Teil eines Abonnements erfolgt, wird das aufgewendete Guthaben nicht zurückerstattet.</p>"
|
||||
reservation_was_cancelled_successfully: "Die Reservierung wurde erfolgreich storniert."
|
||||
cancellation_failed: "Stornierung fehlgeschlagen."
|
||||
confirm_payment_of_html: "{ROLE, select, admin{Bezahlung vor Ort} other{Bezahlen}}: {AMOUNT}" #eg. confirm my payment of $20.00
|
||||
a_problem_occurred_during_the_payment_process_please_try_again_later: "Während des Zahlungsvorgangs ist ein Problem aufgetreten. Bitte versuchen Sie es später erneut."
|
||||
none: "Keine"
|
||||
online_payment_disabled: "Online-Zahlung ist nicht verfügbar. Bitte kontaktieren Sie die FabLab-Rezeption direkt."
|
||||
slot_restrict_plans: "Dieser Slot ist auf die folgenden Pläne beschränkt:"
|
||||
slot_restrict_subscriptions_must_select_plan: "Der Slot ist nur für Abonnenten verfügbar. Bitte wählen Sie zuerst einen Plan aus."
|
||||
slot_restrict_plans_of_others_groups: "Der Slot ist für die Abonnenten anderer Gruppen beschränkt."
|
||||
selected_plan_dont_match_slot: "Ausgewählter Plan stimmt nicht mit diesem Slot überein"
|
||||
user_plan_dont_match_slot: "Vom Nutzer abonnierter Plan stimmt nicht mit diesem Slot überein"
|
||||
no_plan_match_slot: "Sie haben keinen passenden Plan für diesen Slot"
|
||||
slot_at_same_time: "Konflikt mit anderen Reservierungen"
|
||||
do_you_really_want_to_book_slot_at_same_time: "Wollen Sie wirklich diesen Slot buchen? Andere Buchungen finden zur gleichen Zeit statt"
|
||||
unable_to_book_slot_because_really_have_reservation_at_same_time: "Dieser Slot kann nicht gebucht werden, da die folgende Reservierung zur gleichen Zeit erfolgt."
|
||||
tags_mismatch: "Tags stimmen nicht überein"
|
||||
confirm_book_slot_tags_mismatch: "Wollen Sie wirklich diesen Slot buchen? {USER} hat keine der erforderlichen Tags."
|
||||
unable_to_book_slot_tags_mismatch: "Dieser Slot kann nicht gebucht werden, da Sie keine der benötigten Tags haben."
|
||||
slot_tags: "Slot-Tags"
|
||||
user_tags: "Nutzer-Tags"
|
||||
no_tags: "Keine Tags"
|
||||
#feature-tour modal
|
||||
tour:
|
||||
previous: "Vorherige"
|
||||
next: "Nächste"
|
||||
end: "Tour beenden"
|
||||
#help modal
|
||||
help:
|
||||
title: "Hilfe"
|
||||
what_to_do: "Was möchten Sie tun?"
|
||||
tour: "Funktionstour starten"
|
||||
guide: "Benutzerhandbuch öffnen"
|
@ -359,6 +359,8 @@ en:
|
||||
validity_per_user: "Validity per user"
|
||||
once: "Just once"
|
||||
forever: "Each use"
|
||||
warn_validity_once: "Please note that when this coupon will be used with a payment schedule, the discount will be applied to the first deadline only."
|
||||
warn_validity_forever: "Please note that when this coupon will be used with a payment schedule, the discount will be applied to each deadlines."
|
||||
validity_per_user_is_required: "Validity per user is required."
|
||||
valid_until: "Valid until (included)"
|
||||
leave_empty_for_no_limit: "Do not specify any limit by leaving the field empty."
|
||||
@ -371,6 +373,7 @@ en:
|
||||
code_: "Code:"
|
||||
the_coupon_has_been_applied_you_get_PERCENT_discount: "The coupon has been applied. You get a {PERCENT}% discount."
|
||||
the_coupon_has_been_applied_you_get_AMOUNT_CURRENCY: "The coupon has been applied. You get a discount of {AMOUNT} {CURRENCY}."
|
||||
coupon_validity_once: "This coupon is valid only once. In case of payment schedule, only for the first deadline."
|
||||
unable_to_apply_the_coupon_because_disabled: "Unable to apply the coupon: this code was disabled."
|
||||
unable_to_apply_the_coupon_because_expired: "Unable to apply the coupon: this code has expired."
|
||||
unable_to_apply_the_coupon_because_sold_out: "Unable to apply the coupon: this code reached its quota."
|
||||
|
@ -359,6 +359,8 @@ fr:
|
||||
validity_per_user: "Validité par utilisateur"
|
||||
once: "Une seule fois"
|
||||
forever: "À chaque utilisation"
|
||||
warn_validity_once: "Veuillez noter que lors de l'utilisation de ce code promo avec un échéancier de paiement, la réduction sera appliquée uniquement à la première échéance."
|
||||
warn_validity_forever: "Veuillez noter que lors de l'utilisation de ce code promo avec un échéancier de paiement, la réduction sera appliquée à chaque échéance."
|
||||
validity_per_user_is_required: "La validité par utilisateur est requise."
|
||||
valid_until: "Valable jusqu'au (inclus)"
|
||||
leave_empty_for_no_limit: "Laissez vide pour ne pas spécifier de limite."
|
||||
@ -371,6 +373,7 @@ fr:
|
||||
code_: "Code :"
|
||||
the_coupon_has_been_applied_you_get_PERCENT_discount: "Le code promo a bien été appliqué. Vous bénéficiez d'une remise de {PERCENT} %."
|
||||
the_coupon_has_been_applied_you_get_AMOUNT_CURRENCY: "Le code promo a bien été appliqué. Vous bénéficiez d'une remise de {AMOUNT} {CURRENCY}."
|
||||
coupon_validity_once: "Ce code promo n'est valide qu'une seule fois. En cas de paiement échelonné, seulement pour la première échéance."
|
||||
unable_to_apply_the_coupon_because_disabled: "Impossible d'appliquer la réduction : ce code promo a été désactivé."
|
||||
unable_to_apply_the_coupon_because_expired: "Impossible d'appliquer la réduction : ce code promo a expiré."
|
||||
unable_to_apply_the_coupon_because_sold_out: "Impossible d'appliquer la réduction : ce code promo a atteint son quota."
|
||||
|
397
config/locales/de.yml
Normal file
397
config/locales/de.yml
Normal file
@ -0,0 +1,397 @@
|
||||
de:
|
||||
#subscription plan duration
|
||||
duration:
|
||||
year:
|
||||
one: 'ein Jahr'
|
||||
other: '%{count} Jahre'
|
||||
month:
|
||||
one: 'Ein Monat'
|
||||
other: '%{count} Monate'
|
||||
week:
|
||||
one: 'Eine Woche'
|
||||
other: '%{count} Wochen'
|
||||
errors:
|
||||
#CarrierWave
|
||||
messages:
|
||||
carrierwave_processing_error: "konnte nicht verarbeitet werden"
|
||||
carrierwave_integrity_error: "ist kein erlaubter Dateityp"
|
||||
carrierwave_download_error: "konnte nicht heruntergeladen werden"
|
||||
extension_whitelist_error: "Sie sind nicht berechtigt, %{extension} Dateien hochzuladen, erlaubt sind die Typen: %{allowed_types}"
|
||||
extension_blacklist_error: "Sie sind nicht berechtigt, %{extension} Dateien hochzuladen. Unerlaubte Typen: %{prohibited_types}"
|
||||
content_type_whitelist_error: "Sie sind nicht berechtigt, %{content_type} Dateien hochzuladen, erlaubt sind die Typen: %{allowed_types}"
|
||||
rmagick_processing_error: "Fehler beim Bearbeiten mit rmagick, vielleicht ist es kein Bild? Original Fehler: %{e}"
|
||||
mime_types_processing_error: "Fehler beim Verarbeiten der Datei mit MIME::Typen, möglicherweise kein gültiger Inhaltstyp? Original Fehler: %{e}"
|
||||
mini_magick_processing_error: "Fehler beim Bearbeiten mit MiniMagick, vielleicht ist es kein Bild? Original Fehler: %{e}"
|
||||
wrong_size: "hat die falsche Größe (sollte %{file_size} sein)"
|
||||
size_too_small: "ist zu klein (sollte mindestens %{file_size} sein)"
|
||||
size_too_big: "ist zu groß (sollte höchstens %{file_size} sein)"
|
||||
export_not_found: "Der angeforderte Export wurde nicht gefunden. Wahrscheinlich wurde er gelöscht. Bitte erstellen Sie einen neuen Export."
|
||||
percentage_out_of_range: "Prozentwert muss zwischen 0 und 100 liegen"
|
||||
cannot_be_blank_at_same_time: "darf nicht leer sein, wenn %{field} auch leer ist"
|
||||
cannot_be_in_the_past: "darf nicht in der Vergangenheit liegen"
|
||||
cannot_be_before_previous_value: "darf nicht vor dem vorherigen Wert liegen"
|
||||
cannot_overlap: "darf einen bestehenden Abrechnungszeitraum nicht überlappen"
|
||||
cannot_encompass: "darf einen bestehenden Abrechnungszeitraum nicht umfassen"
|
||||
in_closed_period: "darf nicht innerhalb eines geschlossenen Abrechnungszeitraums sein"
|
||||
invalid_footprint: "die Prüfsumme der Rechnung ist ungültig"
|
||||
end_before_start: "Das Enddatum darf nicht vor dem Startdatum liegen. Wählen Sie ein Datum nach %{START}"
|
||||
invalid_duration: "Der zulässige Zeitraum muss zwischen 1 Tag und 1 Jahr lang sein. Ihr Zeitraum ist %{DAYS} Tage lang."
|
||||
must_be_in_the_past: "Der Zeitraum darf ausschließlich vor dem heutigen Datum liegen."
|
||||
apipie:
|
||||
api_documentation: "API-Dokumentation"
|
||||
code: "HTTP code"
|
||||
#error messages when importing an account from a SSO
|
||||
omniauth:
|
||||
email_already_linked_to_another_account_please_input_your_authentication_code: "E-Mail-Adresse \"%{OLD_MAIL}\" ist bereits mit einem Konto verknüpft. Bitte geben Sie Ihren Authentifizierungscode ein."
|
||||
your_username_is_already_linked_to_another_account_unable_to_update_it: "Ihr Benutzername (%{USERNAME}) ist bereits einem anderen Konto zugeordnet. Aktualisierung nicht möglich."
|
||||
your_email_address_is_already_linked_to_another_account_unable_to_update_it: "Ihre E-Mail-Adresse (%{EMAIL}) ist bereits einem anderen Konto zugeordnet. Aktualisierung nicht möglich."
|
||||
this_account_is_already_linked_to_an_user_of_the_platform: "Das Konto %{NAME} wird bereits von einem Benutzer der Plattform verwendet."
|
||||
#availability slots in the calendar
|
||||
availabilities:
|
||||
not_available: "Nicht verfügbar"
|
||||
i_ve_reserved: "Ich reservierte"
|
||||
length_must_be_slot_multiple: "muss mindestens %{MIN} Minuten nach dem Startdatum liegen"
|
||||
must_be_associated_with_at_least_1_machine: "muss mindestens einer Maschine zugeordnet sein"
|
||||
#members management
|
||||
members:
|
||||
unable_to_change_the_group_while_a_subscription_is_running: "Die Gruppe kann während eines Abonnements nicht geändert werden"
|
||||
admins_cant_change_group: "Ein Administrator kann nicht aus seiner eigenen Gruppe entfernt werden"
|
||||
please_input_the_authentication_code_sent_to_the_address: "Bitte geben Sie den Authentifizierungscode ein, der an die E-Mail-Adresse %{EMAIL} gesendet wurde"
|
||||
your_authentication_code_is_not_valid: "Der Authentifizierungscode ist ungültig."
|
||||
current_authentication_method_no_code: "Die aktuelle Authentifizierungsmethode erfordert keinen Migrationscode"
|
||||
requested_account_does_not_exists: "Das gewünschte Konto ist nicht vorhanden"
|
||||
#PDF invoices generation
|
||||
invoices:
|
||||
refund_invoice_reference: "Beleg der Rechnungsrückerstattungung: %{REF}"
|
||||
invoice_reference: "Rechnungsbezug: %{REF}"
|
||||
code: "Code: %{CODE}"
|
||||
order_number: "Bestellnummer: %{NUMBER}"
|
||||
invoice_issued_on_DATE: "Rechnung ausgestellt am %{DATE}"
|
||||
refund_invoice_issued_on_DATE: "Rückerstattungsrechnung ausgestellt am %{DATE}"
|
||||
wallet_credit: "Vorhandenes Guthaben"
|
||||
cancellation_of_invoice_REF: "Stornierung der Rechnung %{REF}"
|
||||
reservation_of_USER_on_DATE_at_TIME: "Reservierung von %{USER} am %{DATE} um %{TIME}"
|
||||
cancellation: "Stornierung"
|
||||
object: "Gegenstand:"
|
||||
order_summary: "Bestellübersicht:"
|
||||
details: "Details"
|
||||
amount: "Betrag"
|
||||
subscription_extended_for_free_from_START_to_END: "Kostenlose Abonnementverlängerung - von %{START} bis %{END}"
|
||||
subscription_NAME_from_START_to_END: "Abonnement %{NAME} - Von %{START} bis %{END}"
|
||||
machine_reservation_DESCRIPTION: "Maschinen-Reservierung - %{DESCRIPTION}"
|
||||
space_reservation_DESCRIPTION: "Raumreservierung - %{DESCRIPTION}"
|
||||
training_reservation_DESCRIPTION: "Trainingsreservierung - %{DESCRIPTION}"
|
||||
event_reservation_DESCRIPTION: "Veranstaltungs-Reservierung - %{DESCRIPTION}"
|
||||
full_price_ticket:
|
||||
one: "Ein Vollpreis-Ticket"
|
||||
other: "%{count} Vollpreis-Tickets"
|
||||
other_rate_ticket:
|
||||
one: "Ein %{NAME}-Ticket"
|
||||
other: "%{count} %{NAME}-Tickets"
|
||||
reservation_other: "Reservierung (andere)"
|
||||
coupon_CODE_discount_of_DISCOUNT: "Gutschein {CODE}: Rabatt von {DISCOUNT}{TYPE, select, percent_off{%} other{}}" #messageFormat interpolation
|
||||
total_including_all_taxes: "Gesamtpreis inkl. Steuern"
|
||||
including_VAT_RATE: "Inklusive MwSt. %{RATE}%"
|
||||
including_total_excluding_taxes: "Gesamtbetrag zzgl. Steuern"
|
||||
including_amount_payed_on_ordering: "Inklusive bei Bestellung bezahlter Betrag"
|
||||
total_amount: "Gesamtbetrag"
|
||||
refund_on_DATE: "Erstattung am %{DATE}"
|
||||
by_stripe_online_payment: "via Stripe (Online-Zahlung)"
|
||||
by_cheque: "per Scheck"
|
||||
by_transfer: "per Banküberweisung"
|
||||
by_cash: "in bar"
|
||||
by_wallet: "durch Guthaben"
|
||||
no_refund: "Keine Rückerstattung"
|
||||
settlement_by_debit_card: "Abrechnung per Debitkarte"
|
||||
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},"
|
||||
for_an_amount_of_AMOUNT: "für einen Betrag von %{AMOUNT}"
|
||||
on_DATE_from_START_to_END: "Am %{DATE} von %{START} bis %{END}" #eg: on feb. 7 from 7AM to 9AM
|
||||
from_STARTDATE_to_ENDDATE_from_STARTTIME_to_ENDTIME: "Von %{STARTDATE} bis %{ENDDATE}, von %{STARTTIME} bis %{ENDTIME}" #eg: from feb. 7 to feb. 10, from 6PM to 10PM
|
||||
subscription_of_NAME_for_DURATION_starting_from_DATE: "Abonnement von %{NAME} für %{DURATION} ab %{DATE}"
|
||||
subscription_of_NAME_extended_starting_from_STARTDATE_until_ENDDATE: "Abonnement von %{NAME} verlängert (kostenlose Tage) ab %{STARTDATE} bis %{ENDDATE}"
|
||||
and: 'und'
|
||||
invoice_text_example: "Unsere Einrichtung ist nicht mehrwertsteuerpflichtig"
|
||||
#CVS accounting export (columns headers)
|
||||
accounting_export:
|
||||
journal_code: "Journalcode"
|
||||
date: "Eintragsdatum"
|
||||
account_code: "Code des Kontos"
|
||||
account_label: "Kontobezeichnung"
|
||||
piece: "Dokument"
|
||||
line_label: "Eintragsbezeichnung"
|
||||
debit_origin: "Ursprungssoll"
|
||||
credit_origin: "Ursprungsguthaben"
|
||||
debit_euro: "Soll in Euro"
|
||||
credit_euro: "Guthaben in Euro"
|
||||
lettering: "Beschriftung"
|
||||
VAT: 'Mwst.'
|
||||
subscription: "Abonnement"
|
||||
Machine_reservation: "Maschinenreservierung"
|
||||
Training_reservation: "Schulungsreservierung"
|
||||
Event_reservation: "Veranstaltungsreservierung"
|
||||
Space_reservation: "Raumreservierung"
|
||||
wallet: "Guthabenkonto"
|
||||
#training availabilities
|
||||
trainings:
|
||||
i_ve_reserved: "Ich reservierte"
|
||||
completed: "Vollständig"
|
||||
#error messages when updating an event
|
||||
events:
|
||||
error_deleting_reserved_price: "Der angeforderte Preis konnte nicht gelöscht werden, da er mit einigen Reservierungen verknüpft ist"
|
||||
other_error: "Unerwarteter Fehler beim Aktualisieren der Veranstaltung"
|
||||
#event duration
|
||||
from_STARTDATE_to_ENDDATE: "Von %{STARTDATE} bis %{ENDDATE},"
|
||||
from_STARTTIME_to_ENDTIME: "von %{STARTTIME} bis %{ENDTIME}"
|
||||
#members list export to EXCEL format
|
||||
export_members:
|
||||
members: "Mitglieder"
|
||||
id: "ID"
|
||||
surname: "Nachname"
|
||||
first_name: "Vorname"
|
||||
email: "E-Mail"
|
||||
newsletter: "Newsletter"
|
||||
last_login: "Letzte Anmeldung"
|
||||
gender: "Geschlecht"
|
||||
age: "Alter"
|
||||
address: "Adresse"
|
||||
phone: "Telefon"
|
||||
website: "Webseite"
|
||||
job: "Aufgabe"
|
||||
interests: "Interessen"
|
||||
cad_software_mastered: "CAD-Software gemeistert"
|
||||
group: "Gruppe"
|
||||
subscription: "Abonnement"
|
||||
subscription_end_date: "Enddatum des Abonnements"
|
||||
validated_trainings: "Validierte Schulungen"
|
||||
tags: "Stichworte"
|
||||
number_of_invoices: "Anzahl der Rechnungen"
|
||||
projects: "Projekte"
|
||||
facebook: "Facebook"
|
||||
twitter: "Twitter"
|
||||
echo_sciences: "Echosciences"
|
||||
organization: "Organisation"
|
||||
organization_address: "Adresse der Organisation"
|
||||
man: "Mann"
|
||||
woman: "Frau"
|
||||
without_subscriptions: "Ohne Abonnement"
|
||||
#machines/trainings/events reservations list to EXCEL format
|
||||
export_reservations:
|
||||
reservations: "Reservierungen"
|
||||
customer_id: "Kunden ID"
|
||||
customer: "Kunde"
|
||||
email: "E-Mail"
|
||||
reservation_date: "Reservierungsdatum"
|
||||
reservation_type: "Reservierungsart"
|
||||
reservation_object: "Gegenstand der Reservierung"
|
||||
slots_number_hours_tickets: "Anzahl Slots (Stunden/Tickets)"
|
||||
payment_method: "Zahlungsmethode"
|
||||
local_payment: "Zahlung an der Rezeption"
|
||||
online_payment: "Online-Zahlung"
|
||||
deleted_user: "Gelöschter Nutzer"
|
||||
#subscriptions list export to EXCEL format
|
||||
export_subscriptions:
|
||||
subscriptions: "Abonnements"
|
||||
id: "ID"
|
||||
customer: "Kunde"
|
||||
email: "E-Mail"
|
||||
subscription: "Abonnement"
|
||||
period: "Zeitraum"
|
||||
start_date: "Startdatum"
|
||||
expiration_date: "Ablaufdatum"
|
||||
amount: "Betrag"
|
||||
payment_method: "Zahlungsmethode"
|
||||
local_payment: "Zahlung an der Rezeption"
|
||||
online_payment: "Online-Zahlung"
|
||||
deleted_user: "Gelöschter Nutzer"
|
||||
#reservation slots export, by type, to EXCEL format
|
||||
export_availabilities:
|
||||
machines: "Maschinen"
|
||||
trainings: "Schulungen"
|
||||
spaces: "Räume"
|
||||
events: "Veranstaltungen"
|
||||
day_of_week: "Wochentag"
|
||||
date: "Datum"
|
||||
slot: "Slot"
|
||||
machine: "Maschine"
|
||||
training: "Schulung"
|
||||
space: "Raum"
|
||||
event: "Veranstaltung"
|
||||
reservations: "Reservierungen"
|
||||
available_seats: "Verfügbare Plätze"
|
||||
roles:
|
||||
member: "Mitglied"
|
||||
manager: "Manager"
|
||||
admin: "Administrator"
|
||||
api:
|
||||
#internal app notifications
|
||||
notifications:
|
||||
deleted_user: "Gelöschter Nutzer"
|
||||
notify_admin_abuse_reported:
|
||||
an_abuse_was_reported_on_TYPE_ID_NAME_html: "Ein Missbrauchsmeldung auf <strong>%{TYPE} %{ID} ist eingegangen: <em>%{NAME}</em></strong>."
|
||||
notify_admin_member_create_reservation:
|
||||
a_RESERVABLE_reservation_was_made_by_USER_html: "Eine <strong><em>%{RESERVABLE}</em></strong> Reservierung wurde von <strong><em>%{USER}</em></strong> vorgenommen."
|
||||
notify_admin_profile_complete:
|
||||
account_imported_from_PROVIDER_UID_has_completed_its_information_html: "Konto importiert von <strong><em>%{PROVIDER}</strong> (%{UID})</em> hat seine Informationen vervollständigt."
|
||||
notify_admin_slot_is_canceled:
|
||||
USER_s_reservation_on_the_DATE_was_cancelled_remember_to_generate_a_refund_invoice_if_applicable_html: "Die Reservierung von <strong><em>%{USER}</em></strong> am %{DATE} wurde storniert. Erstellen Sie eine Rückerstattung, falls zutreffend."
|
||||
notify_admin_slot_is_modified:
|
||||
a_booking_slot_was_modified: "Ein Buchungsplatz wurde geändert."
|
||||
notify_admin_subscribed_plan:
|
||||
subscription_PLAN_has_been_subscribed_by_USER_html: "Das Abonnement <strong><em>%{PLAN}</em></strong> wurde von <strong><em>%{USER}</strong></em> abgeschlossen."
|
||||
notify_admin_subscription_canceled:
|
||||
USER_s_subscription_has_been_cancelled: "Das Abonnement von %{USER} wurde gekündigt."
|
||||
notify_admin_subscription_extended:
|
||||
subscription_PLAN_of_the_member_USER_has_been_extended_FREE_until_DATE_html: "Das Abonnement <strong><em>{PLAN}</em></strong> des Mitglieds <strong><em>{USER}</strong></em> wurde verlängert {FREE, select, true{kostenlos} other{}} bis {DATE}." #messageFormat interpolation
|
||||
notify_admin_subscription_is_expired:
|
||||
USER_s_subscription_has_expired: "Das Abonnement von %{USER} ist abgelaufen."
|
||||
notify_admin_subscription_will_expire_in_7_days:
|
||||
USER_s_subscription_will_expire_in_7_days: "Das Abonnement von %{USER} wird in 7 Tagen ablaufen."
|
||||
notify_admin_user_group_changed:
|
||||
user_NAME_changed_his_group_html: "Benutzer <strong><em>{NAME}</strong></em> hat {GENDER, select, true{seine} other{ihre}} Gruppe geändert." #messageFormat interpolation
|
||||
notify_admin_user_merged:
|
||||
user_NAME_has_merged_his_account_with_the_one_imported_from_PROVIDER_UID_html: "Nutzer <strong><em>{NAME}</strong></em> hat {GENDER, select, true{seinen} other{ihren}} Account mit dem von <strong><em>{PROVIDER} </strong> ({UID})</em> importierten Account zusammengeführt." #messageFormat interpolation
|
||||
notify_admin_when_project_published:
|
||||
project_NAME_has_been_published_html: "Projekt <a href='/#!/projects/%{ID}'><strong><em>%{NAME}<em></strong></a> wurde veröffentlicht."
|
||||
notify_admin_when_user_is_created:
|
||||
a_new_user_account_has_been_created_NAME_EMAIL_html: "Ein neues Benutzerkonto wurde erstellt: <strong><em>%{NAME} <%{EMAIL}></strong></em>."
|
||||
notify_admin_when_user_is_imported:
|
||||
a_new_user_account_has_been_imported_from_PROVIDER_UID_html: "Ein neues Benutzerkonto wurde von <strong><em>%{PROVIDER}</strong> (%{UID})</em> importiert."
|
||||
notify_member_create_reservation:
|
||||
your_reservation_RESERVABLE_was_successfully_saved_html: "Ihre Reservierung <strong><em>%{RESERVABLE}</em></strong> wurde erfolgreich gespeichert."
|
||||
notify_member_reservation_reminder:
|
||||
reminder_you_have_a_reservation_RESERVABLE_to_be_held_on_DATE_html: "Erinnerung: Sie haben eine Reservierung <strong>%{RESERVABLE}</strong> für <em>%{DATE}</em>"
|
||||
notify_member_slot_is_canceled:
|
||||
your_reservation_RESERVABLE_of_DATE_was_successfully_cancelled: "Ihre Reservierung %{RESERVABLE} von %{DATE} wurde erfolgreich storniert."
|
||||
notify_member_slot_is_modified:
|
||||
your_reservation_slot_was_successfully_changed: "Ihr Reservierungsslot wurde erfolgreich geändert."
|
||||
notify_member_subscribed_plan:
|
||||
you_have_subscribed_to_PLAN_html: "Sie haben <strong><em>%{PLAN}</em></strong> abonniert."
|
||||
notify_member_subscribed_plan_is_changed:
|
||||
you_have_changed_your_subscription_to_PLAN_html: "Sie haben Ihr Abonnement für <strong><em>%{PLAN}</em></strong> geändert."
|
||||
notify_member_subscription_canceled:
|
||||
your_subscription_PLAN_was_successfully_cancelled_html: "Ihr Abonnement von <strong><em>%{PLAN}</em></strong> wurde erfolgreich storniert."
|
||||
notify_member_subscription_extended:
|
||||
your_subscription_PLAN_has_been_extended_FREE_until_DATE_html: "Ihr Abonnement von <strong><em>{PLAN}</em></strong> wurde {FREE, select, true{kostenlos} other{}} bis {DATE} verlängert." #messageFormat interpolation
|
||||
notify_member_subscription_is_expired:
|
||||
your_subscription_has_expired: "Ihr Abonnement ist abgelaufen."
|
||||
notify_member_subscription_will_expire_in_7_days:
|
||||
your_subscription_will_expire_in_7_days: "Ihr Abonnement läuft in 7 Tagen ab."
|
||||
notify_partner_subscribed_plan:
|
||||
subscription_partner_PLAN_has_been_subscribed_by_USER_html: "Das Partnerabonnement <strong><em>%{PLAN}</em></strong> wurde von <strong><em>%{USER}</strong></em> abonniert."
|
||||
notify_project_author_when_collaborator_valid:
|
||||
USER_became_collaborator_of_your_project: "%{USER} nimmt nun teil an Ihrem Projekt:"
|
||||
notify_project_collaborator_to_valid:
|
||||
you_are_invited_to_collaborate_on_the_project: "Sie wurden zur Teilnahme am Projekt eingeladen:"
|
||||
notify_user_auth_migration:
|
||||
your_account_was_migrated: "Ihr Konto wurde erfolgreich in das neue Authentifizierungssystem migriert."
|
||||
notify_user_profile_complete:
|
||||
your_profile_was_completed: "Ihr Profil ist vollständig, Sie haben nun Zugriff auf die gesamte Plattform."
|
||||
notify_user_training_valid:
|
||||
your_TRAINING_was_validated_html: "Ihre Schulung <strong><em>%{TRAINING}</em></strong> wurde erfolgreich überprüft."
|
||||
notify_user_user_group_changed:
|
||||
your_group_has_changed: "Ihre Gruppe hat sich geändert."
|
||||
notify_user_when_avoir_ready:
|
||||
your_avoir_is_ready_html: "Ihre Rückerstattungsrechnung #%{REFERENCE}, über %{AMOUNT} wurde erstellt. <a href='api/invoices/%{INVOICE_ID}/download' target='_blank'>Hier herunterladen</a>."
|
||||
notify_user_when_invoice_ready:
|
||||
your_invoice_is_ready_html: "Ihre Rechnung #%{REFERENCE}, über %{AMOUNT} wurde erstellt. <a href='api/invoices/%{INVOICE_ID}/download' target='_blank'>Hier herunterladen</a>."
|
||||
undefined_notification:
|
||||
unknown_notification: "Unbekannte Benachrichtigung"
|
||||
notification_ID_wrong_type_TYPE_unknown: "Benachrichtigung %{ID} falsch (Typ %{TYPE} unbekannt)"
|
||||
notify_user_wallet_is_credited:
|
||||
your_wallet_is_credited: "Eine Gutschrift wurde ihrem Konto gutgeschrieben von einem Administrator"
|
||||
notify_admin_user_wallet_is_credited:
|
||||
wallet_is_credited: "Dem Guthaben des Mitglieds %{USER} wurde %{AMOUNT} gutgeschrieben"
|
||||
notify_admin_export_complete:
|
||||
export: "Der Export"
|
||||
statistics_global: "aller Statistiken"
|
||||
statistics_account: "der Registrierungsstatistiken"
|
||||
statistics_event: "der Veranstaltungsstatistiken"
|
||||
statistics_machine: "der Statistiken der Maschinenslots"
|
||||
statistics_project: "der Projektstatistiken"
|
||||
statistics_subscription: "der Abonnementstatistiken"
|
||||
statistics_training: "der Schulungsstatistiken"
|
||||
statistics_space: "der Raumstatistiken"
|
||||
users_members: "der Mitgliederliste"
|
||||
users_subscriptions: "der Abonnementliste"
|
||||
users_reservations: "der Reservierungsliste"
|
||||
availabilities_index: "der Verfügbarkeit der Reservierungen"
|
||||
accounting_acd: "der Rechnungsdaten für ACD"
|
||||
is_over: "ist beendet."
|
||||
download_here: "Hier herunterladen"
|
||||
notify_admin_import_complete:
|
||||
import_over: "%{CATEGORY} Import ist beendet. "
|
||||
members: "Mitglieder"
|
||||
view_results: "Ergebnisse anzeigen."
|
||||
notify_member_about_coupon:
|
||||
enjoy_a_discount_of_PERCENT_with_code_CODE: "Erhalten Sie %{PERCENT}% Rabatt mit dem Code %{CODE}"
|
||||
enjoy_a_discount_of_AMOUNT_with_code_CODE: "Erhalten Sie %{AMOUNT}% Rabatt mit dem Code %{CODE}"
|
||||
notify_admin_free_disk_space:
|
||||
warning_free_disk_space: "Warnung: Auf dem Server ist noch %{AVAILABLE} MiB Speicherplatz verfügbar"
|
||||
notify_admin_close_period_reminder:
|
||||
warning_last_closed_period_over_1_year: "Bitte schließen Sie Ihre Abrechnungsperioden regelmäßig ab. Der letzte Abschlusszeitraum endete um %{LAST_END}"
|
||||
warning_no_closed_periods: "Bitte schließen Sie Ihre Abrechnungsperioden regelmäßig ab. Sie müssen Abrechnungsperioden ab %{FIRST_DATE} schließen"
|
||||
notify_admin_archive_complete:
|
||||
archive_complete: "Die Datenarchivierung von %{START} bis %{END} ist abgeschlossen. <a href='api/accounting_periods/%{ID}/archive' target='_blank'>Datenarchiv herunterladen</a>. Speichern Sie das Archiv auf einem externen, gesicherten Datenträger."
|
||||
notify_privacy_policy_changed:
|
||||
policy_updated: "Änderung der Datenschutz-Bestimmungen"
|
||||
click_to_show: "Zum Anzeigen hier klicken"
|
||||
notify_admin_refund_created:
|
||||
refund_created: "Eine Rückerstattung von %{AMOUNT} wurde für Benutzer %{USER} erstellt"
|
||||
notify_user_role_update:
|
||||
your_role_is_ROLE: "Ihre Rolle wurde in %{ROLE} geändert."
|
||||
notify_admins_role_update:
|
||||
user_NAME_changed_ROLE_html: "Benutzer <strong><em>%{NAME}</strong></em> ist jetzt %{ROLE}."
|
||||
notify_admin_members_stripe_sync:
|
||||
all_members_sync: "Alle Mitglieder wurden erfolgreich auf Stripe synchronisiert."
|
||||
#statistics tools for admins
|
||||
statistics:
|
||||
subscriptions: "Abonnements"
|
||||
machines_hours: "Maschinen-Slots"
|
||||
spaces: "Räume"
|
||||
trainings: "Schulungen"
|
||||
events: "Veranstaltungen"
|
||||
registrations: "Anmeldungen"
|
||||
projects: "Projekte"
|
||||
users: "Benutzer"
|
||||
training_id: "Schulungs-ID"
|
||||
training_date: "Schulungstermin"
|
||||
event_id: "Veranstaltungs-ID"
|
||||
event_date: "Veranstaltungsdatum"
|
||||
event_name: "Veranstaltungsname"
|
||||
event_theme: "Thema"
|
||||
age_range: "Altersklasse"
|
||||
themes: "Themen"
|
||||
components: "Komponenten"
|
||||
machines: "Maschinen"
|
||||
user_id: "Nutzer-ID"
|
||||
bookings: "Buchungen"
|
||||
hours_number: "Stundenzahl"
|
||||
tickets_number: "Ticket Nummer"
|
||||
revenue: "Einnahmen"
|
||||
account_creation: "Benutzerkontenerstellung"
|
||||
project_publication: "Projektveröffentlichung"
|
||||
duration: "Dauer"
|
||||
#statistics exports to the excel file format
|
||||
export:
|
||||
entries: "Einträge"
|
||||
revenue: "Einnahmen"
|
||||
average_age: "Durchschnittsalter"
|
||||
total: "Gesamt"
|
||||
date: "Datum"
|
||||
user: "Nutzer"
|
||||
email: "E-Mail"
|
||||
phone: "Telefon"
|
||||
gender: "Geschlecht"
|
||||
age: "Alter"
|
||||
type: "Typ"
|
||||
male: "Männlich"
|
||||
female: "Weiblich"
|
||||
#initial price's category for events, created to replace the old "reduced amount" property
|
||||
price_category:
|
||||
reduced_fare: "Ermäßigter Tarif"
|
||||
reduced_fare_if_you_are_under_25_student_or_unemployed: "Ermäßigter Tarif, wenn Sie unter 25, studierend oder arbeitslos sind."
|
||||
group:
|
||||
#name of the user's group for administrators
|
||||
admins: 'Administratoren'
|
63
config/locales/devise.de.yml
Normal file
63
config/locales/devise.de.yml
Normal file
@ -0,0 +1,63 @@
|
||||
#Additional translations at https://github.com/plataformatec/devise/wiki/I18n
|
||||
de:
|
||||
devise:
|
||||
confirmations:
|
||||
confirmed: "Ihr Account wurde erfolgreich bestätigt."
|
||||
send_instructions: "Sie erhalten in Kürze eine E-Mail mit Anweisungen zur Bestätigung Ihres Accounts."
|
||||
send_paranoid_instructions: "Wenn Ihre E-Mail-Adresse in unserer Datenbank existiert, werden Sie in Kürze eine E-Mail mit Anweisungen erhalten, wie Sie Ihr Konto bestätigen."
|
||||
failure:
|
||||
already_authenticated: "Sie sind bereits angemeldet."
|
||||
inactive: "Ihr Konto wurde noch nicht aktiviert."
|
||||
invalid: "Ungültige E-Mail-Adresse oder Passwort."
|
||||
locked: "Ihr Account ist gesperrt."
|
||||
last_attempt: "Sie haben noch einen weiteren Versuch, bevor Ihr Konto gesperrt wird."
|
||||
not_found_in_database: "Ungültige E-Mail-Adresse oder Passwort."
|
||||
timeout: "Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an."
|
||||
unauthenticated: "Sie müssen sich anmelden oder registrieren, bevor Sie fortfahren."
|
||||
unconfirmed: "Sie müssen Ihr Konto bestätigen, bevor Sie fortfahren. Bitte klicken Sie auf den Link unter dem Formular."
|
||||
mailer:
|
||||
confirmation_instructions:
|
||||
action: "Meine E-Mail-Adresse bestätigen"
|
||||
instruction: "Sie können Ihre Registrierung abschließen, indem Sie Ihre E-Mail-Adresse bestätigen. Bitte klicken Sie auf den folgenden Link:"
|
||||
subject: "Anleitung zur Bestätigung Ihres Accounts"
|
||||
reset_password_instructions:
|
||||
action: "Mein Passwort ändern"
|
||||
instruction: "Ein Link zur Änderung ihres Passwortes wurde angefordert. Sie können Ihr Passwort über diesen Link ändern."
|
||||
ignore_otherwise: "Falls Sie kein neues Passwort angefordert haben, ignorieren Sie bitte diese Nachricht."
|
||||
subject: "Anleitung für das Zurücksetzen Ihres Passworts"
|
||||
unlock_instructions:
|
||||
subject: "Anweisungen zum Entsperren"
|
||||
omniauth_callbacks:
|
||||
failure: "Sie konnten auf %{kind} nicht authentifiziert werden. Grund: \"%{reason}\"."
|
||||
success: "Erfolgreich über den Account %{kind} authentifiziert."
|
||||
passwords:
|
||||
no_token: "Diese Seite kann nur über eine E-Mail zur Passwort-Zurücksetzung aufgerufen werden. Wenn Sie über eine solche E-Mail auf die Seite zugreifen, vergewissern Sie sich, dass die URL vollständig und korrekt ist."
|
||||
send_instructions: "Sie erhalten in Kürze eine Email mit Anweisungen, wie Sie Ihr Passwort zurücksetzen können."
|
||||
send_paranoid_instructions: "Wenn Ihre E-Mail-Adresse in unserer Datenbank vorhanden ist, erhalten Sie in Kürze eine E-Mail mit einem Link zur Passwortwiederherstellung."
|
||||
updated: "Ihr Passwort wurde erfolgreich geändert. Sie sind jetzt angemeldet."
|
||||
updated_not_active: "Ihr Passwort wurde erfolgreich geändert."
|
||||
registrations:
|
||||
destroyed: "Auf Wiedersehen! Ihr Account wurde erfolgreich gelöscht. Wir hoffen, Sie bald wiederzusehen."
|
||||
signed_up: "Willommen! Ihre Registierung war erfolgreich."
|
||||
signed_up_but_inactive: "Sie haben sich erfolgreich registiert. Sie können sich jedoch erst nach der Aktivierung Ihres Accounts anmelden."
|
||||
signed_up_but_locked: "Sie haben sich erfolgreich registriert. Wir konnten Sie jedoch nicht anmelden, weil Ihr Account gesperrt ist."
|
||||
signed_up_but_unconfirmed: "Eine Nachricht mit einem Bestätigungslink wurde an Ihre E-Mail-Adresse gesendet. Öffnen Sie bitte den Link, um Ihr Konto zu aktivieren."
|
||||
update_needs_confirmation: "Sie haben Ihr Konto erfolgreich aktualisiert. Wir müssen allerdings Ihre neue E-Mail-Adresse verifizieren. Bitte überprüfen Sie Ihr Postfach und klicken Sie auf den Bestätigungslink, um die Bestätigung Ihrer neuen E-Mail-Adresse abzuschließen."
|
||||
updated: "Sie haben Ihren Account erfolgreich aktualisiert."
|
||||
sessions:
|
||||
signed_in: "Anmeldung erfolgreich."
|
||||
signed_out: "Sie sind nun abgemeldet."
|
||||
unlocks:
|
||||
send_instructions: "Sie werden in Kürze eine E-Mail mit Anweisungen erhalten, wie Sie Ihr Konto entsperren."
|
||||
send_paranoid_instructions: "Falls Ihr Konto existiert, erhalten Sie in wenigen Minuten eine E-Mail mit Anweisungen, wie Sie es entsperren können."
|
||||
unlocked: "Ihr Account wurde erfolgreich entsperrt. Bitte melden Sie sich an, um fortzufahren."
|
||||
errors:
|
||||
messages:
|
||||
already_confirmed: "Diese E-Mail wurde bereits bestätigt. Bitte melden Sie sich an."
|
||||
confirmation_period_expired: "muss innerhalb von %{period} bestätigt werden. Bitte neu anfordern"
|
||||
expired: "ist abgelaufen, bitte neu anfordern"
|
||||
not_found: "Die E-Mail wurde nicht gefunden"
|
||||
not_locked: "war nicht gesperrt"
|
||||
not_saved:
|
||||
one: "Ein Fehler hat verhindert, dass %{resource} gespeichert werden konnte:"
|
||||
other: "%{count} Fehler haben verhindert, dass %{resource} gespeichert werden konnte:"
|
@ -39,6 +39,7 @@ en:
|
||||
must_be_in_the_past: "The period must be strictly prior to today's date."
|
||||
apipie:
|
||||
api_documentation: "API Documentation"
|
||||
code: "HTTP code"
|
||||
#error messages when importing an account from a SSO
|
||||
omniauth:
|
||||
email_already_linked_to_another_account_please_input_your_authentication_code: "E-mail address \"%{OLD_MAIL}\" is already linked to another account, please input your authentication code."
|
||||
@ -112,6 +113,18 @@ en:
|
||||
subscription_of_NAME_extended_starting_from_STARTDATE_until_ENDDATE: "Subscription of %{NAME} extended (Free days) starting from %{STARTDATE} until %{ENDDATE}"
|
||||
and: 'and'
|
||||
invoice_text_example: "Our association is not subject to VAT"
|
||||
#PDF payment schedule generation
|
||||
payment_schedules:
|
||||
schedule_reference: "Payment schedule reference: %{REF}"
|
||||
schedule_issued_on_DATE: "Schedule issued on %{DATE}"
|
||||
object: "Object: Payment schedule for %{ITEM}"
|
||||
subscription_of_NAME_for_DURATION_starting_from_DATE: "the subscription of %{NAME} for %{DURATION} starting from %{DATE}"
|
||||
deadlines: "Table of your deadlines"
|
||||
deadline_date: "Payment date"
|
||||
deadline_amount: "Amount including tax"
|
||||
total_amount: "Total amount"
|
||||
settlement_by_METHOD: "Debits will be made by {METHOD, select, stripe{card} other{check}} for each deadlines."
|
||||
settlement_by_wallet: "%{AMOUNT} will be debited from your wallet to settle the first deadline."
|
||||
# CVS accounting export (columns headers)
|
||||
accounting_export:
|
||||
journal_code: "Journal code"
|
||||
@ -344,6 +357,14 @@ en:
|
||||
user_NAME_changed_ROLE_html: "User <strong><em>%{NAME}</strong></em> is now %{ROLE}."
|
||||
notify_admin_members_stripe_sync:
|
||||
all_members_sync: "All members were successfully synchronized on Stripe."
|
||||
notify_user_when_payment_schedule_ready:
|
||||
your_schedule_is_ready_html: "Your payment schedule #%{REFERENCE}, of %{AMOUNT}, is ready. <a href='api/payment_schedules/%{SCHEDULE_ID}/download' target='_blank'>Click here to download</a>."
|
||||
notify_admin_payment_schedule_failed:
|
||||
schedule_failed: "Failed card debit for the %{DATE} deadline, for schedule %{REFERENCE}"
|
||||
notify_member_payment_schedule_failed:
|
||||
schedule_failed: "Failed card debit for the %{DATE} deadline, for your schedule %{REFERENCE}"
|
||||
notify_admin_payment_schedule_check_deadline:
|
||||
schedule_deadline: "You must cash the check for the %{DATE} deadline, for schedule %{REFERENCE}"
|
||||
#statistics tools for admins
|
||||
statistics:
|
||||
subscriptions: "Subscriptions"
|
||||
|
@ -39,6 +39,7 @@ es:
|
||||
must_be_in_the_past: "El período debe ser estrictamente anterior a la fecha de hoy."
|
||||
apipie:
|
||||
api_documentation: "Documentación API"
|
||||
code: "HTTP code"
|
||||
#error messages when importing an account from a SSO
|
||||
omniauth:
|
||||
email_already_linked_to_another_account_please_input_your_authentication_code: "El correo electrónico \"%{OLD_MAIL}\" ya está ligado a otra cuenta, ingrese su código de autenticación."
|
||||
|
@ -39,6 +39,7 @@ fr:
|
||||
must_be_in_the_past: "La période doit être strictement antérieure à la date du jour."
|
||||
apipie:
|
||||
api_documentation: "Documentation de l'API"
|
||||
code: "Code HTTP "
|
||||
#error messages when importing an account from a SSO
|
||||
omniauth:
|
||||
email_already_linked_to_another_account_please_input_your_authentication_code: "L'adresse de courriel \"%{OLD_MAIL}\" est déjà associée à un compte utilisateur, merci de saisir votre code d'authentification."
|
||||
@ -112,6 +113,18 @@ fr:
|
||||
subscription_of_NAME_extended_starting_from_STARTDATE_until_ENDDATE: "Prolongement Abonnement (Jours gratuits) de %{NAME} à compter du %{STARTDATE} jusqu'au %{ENDDATE}"
|
||||
and: 'et'
|
||||
invoice_text_example: "Notre association n'est pas assujettie à la TVA"
|
||||
#PDF payment schedule generation
|
||||
payment_schedules:
|
||||
schedule_reference: "Référence de l'échéancier : %{REF}"
|
||||
schedule_issued_on_DATE: "Échéancier édité le %{DATE}"
|
||||
object: "Objet : Échéancier de paiement de %{ITEM}"
|
||||
subscription_of_NAME_for_DURATION_starting_from_DATE: "l'abonnement de %{NAME} pour %{DURATION} à compter du %{DATE}"
|
||||
deadlines: "Tableau de vos mensualités"
|
||||
deadline_date: "Date du prélèvement"
|
||||
deadline_amount: "Montant TTC"
|
||||
total_amount: "Montant total"
|
||||
settlement_by_METHOD: "Les prélèvements seront effectués par {METHOD, select, stripe{carte bancaire} other{chèque}} à l'échéance."
|
||||
settlement_by_wallet: "%{AMOUNT} seront prélevés de votre porte-monnaie pour régler la première échéance."
|
||||
#CVS accounting export (columns headers)
|
||||
accounting_export:
|
||||
journal_code: "Code journal"
|
||||
@ -344,6 +357,14 @@ fr:
|
||||
user_NAME_changed_ROLE_html: "L'utilisateur <strong><em>%{NAME}</strong></em> est maintenant %{ROLE}."
|
||||
notify_admin_members_stripe_sync:
|
||||
all_members_sync: "Tous les membres ont été synchronisés avec succès sur Stripe."
|
||||
notify_user_when_payment_schedule_ready:
|
||||
your_schedule_is_ready_html: "Votre échéancier n°%{REFERENCE}, d'un montant de %{AMOUNT}, est prêt. <a href='api/payment_schedules/%{SCHEDULE_ID}/download' target='_blank'>Cliquez ici pour le télécharger</a>."
|
||||
notify_admin_payment_schedule_failed:
|
||||
schedule_failed: "Échec du prélèvement par carte de l'échéance du %{DATE}, pour l'échéancier %{REFERENCE}"
|
||||
notify_member_payment_schedule_failed:
|
||||
schedule_failed: "Échec du prélèvement par carte de l'échéance du %{DATE}, pour votre échéancier %{REFERENCE}"
|
||||
notify_admin_payment_schedule_check_deadline:
|
||||
schedule_deadline: "Vous devez encaisser le chèque de l'échéance du %{DATE}, pour l'échéancier %{REFERENCE}"
|
||||
#statistics tools for admins
|
||||
statistics:
|
||||
subscriptions: "Abonnements"
|
||||
|
291
config/locales/mails.de.yml
Normal file
291
config/locales/mails.de.yml
Normal file
@ -0,0 +1,291 @@
|
||||
de:
|
||||
layouts:
|
||||
notifications_mailer:
|
||||
see_you_later: "Bis bald auf {GENDER, select, neutral{} other{das}}" #messageFormat interpolation
|
||||
sincerely: "Mit freundlichen Grüßen,"
|
||||
signature: "Das Fab Lab Team."
|
||||
do_not_reply: "Bitte antworte nicht auf diese E-Mail."
|
||||
users_mailer:
|
||||
notify_user_account_created:
|
||||
subject: "Dein FabLab Account wurde erfolgreich erstellt"
|
||||
body:
|
||||
hello: "Hallo %{NAME},"
|
||||
intro: "Das FabLab-Team hat Ihren Account eingerichtet auf der {FABLAB}-Website:" #messageFormat interpolation
|
||||
connection_parameters: "Hier sind Ihre Verbindungsparameter:"
|
||||
account_name: "Kontoname:"
|
||||
password: "Passwort:"
|
||||
temporary_password: "Dies ist ein temporäres Passwort. Sie können es in Ihrem «Mein Konto»-Bereich ändern."
|
||||
keep_advantages: "Mit diesem Konto behalten Sie alle Vorteile (Schulungen, Abonnementpläne), die mit Ihrem FabLab-Benutzerprofil verbunden sind."
|
||||
to_use_platform: "Um die Website zu nutzen, bitte"
|
||||
logon_or_login: "erstellen Sie ein neues Konto oder melden Sie sich an, indem Sie hier klicken."
|
||||
token_if_link_problem: "Wenn Sie Probleme mit dem Link haben, können Sie den folgenden Code bei Ihrem ersten Verbindungsversuch eingeben:"
|
||||
notifications_mailer:
|
||||
notify_user_user_group_changed:
|
||||
subject: "Ihre Gruppe wurde geändert"
|
||||
body:
|
||||
warning: "Sie haben die Gruppe gewechselt. Im FabLab kann geprüft werden, ob diese Änderung zulässig ist."
|
||||
notify_admin_user_group_changed:
|
||||
subject: "Ein Mitglied hat die Gruppe geändert"
|
||||
body:
|
||||
user_changed_group_html: "Benutzer <em><strong>%{NAME}</strong></em> hat die Gruppe geändert."
|
||||
previous_group: "Vorherige Gruppe:"
|
||||
new_group: "Neue Gruppe:"
|
||||
notify_admin_subscription_extended:
|
||||
subject: "Ein Abonnement wurde verlängert"
|
||||
body:
|
||||
subscription_extended_html: "Das Abonnement <strong><em>{PLAN}</em></strong> des Nutzers <strong><em>{NAME}</strong></em> wurde {FREE, select, true{kostenlos} other{}} verlängert bis {DATE}." #messageFormat interpolation
|
||||
notify_member_subscription_extended:
|
||||
subject: "Ihr Abonnement wurde verlängert"
|
||||
body:
|
||||
your_plan: "Ihr Abonnement"
|
||||
has_been_extended: "wurde verlängert"
|
||||
free: "kostenlos"
|
||||
until: "bis"
|
||||
notify_partner_subscribed_plan:
|
||||
subject: "Ein Abonnement wurde gekauft"
|
||||
body:
|
||||
a_plan: "Ein Abonnement"
|
||||
was_purchased_by_member: "wurde vom Nutzer gekauft"
|
||||
notify_admin_when_project_published:
|
||||
subject: "Ein Projekt wurde veröffentlicht"
|
||||
body:
|
||||
new_project_published: "Ein neues Projekt wurde veröffentlicht:"
|
||||
notify_project_collaborator_to_valid:
|
||||
subject: "Einladung zur Zusammenarbeit an einem Projekt"
|
||||
body:
|
||||
your_are_invited_to_take_part_in_a_project: "Sie wurden eingeladen, an einem Projekt mitzuarbeiten:"
|
||||
to_accept_the_invitation_click_on_following_link: "Um diese Einladung anzunehmen, klicken Sie bitte auf den folgenden Link:"
|
||||
notify_project_author_when_collaborator_valid:
|
||||
subject: "Neuer Mitarbeiter in Ihrem Projekt"
|
||||
body:
|
||||
the_member: "der Benutzer"
|
||||
accepted_your_invitation_to_take_part_in_the_project: "hat Ihre Einladung zur Projektmitarbeit angenommen:"
|
||||
notify_user_training_valid:
|
||||
subject: "Ihre Schulung wurde validiert"
|
||||
body:
|
||||
your_training: "Ihre Schulung"
|
||||
has_been_validated: "wurde validiert"
|
||||
notify_member_subscribed_plan:
|
||||
subject: "Ihr Abonnement wurde erfolgreich gekauft"
|
||||
body:
|
||||
plan_subscribed_html: "Sie haben <strong><em>%{PLAN}</em></strong> abonniert."
|
||||
rolling_subscription_stops_on: "Dein Abonnement endet %{DURATION} nach Ihrer ersten Schulung. Andernfalls wird es am %{DATE} angehalten."
|
||||
subscription_stops_on: "Ihr Abonnement endet am %{DATE}."
|
||||
notify_member_create_reservation:
|
||||
subject: "Ihre Reservierung wurde erfolgreich gespeichert"
|
||||
body:
|
||||
reservation_saved_html: "Ihre Reservierung <strong><em>%{RESERVATION}</em></strong> wurde erfolgreich gespeichert"
|
||||
your_reserved_slots: "Ihre reservierten Slots sind:"
|
||||
notify_member_subscribed_plan_is_changed:
|
||||
subject: "Ihr Abonnement wurde aktualisiert"
|
||||
body:
|
||||
new_plan_html: "Sie haben Ihr Abonnement für <strong><em>%{PLAN}</em></strong> geändert."
|
||||
notify_admin_member_create_reservation:
|
||||
subject: "Neue Reservierung"
|
||||
body:
|
||||
member_reserved_html: "Nutzer %{NAME} hat <strong><em>%{RESERVABLE}</em></strong> reserviert."
|
||||
reserved_slots: "Reservierte Slots sind:"
|
||||
notify_member_slot_is_modified:
|
||||
subject: "Ihr Reservierungsslot wurde erfolgreich geändert"
|
||||
body:
|
||||
reservation_changed_to: "Ihr Reservierungs-Slot wurde geändert zu:"
|
||||
previous_date: "Vorheriges Datum:"
|
||||
notify_admin_slot_is_modified:
|
||||
subject: "Ein reservierter Slot wurde geändert"
|
||||
body:
|
||||
slot_modified: "Benutzer %{NAME} hatte seinen Reservierungs-Slot geändert"
|
||||
new_date: "Neuer Slot"
|
||||
old_date: "Vorheriger Slot"
|
||||
notify_admin_when_user_is_created:
|
||||
subject: "Ein Benutzerkonto wurde erstellt"
|
||||
body:
|
||||
new_account_created: "Ein neues Benutzerkonto wurde auf der Website erstellt:"
|
||||
account_for_organization: "Dieses Konto verwaltet eine Organisation:"
|
||||
notify_admin_subscribed_plan:
|
||||
subject: "Ein Abonnement wurde gekauft"
|
||||
body:
|
||||
plan_subscribed_html: "Das Abonnement <strong><em>%{PLAN}</em></strong> wurde von <strong><em>%{NAME}</strong></em> abgeschlossen."
|
||||
notify_member_invoice_ready:
|
||||
subject: "Rechnung Ihres FabLabs"
|
||||
body:
|
||||
please_find_attached_html: "Die angehängte Datei enthält Ihre Rechnung von {DATE}, über den Betrag von {AMOUNT} in Bezug auf Ihr/e {TYPE, select, Reservation{Reservierung} other{Abonnement}}." #messageFormat interpolation
|
||||
invoice_in_your_dashboard_html: "Sie können auf Ihre Rechnung in %{DASHBOARD} auf der FabLab-Website zugreifen."
|
||||
your_dashboard: "Ihr Dashboard"
|
||||
notify_member_reservation_reminder:
|
||||
subject: "Reservierungserinnerung"
|
||||
body:
|
||||
this_is_a_reminder_about_your_reservation_RESERVABLE_to_be_held_on_DATE_html: "Erinnerung: Sie haben eine Reservierung <strong>%{RESERVABLE}</strong> für <em>%{DATE}</em>"
|
||||
this_reservation_concerns_the_following_slots: "Diese Reservierung betrifft folgende Slots:"
|
||||
notify_member_avoir_ready:
|
||||
subject: "Die Rückerstattungsrechnung Ihres FabLabs"
|
||||
body:
|
||||
please_find_attached_html: "Die angehängte Datei enthält Ihre Rückerstattungsrechnung von {DATE}, über den Betrag von {AMOUNT} in Bezug auf Ihr/e {TYPE, select, Reservation{Reservierung} other{Abonnement}}." #messageFormat interpolation
|
||||
invoice_in_your_dashboard_html: "Sie können auf Ihre Rückerstattungsrechnung in %{DASHBOARD} auf der FabLab-Website zugreifen."
|
||||
your_dashboard: "Ihr Dashboard"
|
||||
notify_member_subscription_will_expire_in_7_days:
|
||||
subject: "Ihr Abonnement läuft in 7 Tagen ab"
|
||||
body:
|
||||
your_plan: "Ihr Plan"
|
||||
expires_in_7_days: "läuft in 7 Tagen ab."
|
||||
to_renew_your_plan_follow_the_link: "Bitte folgen Sie diesem Link, um Ihren Plan zu erneuern"
|
||||
notify_member_subscription_is_expired:
|
||||
subject: "Ihr Abonnement ist abgelaufen"
|
||||
body:
|
||||
your_plan: "Ihr Plan"
|
||||
has_expired: "ist abgelaufen."
|
||||
you_can_go_to: "Bitte gehen Sie zu"
|
||||
to_renew_your_plan: "um Ihren Plan zu erneuern"
|
||||
notify_admin_subscription_will_expire_in_7_days:
|
||||
subject: "Ein Mitgliedsabonnement läuft in 7 Tagen ab"
|
||||
body:
|
||||
subscription_will_expire_html: "Abonnement für Benutzer %{NAME} <strong><em>%{PLAN}</em></strong> läuft in 7 Tagen ab."
|
||||
notify_admin_subscription_is_expired:
|
||||
subject: "Ein Mitgliedsabonnement ist abgelaufen"
|
||||
body:
|
||||
subscription_expired_html: "Abonnementplan für Benutzer %{NAME} <strong><em>%{PLAN}</em></strong> ist jetzt abgelaufen."
|
||||
notify_admin_subscription_canceled:
|
||||
subject: "Ein Mitgliedsabonnement wurde storniert"
|
||||
body:
|
||||
subscription_canceled_html: "Abonnement <strong><em>%{PLAN}</em></strong> für Nutzer %{NAME} wurde storniert."
|
||||
notify_member_subscription_canceled:
|
||||
subject: "Ihr Abonnement wurde storniert"
|
||||
body:
|
||||
your_plan_was_canceled: "Ihr Abonnementsplan wurde storniert."
|
||||
your_plan: "ihr Abonnement"
|
||||
end_at: "endet am"
|
||||
notify_member_slot_is_canceled:
|
||||
subject: "Ihre Reservierung wurde storniert"
|
||||
body:
|
||||
reservation_canceled: "Ihre Reservierung für %{RESERVABLE} wurde storniert"
|
||||
notify_admin_slot_is_canceled:
|
||||
subject: "Eine Reservierung wurde storniert"
|
||||
body:
|
||||
member_cancelled: "Benutzer %{NAME} hat seine Reservierung storniert"
|
||||
item_details: "%{START} - %{END}, in Bezug auf %{RESERVABLE}"
|
||||
generate_refund: "Vergessen Sie nicht, eine Gutschrift oder eine Rückerstattung für diese Stornierung zu buchen."
|
||||
notify_admin_when_user_is_imported:
|
||||
subject: "Ein Benutzerkonto wurde aus der SSO importiert"
|
||||
body:
|
||||
new_account_imported: "Ein neues Benutzerkonto (ID: %{ID}) wurde über %{PROVIDER} auf die Website importiert."
|
||||
provider_uid: "seine Provider-ID ist: "
|
||||
known_information: "Folgendes wissen wir über diesen Anbieter:"
|
||||
address_already_used: "Diese Adresse wird schon von einem anderen Nutzer verwendet"
|
||||
no_more_info_available: "Für diesen Nutzer sind keine weiteren Informationen verfügbar, solange er sein Profil nicht vervollständigt hat."
|
||||
notify_user_profile_complete:
|
||||
subject: "Sie haben nun Zugriff auf die gesamte Website"
|
||||
body:
|
||||
message: "Ihre Kontoinformationen wurden korrekt aktualisiert, Sie haben nun Zugriff auf die gesamte Website."
|
||||
notify_user_auth_migration:
|
||||
subject: "Wichtige Änderung Ihres FabLab Accounts"
|
||||
body:
|
||||
the_platform: "die Website"
|
||||
is_changing_its_auth_system_and_will_now_use: "ändert momentan das Benutzeridentifikationssystem und verwendet zukünftig"
|
||||
instead_of: "anstatt"
|
||||
consequence_of_the_modification: "Aufgrund dieser Änderung können Sie sich nicht mit Ihren momentanen Benutzernamen auf der Website anmelden"
|
||||
to_use_the_platform_thanks_for: "Um die Webseite weiter zu nutzen, bitte"
|
||||
create_an_account_on: "erstellen Sie ein Konto auf"
|
||||
or_use_an_existing_account_clicking_here: "oder verwenden Sie ein bestehendes Konto, indem Sie hier klicken"
|
||||
in_case_of_problem_enter_the_following_code: "Falls beim Aufruf des Links zu Problemen kommt, können Sie den folgenden Code bei Ihrem ersten Verbindungsversuch eingeben, um Ihr aktuelles Konto in das neue Authentifizierungssystem zu migrieren:"
|
||||
notify_admin_user_merged:
|
||||
subject: "Ein importiertes Konto wurde mit einem bestehenden Konto zusammengeführt"
|
||||
body:
|
||||
imported_account_merged: "Ein zuvor importiertes Benutzerkonto über %{PROVIDER) wurde mit dem bestehenden Konto %{NAME} zusammengeführt"
|
||||
provider_uid: "seine Provider-ID ist:"
|
||||
notify_admin_profile_complete:
|
||||
subject: "Ein importiertes Konto hat sein Profil vervollständigt"
|
||||
body:
|
||||
account_completed: "Ein Benutzerkonto hat sein Profil vervollständigt:"
|
||||
imported_account_completed: "Ein Benutzerkonto, das zuvor über %{PROVIDER} importiert wurde, hat sein Profil vervollständigt:"
|
||||
provider_id: "seine Provider-ID ist:"
|
||||
notify_admin_abuse_reported:
|
||||
subject: "Ein missbräuchlicher Inhalt wurde gemeldet"
|
||||
body:
|
||||
intro: "Ein Benutzer wurde als beleidigend markiert"
|
||||
signaled_content: "gemeldeter Inhalt:"
|
||||
signaled_by: "gemeldet von:"
|
||||
signaled_on: "gemeldet auf:"
|
||||
message: "Nachricht:"
|
||||
visit_management_interface: "Weitere Informationen finden Sie im Bereich Reporting Management."
|
||||
notify_user_wallet_is_credited:
|
||||
subject: "Eine Gutschrift ist auf Ihrem Konto eingegangen"
|
||||
body:
|
||||
wallet_credit_html: "Ihrem Guthaben wurde %{AMOUNT} vom Administrator gutgeschrieben."
|
||||
notify_admin_user_wallet_is_credited:
|
||||
subject: "Dem Guthaben des Mitglieds wurde gutgeschrieben"
|
||||
body:
|
||||
wallet_credit_html: "Dem Guthaben von %{USER} wurde %{AMOUNT} vom Administrator %{ADMIN} gutgeschrieben."
|
||||
notify_admin_export_complete:
|
||||
subject: "Export abgeschlossen"
|
||||
body:
|
||||
you_asked_for_an_export: "Sie haben einen Export angefordert"
|
||||
statistics_global: "aller Statistiken"
|
||||
statistics_account: "der Registrierungsstatistiken"
|
||||
statistics_event: "der Veranstaltungsstatistiken"
|
||||
statistics_machine: "der Statistiken der Maschinenslots"
|
||||
statistics_project: "der Projektstatistiken"
|
||||
statistics_subscription: "der Abonnementstatistiken"
|
||||
statistics_training: "der Schulungsstatistiken"
|
||||
statistics_space: "der Raumstatistiken"
|
||||
users_members: "der Mitgliederliste"
|
||||
users_subscriptions: "der Abonnementliste"
|
||||
users_reservations: "der Reservierungsliste"
|
||||
availabilities_index: "der Verfügbarkeit der Reservierungen"
|
||||
accounting_accounting-software: "der Buchhaltungsdaten"
|
||||
click_to_download: "Excel-Datei erfolgreich erstellt. Zum Herunterladen klicken Sie"
|
||||
here: "hier"
|
||||
file_type:
|
||||
xlsx: "Excel"
|
||||
csv: "CSV"
|
||||
notify_admin_import_complete:
|
||||
subject: "Import abgeschlossen"
|
||||
body:
|
||||
you_made_an_import: "Sie haben einen Import von %{CATEGORY} gestartet"
|
||||
category_members: "der Mitglieder"
|
||||
click_to_view_results: "Klicken Sie hier, um die Ergebnisse anzuzeigen"
|
||||
notify_member_about_coupon:
|
||||
subject: "Gutschein"
|
||||
body:
|
||||
enjoy_a_discount_of_PERCENT_with_code_CODE: "Erhalten Sie %{PERCENT}% Rabatt auf der gesamten Seite mit dem Code %{CODE}."
|
||||
enjoy_a_discount_of_AMOUNT_with_code_CODE: "Erhalten Sie %{AMOUNT}% Rabatt auf der gesamten Seite mit dem Code %{CODE}."
|
||||
this_coupon_is_valid_USAGE_times_until_DATE_for_all_your_purchases: "Dieser Gutschein ist {USAGE, plural, =1{einmalig} other{mehrfach}} gültig für alle Ihre Käufe {TYPE, select, amount_off{mindestens gleich dem Gutscheinbetrag} other{}} ab sofort {DATE, select, NO-DATE{und ohne Ablaufdatum} other{und einlösbar bis {DATE}}}."
|
||||
notify_admin_free_disk_space:
|
||||
subject: "Wenig Speicherplatz auf der Festplatte"
|
||||
body: "Warnung: verfügbarer Festplattenspeicher auf dem Server mit Fab-Manager ist weniger als %{THRESHOLD} MiB. Dies kann den Betrieb beeinflussen und das Speichern von Daten verhindern. Derzeit sind %{AVAILABLE} MiB freier Speicherplatz am Mount-Punkt verfügbar."
|
||||
notify_admin_close_period_reminder:
|
||||
subject: "Bitte schließen Sie Ihre Abrechnungsperioden regelmäßig ab"
|
||||
body:
|
||||
warning_last_closed_period_over_1_year: "Bitte schließen Sie Ihre Abrechnungsperioden regelmäßig ab. Der letzte Abschlusszeitraum endete um %{LAST_END}."
|
||||
warning_no_closed_periods: "Bitte schließen Sie Ihre Abrechnungsperioden regelmäßig ab. Sie müssen Abrechnungsperioden ab %{FIRST_DATE} schließen."
|
||||
notify_admin_archive_complete:
|
||||
subject: "Archivierung abgeschlossen"
|
||||
body:
|
||||
archive_complete: "Sie haben den Abrechnungszeitraum von %{START} bis %{END} abgeschlossen. Die Archivierung der Daten ist nun abgeschlossen."
|
||||
click_to_download: "Um das ZIP-Archiv herunterzuladen, klicken Sie"
|
||||
here: "hier."
|
||||
save_on_secured: "Speichern Sie dieses Archiv auf einem gesicherten externen Speichermedium und bedenken Sie, dass es bei einer Überprüfung durch die Steuerbehörde angefordert werden kann."
|
||||
notify_privacy_policy_changed:
|
||||
subject: "Datenschutzerklärung aktualisiert"
|
||||
body:
|
||||
content_html: "<p>Wir möchten Sie darüber informieren, dass wir unsere Datenschutzrichtlinie gerade aktualisiert haben.</p><p>Wir können unsere Datenschutzrichtlinien jederzeit ändern. Gesetzesgemäß erhalten Sie eine Benachrichtigung für jedes Update.</p><p>Durch den Zugriff auf oder die Nutzung unserer Dienste nach dem Update der Datenschutzrichtlinien gehen wir davon aus, dass Sie den Bedingungen einschließlich der Aktualisierungen zugestimmt haben.</p>"
|
||||
link_to_policy: "Klicken Sie hier, um sich die Datenschutzerklärung anzusehen."
|
||||
notify_admin_refund_created:
|
||||
subject: "Eine Rückerstattung wurde durchgeführt"
|
||||
body:
|
||||
refund_created: "Eine Rückerstattung von %{AMOUNT} wurde auf die Rechnung %{INVOICE} des Benutzers %{USER} generiert"
|
||||
download: "Hier klicken, um diese Erstattungsrechnung herunterzuladen"
|
||||
notify_admins_role_update:
|
||||
subject: "Die Rolle eines Benutzers hat sich geändert"
|
||||
body:
|
||||
user_role_changed_html: "Die Rolle des Benutzers <em><strong>%{NAME}</strong></em> hat sich geändert."
|
||||
previous_role: "Vorherige Rolle:"
|
||||
new_role: "Neue Rolle:"
|
||||
notify_user_role_update:
|
||||
subject: "Ihre Rolle hat sich geändert"
|
||||
body:
|
||||
role_changed_html: "Deine Rolle bei {GENDER, select, male{dem} female{der} neutral{} other{dem}} {NAME} hat sich geändert. Sie sind jetzt <strong>{ROLE}</strong>.<br/>Mit großer Macht kommt große Verantwortung, nutzen Sie Ihre neuen Privilegien fair und respektvoll."
|
||||
notify_admin_members_stripe_sync:
|
||||
subject: "Stripe-Synchronisation"
|
||||
body:
|
||||
members_sync: "Alle Mitglieder wurden erfolgreich auf Stripe synchronisiert."
|
||||
shared:
|
||||
hello: "Hallo %{user_name}"
|
@ -287,5 +287,29 @@ en:
|
||||
subject: "Stripe synchronization"
|
||||
body:
|
||||
members_sync: "All members were successfully synchronized on Stripe."
|
||||
notify_member_payment_schedule_ready:
|
||||
subject: "Your payment schedule"
|
||||
body:
|
||||
please_find_attached_html: "Please find attached your payment schedule, issued on {DATE}, with an amount of {AMOUNT} concerning your {TYPE, select, Reservation{reservation} other{subscription}}." #messageFormat interpolation
|
||||
schedule_in_your_dashboard_html: "You can find this payment schedule at any time from %{DASHBOARD} on the Fab Lab's website."
|
||||
your_dashboard: "your dashboard"
|
||||
notify_admin_payment_schedule_failed:
|
||||
subject: "Card debit failure"
|
||||
body:
|
||||
remember: "In accordance with the %{REFERENCE} payment schedule, a debit by card of %{AMOUNT} was scheduled on %{DATE}."
|
||||
error: "Unfortunately, this card debit was unable to complete successfully."
|
||||
action: "Please go to your payment schedule management interface as soon as possible to resolve the problem."
|
||||
notify_member_payment_schedule_failed:
|
||||
subject: "Card debit failure"
|
||||
body:
|
||||
remember: "In accordance with your %{REFERENCE} payment schedule, a debit by card of %{AMOUNT} was scheduled on %{DATE}."
|
||||
error: "Unfortunately, this card debit was unable to complete successfully."
|
||||
action: "Please contact the manager of your FabLab as soon as possible, otherwise your subscription may be interrupted."
|
||||
notify_admin_payment_schedule_check_deadline:
|
||||
subject: "Payment deadline"
|
||||
body:
|
||||
remember: "In accordance with the %{REFERENCE} payment schedule, %{AMOUNT} was due to be debited on %{DATE}."
|
||||
date: "This is a reminder to cash the scheduled check as soon as possible."
|
||||
confirm: "Do not forget to confirm the receipt in your payment schedule management interface, so that the corresponding invoice will be generated."
|
||||
shared:
|
||||
hello: "Hello %{user_name}"
|
||||
|
@ -287,5 +287,29 @@ fr:
|
||||
subject: "Synchronisation Stripe"
|
||||
body:
|
||||
members_sync: "Tous les membres ont été synchronisés avec succès sur Stripe."
|
||||
notify_member_payment_schedule_ready:
|
||||
subject: "Votre échéancier de paiement"
|
||||
body:
|
||||
please_find_attached_html: "Vous trouverez en pièce jointe votre échéancier de paiement du {DATE}, d'un montant de {AMOUNT} concernant votre {TYPE, select, Reservation{réservation} other{abonnement}}." #messageFormat interpolation
|
||||
schedule_in_your_dashboard_html: "Vous pouvez à tout moment retrouver votre échéancier dans %{DASHBOARD} sur le site du Fab Lab."
|
||||
your_dashboard: "votre tableau de bord"
|
||||
notify_admin_payment_schedule_failed:
|
||||
subject: "Échec du prélèvement par carte"
|
||||
body:
|
||||
remember: "Conformément à l'échéancier de paiement %{REFERENCE}, un prélèvement par carte de %{AMOUNT} était prévu le %{DATE}."
|
||||
error: "Malheureusement, ce prélèvement n'a pas pu être effectué correctement."
|
||||
action: "Veuillez vous rendre au plus tôt dans votre interface de gestion des échéanciers pour régler le problème."
|
||||
notify_member_payment_schedule_failed:
|
||||
subject: "Échec du prélèvement par carte"
|
||||
body:
|
||||
remember: "Conformément à votre échéancier de paiement %{REFERENCE}, un prélèvement par carte de %{AMOUNT} était prévu le %{DATE}."
|
||||
error: "Malheureusement, ce prélèvement n'a pas pu être effectué correctement."
|
||||
action: "Veuillez prendre contact avec le gestionnaire de votre FabLab au plus tôt, faute de quoi votre abonnement risque d'être interrompu."
|
||||
notify_admin_payment_schedule_check_deadline:
|
||||
subject: "Échéance d'encaissement"
|
||||
body:
|
||||
remember: "Conformément à l'échéancier de paiement %{REFERENCE}, une échéance de %{AMOUNT} était prévu pour être prélevée le %{DATE}."
|
||||
date: "Ceci est un rappel d'encaisser le chèque prévu dès que possible."
|
||||
confirm: "N'oubliez pas de confirmer l'encaissement dans votre interface de gestion des échéanciers, afin que la facture correspondante soit générée."
|
||||
shared:
|
||||
hello: "Bonjour %{user_name}"
|
||||
|
@ -39,6 +39,7 @@ pt:
|
||||
must_be_in_the_past: "O período deve ser estritamente anterior à data de hoje."
|
||||
apipie:
|
||||
api_documentation: "Documentação da API"
|
||||
code: "HTTP code"
|
||||
#error messages when importing an account from a SSO
|
||||
omniauth:
|
||||
email_already_linked_to_another_account_please_input_your_authentication_code: "E-mail \"%{OLD_MAIL}\" já está vinculado a outra conta, insira seu código de autenticação."
|
||||
|
@ -1,198 +0,0 @@
|
||||
af:
|
||||
date:
|
||||
abbr_day_names:
|
||||
- Son
|
||||
- Maan
|
||||
- Dins
|
||||
- Woe
|
||||
- Don
|
||||
- Vry
|
||||
- Sat
|
||||
abbr_month_names:
|
||||
-
|
||||
- Jan
|
||||
- Feb
|
||||
- Mar
|
||||
- Apr
|
||||
- Mei
|
||||
- Jun
|
||||
- Jul
|
||||
- Aug
|
||||
- Sep
|
||||
- Okt
|
||||
- Nov
|
||||
- Des
|
||||
day_names:
|
||||
- Sondag
|
||||
- Maandag
|
||||
- Dinsdag
|
||||
- Woensdag
|
||||
- Donderdag
|
||||
- Vrydag
|
||||
- Saterdag
|
||||
formats:
|
||||
default: "%Y-%m-%d"
|
||||
long: "%B %d, %Y"
|
||||
short: "%b %d"
|
||||
month_names:
|
||||
-
|
||||
- Januarie
|
||||
- Februarie
|
||||
- Maart
|
||||
- April
|
||||
- Mai
|
||||
- Junie
|
||||
- Julie
|
||||
- Augustus
|
||||
- September
|
||||
- Oktober
|
||||
- November
|
||||
- Desember
|
||||
order:
|
||||
- :year
|
||||
- :month
|
||||
- :day
|
||||
datetime:
|
||||
distance_in_words:
|
||||
about_x_hours:
|
||||
one: ongeveer 1 uur
|
||||
other: ongeveer %{count} ure
|
||||
about_x_months:
|
||||
one: ongeveer 1 maand
|
||||
other: ongeveer %{count} maande
|
||||
about_x_years:
|
||||
one: ongeveer 1 jaar
|
||||
other: ongeveer %{count} jaar
|
||||
almost_x_years:
|
||||
one: sowat 1 jaar
|
||||
other: sowat %{count} jaar
|
||||
half_a_minute: halfminuut
|
||||
less_than_x_minutes:
|
||||
one: minder as n minuut
|
||||
other: minder as %{count} minute
|
||||
less_than_x_seconds:
|
||||
one: minder as 1 second
|
||||
other: minder as %{count} sekondes
|
||||
over_x_years:
|
||||
one: meer as 1 jaar
|
||||
other: meer as %{count} jaar
|
||||
x_days:
|
||||
one: 1 dag
|
||||
other: "%{count} days"
|
||||
x_minutes:
|
||||
one: 1 minuut
|
||||
other: "%{count} minute"
|
||||
x_months:
|
||||
one: 1 maand
|
||||
other: "%{count} maande"
|
||||
x_seconds:
|
||||
one: 1 sekonde
|
||||
other: "%{count} sekondes"
|
||||
prompts:
|
||||
day: Dag
|
||||
hour: Uur
|
||||
minute: Minuut
|
||||
month: Maand
|
||||
second: Sekondes
|
||||
year: Jaar
|
||||
errors:
|
||||
format: "%{attribute} %{message}"
|
||||
messages:
|
||||
accepted: moet aanvaar word
|
||||
blank: mag nie leeg wees nie
|
||||
confirmation: pas nie by bevestiging nie
|
||||
empty: mag nie leeg wees nie
|
||||
equal_to: moet gelyk wees aan %{count}
|
||||
even: moet gelykstaande wees
|
||||
exclusion: is bespreek
|
||||
greater_than: moet meer wees as %{count}
|
||||
greater_than_or_equal_to: moet meer of gelykstaande wees aan %{count}
|
||||
inclusion: is nie by die lys ingesluit nie
|
||||
invalid: is ongeldig
|
||||
less_than: moet minder wees as %{count}
|
||||
less_than_or_equal_to: moet minder of gelykstaande wees aan %{count}
|
||||
not_a_number: is nie n getal nie
|
||||
not_an_integer: moet n integer wees
|
||||
odd: moet onewe wees
|
||||
record_invalid: 'Validation failed: %{errors}'
|
||||
taken: is reeds geneem
|
||||
too_long:
|
||||
one: is te lank (maksimum is 1 karakter)
|
||||
other: is te lank (maksimum is %{count} karakters)
|
||||
too_short:
|
||||
one: is te kort (minimum is 1 karakter)
|
||||
other: is te kort (minimum is %{count} karakters)
|
||||
wrong_length:
|
||||
one: is die verkeerde lengte (moet 1 karakter wees)
|
||||
other: is die verkeerde lengte (moet %{count} karakters wees)
|
||||
template:
|
||||
body: 'There were problems with the following fields:'
|
||||
header:
|
||||
one: 1 fout het verhoed dat hierdie %{model} gestoor kon word
|
||||
other: "%{count} foute het verhoed dat hierdie %{model} gestoor kon word"
|
||||
helpers:
|
||||
select:
|
||||
prompt: Kies asseblief
|
||||
submit:
|
||||
create: Skep %{model}
|
||||
submit: Stoor %{model}
|
||||
update: Dateer %{model} op
|
||||
number:
|
||||
currency:
|
||||
format:
|
||||
delimiter: ","
|
||||
format: "%u%n"
|
||||
precision: 2
|
||||
separator: "."
|
||||
significant: vals
|
||||
strip_insignificant_zeros: vals
|
||||
unit: R
|
||||
format:
|
||||
delimiter: ","
|
||||
precision: 3
|
||||
separator: "."
|
||||
significant: vals
|
||||
strip_insignificant_zeros: vals
|
||||
human:
|
||||
decimal_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
billion: miljard
|
||||
million: miljoen
|
||||
quadrillion: kwadriljon
|
||||
thousand: duisend
|
||||
trillion: biljoen
|
||||
unit: ''
|
||||
format:
|
||||
delimiter: ''
|
||||
precision: 3
|
||||
significant: waar
|
||||
strip_insignificant_zeros: waar
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: Byte
|
||||
other: Bytes
|
||||
gb: GB
|
||||
kb: KB
|
||||
mb: MB
|
||||
tb: TB
|
||||
percentage:
|
||||
format:
|
||||
delimiter: ''
|
||||
precision:
|
||||
format:
|
||||
delimiter: ''
|
||||
support:
|
||||
array:
|
||||
last_word_connector: ", en "
|
||||
two_words_connector: " en "
|
||||
words_connector: ", "
|
||||
time:
|
||||
am: vm
|
||||
formats:
|
||||
default: "%a, %d %b %Y %H:%M:%S %z"
|
||||
long: "%B %d, %Y %H:%M"
|
||||
short: "%d %b %H:%M"
|
||||
pm: nm
|
@ -1,274 +0,0 @@
|
||||
ar:
|
||||
date:
|
||||
abbr_day_names:
|
||||
- الأحد
|
||||
- الإثنين
|
||||
- الثّلاثاء
|
||||
- الأربعاء
|
||||
- الخميس
|
||||
- الجمعة
|
||||
- السّبت
|
||||
abbr_month_names:
|
||||
-
|
||||
- يناير/كانون الثّاني
|
||||
- فبراير/شباط
|
||||
- مارس/آذَار
|
||||
- إبريل/نَيْسان
|
||||
- مايو/أيار
|
||||
- يونيو/حَزيران
|
||||
- يوليو/تمُّوز
|
||||
- أغسطس/آب
|
||||
- سبتمبر/أيلول
|
||||
- أكتوبر/تشرين الأوّل
|
||||
- نوفمبر/تشرين الثّاني
|
||||
- ديسمبر/كانون الأَوّل
|
||||
day_names:
|
||||
- الأحد
|
||||
- الإثنين
|
||||
- الثّلاثاء
|
||||
- الأربعاء
|
||||
- الخميس
|
||||
- الجمعة
|
||||
- السّبت
|
||||
formats:
|
||||
default: "%Y-%m-%d"
|
||||
long: "%B %e، %Y"
|
||||
short: "%e %b"
|
||||
month_names:
|
||||
-
|
||||
- يناير/كانون الثّاني
|
||||
- فبراير/شباط
|
||||
- مارس/آذَار
|
||||
- إبريل/نَيْسان
|
||||
- مايو/أيار
|
||||
- يونيو/حَزيران
|
||||
- يوليو/تمُّوز
|
||||
- أغسطس/آب
|
||||
- سبتمبر/أيلول
|
||||
- أكتوبر/تشرين الأوّل
|
||||
- نوفمبر/تشرين الثّاني
|
||||
- ديسمبر/كانون الأَوّل
|
||||
order:
|
||||
- :day
|
||||
- :month
|
||||
- :year
|
||||
datetime:
|
||||
distance_in_words:
|
||||
about_x_hours:
|
||||
zero: حوالي صفر ساعات
|
||||
one: حوالي ساعة واحدة
|
||||
two: حوالي ساعتان
|
||||
few: حوالي %{count} ساعات
|
||||
many: حوالي %{count} ساعة
|
||||
other: حوالي %{count} ساعة
|
||||
about_x_months:
|
||||
zero: حوالي صفر أشهر
|
||||
one: حوالي شهر واحد
|
||||
two: حوالي شهران
|
||||
few: حوالي %{count} أشهر
|
||||
many: حوالي %{count} شهر
|
||||
other: حوالي %{count} شهر
|
||||
about_x_years:
|
||||
zero: حوالي صفر سنوات
|
||||
one: حوالي سنة
|
||||
two: حوالي سنتان
|
||||
few: حوالي %{count} سنوات
|
||||
many: حوالي %{count} سنة
|
||||
other: حوالي %{count} سنة
|
||||
almost_x_years:
|
||||
zero: ما يقرب من صفر سنوات
|
||||
one: تقريبا سنة واحدة
|
||||
two: ما يقرب من سنتين
|
||||
few: ما يقرب من %{count} سنوات
|
||||
many: ما يقرب من %{count} سنة
|
||||
other: ما يقرب من %{count} سنة
|
||||
half_a_minute: نصف دقيقة
|
||||
less_than_x_minutes:
|
||||
zero: أقل من صفر دقائق
|
||||
one: أقل من دقيقة
|
||||
two: أقل من دقيقتان
|
||||
few: أقل من %{count} دقائق
|
||||
many: أقل من %{count} دقيقة
|
||||
other: أقل من %{count} دقيقة
|
||||
less_than_x_seconds:
|
||||
zero: أقل من صفر ثواني
|
||||
one: أقل من ثانية
|
||||
two: أقل من ثانيتان
|
||||
few: أقل من %{count} ثوان
|
||||
many: أقل من %{count} ثانية
|
||||
other: أقل من %{count} ثانية
|
||||
over_x_years:
|
||||
zero: أكثر من صفر سنوات
|
||||
one: أكثر من سنة
|
||||
two: أكثر من سنتين
|
||||
few: أكثر من %{count} سنوات
|
||||
many: أكثر من %{count} سنة
|
||||
other: أكثر من %{count} سنة
|
||||
x_days:
|
||||
zero: صفر أيام
|
||||
one: يوم واحد
|
||||
two: يومان
|
||||
few: "%{count} أيام"
|
||||
many: "%{count} يوم"
|
||||
other: "%{count} يوم"
|
||||
x_minutes:
|
||||
zero: صفر دقائق
|
||||
one: دقيقة واحدة
|
||||
two: دقيقتان
|
||||
few: "%{count} دقائق"
|
||||
many: "%{count} دقيقة"
|
||||
other: "%{count} دقيقة"
|
||||
x_months:
|
||||
zero: صفر أشهر
|
||||
one: شهر واحد
|
||||
two: شهران
|
||||
few: "%{count} أشهر"
|
||||
many: "%{count} شهر"
|
||||
other: "%{count} شهر"
|
||||
x_seconds:
|
||||
zero: صفر ثواني
|
||||
one: ثانية واحدة
|
||||
two: ثانيتان
|
||||
few: "%{count} ثوان"
|
||||
many: "%{count} ثانية"
|
||||
other: "%{count} ثانية"
|
||||
prompts:
|
||||
day: اليوم
|
||||
hour: ساعة
|
||||
minute: دقيقة
|
||||
month: الشهر
|
||||
second: ثانية
|
||||
year: السنة
|
||||
errors:
|
||||
format: "%{attribute} %{message}"
|
||||
messages:
|
||||
accepted: يجب أن تقبل
|
||||
blank: فارغ، يرجى ملء الحقل
|
||||
present: يجب ترك الحقل فارغاً
|
||||
confirmation: لا يتوافق مع %{attribute}
|
||||
empty: فارغ، يرجى ملء الحقل
|
||||
equal_to: يجب أن يساوي %{count}
|
||||
even: يجب أن يكون عددًا زوجيًّا
|
||||
exclusion: محجوز
|
||||
greater_than: يجب أن يكون أكبر من %{count}
|
||||
greater_than_or_equal_to: يجب أن يكون أكبر من أو يساوي %{count}
|
||||
inclusion: غير مُدرج في القائمة
|
||||
invalid: غير مقبول
|
||||
less_than: يجب أن يكون أصغر من %{count}
|
||||
less_than_or_equal_to: يجب أن يكون أصغر من أو يساوي %{count}
|
||||
not_a_number: ليس رقمًا
|
||||
not_an_integer: يجب أن يكون عدداً صحيحاً
|
||||
odd: يجب أن يكون عددًا فرديًّا
|
||||
record_invalid: 'فشل التحقّق من: %{errors}'
|
||||
restrict_dependent_destroy:
|
||||
one: لا يمكن حذف السجل لوجود سجل يعتمد عليه %{record}
|
||||
many: لا يمكن حذف السجل لوجود سجلات تعتمد عليه %{record}
|
||||
taken: محجوز مُسبقًا
|
||||
too_long:
|
||||
zero: أطول من اللّازم (الحد الأقصى هو ولا حرف)
|
||||
one: أطول من اللّازم (الحد الأقصى هو حرف واحد)
|
||||
two: أطول من اللّازم (الحد الأقصى هو حرفان)
|
||||
few: أطول من اللّازم (الحد الأقصى هو %{count} حروف)
|
||||
many: أطول من اللّازم (الحد الأقصى هو %{count} حرف)
|
||||
other: أطول من اللّازم (الحد الأقصى هو %{count} حرف)
|
||||
too_short:
|
||||
zero: أقصر من اللّازم (الحد الأدنى هو ولا حرف)
|
||||
one: أقصر من اللّازم (الحد الأدنى هو حرف واحد)
|
||||
two: أقصر من اللّازم (الحد الأدنى هو حرفان)
|
||||
few: أقصر من اللّازم (الحد الأدنى هو %{count} حروف)
|
||||
many: أقصر من اللّازم (الحد الأدنى هو %{count} حرف)
|
||||
other: أقصر من اللّازم (الحد الأدنى هو %{count} حرف)
|
||||
wrong_length:
|
||||
zero: الطول غير مطابق للحد المطلوب (يجب أن يكون ولا حرف)
|
||||
one: الطول غير مطابق للحد المطلوب (يجب أن يكون حرف واحد)
|
||||
two: الطول غير مطابق للحد المطلوب (يجب أن يكون حرفان)
|
||||
few: الطول غير مطابق للحد المطلوب (يجب أن يكون %{count} أحرف)
|
||||
many: الطول غير مطابق للحد المطلوب (يجب أن يكون %{count} حرف)
|
||||
other: الطول غير مطابق للحد المطلوب (يجب أن يكون %{count} حرف)
|
||||
other_than:
|
||||
zero: الطول يجب ألاّ يكون صفر أحرف
|
||||
one: الطول يجب ألاّ يكون حرفاً وحداً
|
||||
two: الطول يجب ألاّ يكون حرفان
|
||||
few: الطول يجب ألاّ يكون %{count} أحرف
|
||||
many: الطول يجب ألاّ يكون %{count} حرفاً
|
||||
other: الطول يجب ألاّ يكون %{count} حرفاً
|
||||
template:
|
||||
body: 'يُرجى التحقّق من الحقول التّالية:'
|
||||
header:
|
||||
zero: 'ليس بالامكان حفظ %{model}: لايوجد أخطاء.'
|
||||
one: 'ليس بالامكان حفظ %{model}: خطأ واحد.'
|
||||
two: 'ليس بالامكان حفظ %{model}: خطئان.'
|
||||
few: 'ليس بالامكان حفظ %{model}: %{count} أخطاء.'
|
||||
many: 'ليس بالامكان حفظ %{model}: %{count} أخطاء.'
|
||||
other: 'ليس بالامكان حفظ %{model}: %{count} خطأ.'
|
||||
helpers:
|
||||
select:
|
||||
prompt: يُرجى الاختيار
|
||||
submit:
|
||||
create: "%{model} إنشاء"
|
||||
submit: "%{model} حِفظ"
|
||||
update: "%{model} تحديث"
|
||||
number:
|
||||
currency:
|
||||
format:
|
||||
delimiter: "،"
|
||||
format: "%u%n"
|
||||
precision: 2
|
||||
separator: "."
|
||||
significant: false
|
||||
strip_insignificant_zeros: false
|
||||
unit: "$"
|
||||
format:
|
||||
delimiter: "،"
|
||||
precision: 3
|
||||
separator: "."
|
||||
significant: false
|
||||
strip_insignificant_zeros: false
|
||||
human:
|
||||
decimal_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
billion: مليار
|
||||
million: مليون
|
||||
quadrillion: كدريليون
|
||||
thousand: ألفّ
|
||||
trillion: تريليون
|
||||
unit: ''
|
||||
format:
|
||||
delimiter: ''
|
||||
precision: 3
|
||||
significant: true
|
||||
strip_insignificant_zeros: true
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
zero: Bytes
|
||||
one: Byte
|
||||
two: Bytes
|
||||
few: Bytes
|
||||
many: Bytes
|
||||
other: Bytes
|
||||
gb: GB
|
||||
kb: KB
|
||||
mb: MB
|
||||
tb: TB
|
||||
percentage:
|
||||
format:
|
||||
delimiter: ''
|
||||
format: "%n%"
|
||||
precision:
|
||||
format:
|
||||
delimiter: ''
|
||||
support:
|
||||
array:
|
||||
last_word_connector: " و "
|
||||
two_words_connector: " و "
|
||||
words_connector: " و "
|
||||
time:
|
||||
am: صباحًا
|
||||
formats:
|
||||
default: "%a %b %d %H:%M:%S %Z %Y"
|
||||
long: "%B %d, %Y %H:%M"
|
||||
short: "%d %b %H:%M"
|
||||
pm: مساءً
|
@ -1,192 +0,0 @@
|
||||
az:
|
||||
date:
|
||||
abbr_day_names:
|
||||
- B.
|
||||
- B.E.
|
||||
- Ç.A.
|
||||
- Ç.
|
||||
- C.A.
|
||||
- C.
|
||||
- Ş.
|
||||
abbr_month_names:
|
||||
-
|
||||
- Yan
|
||||
- Fev
|
||||
- Mar
|
||||
- Apr
|
||||
- May
|
||||
- İyn
|
||||
- İyl
|
||||
- Avq
|
||||
- Sen
|
||||
- Okt
|
||||
- Noy
|
||||
- Dek
|
||||
day_names:
|
||||
- Bazar
|
||||
- Bazar ertəsi
|
||||
- Çərşənbə axşamı
|
||||
- Çərşənbə
|
||||
- Cümə axşamı
|
||||
- Cümə
|
||||
- Şənbə
|
||||
formats:
|
||||
default: "%d.%m.%Y"
|
||||
long: "%d %B %Y"
|
||||
short: "%d %b"
|
||||
month_names:
|
||||
-
|
||||
- Yanvar
|
||||
- Fevral
|
||||
- Mart
|
||||
- Aprel
|
||||
- May
|
||||
- İyun
|
||||
- İyul
|
||||
- Avqust
|
||||
- Sentyabr
|
||||
- Oktyabr
|
||||
- Noyabr
|
||||
- Dekabr
|
||||
order:
|
||||
- :day
|
||||
- :month
|
||||
- :year
|
||||
datetime:
|
||||
distance_in_words:
|
||||
about_x_hours:
|
||||
one: təxminən 1 saat
|
||||
other: təxminən %{count} saat
|
||||
about_x_months:
|
||||
one: təxminən 1 ay
|
||||
other: təxminən %{count} ay
|
||||
about_x_years:
|
||||
one: təxminən 1 il
|
||||
other: təxminən %{count} il
|
||||
almost_x_years:
|
||||
one: təqribən 1 il
|
||||
other: təqribən %{count} il
|
||||
half_a_minute: yarım dəqiqə
|
||||
less_than_x_minutes:
|
||||
one: 1 dəqiqədən az
|
||||
other: "%{count} dəqiqədən az"
|
||||
less_than_x_seconds:
|
||||
one: 1 saniyədən az
|
||||
other: "%{count} saniyədən az"
|
||||
over_x_years:
|
||||
one: 1 ildən çox
|
||||
other: "%{count} ildən çox"
|
||||
x_days:
|
||||
one: 1 gün
|
||||
other: "%{count} gün"
|
||||
x_minutes:
|
||||
one: 1 dəqiqə
|
||||
other: "%{count} dəqiqə"
|
||||
x_months:
|
||||
one: 1 ay
|
||||
other: "%{count} ay"
|
||||
x_seconds:
|
||||
one: 1 saniyə
|
||||
other: "%{count} saniyə"
|
||||
prompts:
|
||||
day: Gün
|
||||
hour: Saat
|
||||
minute: Dəqiqə
|
||||
month: Ay
|
||||
second: Saniyə
|
||||
year: İl
|
||||
errors:
|
||||
format: "%{attribute} %{message}"
|
||||
messages:
|
||||
accepted: qəbul olunmalıdır
|
||||
blank: boş ola bilməz
|
||||
confirmation: təsdiqə uygun deyil
|
||||
empty: boş ola bilməz
|
||||
equal_to: "%{count}-ə bərabər olmalıdır"
|
||||
even: cüt olmalıdır
|
||||
exclusion: qorunur
|
||||
greater_than: "%{count}-dən böyük olmalıdır"
|
||||
greater_than_or_equal_to: böyük və ya %{count}-ə bərabər olmalıdır
|
||||
inclusion: siyahiyə daxil deyil
|
||||
invalid: yalnışdır
|
||||
less_than: "%{count}-dən kiçik olmalıdır"
|
||||
less_than_or_equal_to: kiçik və ya %{count}-ə bərabər olmalıdır
|
||||
not_a_number: rəqəm deyil
|
||||
not_an_integer: tam rəqəm olmalıdır
|
||||
odd: tək olmalıdır
|
||||
record_invalid: 'Yoxlama uğursuz oldu: %{errors}'
|
||||
taken: artıq mövcuddur
|
||||
too_long: çox uzundur (%{count} simvoldan çox olmalı deyil)
|
||||
too_short: çox qısadır (%{count} simvoldan az olmalı deyil)
|
||||
wrong_length: uzunluqu səhvdir (%{count} simvol olmalıdır)
|
||||
template:
|
||||
body: 'Aşağıdaki səhvlər üzə çıxdı:'
|
||||
header:
|
||||
one: "%{model} saxlanmadı: 1 səhv"
|
||||
other: "%{model} saxlanmadı: %{count} səhv"
|
||||
helpers:
|
||||
select:
|
||||
prompt: Seçin
|
||||
submit:
|
||||
create: "%{model} yarat"
|
||||
submit: "%{model} saxla"
|
||||
update: "%{model} yenilə"
|
||||
number:
|
||||
currency:
|
||||
format:
|
||||
delimiter: " "
|
||||
format: "%n %u"
|
||||
precision: 2
|
||||
separator: "."
|
||||
significant: false
|
||||
strip_insignificant_zeros: false
|
||||
unit: AZN
|
||||
format:
|
||||
delimiter: " "
|
||||
precision: 3
|
||||
separator: "."
|
||||
significant: false
|
||||
strip_insignificant_zeros: false
|
||||
human:
|
||||
decimal_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
billion: Milyard
|
||||
million: Milyon
|
||||
quadrillion: Katrilyon
|
||||
thousand: Min
|
||||
trillion: Trilyon
|
||||
unit: ''
|
||||
format:
|
||||
delimiter: ''
|
||||
precision: 1
|
||||
significant: false
|
||||
strip_insignificant_zeros: false
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: Bayt
|
||||
other: Bayt
|
||||
gb: GB
|
||||
kb: KB
|
||||
mb: MB
|
||||
tb: TB
|
||||
percentage:
|
||||
format:
|
||||
delimiter: ''
|
||||
precision:
|
||||
format:
|
||||
delimiter: ''
|
||||
support:
|
||||
array:
|
||||
last_word_connector: " və "
|
||||
two_words_connector: " və "
|
||||
words_connector: ", "
|
||||
time:
|
||||
am: günortaya qədər
|
||||
formats:
|
||||
default: "%a, %d %b %Y, %H:%M:%S %z"
|
||||
long: "%d %B %Y, %H:%M"
|
||||
short: "%d %b, %H:%M"
|
||||
pm: günortadan sonra
|
@ -1,204 +0,0 @@
|
||||
be:
|
||||
date:
|
||||
abbr_day_names:
|
||||
- Пан
|
||||
- Аўт
|
||||
- Сер
|
||||
- Чцв
|
||||
- Пят
|
||||
- Суб
|
||||
- Ндз
|
||||
abbr_month_names:
|
||||
-
|
||||
- Сту
|
||||
- Лют
|
||||
- Сак
|
||||
- Кра
|
||||
- Тра
|
||||
- Чэр
|
||||
- Ліп
|
||||
- Жні
|
||||
- Вер
|
||||
- Кас
|
||||
- Ліс
|
||||
- Сне
|
||||
day_names:
|
||||
- Нядзеля
|
||||
- Панядзелак
|
||||
- Аўторак
|
||||
- Серада
|
||||
- Чацвер
|
||||
- Пятніца
|
||||
- Субота
|
||||
formats:
|
||||
default: "%d-%m-%Y"
|
||||
long: "%B %d, %Y"
|
||||
short: "%b %d"
|
||||
month_names:
|
||||
-
|
||||
- Студзень
|
||||
- Люты
|
||||
- Сакавік
|
||||
- Красавік
|
||||
- Травень
|
||||
- Чэрвень
|
||||
- Ліпень
|
||||
- Жнівень
|
||||
- Верасень
|
||||
- Кастрычнік
|
||||
- Лістапад
|
||||
- Снежань
|
||||
order:
|
||||
- :day
|
||||
- :month
|
||||
- :year
|
||||
datetime:
|
||||
distance_in_words:
|
||||
about_x_hours:
|
||||
one: каля 1 гадзіны
|
||||
other: каля %{count} гадзін
|
||||
about_x_months:
|
||||
one: каля 1 месяца
|
||||
other: каля %{count} месяцаў
|
||||
about_x_years:
|
||||
one: каля 1 года
|
||||
other: каля %{count} гадоў
|
||||
almost_x_years:
|
||||
one: амаль 1 год
|
||||
other: амаль %{count} гадоў
|
||||
half_a_minute: палова хвіліны
|
||||
less_than_x_minutes:
|
||||
one: меней за 1 хвіліну
|
||||
other: меней за %{count} хвілін
|
||||
less_than_x_seconds:
|
||||
one: меней за 1 секунду
|
||||
other: меней за %{count} секундаў
|
||||
over_x_years:
|
||||
one: болей за 1 год
|
||||
other: болей за %{count} гадоў
|
||||
x_days:
|
||||
one: 1 дзень
|
||||
other: "%{count} дзён"
|
||||
x_minutes:
|
||||
one: 1 хвіліна
|
||||
other: "%{count} хвілін"
|
||||
x_months:
|
||||
one: 1 месяц
|
||||
other: "%{count} месяцаў"
|
||||
x_seconds:
|
||||
one: 1 секунда
|
||||
other: "%{count} секундаў"
|
||||
prompts:
|
||||
day: Дзень
|
||||
hour: Гадзіна
|
||||
minute: Хвіліна
|
||||
month: Месяц
|
||||
second: Секунда
|
||||
year: Год
|
||||
errors:
|
||||
format: "%{attribute} %{message}"
|
||||
messages:
|
||||
accepted: трэба прыняць
|
||||
blank: не можа быць пустым
|
||||
present: павінна быць пустым
|
||||
confirmation: не супадае з %{attribute}
|
||||
empty: не можа быць пустым
|
||||
equal_to: павінна быць роўным %{count}
|
||||
even: павінна быць цотным
|
||||
exclusion: мае зарэзерваванае значэнне
|
||||
greater_than: павінна быць болей за %{count}
|
||||
greater_than_or_equal_to: павінна быць болей ці роўным %{count}
|
||||
inclusion: значэнне не уключана ў спіс
|
||||
invalid: няправільнае значэнне
|
||||
less_than: павінна быць меней за %{count}
|
||||
less_than_or_equal_to: павінна быць меней ці роўным %{count}
|
||||
not_a_number: гэта не лічба
|
||||
not_an_integer: павінна быць цэлай лічбай
|
||||
odd: павінна быць няцотным
|
||||
record_invalid: 'Памылкі валідацыі: %{errors}'
|
||||
restrict_dependent_destroy:
|
||||
one: Нельга выдаліць запіс, таму што існуе залежнасць %{record}
|
||||
many: Нельга выдаліць запіс, таму што існуюць залежнасці %{record}
|
||||
taken: ўжо занята
|
||||
too_long:
|
||||
one: занадта доўгі (максімум 1 сімвал)
|
||||
other: занадта доўгі (максімум %{count} сімвалаў)
|
||||
too_short:
|
||||
one: занадта кароткі (мінімум 1 сімвал)
|
||||
other: занадта кароткі (мінімум %{count} сімвалаў)
|
||||
wrong_length:
|
||||
one: няправільная даўжыня (павінен быць 1 сімвал)
|
||||
other: няправільная даўжыня (павінны быць %{count} сімвалаў)
|
||||
other_than: павінна адрознівацца ад %{count}
|
||||
template:
|
||||
body: 'Узніклі праблемы з наступнымі палямі:'
|
||||
header:
|
||||
one: не атрымалася захаваць %{model} з-за 1 памылкі
|
||||
other: не атрымалася захаваць %{model} з-за %{count} памылак
|
||||
helpers:
|
||||
select:
|
||||
prompt: Калі ласка, абярыце
|
||||
submit:
|
||||
create: Стварыць %{model}
|
||||
submit: Захаваць %{model}
|
||||
update: Абнавіць %{model}
|
||||
number:
|
||||
currency:
|
||||
format:
|
||||
delimiter: ","
|
||||
format: "%u%n"
|
||||
precision: 2
|
||||
separator: "."
|
||||
significant: false
|
||||
strip_insignificant_zeros: false
|
||||
unit: "$"
|
||||
format:
|
||||
delimiter: ","
|
||||
precision: 3
|
||||
separator: "."
|
||||
significant: false
|
||||
strip_insignificant_zeros: false
|
||||
human:
|
||||
decimal_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
billion: мільярд
|
||||
million: мільён
|
||||
quadrillion: квадрыльён
|
||||
thousand: тысяча
|
||||
trillion: трыльён
|
||||
unit: ''
|
||||
format:
|
||||
delimiter: ''
|
||||
precision: 3
|
||||
significant: true
|
||||
strip_insignificant_zeros: true
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: Байт
|
||||
other: Байтаў
|
||||
gb: ГБ
|
||||
kb: КБ
|
||||
mb: МБ
|
||||
tb: ТБ
|
||||
percentage:
|
||||
format:
|
||||
delimiter: ''
|
||||
format: "%n%"
|
||||
precision:
|
||||
format:
|
||||
delimiter: ''
|
||||
support:
|
||||
array:
|
||||
last_word_connector: " і "
|
||||
two_words_connector: " і "
|
||||
words_connector: ", "
|
||||
time:
|
||||
am: раніцы
|
||||
formats:
|
||||
default: "%a, %d %b %Y %H:%M:%S %z"
|
||||
long: "%B %d, %Y %H:%M"
|
||||
short: "%d %b %H:%M"
|
||||
pm: вечара
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user