commit e7c39e429baffc28b1ead12fd6978661b548c369
Author: Tamino Steinert <tamino.steinert@tamino.st>
Date:   Thu Feb 1 16:38:31 2024 +0100

    locales

diff --git a/SL/Controller/Part.pm b/SL/Controller/Part.pm
index c578600c8..bbc94d477 100644
--- a/SL/Controller/Part.pm
+++ b/SL/Controller/Part.pm
@@ -1882,7 +1882,11 @@ sub _check_variant_property_values_not_taken {
   }
 
   if (@double_lists) {
-    die t8("There is already a variant with the property values: #1.", join("; ", @double_lists));
+    die t8(
+      "There is already a variant of '#1' with the property values: #2",
+      $parent_variant->displayable_name,
+      join("; ", @double_lists)
+    );
   }
 }
 
diff --git a/SL/Controller/PartsGroup.pm b/SL/Controller/PartsGroup.pm
index 56163bfa1..a26873b94 100644
--- a/SL/Controller/PartsGroup.pm
+++ b/SL/Controller/PartsGroup.pm
@@ -203,7 +203,7 @@ sub action_update_partsgroup_for_parts{
       $self->js->flash('info', t8("Moved #1 parts.", $parts_updated_count));
     }
   } else {
-    $self->js->flash('error', t8("No parts selected"));
+    $self->js->flash('error', t8("No parts selected."));
   }
 
   $self->_render_parts_table_body; # needs $::form->{current_partsgroup_id}
diff --git a/SL/DB/Part.pm b/SL/DB/Part.pm
index 9812074b2..55a09c4fc 100644
--- a/SL/DB/Part.pm
+++ b/SL/DB/Part.pm
@@ -24,7 +24,7 @@ use SL::DB::Helper::DisplayableNamePreferences (
   options => [
     {name => 'partnumber',     title => t8('Part Number')},
     {name => 'description',    title => t8('Description')},
-    {name => 'variant_values', title => t8('Varaint Values')},
+    {name => 'variant_values', title => t8('Variant Property Values')},
     {name => 'notes',          title => t8('Notes')},
     {name => 'ean',            title => t8('EAN')},
   ],
@@ -163,8 +163,11 @@ sub _before_check_variant_property_values {
       next if $variant->id == $self->id;
       my @other_property_value_ids = sort map {$_->id} $variant->variant_property_values;
       if ("@other_property_value_ids" eq "@property_value_ids") {
-        die t8("There is already a variant of '#1' with the property values: ", $parent_variant->displayable_name),
-          join(' ,', map {$_->displayable_name} $self->variant_property_values);
+        die t8(
+          "There is already a variant of '#1' with the property values: #2",
+          $parent_variant->displayable_name,
+          join(', ', map {$_->displayable_name} $self->variant_property_values)
+        );
       }
     }
   }
