Added feature for part IPN suggest with category prefixes (#1054)

* Erweiterungstätigkeiten zur IPN-Vorschlagsliste anhand von Präfixen aus den Kategorien

* Umstellung Migrationen bzgl. Multi-Plattform-Support.
Zunächst MySQL, SQLite Statements integrieren.

* Postgre Statements integrieren

* SQL-Formatierung in Migration verbessern

* Erweitere IPN-Suggest um Bauteilbeschreibung.

Die Implementierung berücksichtigt nun zusätzlich die Bauteilbeschreibung zu maximal 150 Zeichen Länge für die Generierung von IPN-Vorschlägen und Inkrementen.

* Anpassungen aus Analyse vornehmen

* IPN-Validierung für Parts überarbeiten

* IPN-Vorschlagslogik um Konfiguration erweitert

* Anpassungen aus phpstan Analyse

* IPN-Vorschlagslogik erweitert und Bauteil-IPN vereindeutigt

Die IPN-Logik wurde um eine Konfiguration zur automatischen Suffix-Anfügung und die Berücksichtigung von doppelten Beschreibungen bei Bedarf ergänzt. Zudem wurde das Datenmodell angepasst, um eine eindeutige Speicherung der IPN zu gewährleisten.

* Regex-Konfigurationsmöglichkeit für IPN-Vorschläge einführen

Die Einstellungen für die IPN-Vorschlagslogik wurden um eine Regex-Validierung und eine Hilfetext-Konfiguration erweitert. Tests und Änderungen an den Formularoptionen wurden implementiert.

* Match range assert and form limits in suggestPartDigits

* Keep existing behavior with autoAppend suffix by default

* Show the regex hint in the browser validation notice.

* Improved translations

* Removed unnecessary service definition

* Removed german comments

---------

Co-authored-by: Marcel Diegelmann <marcel.diegelmann@gmail.com>
Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
This commit is contained in:
web-devinition.de 2025-11-03 00:31:47 +01:00 committed by GitHub
parent 14a4f1f437
commit 771857e014
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 2791 additions and 115 deletions

View file

@ -84,6 +84,17 @@ class CategoryAdminForm extends BaseEntityAdminForm
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
]);
$builder->add('part_ipn_prefix', TextType::class, [
'required' => false,
'empty_data' => '',
'label' => 'category.edit.part_ipn_prefix',
'help' => 'category.edit.part_ipn_prefix.help',
'attr' => [
'placeholder' => 'category.edit.part_ipn_prefix.placeholder',
],
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
]);
$builder->add('default_description', RichTextEditorType::class, [
'required' => false,
'empty_data' => '',

View file

@ -42,6 +42,7 @@ use App\Form\Type\StructuralEntityType;
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\LogSystem\EventCommentNeededHelper;
use App\Services\LogSystem\EventCommentType;
use App\Settings\MiscSettings\IpnSuggestSettings;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
@ -57,8 +58,12 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class PartBaseType extends AbstractType
{
public function __construct(protected Security $security, protected UrlGeneratorInterface $urlGenerator, protected EventCommentNeededHelper $event_comment_needed_helper)
{
public function __construct(
protected Security $security,
protected UrlGeneratorInterface $urlGenerator,
protected EventCommentNeededHelper $event_comment_needed_helper,
protected IpnSuggestSettings $ipnSuggestSettings,
) {
}
public function buildForm(FormBuilderInterface $builder, array $options): void
@ -70,6 +75,39 @@ class PartBaseType extends AbstractType
/** @var PartDetailDTO|null $dto */
$dto = $options['info_provider_dto'];
$descriptionAttr = [
'placeholder' => 'part.edit.description.placeholder',
'rows' => 2,
];
if ($this->ipnSuggestSettings->useDuplicateDescription) {
// Only add attribute when duplicate description feature is enabled
$descriptionAttr['data-ipn-suggestion'] = 'descriptionField';
}
$ipnAttr = [
'class' => 'ipn-suggestion-field',
'data-elements--ipn-suggestion-target' => 'input',
'autocomplete' => 'off',
];
if ($this->ipnSuggestSettings->regex !== null && $this->ipnSuggestSettings->regex !== '') {
$ipnAttr['pattern'] = $this->ipnSuggestSettings->regex;
$ipnAttr['placeholder'] = $this->ipnSuggestSettings->regex;
$ipnAttr['title'] = $this->ipnSuggestSettings->regexHelp;
}
$ipnOptions = [
'required' => false,
'empty_data' => null,
'label' => 'part.edit.ipn',
'attr' => $ipnAttr,
];
if (isset($ipnAttr['pattern']) && $this->ipnSuggestSettings->regexHelp !== null && $this->ipnSuggestSettings->regexHelp !== '') {
$ipnOptions['help'] = $this->ipnSuggestSettings->regexHelp;
}
//Common section
$builder
->add('name', TextType::class, [
@ -84,10 +122,7 @@ class PartBaseType extends AbstractType
'empty_data' => '',
'label' => 'part.edit.description',
'mode' => 'markdown-single_line',
'attr' => [
'placeholder' => 'part.edit.description.placeholder',
'rows' => 2,
],
'attr' => $descriptionAttr,
])
->add('minAmount', SIUnitType::class, [
'attr' => [
@ -105,6 +140,9 @@ class PartBaseType extends AbstractType
'disable_not_selectable' => true,
//Do not require category for new parts, so that the user must select the category by hand and cannot forget it (the requirement is handled by the constraint in the entity)
'required' => !$new_part,
'attr' => [
'data-ipn-suggestion' => 'categoryField',
]
])
->add('footprint', StructuralEntityType::class, [
'class' => Footprint::class,
@ -178,11 +216,7 @@ class PartBaseType extends AbstractType
'disable_not_selectable' => true,
'label' => 'part.edit.partCustomState',
])
->add('ipn', TextType::class, [
'required' => false,
'empty_data' => null,
'label' => 'part.edit.ipn',
]);
->add('ipn', TextType::class, $ipnOptions);
//Comment section
$builder->add('comment', RichTextEditorType::class, [