feat: expand i18n locale support and fallback handling
This commit is contained in:
@@ -9,6 +9,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.ResourceBundle.Control;
|
||||
|
||||
@@ -16,6 +17,7 @@ import java.util.ResourceBundle.Control;
|
||||
public class TranslationProvider implements I18NProvider {
|
||||
|
||||
public static final String BUNDLE_PREFIX = "messages";
|
||||
private static final Locale DEFAULT_LOCALE = Locale.GERMAN;
|
||||
|
||||
// Custom Control to map language codes to file names
|
||||
private static final Control BUNDLE_CONTROL = new Control() {
|
||||
@@ -35,7 +37,7 @@ public class TranslationProvider implements I18NProvider {
|
||||
case "es" -> Locale.of("es"); // Spanish -> messages_es.properties
|
||||
case "fr" -> Locale.of("fr"); // French -> messages_fr.properties
|
||||
case "en" -> Locale.of("en"); // English -> messages_en.properties
|
||||
case "de" -> Locale.of("de"); // German -> messages.properties (default)
|
||||
case "de" -> Locale.of("de"); // German -> messages_de.properties
|
||||
default -> locale;
|
||||
};
|
||||
|
||||
@@ -57,19 +59,38 @@ public class TranslationProvider implements I18NProvider {
|
||||
}
|
||||
|
||||
try {
|
||||
ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_PREFIX, locale, BUNDLE_CONTROL);
|
||||
String value = bundle.getString(key);
|
||||
String value = findTranslation(key, locale);
|
||||
if (value == null) {
|
||||
return key;
|
||||
}
|
||||
|
||||
if (params.length > 0) {
|
||||
value = MessageFormat.format(value, params);
|
||||
}
|
||||
|
||||
return value;
|
||||
} catch (Exception e) {
|
||||
} catch (MissingResourceException e) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
private String findTranslation(String key, Locale locale) {
|
||||
Locale effectiveLocale = locale != null ? locale : DEFAULT_LOCALE;
|
||||
ResourceBundle localizedBundle = ResourceBundle.getBundle(BUNDLE_PREFIX, effectiveLocale, BUNDLE_CONTROL);
|
||||
if (localizedBundle.containsKey(key)) {
|
||||
return localizedBundle.getString(key);
|
||||
}
|
||||
|
||||
if (!DEFAULT_LOCALE.getLanguage().equals(effectiveLocale.getLanguage())) {
|
||||
ResourceBundle germanBundle = ResourceBundle.getBundle(BUNDLE_PREFIX, DEFAULT_LOCALE, BUNDLE_CONTROL);
|
||||
if (germanBundle.containsKey(key)) {
|
||||
return germanBundle.getString(key);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getTranslation(String key, Language language) {
|
||||
Locale locale = switch (language) {
|
||||
case DE -> Locale.GERMAN;
|
||||
@@ -85,4 +106,4 @@ public class TranslationProvider implements I18NProvider {
|
||||
};
|
||||
return getTranslation(key, locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package de.assecutor.votianlt.service;
|
||||
|
||||
import com.vaadin.flow.component.UI;
|
||||
import de.assecutor.votianlt.config.TranslationProvider;
|
||||
import de.assecutor.votianlt.model.Language;
|
||||
import de.assecutor.votianlt.model.User;
|
||||
import de.assecutor.votianlt.repository.UserRepository;
|
||||
@@ -8,16 +9,17 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@Service
|
||||
public class LanguageService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final TranslationProvider translationProvider;
|
||||
|
||||
@Autowired
|
||||
public LanguageService(UserRepository userRepository) {
|
||||
public LanguageService(UserRepository userRepository, TranslationProvider translationProvider) {
|
||||
this.userRepository = userRepository;
|
||||
this.translationProvider = translationProvider;
|
||||
}
|
||||
|
||||
public void updateUserLanguage(User user, Language language) {
|
||||
@@ -30,31 +32,7 @@ public class LanguageService {
|
||||
}
|
||||
|
||||
public String getTranslation(String key, Language language) {
|
||||
try {
|
||||
Locale locale;
|
||||
switch (language) {
|
||||
case DE:
|
||||
locale = Locale.GERMAN;
|
||||
break;
|
||||
case EN:
|
||||
locale = Locale.ENGLISH;
|
||||
break;
|
||||
case FR:
|
||||
locale = Locale.FRENCH;
|
||||
break;
|
||||
case ES:
|
||||
locale = Locale.of("es", "ES");
|
||||
break;
|
||||
default:
|
||||
locale = Locale.GERMAN;
|
||||
}
|
||||
|
||||
ResourceBundle bundle = ResourceBundle.getBundle("messages", locale);
|
||||
return bundle.getString(key);
|
||||
} catch (Exception e) {
|
||||
// Fallback to key itself if translation not found
|
||||
return key;
|
||||
}
|
||||
return translationProvider.getTranslation(key, language != null ? language : Language.DE);
|
||||
}
|
||||
|
||||
public String getTranslation(String key, User user) {
|
||||
@@ -78,6 +56,12 @@ public class LanguageService {
|
||||
case EN -> Locale.ENGLISH;
|
||||
case FR -> Locale.FRENCH;
|
||||
case ES -> Locale.of("es", "ES");
|
||||
case TR -> Locale.of("tr", "TR");
|
||||
case PL -> Locale.of("pl", "PL");
|
||||
case RU -> Locale.of("ru", "RU");
|
||||
case EE -> Locale.of("et", "EE");
|
||||
case LV -> Locale.of("lv", "LV");
|
||||
case LT -> Locale.of("lt", "LT");
|
||||
default -> Locale.GERMAN;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ page.title.customer.create=Neuen Kunden anlegen
|
||||
page.title.login=Bei VotianLT anmelden
|
||||
page.title.jobs=Aufträge
|
||||
page.title.appuser.edit=App-Nutzer bearbeiten
|
||||
page.title.statistics=KI-Statistiken
|
||||
page.title.statistics=Statistiken
|
||||
page.title.password.forget=Passwort zurücksetzen
|
||||
page.title.invoices=Rechnungen
|
||||
page.title.appusers=App-Nutzer
|
||||
@@ -268,10 +268,7 @@ page.title.create.invoice=Rechnung erstellen
|
||||
page.title.add.customer=Neuen Kunden anlegen
|
||||
page.title.edit.appuser=App-Nutzer bearbeiten
|
||||
page.title.forget.password=Passwort zurücksetzen
|
||||
page.title.job.history=Job Historie
|
||||
page.title.admin.pricetable=Preis-Tabelle
|
||||
page.title.invoice.generator=Rechnungsgenerator
|
||||
page.title.job.summary=Zusammenfassung
|
||||
page.title.add.job=Neuen Auftrag anlegen
|
||||
|
||||
# Dashboard
|
||||
@@ -638,7 +635,6 @@ jobs.dialog.complete.text=Möchten Sie den Auftrag {0} manuell abschließen?
|
||||
jobs.dialog.complete.confirm=Abschließen
|
||||
jobs.dialog.delete.title=Auftrag löschen
|
||||
jobs.dialog.delete.text=Möchten Sie den Auftrag {0} wirklich löschen?
|
||||
jobs.notification.completed=Auftrag {0} wurde abgeschlossen
|
||||
jobs.notification.complete.error=Fehler beim Abschließen: {0}
|
||||
jobs.notification.deleted=Auftrag {0} wurde gelöscht
|
||||
jobs.notification.delete.error=Fehler beim Löschen: {0}
|
||||
@@ -721,7 +717,7 @@ appuser.column.appcode=App-Code
|
||||
appuser.column.email=E-Mail
|
||||
|
||||
# Statistics
|
||||
statistics.title=KI-Statistiken
|
||||
statistics.title=Statistiken
|
||||
statistics.subtitle=Stellen Sie Fragen zu Ihren Aufträgen und Kunden
|
||||
statistics.prompt.placeholder=Frage eingeben...
|
||||
statistics.quick.jobcount=Anzahl Aufträge
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,50 +4,50 @@ dialog.confirm=Confirm
|
||||
|
||||
# Navigation and Main Layout
|
||||
nav.jobs=Jobs
|
||||
nav.job.create=Create New Job
|
||||
nav.job.create=Create Job
|
||||
nav.customers=Customers
|
||||
nav.appusers=App Users
|
||||
nav.statistics=Statistics
|
||||
nav.invoices=Invoices
|
||||
nav.messages=Messages
|
||||
nav.profile=My Profile
|
||||
nav.myinvoices=My Invoices
|
||||
nav.myinvoices=Invoices
|
||||
nav.imprint=Imprint
|
||||
nav.management=Management
|
||||
nav.users=Users
|
||||
nav.showprofile=Show Profile
|
||||
nav.settings=Settings
|
||||
nav.logout=Logout
|
||||
nav.logout=Log Out
|
||||
|
||||
# Profile View
|
||||
profile.title=Edit Profile
|
||||
profile.language=Language
|
||||
profile.company=Company
|
||||
profile.companyadd=Company Addition
|
||||
profile.companyadd=Company Suffix
|
||||
profile.firstname=First Name
|
||||
profile.lastname=Last Name
|
||||
profile.phone=Phone Number
|
||||
profile.fax=Fax
|
||||
profile.mobile=Mobile
|
||||
profile.fax=Phone (Fax)
|
||||
profile.mobile=Phone (Mobile)
|
||||
profile.email=Email Address (Login)*
|
||||
profile.street=Street
|
||||
profile.housenr=House No.
|
||||
profile.addressadd=Address Addition
|
||||
profile.zip=Zip Code
|
||||
profile.addressadd=Address Suffix
|
||||
profile.zip=Postal Code
|
||||
profile.city=City
|
||||
profile.diffinvoice=Different Invoice Address
|
||||
profile.basicdata=Basic Data
|
||||
profile.diffinvoice=Different Billing Address
|
||||
profile.basicdata=Master Data
|
||||
profile.map=Map
|
||||
profile.invoicecreation=Invoice Creation
|
||||
profile.settings=Settings
|
||||
profile.settings.digitalprocess=Digital Processing
|
||||
profile.settings.digitalprocess.info=Jobs are processed digitally via the app
|
||||
profile.settings.locateappuser=Locate App User
|
||||
profile.settings.locateappuser.info=Location of app users is regularly transmitted
|
||||
profile.settings.locateappuser=Locate App Users
|
||||
profile.settings.locateappuser.info=App user location is transmitted regularly
|
||||
profile.account=Account
|
||||
profile.security=Security
|
||||
profile.security.twofactor=Two-Factor Authentication
|
||||
profile.security.twofactor.info=An additional code is sent by email when logging in
|
||||
profile.security.twofactor.info=An additional code is sent via email when logging in
|
||||
profile.services=Service Catalog
|
||||
profile.saved=Profile saved
|
||||
profile.save.error=Error saving: {0}
|
||||
@@ -55,14 +55,14 @@ profile.validation.required.fill=Please fill in all required fields correctly
|
||||
|
||||
# Profile Settings
|
||||
settings.digitalprocessing=Digital Processing via App
|
||||
settings.digitalprocessinginfo=Enables digital order processing through the mobile app
|
||||
settings.locationtracking=Track App Users
|
||||
settings.locationtrackinginfo=Allows tracking of app users during order execution
|
||||
settings.twofactor=Two-Factor Authentication
|
||||
settings.twofactorinfo=When enabled, a code will be sent via email for each login
|
||||
settings.digitalprocessinginfo=Enables digital job processing via the mobile app
|
||||
settings.locationtracking=Locate App Users
|
||||
settings.locationtrackinginfo=Allows locating app users during job execution
|
||||
settings.twofactor=2-Factor Authentication
|
||||
settings.twofactorinfo=When enabled, a code is sent via email at each login
|
||||
|
||||
# Profile Billing
|
||||
profile.billing.enabled=Billing via votianLT
|
||||
profile.billing.enabled=Invoicing via votianLT
|
||||
profile.billing.prefix=Invoice Prefix
|
||||
|
||||
# Profile Validation
|
||||
@@ -72,21 +72,21 @@ profile.validation.lastname=Last name is a required field
|
||||
profile.validation.phone=Phone number is a required field
|
||||
profile.validation.street=Street is a required field
|
||||
profile.validation.housenr=House number is a required field
|
||||
profile.validation.zip=Zip code is a required field
|
||||
profile.validation.zip=Postal code is a required field
|
||||
profile.validation.city=City is a required field
|
||||
profile.validation.email.required=Email address is a required field
|
||||
profile.validation.email.invalid=Please enter a valid email address
|
||||
profile.validation.company.required=Company is required
|
||||
profile.validation.street.required=Street is required
|
||||
profile.validation.housenr.required=House number is required
|
||||
profile.validation.zip.required=Zip code is required
|
||||
profile.validation.zip.required=Postal code is required
|
||||
profile.validation.city.required=City is required
|
||||
profile.validation.firstname.required=First name is required
|
||||
profile.validation.lastname.required=Last name is required
|
||||
profile.validation.phone.required=Phone number is required
|
||||
|
||||
# Profile Invoice
|
||||
profile.invoice.masterdata=My Data
|
||||
profile.invoice.masterdata=My Master Data
|
||||
profile.invoice.name=Name
|
||||
profile.invoice.city=City
|
||||
profile.invoice.email=Email
|
||||
@@ -94,7 +94,7 @@ profile.invoice.phone=Phone
|
||||
profile.invoice.placeholder.company=Your Company
|
||||
profile.invoice.placeholder.name=Your Name
|
||||
profile.invoice.placeholder.street=Your Street
|
||||
profile.invoice.placeholder.city=ZIP City
|
||||
profile.invoice.placeholder.city=Postal Code City
|
||||
profile.invoice.placeholder.email=your@email.com
|
||||
profile.invoice.placeholder.phone=Your Phone Number
|
||||
profile.invoice.services.list=List Services
|
||||
@@ -119,7 +119,7 @@ profile.invoice.element.line=Line
|
||||
profile.invoice.element.image=Image
|
||||
profile.invoice.element.invoicenumber=Invoice Number
|
||||
profile.invoice.properties=Properties
|
||||
profile.invoice.properties.info=Click on an element in the canvas to edit its properties
|
||||
profile.invoice.properties.info=Click on an element in the canvas to edit its properties.
|
||||
profile.invoice.type=Type
|
||||
profile.invoice.variable=Variable
|
||||
profile.invoice.xposition=X Position
|
||||
@@ -133,8 +133,8 @@ profile.invoice.image.uploaded=Image uploaded successfully
|
||||
profile.invoice.image.upload.error=Error uploading: {0}
|
||||
profile.invoice.file.rejected=File rejected: {0}
|
||||
profile.invoice.text.from.masterdata=Text comes from your master data
|
||||
profile.invoice.canvas.cleared=Canvas cleared
|
||||
profile.invoice.canvas.read.error=Error: Could not read canvas data
|
||||
profile.invoice.canvas.cleared=Canvas has been cleared
|
||||
profile.invoice.canvas.read.error=Error: Canvas data could not be read
|
||||
profile.invoice.template.saved=Template saved successfully
|
||||
profile.invoice.pdf.error=Error generating PDF: {0}
|
||||
profile.invoice.pdf.preview=Preview
|
||||
@@ -142,7 +142,7 @@ profile.invoice.pdf.preview.error=Error generating preview: {0}
|
||||
|
||||
# Profile Services
|
||||
profile.services.label=Services
|
||||
profile.services.description=Manage your services that you offer to your customers
|
||||
profile.services.description=Manage your services that you offer to your customers here.
|
||||
profile.services.add=Add New Service
|
||||
profile.services.load.error=Error loading services: {0}
|
||||
profile.services.saved=Service saved successfully
|
||||
@@ -152,14 +152,14 @@ profile.services.delete.error=Error deleting service: {0}
|
||||
profile.services.dialog.create=Create New Service
|
||||
profile.services.dialog.edit=Edit Service
|
||||
profile.services.basis=Calculation Basis
|
||||
profile.services.basis.distance=Distance (km)
|
||||
profile.services.basis.distance=Distance Driven
|
||||
profile.services.basis.time=Time
|
||||
profile.services.basis.flatrate=Flat Rate
|
||||
profile.services.vatrate=VAT Rate (%)
|
||||
profile.services.vatrate.percent=VAT Rate (%)
|
||||
profile.services.price.flatrate=Flat Rate Price (€)
|
||||
profile.services.price.distance=Price per Kilometer (€)
|
||||
profile.services.price.time=Price per 15 Minutes (€)
|
||||
profile.services.price.flatrate=Flat Rate Price (\u20ac)
|
||||
profile.services.price.distance=Price per Kilometer (\u20ac)
|
||||
profile.services.price.time=Price per 15 Minutes (\u20ac)
|
||||
profile.services.mandatory=Mandatory
|
||||
profile.services.calculated=Calculated
|
||||
profile.services.validation.name=Name is required
|
||||
@@ -211,15 +211,15 @@ notification.error=Error saving
|
||||
notification.languagechanged=Language changed
|
||||
|
||||
# Login
|
||||
login.title=Login
|
||||
login.title=Log In
|
||||
login.username=Username
|
||||
login.password=Password
|
||||
login.login=Login
|
||||
login.forgotpassword=Forgot password?
|
||||
login.rememberme=Remember me
|
||||
login.login=Log In
|
||||
login.forgotpassword=Forgot Password?
|
||||
login.rememberme=Remember Me
|
||||
login.register=Register
|
||||
login.2fa.helper=6-digit code
|
||||
login.2fa.sent=Code sent via email
|
||||
login.2fa.sent=Code was sent via email
|
||||
login.2fa.no.credentials=No credentials available
|
||||
login.2fa.invalid.code=Invalid code
|
||||
login.2fa.wrong.code=Wrong code
|
||||
@@ -233,7 +233,7 @@ error.validation=Validation error
|
||||
page.title.dashboard=VotianLT - Dashboard
|
||||
page.title.appuser.create=Create New App User
|
||||
page.title.messages=Messages
|
||||
page.title.register=Register with VotianLT
|
||||
page.title.register=Register at VotianLT
|
||||
page.title.customers=Customers
|
||||
page.title.customer.edit=Edit Customer
|
||||
page.title.verwaltung=Management
|
||||
@@ -243,22 +243,22 @@ page.title.profile.edit=Edit Profile
|
||||
page.title.admin.dashboard=Admin Dashboard
|
||||
page.title.invoice.create=Create Invoice
|
||||
page.title.customer.create=Create New Customer
|
||||
page.title.login=Login to VotianLT
|
||||
page.title.login=Log In to VotianLT
|
||||
page.title.jobs=Jobs
|
||||
page.title.appuser.edit=Edit App User
|
||||
page.title.statistics=AI Statistics
|
||||
page.title.statistics=Statistics
|
||||
page.title.password.forget=Reset Password
|
||||
page.title.invoices=Invoices
|
||||
page.title.appusers=App Users
|
||||
page.title.job.history=Job History
|
||||
page.title.message.history=Message History
|
||||
page.title.myinvoices=My Invoices
|
||||
page.title.myinvoices=Invoices
|
||||
page.title.job.create=Create New Job
|
||||
page.title.job.summary=Summary
|
||||
page.title.pricetable=Price Table
|
||||
page.title.invoice.generator=Invoice Generator
|
||||
page.title.welcome=VotianLT - Welcome
|
||||
page.title.password.reset=Reset Password - Enter Email
|
||||
page.title.password.reset=Reset Password \u2013 Enter Email
|
||||
page.title.add.appuser=Create New App User
|
||||
page.title.user.messages=Messages
|
||||
page.title.edit.customer=Edit Customer
|
||||
@@ -268,16 +268,13 @@ page.title.create.invoice=Create Invoice
|
||||
page.title.add.customer=Create New Customer
|
||||
page.title.edit.appuser=Edit App User
|
||||
page.title.forget.password=Reset Password
|
||||
page.title.job.history=Job History
|
||||
page.title.admin.pricetable=Price Table
|
||||
page.title.invoice.generator=Invoice Generator
|
||||
page.title.job.summary=Summary
|
||||
page.title.add.job=Create New Job
|
||||
|
||||
# Dashboard
|
||||
dashboard.welcome=Welcome, {0}!
|
||||
dashboard.footer.copyright=© 2024 VotianLT. All rights reserved.
|
||||
dashboard.description=Here you can manage your jobs, organize customers and use all important features of VotianLT.
|
||||
dashboard.footer.copyright=\u00a9 2024 VotianLT. All rights reserved.
|
||||
dashboard.description=Here you can manage your jobs, organize customers, and use all important features of VotianLT.
|
||||
dashboard.system.title=System Overview
|
||||
dashboard.system.intro=Manage your business processes efficiently with the following features
|
||||
dashboard.feature.setup.title=Setup
|
||||
@@ -287,7 +284,7 @@ dashboard.feature.customers.desc=Manage your customer relationships and contacts
|
||||
dashboard.feature.jobs.title=Jobs
|
||||
dashboard.feature.jobs.desc=Create and manage jobs efficiently
|
||||
dashboard.app.title=Mobile App
|
||||
dashboard.app.description=Use the VotianLT app on the go and stay connected
|
||||
dashboard.app.description=Use the VotianLT App on the go and stay connected at all times
|
||||
|
||||
# Add App User
|
||||
addappuser.title=Create New App User
|
||||
@@ -299,7 +296,7 @@ addappuser.button.submit=Create App User
|
||||
addappuser.validation.designation=Designation is required
|
||||
addappuser.validation.phone=Phone number is required
|
||||
addappuser.validation.password.required=Password is required
|
||||
addappuser.validation.password.min=Password must be at least 6 characters
|
||||
addappuser.validation.password.min=Password must have at least 6 characters
|
||||
addappuser.validation.password.confirm=Password confirmation is required
|
||||
addappuser.validation.password.mismatch=Passwords do not match
|
||||
addappuser.validation.email.required=Email is required
|
||||
@@ -323,13 +320,13 @@ editappuser.notification.check=Please check your input
|
||||
editappuser.notification.password.confirm=Please confirm the new password
|
||||
editappuser.notification.password.enter=Please enter a new password
|
||||
editappuser.notification.deleted=App user deleted successfully
|
||||
editappuser.dialog.delete.text=Do you really want to delete this app user?
|
||||
editappuser.dialog.delete.text=Are you sure you want to delete this app user?
|
||||
editappuser.dialog.delete.confirm=Delete
|
||||
|
||||
# Customers
|
||||
customers.title=Customers
|
||||
customers.button.add=Add New Customer
|
||||
customers.hint.click=Click on a customer to view details
|
||||
customers.hint.click=Click on a customer to see details
|
||||
customers.column.company=Company
|
||||
customers.column.name=Name
|
||||
customers.column.email=Email
|
||||
@@ -344,7 +341,7 @@ editcustomer.notification.invalid.id=Invalid customer ID
|
||||
editcustomer.notification.saved=Customer saved successfully
|
||||
editcustomer.notification.check=Please check your input
|
||||
editcustomer.notification.deleted=Customer deleted successfully
|
||||
editcustomer.dialog.delete.text=Do you really want to delete this customer?
|
||||
editcustomer.dialog.delete.text=Are you sure you want to delete this customer?
|
||||
editcustomer.dialog.delete.confirm=Delete
|
||||
|
||||
# Add Customer
|
||||
@@ -362,13 +359,13 @@ addcompany.button.submit=Create Company
|
||||
|
||||
# Verwaltung
|
||||
verwaltung.title=Management
|
||||
verwaltung.description=Manage your companies, customers and system settings here
|
||||
verwaltung.description=Manage your companies, customers, and system settings here
|
||||
|
||||
# User Messages
|
||||
usermessages.title.with=Messages with {0}
|
||||
usermessages.general.title=General Conversations
|
||||
usermessages.general.conversation=General Conversation
|
||||
usermessages.job.title=Job-related Messages
|
||||
usermessages.job.title=Job-Related Messages
|
||||
usermessages.job.conversation=Job {0}
|
||||
usermessages.no.job.messages=No job-related messages
|
||||
usermessages.preview.empty=No preview available
|
||||
@@ -394,7 +391,7 @@ admindashboard.stat.inprogress=In Progress
|
||||
admindashboard.stat.completed=Completed
|
||||
admindashboard.stat.cargo=Cargo Items
|
||||
admindashboard.stat.status.info=Status
|
||||
admindashboard.stat.status.unavailable=Not Available
|
||||
admindashboard.stat.status.unavailable=Unavailable
|
||||
admindashboard.stat.totaltasks=Total Tasks
|
||||
admindashboard.stat.completedtasks=Completed
|
||||
admindashboard.stat.pendingtasks=Pending
|
||||
@@ -415,7 +412,7 @@ admindashboard.stat.memory=Memory
|
||||
# Messages
|
||||
messages.title=Messages
|
||||
messages.column.status=Status
|
||||
messages.column.client=Client
|
||||
messages.column.client=Customer
|
||||
messages.column.email=Email
|
||||
messages.column.total=Total
|
||||
messages.column.unread=Unread
|
||||
@@ -424,51 +421,51 @@ messages.column.preview=Preview
|
||||
messages.notification.error=Error loading messages
|
||||
messages.preview.image=Image
|
||||
messages.preview.empty=No preview
|
||||
messages.sender.unknown=Unknown sender
|
||||
messages.sender.unknown=Unknown Sender
|
||||
|
||||
# Add Job
|
||||
addjob.title=Create New Job
|
||||
addjob.customer.label=Customer
|
||||
addjob.customer.placeholder=Select customer
|
||||
addjob.customer.placeholder=Select Customer
|
||||
addjob.customer.unnamed=Unnamed Customer
|
||||
addjob.button.clearfields=Clear Fields
|
||||
addjob.button.submit=Create Job
|
||||
addjob.address.salutation=Salutation
|
||||
addjob.address.salutation.placeholder=Select salutation
|
||||
addjob.address.salutation.placeholder=Select Salutation
|
||||
addjob.salutation.mr=Mr
|
||||
addjob.salutation.ms=Ms
|
||||
addjob.salutation.other=Other
|
||||
addjob.address.company.placeholder=Enter company
|
||||
addjob.address.street.placeholder=Enter street
|
||||
addjob.address.housenumber=House Number
|
||||
addjob.address.addition.placeholder=Address addition
|
||||
addjob.address.addition.placeholder=Address suffix
|
||||
addjob.address.city=City
|
||||
addjob.address.city.placeholder.pickup=City (Pickup)
|
||||
addjob.address.city.placeholder.delivery=City (Delivery)
|
||||
addjob.address.delivery.street.placeholder=Street (Delivery)
|
||||
addjob.address.delivery.addition.placeholder=Address addition (Delivery)
|
||||
addjob.address.delivery.addition.placeholder=Address suffix (Delivery)
|
||||
addjob.address.save=Save Address
|
||||
addjob.section.pickup=Pickup
|
||||
addjob.section.delivery=Delivery
|
||||
addjob.stations.apply=Apply Stations
|
||||
addjob.station.delivery=Delivery Station {0}
|
||||
addjob.station.add=Add delivery station
|
||||
addjob.station.add=Add Delivery Station
|
||||
addjob.station.remove.confirm=Really remove delivery station {0}?
|
||||
addjob.station.max.reached=Maximum of 25 delivery stations reached
|
||||
addjob.station.max.reached=Maximum number of 25 delivery stations reached
|
||||
addjob.station.unused=Not used
|
||||
addjob.appointment.delivery.info=Delivery dates are set directly in the delivery stations.
|
||||
addjob.tab.addresses=Customer & Addresses
|
||||
addjob.tab.addresses=Client & Addresses
|
||||
addjob.tab.appointments=Appointments & Processing
|
||||
addjob.tab.cargo=Cargo
|
||||
addjob.tab.tasks=Tasks
|
||||
addjob.tab.price=Price & Submit
|
||||
addjob.tab.price=Price & Completion
|
||||
addjob.appointment.date=Date
|
||||
addjob.appointment.time=Time
|
||||
addjob.appointment.pickup=Pickup Appointment
|
||||
addjob.appointment.delivery=Delivery Appointment
|
||||
addjob.appointment.pickup=Pickup Date
|
||||
addjob.appointment.delivery=Delivery Date
|
||||
addjob.settings.digitalprocess=Digital Processing via App
|
||||
addjob.appuser.label=App User
|
||||
addjob.appuser.placeholder=Select app user
|
||||
addjob.appuser.placeholder=Select App User
|
||||
addjob.cargo.description=Description
|
||||
addjob.cargo.description.placeholder=Enter description
|
||||
addjob.cargo.quantity=Quantity
|
||||
@@ -478,14 +475,14 @@ addjob.cargo.width=Width
|
||||
addjob.cargo.height=Height
|
||||
addjob.cargo.europalette=Euro Pallet
|
||||
addjob.cargo.disposablepalette=Disposable Pallet
|
||||
addjob.cargo.dusseldorfpalette=Düsseldorf Pallet
|
||||
addjob.cargo.dusseldorfpalette=Dusseldorf Pallet
|
||||
addjob.cargo.gridboxpalette=Grid Box Pallet
|
||||
addjob.cargo.gridcart=Grid Cart
|
||||
addjob.cargo.parcel=Parcel
|
||||
addjob.cargo.add=Add Cargo
|
||||
addjob.tasks.title=Tasks
|
||||
addjob.tasks.template.placeholder=Select template
|
||||
addjob.tasks.template.save.tooltip=Save as template
|
||||
addjob.tasks.template.placeholder=Select Template
|
||||
addjob.tasks.template.save.tooltip=Save as Template
|
||||
addjob.tasks.template.save.title=Save Template
|
||||
addjob.tasks.template.name=Template Name
|
||||
addjob.tasks.template.name.placeholder=Enter name
|
||||
@@ -495,14 +492,14 @@ addjob.tasks.template.save.error=Error saving: {0}
|
||||
addjob.tasks.template.dialog.error=Error opening dialog: {0}
|
||||
addjob.tasks.template.no.tasks=No tasks to save
|
||||
addjob.tasks.template.load.title=Load Template
|
||||
addjob.tasks.template.load.text=Do you want to load template "{0}"? This will replace all current tasks.
|
||||
addjob.tasks.template.load.text=Do you want to load the template "{0}"? This action will replace all current tasks.
|
||||
addjob.tasks.template.load.confirm=Load
|
||||
addjob.tasks.template.loaded=Template "{0}" loaded
|
||||
addjob.tasks.template.load.error=Error loading: {0}
|
||||
addjob.tasks.template.load.templates.error=Error loading templates: {0}
|
||||
addjob.tasks.add=Add Task
|
||||
addjob.tasks.tasktype=Task Type
|
||||
addjob.tasks.tasktype.placeholder=Select type
|
||||
addjob.tasks.tasktype.placeholder=Select Type
|
||||
addjob.tasks.description=Description
|
||||
addjob.tasks.description.placeholder=Enter description
|
||||
addjob.tasks.buttontext=Button Text
|
||||
@@ -524,14 +521,14 @@ addjob.tasks.optional=Task is optional
|
||||
addjob.services.title=Services
|
||||
addjob.services.add=Add Service
|
||||
addjob.services.calculation=Calculation
|
||||
addjob.services.basis.distance=Distance (km)
|
||||
addjob.services.basis.distance=Distance Driven
|
||||
addjob.services.basis.time=Time
|
||||
addjob.services.basis.flatrate=Flat Rate
|
||||
addjob.services.vat=VAT
|
||||
addjob.services.route.missing=Route missing
|
||||
addjob.services.dialog.title=Select Service
|
||||
addjob.services.dialog.placeholder=Select service
|
||||
addjob.services.dialog.station.placeholder=Select delivery station
|
||||
addjob.services.dialog.placeholder=Select Service
|
||||
addjob.services.dialog.station.placeholder=Select Delivery Station
|
||||
addjob.services.dialog.add=Add
|
||||
addjob.services.deliverystation=Delivery Station
|
||||
addjob.summary.title=Summary
|
||||
@@ -543,34 +540,34 @@ addjob.route.distance=Distance
|
||||
addjob.route.distance.km=Distance (km)
|
||||
addjob.route.distance.placeholder=e.g. 150.5
|
||||
addjob.route.duration=Duration
|
||||
addjob.route.duration.min=Duration (Min.)
|
||||
addjob.route.duration.min=Duration (min.)
|
||||
addjob.route.duration.placeholder=e.g. 120
|
||||
addjob.route.manual.title=Manual Route Entry
|
||||
addjob.route.manual.hint=Enter distance and duration manually if no route was calculated
|
||||
addjob.notification.success=Job {0} created successfully
|
||||
addjob.notification.cleared=All fields cleared
|
||||
addjob.notification.cleared=All fields have been cleared
|
||||
addjob.notification.draft.restored=Draft restored
|
||||
addjob.validation.required.fields=Please fill in all required fields
|
||||
addjob.validation.appuser.required=Please select an app user
|
||||
addjob.validation.cargo.required=Please enter at least one cargo item
|
||||
addjob.validation.cargo.required=Please specify at least one cargo item
|
||||
addjob.validation.pickupdate.future=Pickup date must be today or in the future
|
||||
addjob.validation.deliverydate.future=Delivery date must be today or in the future
|
||||
addjob.validation.dialog.title=Address Validation
|
||||
addjob.validation.dialog.loading=Validating addresses...
|
||||
addjob.validation.dialog.back=Back
|
||||
addjob.validation.dialog.continue=Continue
|
||||
addjob.validation.dialog.continue.anyway=Continue anyway
|
||||
addjob.validation.dialog.continue.anyway=Continue Anyway
|
||||
addjob.validation.pickup.address=Pickup Address
|
||||
addjob.validation.delivery.address=Delivery Address
|
||||
addjob.validation.route=Route
|
||||
addjob.validation.address.not.found.title=Address not found
|
||||
addjob.validation.address.not.found.message=The entered address could not be clearly found on Google. Do you still want to save?
|
||||
addjob.validation.address.save.anyway=Save anyway
|
||||
addjob.validation.address.correct=Correct address
|
||||
addjob.validation.address.not.found.title=Address Not Found
|
||||
addjob.validation.address.not.found.message=The entered address could not be clearly found on Google. Do you want to save anyway?
|
||||
addjob.validation.address.save.anyway=Save Anyway
|
||||
addjob.validation.address.correct=Correct Address
|
||||
|
||||
# Job Summary
|
||||
jobsummary.title=Summary
|
||||
jobsummary.error.noid=No job ID provided
|
||||
jobsummary.error.noid=No job ID specified
|
||||
jobsummary.error.invalidid=Invalid job ID format: {0}
|
||||
jobsummary.error.notfound=Job with ID {0} not found
|
||||
jobsummary.button.sendmessage=Send Message
|
||||
@@ -580,9 +577,9 @@ jobsummary.dialog.complete.title=Complete Job
|
||||
jobsummary.dialog.complete.text=Do you want to manually complete job {0}?
|
||||
jobsummary.dialog.complete.cancel=Cancel
|
||||
jobsummary.dialog.complete.confirm=Complete
|
||||
jobsummary.notification.completed=Job {0} completed
|
||||
jobsummary.notification.complete.error=Error completing job: {0}
|
||||
jobsummary.notification.noappuser=No app user assigned to this job
|
||||
jobsummary.notification.completed=Job {0} has been completed
|
||||
jobsummary.notification.complete.error=Error completing: {0}
|
||||
jobsummary.notification.noappuser=No app user is assigned to this job
|
||||
jobsummary.section.pickup=Pickup
|
||||
jobsummary.section.delivery=Delivery
|
||||
jobsummary.station.phone=Phone
|
||||
@@ -590,17 +587,17 @@ jobsummary.section.tasks=Tasks to Confirm
|
||||
jobsummary.section.cargo=Cargo to Transport
|
||||
jobsummary.section.info=Additional Information
|
||||
jobsummary.tasks.none=No tasks
|
||||
jobsummary.cargo.none=No cargo information
|
||||
jobsummary.cargo.none=No cargo details
|
||||
jobsummary.info.netto=Net
|
||||
jobsummary.info.ust=VAT
|
||||
jobsummary.info.gesamt=Total
|
||||
jobsummary.info.bemerkung=Remark
|
||||
jobsummary.info.digital=Digital Processing via App: enabled
|
||||
jobsummary.info.digital=Digital processing via app: enabled
|
||||
jobsummary.info.appuser=App User
|
||||
jobsummary.task.status.abgeschlossen=Completed
|
||||
jobsummary.task.status.offen=Open
|
||||
jobsummary.task.typ=Type
|
||||
jobsummary.task.completedAt=Completed at
|
||||
jobsummary.task.completedAt=Completed on
|
||||
jobsummary.task.completedBy=Completed by
|
||||
jobsummary.task.todo.items=To-Do Items
|
||||
jobsummary.task.photo.info=Photos
|
||||
@@ -621,7 +618,7 @@ jobs.filter.apply=Apply Filter
|
||||
jobs.status.all=All
|
||||
jobs.status.open=Open
|
||||
jobs.status.done=Done
|
||||
jobs.notification.completed=Job {0} completed
|
||||
jobs.notification.completed=Job {0} has been completed
|
||||
jobs.column.status=Status
|
||||
jobs.column.customer=Customer
|
||||
jobs.column.jobnumber=Job Number
|
||||
@@ -637,11 +634,10 @@ jobs.dialog.complete.title=Complete Job
|
||||
jobs.dialog.complete.text=Do you want to manually complete job {0}?
|
||||
jobs.dialog.complete.confirm=Complete
|
||||
jobs.dialog.delete.title=Delete Job
|
||||
jobs.dialog.delete.text=Do you really want to delete job {0}?
|
||||
jobs.notification.completed=Job {0} completed
|
||||
jobs.notification.complete.error=Error completing job: {0}
|
||||
jobs.notification.deleted=Job {0} deleted
|
||||
jobs.notification.delete.error=Error deleting job: {0}
|
||||
jobs.dialog.delete.text=Are you sure you want to delete job {0}?
|
||||
jobs.notification.complete.error=Error completing: {0}
|
||||
jobs.notification.deleted=Job {0} has been deleted
|
||||
jobs.notification.delete.error=Error deleting: {0}
|
||||
|
||||
# Create Invoice
|
||||
createinvoice.title=Create Invoice \u2013 Job {0}
|
||||
@@ -657,12 +653,12 @@ createinvoice.field.customer=Customer
|
||||
createinvoice.field.status=Status
|
||||
createinvoice.field.price=Price
|
||||
createinvoice.route.distance=Distance
|
||||
createinvoice.route.duration=Duration
|
||||
createinvoice.route.duration=Travel Time
|
||||
createinvoice.column.service=Service
|
||||
createinvoice.column.basis=Calculation Basis
|
||||
createinvoice.summary.net=Net Total
|
||||
createinvoice.summary.vat=VAT ({0}%)
|
||||
createinvoice.summary.total=Total Amount
|
||||
createinvoice.summary.total=Grand Total
|
||||
createinvoice.notification.noservices=Please select at least one service
|
||||
createinvoice.notification.nouser=User not found
|
||||
createinvoice.notification.notemplate=No invoice template found
|
||||
@@ -672,7 +668,7 @@ createinvoice.preview.title=Invoice Preview
|
||||
createinvoice.preview.number=PREVIEW
|
||||
createinvoice.button.save=Save
|
||||
createinvoice.confirm.save.title=Save Invoice
|
||||
createinvoice.confirm.save.message=This invoice will be permanently saved and can no longer be modified. Continue?
|
||||
createinvoice.confirm.save.message=This invoice will be permanently saved and cannot be modified afterwards. Continue?
|
||||
createinvoice.confirm.save.confirm=Yes, save
|
||||
|
||||
# Invoices
|
||||
@@ -686,8 +682,8 @@ invoices.empty=No invoices have been created yet.
|
||||
invoices.notification.pdf.missing=No PDF is stored for this invoice.
|
||||
|
||||
# My Invoices
|
||||
myinvoices.title=My Invoices
|
||||
myinvoices.hint.noopen=You have no open invoices. All invoices are settled.
|
||||
myinvoices.title=Invoices
|
||||
myinvoices.hint.noopen=You have no open invoices. All invoices have been paid.
|
||||
myinvoices.bank.institute=Bank
|
||||
myinvoices.bank.beneficiary=Beneficiary
|
||||
myinvoices.bank.iban=IBAN
|
||||
@@ -695,10 +691,10 @@ myinvoices.recipient.name=Customer
|
||||
myinvoices.recipient.department=
|
||||
myinvoices.item.description=Item: {0}
|
||||
myinvoices.card.open=Open Invoices
|
||||
myinvoices.card.bank=Bank Account
|
||||
myinvoices.bank.reference=Reference
|
||||
myinvoices.card.bank=Bank Details
|
||||
myinvoices.bank.reference=Payment Reference
|
||||
myinvoices.section.title=All Invoices
|
||||
myinvoices.filter.pagesize=Entries per page
|
||||
myinvoices.filter.pagesize=Entries per Page
|
||||
myinvoices.filter.search=Search
|
||||
myinvoices.filter.search.placeholder=Search invoice number...
|
||||
myinvoices.column.status=Status
|
||||
@@ -721,7 +717,7 @@ appuser.column.appcode=App Code
|
||||
appuser.column.email=Email
|
||||
|
||||
# Statistics
|
||||
statistics.title=AI Statistics
|
||||
statistics.title=Statistics
|
||||
statistics.subtitle=Ask questions about your jobs and customers
|
||||
statistics.prompt.placeholder=Enter question...
|
||||
statistics.quick.jobcount=Number of Jobs
|
||||
@@ -729,9 +725,9 @@ statistics.quick.jobcount.prompt=How many jobs do I currently have?
|
||||
statistics.quick.revenue=Revenue
|
||||
statistics.quick.revenue.prompt=What is my revenue this month?
|
||||
statistics.quick.trend=Trends
|
||||
statistics.quick.trend.prompt=Show me trends in the last 3 months
|
||||
statistics.quick.trend.prompt=Show me trends from the last 3 months as a bar chart
|
||||
statistics.ai.label=AI Response
|
||||
statistics.data.fetched=Data fetched
|
||||
statistics.data.fetched=Data has been retrieved
|
||||
statistics.loading=Calculating...
|
||||
|
||||
# Job Status
|
||||
@@ -754,12 +750,12 @@ passwordreset.button.submit=Save Password
|
||||
passwordreset.button.cancel=Cancel
|
||||
passwordreset.button.send=Send Email
|
||||
passwordreset.notification.enterpassword=Please enter a new password
|
||||
passwordreset.notification.mismatch=Passwords do not match
|
||||
passwordreset.notification.success=Password changed successfully
|
||||
passwordreset.notification.mismatch=The passwords do not match
|
||||
passwordreset.notification.success=Password has been changed successfully
|
||||
passwordreset.notification.invalidtoken=Token invalid or expired
|
||||
passwordreset.notification.entermail=Please enter email
|
||||
passwordreset.notification.sent=If the email exists, a link has been sent
|
||||
passwordreset.notification.wait=Please wait {0} seconds before sending the code again
|
||||
passwordreset.notification.wait=Please wait {0} seconds before resending the code
|
||||
|
||||
# Email
|
||||
email.2fa.subject=Your VotianLT Verification Code
|
||||
@@ -779,31 +775,31 @@ register.phone=Phone Number
|
||||
register.company=Company
|
||||
register.street=Street
|
||||
register.housenr=House No.
|
||||
register.zip=Zip Code
|
||||
register.zip=Postal Code
|
||||
register.city=City
|
||||
register.code.label=Verification Code (6 digits)
|
||||
register.code.placeholder=e.g. 123456
|
||||
register.button.submit=Register
|
||||
register.button.verify=Verify Code and Register
|
||||
register.button.resend=Resend Code
|
||||
register.button.back=Back to Start Page
|
||||
register.button.back=Back to Home
|
||||
register.notification.email.required=Please enter an email address
|
||||
register.notification.email.invalid=Please enter a valid email address
|
||||
register.notification.email.duplicate=A user with this email address already exists
|
||||
register.notification.password.required=Please enter a password
|
||||
register.notification.password.min=Password must be at least 6 characters long
|
||||
register.notification.password.mismatch=Passwords do not match
|
||||
register.notification.password.min=The password must be at least 6 characters long
|
||||
register.notification.password.mismatch=The passwords do not match
|
||||
register.notification.firstname.required=Please enter your first name
|
||||
register.notification.lastname.required=Please enter your last name
|
||||
register.notification.phone.required=Please enter your phone number
|
||||
register.notification.company.required=Please enter the company name
|
||||
register.notification.street.required=Please enter the street
|
||||
register.notification.housenr.required=Please enter the house number
|
||||
register.notification.zip.required=Please enter the zip code
|
||||
register.notification.zip.required=Please enter the postal code
|
||||
register.notification.city.required=Please enter the city
|
||||
register.notification.code.sent=A verification code has been sent to {0}
|
||||
register.notification.code.emailerror=Error sending email: {0}
|
||||
register.notification.code.expired=The code has expired. Please request a new code.
|
||||
register.notification.code.expired=The code has expired. Please send a new code.
|
||||
register.notification.code.invalid=The entered code is invalid
|
||||
register.notification.code.startfirst=Please start the registration first
|
||||
register.notification.code.required=Please enter the 6-digit code
|
||||
@@ -812,29 +808,29 @@ register.notification.failed=Registration failed: {0}
|
||||
|
||||
# Start Page
|
||||
start.title=VotianLT - Your Digital Transport Partner
|
||||
start.button.login=Login
|
||||
start.button.login=Log In
|
||||
start.button.register=Register
|
||||
start.button.createorder=Create Order
|
||||
start.button.createorder=Create Job
|
||||
start.button.notifications=Notifications
|
||||
start.button.nonotifications=No new notifications
|
||||
start.hero.description=For solo self-employed and small business owners in the transport industry - fully digital and all-in-one. Focus on your business, we take care of the paperwork.
|
||||
start.system.title=The System
|
||||
start.system.intro=For solo self-employed and small business owners in the transport industry, it is crucial to focus primarily on their core business: winning customers and delivering goods from A to B.
|
||||
start.feature.setup.title=Setup Assistant
|
||||
start.feature.setup.desc=Use the setup assistant to complete your user profile.
|
||||
start.feature.customers.title=Customer and Job Management
|
||||
start.feature.customers.desc=With customer and job management, you always have all contact details and job details in view.
|
||||
start.system.intro=For solo self-employed and small business owners in the transport industry, it is crucial that they can primarily focus on their actual business: winning customers and delivering goods from A to B.
|
||||
start.feature.setup.title=Setup Wizard
|
||||
start.feature.setup.desc=With the setup wizard, you can complete your user profile.
|
||||
start.feature.customers.title=Customer & Job Management
|
||||
start.feature.customers.desc=With customer and job management, you always have all contact details and job details at a glance.
|
||||
start.feature.jobs.title=Job Creation
|
||||
start.feature.jobs.desc=Create jobs in the system with just a few clicks and determine which employee should process which transport job.
|
||||
start.feature.jobs.desc=Create jobs in the system with just a few clicks and assign which employee should handle which transport job.
|
||||
start.app.title=The App
|
||||
start.app.description=Every job can optionally be processed via the votianLT app - completely without "paperwork". All relevant job information goes directly to the driver's smartphone.
|
||||
start.app.description=Every job can optionally be processed via the votianLT app \u2013 completely paperless. All relevant job information is delivered directly to the driver's smartphone.
|
||||
start.imprint.title=Imprint
|
||||
start.imprint.company=Assecutor Data Service GmbH
|
||||
start.imprint.address=Ottensener Str. 8, 22525 Hamburg
|
||||
start.imprint.phone=Phone: +49 40 18 123 771 0
|
||||
start.imprint.email=Email: ahoi@assecutor.de
|
||||
start.cta.text=Register today and use the free trial month to test the system thoroughly.
|
||||
start.slogan=Run your business smart … with votianLT!
|
||||
start.cta.text=Register today and use the free trial month to put the system through its paces.
|
||||
start.slogan=Run your business smart ... with votianLT!
|
||||
start.version=Version
|
||||
|
||||
# Login View
|
||||
@@ -847,14 +843,14 @@ login.version=Version
|
||||
messagedetails.button.send=Send
|
||||
messagedetails.placeholder=Enter message...
|
||||
messagedetails.noimage=(no image content)
|
||||
messagedetails.imageerror=(image could not be loaded)
|
||||
messagedetails.imageerror=(Image could not be loaded)
|
||||
|
||||
# Invoice Generator
|
||||
invoicegenerator.properties.title=Properties
|
||||
invoicegenerator.properties.type=Type
|
||||
invoicegenerator.fontsize.label=Font Size
|
||||
invoicegenerator.color.label=Text Color
|
||||
invoicegenerator.color.dialog.title=Choose Text Color
|
||||
invoicegenerator.color.label=Font Color
|
||||
invoicegenerator.color.dialog.title=Choose Font Color
|
||||
invoicegenerator.color.dialog.hex=Hex Color Value
|
||||
invoicegenerator.button.cancel=Cancel
|
||||
invoicegenerator.button.apply=Apply
|
||||
@@ -864,10 +860,11 @@ invoicegenerator.upload.drop=Drag image here or click
|
||||
invoicegenerator.upload.success=Image uploaded successfully
|
||||
invoicegenerator.upload.error=Error uploading: {0}
|
||||
invoicegenerator.file.rejected=File rejected: {0}
|
||||
invoicegenerator.properties.select.info=Click on an element in the canvas to edit its properties
|
||||
invoicegenerator.properties.select.info=Click on an element in the canvas to edit its properties.
|
||||
invoicegenerator.template.vline=Vertical Line
|
||||
|
||||
# CSV Export
|
||||
csv.header.customer=Customer
|
||||
csv.header.customer=Client
|
||||
csv.header.jobnumber=Job Number
|
||||
csv.header.jobdate=Job Date
|
||||
csv.header.destination=Destination
|
||||
@@ -876,7 +873,7 @@ csv.filename=jobs.csv
|
||||
# DatePicker I18n
|
||||
datepicker.month.januar=January
|
||||
datepicker.month.februar=February
|
||||
datepicker.month.märz=March
|
||||
datepicker.month.m\u00e4rz=March
|
||||
datepicker.month.april=April
|
||||
datepicker.month.mai=May
|
||||
datepicker.month.juni=June
|
||||
@@ -893,13 +890,13 @@ datepicker.weekday.mittwoch=Wednesday
|
||||
datepicker.weekday.donnerstag=Thursday
|
||||
datepicker.weekday.freitag=Friday
|
||||
datepicker.weekday.samstag=Saturday
|
||||
datepicker.weekdayshort.so=Su
|
||||
datepicker.weekdayshort.mo=Mo
|
||||
datepicker.weekdayshort.di=Tu
|
||||
datepicker.weekdayshort.mi=We
|
||||
datepicker.weekdayshort.do=Th
|
||||
datepicker.weekdayshort.fr=Fr
|
||||
datepicker.weekdayshort.sa=Sa
|
||||
datepicker.weekdayshort.so=Sun
|
||||
datepicker.weekdayshort.mo=Mon
|
||||
datepicker.weekdayshort.di=Tue
|
||||
datepicker.weekdayshort.mi=Wed
|
||||
datepicker.weekdayshort.do=Thu
|
||||
datepicker.weekdayshort.fr=Fri
|
||||
datepicker.weekdayshort.sa=Sat
|
||||
|
||||
# Job History
|
||||
jobhistory.status.pickupscheduled=Pickup Scheduled
|
||||
@@ -908,11 +905,11 @@ jobhistory.status.intransit=In Transit
|
||||
jobhistory.status.delivered=Delivered
|
||||
jobhistory.image.alt=Enlarged Photo
|
||||
jobhistory.title=Job History
|
||||
jobhistory.header=Job history for {0}
|
||||
jobhistory.header=Job History for {0}
|
||||
jobhistory.info.customer=Customer: {0}
|
||||
jobhistory.info.createdat=Created at: {0}
|
||||
jobhistory.info.createdat=Created on: {0}
|
||||
jobhistory.info.status=Status: {0}
|
||||
jobhistory.count={0} history entries
|
||||
jobhistory.count={0} entries in history
|
||||
jobhistory.changedby=Changed by: {0}
|
||||
|
||||
# Version
|
||||
@@ -927,7 +924,7 @@ management.companies=Companies
|
||||
# User Menu
|
||||
usermenu.profile=Show Profile
|
||||
usermenu.settings=Settings
|
||||
usermenu.logout=Logout
|
||||
usermenu.logout=Log Out
|
||||
|
||||
# CTA Button
|
||||
cta.freetest=Try for free now
|
||||
@@ -937,14 +934,14 @@ misc.toggle.hide=Hide
|
||||
misc.toggle.show=Show
|
||||
misc.nodata=No data available
|
||||
misc.loading=Loading data...
|
||||
misc.error=Error occurred
|
||||
misc.error=An error occurred
|
||||
misc.retry=Retry
|
||||
|
||||
# Admin Price Table
|
||||
adminpricetable.title=Price Table
|
||||
adminpricetable.field.monthly=Monthly Base Package
|
||||
adminpricetable.field.applicense=App Usage License
|
||||
adminpricetable.field.revenue=Revenue Participation
|
||||
adminpricetable.field.revenue=Revenue Share
|
||||
adminpricetable.notification.saved=Price table has been saved
|
||||
adminpricetable.notification.save.error=Error saving: {0}
|
||||
adminpricetable.notification.load.error=Error loading: {0}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user