diff --git a/locale/de/all b/locale/de/all
index 6cb33961b..af7f3e0fa 100644
--- a/locale/de/all
+++ b/locale/de/all
@@ -118,6 +118,7 @@ $self->{texts} = {
   'ATTENTION! If you enabled this feature you can not simply turn it off again without taking care that best_before fields are emptied in the database.' => 'ACHTUNG! Wenn Sie diese Einstellung aktivieren, dann können Sie sie später nicht ohne Weiteres deaktivieren, ohne dafür zu sorgen, dass die Felder der Mindeshaltbarkeitsdaten in der Datenbank leer gemacht werden.',
   'ATTENTION! You can not simply change it from periodic to perpetual once you started posting.' => 'ACHTUNG! Es kann nicht ohne Weiteres im laufenden Betrieb von der Aufwandsmethode zur Bestandsmethode gewechselt werden.',
   'AUTOMATICALLY MATCH BINS'    => 'LAGERPLÄTZE AUTOMATISCH ZUWEISEN',
+  'Abbreviation'                => 'Abkürzung',
   'Abbreviation Legend'         => 'Beschreibung der Typ-Abkürzungen (1 Zeichen Typ, 1-2 Zeichen Klassifizierung)',
   'Abort'                       => 'Abbrechen',
   'Abrechnungsnummer'           => 'Abrechnungsnummer',
@@ -205,6 +206,9 @@ $self->{texts} = {
   'Add Invoice for Advance Payment' => 'Anzahlungsrechnung erfassen',
   'Add Letter'                  => 'Brief hinzufügen',
   'Add Parent Variant'          => 'Stammartikel erfassen',
+  'Add Parent Variant Assembly' => 'Stammartikel Erzeugnis erfassen',
+  'Add Parent Variant Part'     => 'Stammartikel Ware erfassen',
+  'Add Parent Variant Service'  => 'Stammartikel Dienstleistung erfassen',
   'Add Part'                    => 'Ware erfassen',
   'Add Parts here!'             => 'Artikel hier hinzufügen!',
   'Add Price Factor'            => 'Preisfaktor erfassen',
@@ -237,7 +241,7 @@ $self->{texts} = {
   'Add Transaction'             => 'Dialogbuchen',
   'Add User'                    => 'Neuer Benutzer',
   'Add User Group'              => 'Neue Benutzergruppe',
-  'Add Variant'                 => 'Variante erfassen',
+  'Add Variant Property'        => 'Varianteneigenschaft erfassen',
   'Add Vendor'                  => 'Lieferant erfassen',
   'Add Vendor Invoice'          => 'Einkaufsrechnung erfassen',
   'Add Warehouse'               => 'Lager erfassen',
@@ -844,6 +848,8 @@ $self->{texts} = {
   'Conversion of "birthday" contact person attribute' => 'Umstellung des Kontaktpersonenfeldes "Geburtstag"',
   'Conversion to PDF failed: #1' => 'Konvertierung zu PDF schlug fehl: #1',
   'Conversion:'                 => 'Konversion',
+  'Convert'                     => 'Umwandeln',
+  'Convert Part to Variant'     => 'Artikel in Variante umwandeln',
   'Converting to deliveryorder' => 'Konvertiere zu Lieferschein',
   'Copies'                      => 'Kopien',
   'Copy'                        => 'Kopieren',
@@ -857,6 +863,7 @@ $self->{texts} = {
   'Costs'                       => 'Kosten',
   'Could not create new project #1' => 'Neues Projekt #1 kann nicht angelegt werden',
   'Could not extract Factur-X/ZUGFeRD data, data and error message:' => 'Konnte keine Factur-X-/ZUGFeRD-Daten extrahieren, folgende Fehlermeldung und das PDF:',
+  'Could not find Variant Property Value' => 'Konnte keine Ausprägung finden',
   'Could not find an entry for this part in the pricegroup.' => 'Konnte keinen Eintrag für diesen Artikel in der Preisgruppe finden.',
   'Could not find email import(s): ' => 'Konnte folgende E-Mailimport(e) nicht finden: ',
   'Could not load class #1 (#2): "#3"' => 'Konnte Klasse #1 (#2) nicht laden: "#3"',
@@ -1305,8 +1312,8 @@ $self->{texts} = {
   'Do you really want to delete the selected objects?' => 'Möchten Sie die ausgewählten Objekte wirklich löschen?',
   'Do you really want to delete this draft?' => 'Möchten Sie diesen Entwurf wirklich löschen?',
   'Do you really want to delete this object?' => 'Möchten Sie dieses Objekt wirklich löschen?',
-  'Do you really want to delete this reclamation reason?' => 'Möchten Sie diesen Reklamationsgrund wirklich löschen?',
   'Do you really want to delete this partsgroup?' => 'Möchten Sie diese Warengruppe wirklich löschen?',
+  'Do you really want to delete this reclamation reason?' => 'Möchten Sie diesen Reklamationsgrund wirklich löschen?',
   'Do you really want to delete this record template?' => 'Möchten Sie diese Belegvorlage wirklich löschen?',
   'Do you really want to mark the selected entries as booked?' => 'Möchten Sie die ausgewählten Einträge wirklich als gebucht markieren?',
   'Do you really want to print?' => 'Wollen Sie wirklich drucken?',
@@ -1427,7 +1434,6 @@ $self->{texts} = {
   'Edit Invoice'                => 'Rechnung bearbeiten',
   'Edit Invoice for Advance Payment' => 'Anzahlungsrechnung bearbeiten',
   'Edit Letter'                 => 'Brief bearbeiten',
-  'Edit Parent Variant'         => 'Stammartikel bearbeiten',
   'Edit Part'                   => 'Ware bearbeiten',
   'Edit Preferences for #1'     => 'Einstellungen von #1 bearbeiten',
   'Edit Price Factor'           => 'Preisfaktor bearbeiten',
@@ -1455,7 +1461,7 @@ $self->{texts} = {
   'Edit Supplier Delivery Order' => 'Beistell-Lieferschein bearbeiten',
   'Edit User'                   => 'Benutzerdaten bearbeiten',
   'Edit User Group'             => 'Benutzergruppe bearbeiten',
-  'Edit Variant'                => 'Variante bearbeiten',
+  'Edit Variant Property'       => 'Varianteneigenschaft bearbeiten',
   'Edit Vendor'                 => 'Lieferant editieren',
   'Edit Vendor Invoice'         => 'Einkaufsrechnung bearbeiten',
   'Edit Warehouse'              => 'Lager bearbeiten',
@@ -1585,8 +1591,11 @@ $self->{texts} = {
   'Error message from the database: #1' => 'Fehlermeldung der Datenbank: #1',
   'Error message from the webshop api:' => 'Fehlermeldung der Webshop Api',
   'Error when saving: #1'       => 'Fehler beim Speichern: #1',
+  'Error while adding variant property: #1' => 'Fehler beim Hinzufügen der Varianteneigenschaft: #1',
   'Error while applying year-end bookings!' => 'Fehler beim Durchführen der Abschlußbuchungen!',
+  'Error while converting part to variant: ' => 'Fehler beim Umwandeln des Artikel zur Variante: ',
   'Error while creating project with project number of new order number, project number #1 already exists!' => 'Fehler beim Erstellen eines Projekts mit der Projektnummer der neuen Auftragsnummer, Projektnummer #1 existiert bereits!',
+  'Error while creating variants: ' => 'Fehler beim Erstellen von Varianten: ',
   'Error while processing email journal (\'#1\') attachments with \'#2\': ' => 'Fehler beim Verarbeiten der E-Mail-Journals (\'#1\') Anhänge mit \'#2\': ',
   'Error while saving shop order #1. DB Error #2. Generic exception #3.' => 'Fehler beim Speichern der Shop-Bestellung #1. DB Fehler #2. Genereller Fehler #3.',
   'Error with default taxzone'  => 'Ungültige Standardsteuerzone',
@@ -2216,7 +2225,6 @@ $ ./scripts/installation_check.pl',
   'Last Dunning'                => 'Letzte Mahnung',
   'Last Invoice Number'         => 'Letzte Rechnungsnummer',
   'Last Numbers / Prefixes'     => 'Letzte Nummern / Präfixe',
-  'Last Parent Variant Number'  => 'Letzte Stammartikelnummer',
   'Last Purchase Delivery Order Number' => 'Letzte Lieferscheinnummer (Einkauf)',
   'Last Purchase Order Confirmation Number' => 'Letzte Lieferantenauftragsbestätigungs-Nummer',
   'Last Purchase Order Number'  => 'Letzte Lieferantenauftragsnummer',
@@ -2232,7 +2240,6 @@ $ ./scripts/installation_check.pl',
   'Last Service Number'         => 'Letzte Dienstleistungsnr.',
   'Last Supplier Delivery Order Number' => 'Letzte Beistell-Lieferscheinnummer',
   'Last Transaction'            => 'Letzte Buchung',
-  'Last Variant Number'         => 'Letzte Variantennummer',
   'Last Vendor Number'          => 'Letzte Lieferantennummer',
   'Last command output'         => 'Ausgabe des letzten Befehls',
   'Last modification'           => 'Letzte Änderung',
@@ -2499,6 +2506,7 @@ $ ./scripts/installation_check.pl',
   'No Order items fetched'      => 'Keine Auftragspositionen gefunden',
   'No Shopdescription'          => 'Keine Shop-Artikelbeschreibung',
   'No Shopimages'               => 'Keine Shop-Bilder',
+  'No Variant Property has been created yet.' => 'Es wurde noch keine Varianteneigenschaft hinzugefügt.',
   'No Vendor'                   => 'Kein Lieferant',
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No account selected. Please select an account.' => 'Kein Konto ausgewählt. Bitte Konto auswählen.',
@@ -2566,6 +2574,7 @@ $ ./scripts/installation_check.pl',
   'No problems were recognized.' => 'Es wurden keine Probleme gefunden.',
   'No profit and loss carried forward chart configured!' => 'Kein Verlustvortragskonto konfiguriert!',
   'No profit carried forward chart configured!' => 'Kein Gewinnvortragskonto konfiguriert!',
+  'No property value selected for variant properties: #1.' => 'Keine Ausprägung ausgewählt für Varianteneigenschaft: #1.',
   'No quotations or orders have been created yet.' => 'Es wurden noch keine Angebote oder Aufträge angelegt.',
   'No record is selected.'      => 'Kein Beleg ausgewählt.',
   'No record type is selected.' => 'Kein Belegtyp ausgewählt.',
@@ -2798,9 +2807,10 @@ $ ./scripts/installation_check.pl',
   'Paid amount'                 => 'Bezahlter Betrag',
   'Parameter module must be given.' => 'Der Parameter "module" miss angegeben werden.',
   'Parent Variant'              => 'Stammartikel',
+  'Parent Variant (typeabbreviation)' => 'S',
+  'Parents'                     => 'Obergruppen',
   'Parsing the XML data failed: #1' => 'Parsen der XML-Daten fehlgeschlagen: #1',
   'Parsing the XMP metadata failed.' => 'Parsen der XMP-Metadaten schlug fehl.',
-  'Parents'                     => 'Obergruppen',
   'Part'                        => 'Ware',
   'Part "#1" has chargenumber or best before date set. So it cannot be transfered automatically.' => 'Bei Artikel "#1" ist eine Chargenummer oder ein Mindesthaltbarkeitsdatum vergeben. Deshalb kann dieser Artikel nicht automatisch ausgelagert werden.',
   'Part #1 exists in warehouse #2, but not in warehouse #3 ' => 'Artikel #1 existiert im Lager #2, aber nicht im Lager #3',
@@ -2821,6 +2831,7 @@ $ ./scripts/installation_check.pl',
   'Part already in purchasebasket or has no vendor' => 'Artikel ist schon im Bestellwarenkorb oder hat keinen Lieferanten',
   'Part already ordered'        => 'Artikel ist bestellt',
   'Part classifications'        => 'Artikel-Klassifizierungen',
+  'Part for conversion:'        => 'Artikel für Konvertierung:',
   'Part marked as "Shop part"'  => 'Markiert als Shopartikel',
   'Part picker'                 => 'Artikelauswahl',
   'Part successful counted'     => 'Der Artikel wurde gezählt',
@@ -2937,6 +2948,8 @@ $ ./scripts/installation_check.pl',
   'Please select a customer.'   => 'Bitte wählen Sie einen Kunden aus.',
   'Please select a deadline date.' => 'Bitte wählen Sie ein Datum für die Fristsetzung aus.',
   'Please select a delivery date.' => 'Bitte einen Liefertermin auswählen',
+  'Please select a new variant property value for all variants' => 'Bitte wähle eine neue Ausprägung für alle Varianten',
+  'Please select a part to convert.' => 'Bitte wähle ein Artikel zur Konvertierung aus.',
   'Please select a vendor from the list below.' => 'Bitte einen Händler aus der Liste auswählen',
   'Please select a vendor.'     => 'Bitte wählen Sie einen Lieferanten aus.',
   'Please select the dataset you want to delete:' => 'Bitte wählen Sie die zu löschende Datenbank aus:',
@@ -3106,6 +3119,7 @@ $ ./scripts/installation_check.pl',
   'Projects: edit the list of employees allowed to view invoices' => 'Projekte: Liste der Angestellten bearbeiten, die Projektrechnungen ansehen dürfen',
   'Projecttransactions'         => 'Projektbuchungen',
   'Promotion Code'              => 'Aktionscode',
+  'Property Values (Abbreviation)' => 'Ausprägungen (Abkürzungen)',
   'Proposal'                    => 'Vorschlag',
   'Proposals'                   => 'Vorschläge',
   'Protocol'                    => 'Protokoll',
@@ -3528,6 +3542,7 @@ $ ./scripts/installation_check.pl',
   'Select Deliveries'           => 'Lieferungen auswählen',
   'Select Mulit-Item Options'   => 'Multi-Treffer Auswahlliste',
   'Select Shipping Address'     => 'Lieferadresse auswählen',
+  'Select Variant Property First' => 'Wähle zuerst Varianteneigenschaft',
   'Select a Customer'           => 'Endkunde auswählen',
   'Select a period'             => 'Bitte Zeitraum auswählen',
   'Select article'              => 'Artikel auswählen',
@@ -3755,7 +3770,6 @@ $ ./scripts/installation_check.pl',
   'Solution'                    => 'Lösung',
   'Sorry, I am too stupid to figure out the default warehouse/bin and the sold qty. I drop the default warehouse/bin option.' => 'Entschuldigung, ich bin nicht in der Lage Standard-Lager und die Menge in gewählten Belegen gleichzeitig anzuzeigen. Ich lass die Standard-Lager weg.',
   'Sort'                        => 'Sortieren',
-  'Sort & Save'                 => '',
   'Sort By'                     => 'Sortiert nach',
   'Sort by'                     => 'Sortieren nach',
   'Sort order'                  => 'Sortierfolge',
@@ -3986,10 +4000,16 @@ $ ./scripts/installation_check.pl',
   'The VAT ID number \'#1\' is invalid.' => 'Die UStID-Nummer »#1« ist ungültig.',
   'The VAT ID number in the client configuration is invalid.' => 'Die UStID-Nummer in der Mandantenkonfiguraiton ist ungültig.',
   'The VAT registration number is missing in the client configuration.' => 'Die Umsatzsteuer-ID-Nummer fehlt in der Mandantenkonfiguration.',
+  'The Variant Property Value has been saved.' => 'Die Ausprägung wurde gespeichert.',
+  'The Variant Property has been created.' => 'Die Varianteneigenschaft wurde erfasst.',
+  'The Variant Property has been deleted.' => 'Die Varianteneigenschaft wurde gelöscht.',
+  'The Variant Property has been saved.' => 'Die Varianteneigenschaft wurde gespeichert.',
+  'The Variant Property is in use and cannot be deleted.' => 'Die Varianteneigenschaft ist in Verwendung und kann nicht gelöscht werden.',
   'The WebDAV feature has been used.' => 'Das WebDAV-Feature wurde benutzt.',
   'The XMP metadata does not declare the Factur-X/ZUGFeRD data.' => 'Die XMP-Metadaten enthalten keine Factur-X-/ZUGFeRD-Deklaration.',
   'The ZUGFeRD invoice data cannot be generated because the data validation failed.' => 'Die ZUGFeRD-Rechnungsdaten können nicht erzeugt werden, da die Validierung fehlschlug.',
   'The ZUGFeRD/Factur-X invoice \'#1\' has been loaded.' => 'Die ZUGFeRD-/Factur-X-Rechnung \'#1\' wurde geladen.',
+  'The abbreviation is missing' => 'Die Abkürzung fehlt',
   'The abbreviation is missing.' => 'Abkürzung fehlt',
   'The access rights a user has within a client instance is still governed by his group membership.' => 'Welche Zugriffsrechte ein Benutzer innerhalb eines Mandanten hat, wird weiterhin über Gruppenmitgliedschaften geregelt.',
   'The access rights have been saved.' => 'Die Zugriffsrechte wurden gespeichert.',
@@ -4192,6 +4212,7 @@ $ ./scripts/installation_check.pl',
   'The partnumber already exists.' => 'Die Artikelnummer wird bereits verwendet.',
   'The partnumber is already being used' => 'Der Artikel ist bereits in Verwendung',
   'The partnumber is missing.'  => 'Die Artikelnummer fehlt.',
+  'The parts couldn\'t be updated!' => 'Die Artikel konnten nicht aktualisiert werden!',
   'The parts for this delivery order have already been transferred in.' => 'Die Artikel dieses Lieferscheins wurden bereits eingelagert.',
   'The parts for this delivery order have already been transferred out.' => 'Die Artikel dieses Lieferscheins wurden bereits ausgelagert.',
   'The parts for this order have already been transferred' => 'Die Artikel in diesem Lieferschein wurden schon umgelagert',
@@ -4316,6 +4337,7 @@ $ ./scripts/installation_check.pl',
   'The transfer has been canceled by the user.' => 'Der Vorgang wurde durch den Benutzer abgebrochen.',
   'The transport cost article \'#1\' is missing. Do you want to continue anyway?' => 'Der Transportkostenartikel »#1« fehlt. Möchten Sie trotzdem fortfahren?',
   'The type is missing.'        => 'Der Typ fehlt.',
+  'The unique name is missing.' => 'Ein eindeutiger Name fehlt.',
   'The unit has been added.'    => 'Die Einheit wurde erfasst.',
   'The unit in row %d has been deleted in the meantime.' => 'Die Einheit in Zeile %d ist in der Zwischentzeit gelöscht worden.',
   'The unit in row %d has been used in the meantime and cannot be changed anymore.' => 'Die Einheit in Zeile %d wurde in der Zwischenzeit benutzt und kann nicht mehr geändert werden.',
@@ -4381,6 +4403,7 @@ $ ./scripts/installation_check.pl',
   'There is a better discount available' => 'Es is ein besserer Rabatt verfügbar',
   'There is a better price available' => 'Es ist ein besserer Preis verfügbar',
   'There is already a taxkey 0 with tax rate not 0.' => 'Es existiert bereits ein Steuerschlüssel mit Steuersatz ungleich 0%.',
+  'There is already a variant of \'#1\' with the property values: #2' => 'Es existiert bereits eine Variante von \'#1\' mit den Ausprägungen: #2',
   'There is an inconsistancy in your database.' => 'In Ihrer Datenbank sind Unstimmigkeiten vorhanden.',
   'There is at least one sales or purchase invoice for which kivitendo recorded an inventory transaction with taxkeys even though no tax was recorded.' => 'Es gibt mindestens eine Verkaufs- oder Einkaufsrechnung, für die kivitendo eine Warenbestandsbuchung ohne dazugehörige Steuerbuchung durchgeführt hat.',
   'There is at least one transaction for which the user has chosen a logically wrong taxkey.' => 'Es gibt mindestens eine Buchung, bei der ein logisch nicht passender Steuerschlüssel ausgewählt wurde.',
@@ -4610,6 +4633,7 @@ $ ./scripts/installation_check.pl',
   'Type of Business'            => 'Kunden-/Lieferantentyp',
   'Type of Customer'            => 'Kundentyp',
   'Type of Vendor'              => 'Lieferantentyp',
+  'Type:'                       => 'Typ:',
   'TypeAbbreviation'            => 'Typ-Abkürzung',
   'Types of Business'           => 'Kunden-/Lieferantentypen',
   'UNDO TRANSFER'               => 'Zurücklagern',
@@ -4639,6 +4663,7 @@ $ ./scripts/installation_check.pl',
   'Unfortunately you have no warehouse defined.' => 'Leider, gibt es kein Lager in diesem Mandanten.',
   'Unimport all'                => 'Alle zurück zur Quelle',
   'Unimport documents'          => 'Importierte Dokumente zurück zurQuelle',
+  'Unique Name'                 => 'Eindeutiger Name',
   'Unit'                        => 'Einheit',
   'Unit (if missing or empty default unit will be used)' => 'Einheit (falls nicht vorhanden oder leer wird die Standardeinheit benutzt)',
   'Unit missing.'               => 'Die Einheit fehlt.',
@@ -4662,6 +4687,7 @@ $ ./scripts/installation_check.pl',
   'Update Price'                => 'Preis übernehmen',
   'Update Prices'               => 'Preise aktualisieren',
   'Update SKR04: new tax account 3804 (19%)' => 'Update SKR04: neues Steuerkonto 3804 (19%) für innergemeinschaftlichen Erwerb',
+  'Update Variants'             => 'Werte für Varianten übernehmen',
   'Update customer using billing address' => 'Kunde mit Shop-Rechnungsadresse überschreiben',
   'Update from master data'     => 'Aktualisieren aus Stammdaten',
   'Update prices'               => 'Preise aktualisieren',
@@ -4762,6 +4788,7 @@ $ ./scripts/installation_check.pl',
   'Valid/Obsolete'              => 'Gültig/ungültig',
   'Validity'                    => 'Gültigkeit',
   'Value'                       => 'Wert',
+  'Values'                      => 'Werte',
   'Values & Prices'             => 'Werte & Preise',
   'Valutadate'                  => 'Valutadatum',
   'Valutadate from'             => 'Valutadatum von',
@@ -4769,7 +4796,11 @@ $ ./scripts/installation_check.pl',
   'Variable'                    => 'Variable',
   'Variable Description'        => 'Datenfeldbezeichnung',
   'Variable Name'               => 'Datenfeldname (intern)',
-  'Variant'                     => 'Variante',
+  'Variant (typeabbreviation)'  => 'V',
+  'Variant Properties'          => 'Varianteneigenschaften',
+  'Variant Property'            => 'Varianteneigenschaft',
+  'Variant Property Value'      => 'Ausprägung',
+  'Variant Property Values'     => 'Ausprägungen',
   'Variants'                    => 'Varianten',
   'Vendor'                      => 'Lieferant',
   'Vendor & Order'              => 'Lieferant & Bestellung',
diff --git a/locale/en/all b/locale/en/all
index 802a7f8e4..b8537bfdc 100644
--- a/locale/en/all
+++ b/locale/en/all
@@ -118,6 +118,7 @@ $self->{texts} = {
   'ATTENTION! If you enabled this feature you can not simply turn it off again without taking care that best_before fields are emptied in the database.' => '',
   'ATTENTION! You can not simply change it from periodic to perpetual once you started posting.' => '',
   'AUTOMATICALLY MATCH BINS'    => '',
+  'Abbreviation'                => '',
   'Abbreviation Legend'         => '',
   'Abort'                       => '',
   'Abrechnungsnummer'           => '',
@@ -205,6 +206,9 @@ $self->{texts} = {
   'Add Invoice for Advance Payment' => '',
   'Add Letter'                  => '',
   'Add Parent Variant'          => '',
+  'Add Parent Variant Assembly' => '',
+  'Add Parent Variant Part'     => '',
+  'Add Parent Variant Service'  => '',
   'Add Part'                    => '',
   'Add Parts here!'             => '',
   'Add Price Factor'            => '',
@@ -237,7 +241,7 @@ $self->{texts} = {
   'Add Transaction'             => '',
   'Add User'                    => '',
   'Add User Group'              => '',
-  'Add Variant'                 => '',
+  'Add Variant Property'        => '',
   'Add Vendor'                  => '',
   'Add Vendor Invoice'          => '',
   'Add Warehouse'               => '',
@@ -844,6 +848,8 @@ $self->{texts} = {
   'Conversion of "birthday" contact person attribute' => '',
   'Conversion to PDF failed: #1' => '',
   'Conversion:'                 => '',
+  'Convert'                     => '',
+  'Convert Part to Variant'     => '',
   'Converting to deliveryorder' => '',
   'Copies'                      => '',
   'Copy'                        => '',
@@ -857,6 +863,7 @@ $self->{texts} = {
   'Costs'                       => '',
   'Could not create new project #1' => '',
   'Could not extract Factur-X/ZUGFeRD data, data and error message:' => '',
+  'Could not find Variant Property Value' => '',
   'Could not find an entry for this part in the pricegroup.' => '',
   'Could not find email import(s): ' => '',
   'Could not load class #1 (#2): "#3"' => '',
@@ -1305,8 +1312,8 @@ $self->{texts} = {
   'Do you really want to delete the selected objects?' => '',
   'Do you really want to delete this draft?' => '',
   'Do you really want to delete this object?' => '',
-  'Do you really want to delete this reclamation reason?' => '',
   'Do you really want to delete this partsgroup?' => '',
+  'Do you really want to delete this reclamation reason?' => '',
   'Do you really want to delete this record template?' => '',
   'Do you really want to mark the selected entries as booked?' => '',
   'Do you really want to print?' => '',
@@ -1427,7 +1434,6 @@ $self->{texts} = {
   'Edit Invoice'                => '',
   'Edit Invoice for Advance Payment' => '',
   'Edit Letter'                 => '',
-  'Edit Parent Variant'         => '',
   'Edit Part'                   => '',
   'Edit Preferences for #1'     => '',
   'Edit Price Factor'           => '',
@@ -1455,7 +1461,7 @@ $self->{texts} = {
   'Edit Supplier Delivery Order' => '',
   'Edit User'                   => '',
   'Edit User Group'             => '',
-  'Edit Variant'                => '',
+  'Edit Variant Property'       => '',
   'Edit Vendor'                 => '',
   'Edit Vendor Invoice'         => '',
   'Edit Warehouse'              => '',
@@ -1585,8 +1591,11 @@ $self->{texts} = {
   'Error message from the database: #1' => '',
   'Error message from the webshop api:' => '',
   'Error when saving: #1'       => '',
+  'Error while adding variant property: #1' => '',
   'Error while applying year-end bookings!' => '',
+  'Error while converting part to variant: ' => '',
   'Error while creating project with project number of new order number, project number #1 already exists!' => '',
+  'Error while creating variants: ' => '',
   'Error while processing email journal (\'#1\') attachments with \'#2\': ' => '',
   'Error while saving shop order #1. DB Error #2. Generic exception #3.' => '',
   'Error with default taxzone'  => '',
@@ -2215,7 +2224,6 @@ $self->{texts} = {
   'Last Dunning'                => '',
   'Last Invoice Number'         => '',
   'Last Numbers / Prefixes'     => '',
-  'Last Parent Variant Number'  => '',
   'Last Purchase Delivery Order Number' => '',
   'Last Purchase Order Confirmation Number' => '',
   'Last Purchase Order Number'  => '',
@@ -2231,7 +2239,6 @@ $self->{texts} = {
   'Last Service Number'         => '',
   'Last Supplier Delivery Order Number' => '',
   'Last Transaction'            => '',
-  'Last Variant Number'         => '',
   'Last Vendor Number'          => '',
   'Last command output'         => '',
   'Last modification'           => '',
@@ -2498,6 +2505,7 @@ $self->{texts} = {
   'No Order items fetched'      => '',
   'No Shopdescription'          => '',
   'No Shopimages'               => '',
+  'No Variant Property has been created yet.' => '',
   'No Vendor'                   => '',
   'No Vendor was found matching the search parameters.' => '',
   'No account selected. Please select an account.' => '',
@@ -2554,6 +2562,7 @@ $self->{texts} = {
   'No invoice email found.'     => '',
   'No invoices have been selected.' => '',
   'No part was selected.'       => '',
+  'No parts selected.'          => '',
   'No partsgroup selected.'     => '',
   'No payment term has been created yet.' => '',
   'No picture has been uploaded' => '',
@@ -2564,6 +2573,7 @@ $self->{texts} = {
   'No problems were recognized.' => '',
   'No profit and loss carried forward chart configured!' => '',
   'No profit carried forward chart configured!' => '',
+  'No property value selected for variant properties: #1.' => '',
   'No quotations or orders have been created yet.' => '',
   'No record is selected.'      => '',
   'No record type is selected.' => '',
@@ -2796,9 +2806,10 @@ $self->{texts} = {
   'Paid amount'                 => '',
   'Parameter module must be given.' => '',
   'Parent Variant'              => '',
+  'Parent Variant (typeabbreviation)' => 'P',
+  'Parents'                     => '',
   'Parsing the XML data failed: #1' => '',
   'Parsing the XMP metadata failed.' => '',
-  'Parents'                     => '',
   'Part'                        => '',
   'Part "#1" has chargenumber or best before date set. So it cannot be transfered automatically.' => '',
   'Part #1 exists in warehouse #2, but not in warehouse #3 ' => '',
@@ -2819,9 +2830,11 @@ $self->{texts} = {
   'Part already in purchasebasket or has no vendor' => '',
   'Part already ordered'        => '',
   'Part classifications'        => '',
+  'Part for conversion:'        => '',
   'Part marked as "Shop part"'  => '',
   'Part picker'                 => '',
   'Part successful counted'     => '',
+  'Part wasn\'t added to partsgroup!' => '',
   'Part with partnumber: #1 not found' => '',
   'PartClassAbbreviation'       => '',
   'Part_br_Description'         => 'Description',
@@ -2934,6 +2947,8 @@ $self->{texts} = {
   'Please select a customer.'   => '',
   'Please select a deadline date.' => '',
   'Please select a delivery date.' => '',
+  'Please select a new variant property value for all variants' => '',
+  'Please select a part to convert.' => '',
   'Please select a vendor from the list below.' => '',
   'Please select a vendor.'     => '',
   'Please select the dataset you want to delete:' => '',
@@ -3103,6 +3118,7 @@ $self->{texts} = {
   'Projects: edit the list of employees allowed to view invoices' => '',
   'Projecttransactions'         => '',
   'Promotion Code'              => '',
+  'Property Values (Abbreviation)' => '',
   'Proposal'                    => '',
   'Proposals'                   => '',
   'Protocol'                    => '',
@@ -3525,6 +3541,7 @@ $self->{texts} = {
   'Select Deliveries'           => '',
   'Select Mulit-Item Options'   => '',
   'Select Shipping Address'     => '',
+  'Select Variant Property First' => '',
   'Select a Customer'           => '',
   'Select a period'             => '',
   'Select article'              => '',
@@ -3981,10 +3998,16 @@ $self->{texts} = {
   'The VAT ID number \'#1\' is invalid.' => '',
   'The VAT ID number in the client configuration is invalid.' => '',
   'The VAT registration number is missing in the client configuration.' => '',
+  'The Variant Property Value has been saved.' => '',
+  'The Variant Property has been created.' => '',
+  'The Variant Property has been deleted.' => '',
+  'The Variant Property has been saved.' => '',
+  'The Variant Property is in use and cannot be deleted.' => '',
   'The WebDAV feature has been used.' => '',
   'The XMP metadata does not declare the Factur-X/ZUGFeRD data.' => '',
   'The ZUGFeRD invoice data cannot be generated because the data validation failed.' => '',
   'The ZUGFeRD/Factur-X invoice \'#1\' has been loaded.' => '',
+  'The abbreviation is missing' => '',
   'The abbreviation is missing.' => '',
   'The access rights a user has within a client instance is still governed by his group membership.' => '',
   'The access rights have been saved.' => '',
@@ -4187,6 +4210,7 @@ $self->{texts} = {
   'The partnumber already exists.' => '',
   'The partnumber is already being used' => '',
   'The partnumber is missing.'  => '',
+  'The parts couldn\'t be updated!' => '',
   'The parts for this delivery order have already been transferred in.' => '',
   'The parts for this delivery order have already been transferred out.' => '',
   'The parts for this order have already been transferred' => '',
@@ -4311,6 +4335,7 @@ $self->{texts} = {
   'The transfer has been canceled by the user.' => '',
   'The transport cost article \'#1\' is missing. Do you want to continue anyway?' => '',
   'The type is missing.'        => '',
+  'The unique name is missing.' => '',
   'The unit has been added.'    => '',
   'The unit in row %d has been deleted in the meantime.' => '',
   'The unit in row %d has been used in the meantime and cannot be changed anymore.' => '',
@@ -4376,6 +4401,7 @@ $self->{texts} = {
   'There is a better discount available' => '',
   'There is a better price available' => '',
   'There is already a taxkey 0 with tax rate not 0.' => '',
+  'There is already a variant of \'#1\' with the property values: #2' => '',
   'There is an inconsistancy in your database.' => '',
   'There is at least one sales or purchase invoice for which kivitendo recorded an inventory transaction with taxkeys even though no tax was recorded.' => '',
   'There is at least one transaction for which the user has chosen a logically wrong taxkey.' => '',
@@ -4605,6 +4631,7 @@ $self->{texts} = {
   'Type of Business'            => '',
   'Type of Customer'            => '',
   'Type of Vendor'              => '',
+  'Type:'                       => '',
   'TypeAbbreviation'            => '',
   'Types of Business'           => '',
   'UNDO TRANSFER'               => '',
@@ -4634,6 +4661,7 @@ $self->{texts} = {
   'Unfortunately you have no warehouse defined.' => '',
   'Unimport all'                => '',
   'Unimport documents'          => '',
+  'Unique Name'                 => '',
   'Unit'                        => '',
   'Unit (if missing or empty default unit will be used)' => '',
   'Unit missing.'               => '',
@@ -4657,6 +4685,7 @@ $self->{texts} = {
   'Update Price'                => '',
   'Update Prices'               => '',
   'Update SKR04: new tax account 3804 (19%)' => '',
+  'Update Variants'             => '',
   'Update customer using billing address' => '',
   'Update from master data'     => '',
   'Update prices'               => '',
@@ -4757,6 +4786,7 @@ $self->{texts} = {
   'Valid/Obsolete'              => '',
   'Validity'                    => '',
   'Value'                       => '',
+  'Values'                      => '',
   'Values & Prices'             => '',
   'Valutadate'                  => '',
   'Valutadate from'             => '',
@@ -4764,7 +4794,11 @@ $self->{texts} = {
   'Variable'                    => '',
   'Variable Description'        => '',
   'Variable Name'               => '',
-  'Variant'                     => '',
+  'Variant (typeabbreviation)'  => 'V',
+  'Variant Properties'          => '',
+  'Variant Property'            => '',
+  'Variant Property Value'      => '',
+  'Variant Property Values'     => '',
   'Variants'                    => '',
   'Vendor'                      => '',
   'Vendor & Order'              => '',
diff --git a/templates/design40_webpages/part/_parent_variant.html b/templates/design40_webpages/part/_parent_variant.html
index 4c1045006..d57aedf82 100644
--- a/templates/design40_webpages/part/_parent_variant.html
+++ b/templates/design40_webpages/part/_parent_variant.html
@@ -259,7 +259,7 @@
   </div>
 
   <div class="wrapper input-panel">
-    <h3> [% LxERP.t8("Convert part to Variant") %] </h3>
+    <h3> [% LxERP.t8("Convert Part to Variant") %] </h3>
     <table class="tbl-list">
       <caption>
         [% 'Variant Properties' | $T8 %]
@@ -284,7 +284,7 @@
         [% END %]
       </tbody>
     </table>
-    <label for="convert_part.id">[% 'Part to convert:' | $T8 %]</label>
+    <label for="convert_part.id">[% 'Part for conversion:' | $T8 %]</label>
     [% P.part.picker('convert_part.id', undef,
       part_type=SELF.part.part_type, variant_type='single',
       placeholder=(LxERP.t8('Type:') _ ' ' _ LxERP.t8(SELF.part.part_type)),
diff --git a/templates/design40_webpages/variant_property/variant_property_form.html b/templates/design40_webpages/variant_property/variant_property_form.html
index 45f64b95d..d00c1e15e 100644
--- a/templates/design40_webpages/variant_property/variant_property_form.html
+++ b/templates/design40_webpages/variant_property/variant_property_form.html
@@ -18,7 +18,7 @@
     </tr>
      <tr>
       <td> [%- 'Unique Name' | $T8 %] </td>
-      <td> [% P.input_tag("variant_property.unique_name", SELF.variant_property.unique_name , "data-validate"="required", "data-title"=LxERP.t8("Unique Name ")) %] </td>
+      <td> [% P.input_tag("variant_property.unique_name", SELF.variant_property.unique_name , "data-validate"="required", "data-title"=LxERP.t8("Unique Name")) %] </td>
     </tr>
       <tr>
       <td> [%- 'Abbreviation' | $T8 %] </td>
diff --git a/templates/design40_webpages/variant_property/variant_property_list.html b/templates/design40_webpages/variant_property/variant_property_list.html
index ebccc45b1..2c4892438 100644
--- a/templates/design40_webpages/variant_property/variant_property_list.html
+++ b/templates/design40_webpages/variant_property/variant_property_list.html
@@ -11,7 +11,7 @@
 <div class="wrapper">
   [% IF !VARIANTPROPERTIES.size %]
   <p>
-    [%- 'No Variantproperty has been created yet.' | $T8 %]
+    [%- 'No Variant Property has been created yet.' | $T8 %]
   </p>
   [%- ELSE %]
   <table id="variant_properties" class="tbl-list width-moderate">
diff --git a/templates/design40_webpages/variant_property/variant_property_value_form.html b/templates/design40_webpages/variant_property/variant_property_value_form.html
index b7c653e7f..72f29bbb0 100644
--- a/templates/design40_webpages/variant_property/variant_property_value_form.html
+++ b/templates/design40_webpages/variant_property/variant_property_value_form.html
@@ -45,7 +45,7 @@
         <tr>
           <td> [%- 'Value' | $T8 %] </td>
           <input type="text" name="translation_[% language.id %]" value="[%- HTML.escape(variant_property_value.translated_attribute('description_long', language, 1)) %]" size="60">
-          <td> [% P.input_tag("variant_property_value.value", variant_property_value.value, "data-validate"="required", "data-title"=LxERP.t8("value")) %] </td>
+          <td> [% P.input_tag("variant_property_value.value", variant_property_value.value, "data-validate"="required", "data-title"=LxERP.t8("Value")) %] </td>
         </tr>
           <tr>
           <td> [%- 'Abbreviation' | $T8 %] </td>
