diff --git a/src/Form/AdminPages/StorelocationAdminForm.php b/src/Form/AdminPages/StorelocationAdminForm.php
index 8a85e4ec..9e24dcd3 100644
--- a/src/Form/AdminPages/StorelocationAdminForm.php
+++ b/src/Form/AdminPages/StorelocationAdminForm.php
@@ -24,7 +24,9 @@ namespace App\Form\AdminPages;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Parts\MeasurementUnit;
+use App\Entity\UserSystem\User;
use App\Form\Type\StructuralEntityType;
+use App\Form\Type\UserSelectType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
@@ -63,5 +65,16 @@ class StorelocationAdminForm extends BaseEntityAdminForm
'disable_not_selectable' => true,
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
]);
+
+ $builder->add('owner', UserSelectType::class, [
+ 'required' => false,
+ 'label' => 'storelocation.owner.label',
+ 'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
+ ]);
+ $builder->add('part_owner_must_match', CheckboxType::class, [
+ 'required' => false,
+ 'label' => 'storelocation.part_owner_must_match.label',
+ 'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
+ ]);
}
}
diff --git a/src/Form/Type/Helper/StructuralEntityChoiceHelper.php b/src/Form/Type/Helper/StructuralEntityChoiceHelper.php
index db25e6da..6448a734 100644
--- a/src/Form/Type/Helper/StructuralEntityChoiceHelper.php
+++ b/src/Form/Type/Helper/StructuralEntityChoiceHelper.php
@@ -21,8 +21,13 @@
namespace App\Form\Type\Helper;
use App\Entity\Attachments\AttachmentType;
+use App\Entity\Base\AbstractDBElement;
+use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\AbstractStructuralDBElement;
+use App\Entity\Contracts\HasMasterAttachmentInterface;
use App\Entity\PriceInformations\Currency;
+use App\Entity\UserSystem\User;
+use App\Form\Type\MasterPictureAttachmentType;
use App\Services\Attachments\AttachmentURLGenerator;
use RuntimeException;
use Symfony\Component\Intl\Currencies;
@@ -43,37 +48,49 @@ class StructuralEntityChoiceHelper
/**
* Generates the choice attributes for the given AbstractStructuralDBElement.
- * @param AbstractStructuralDBElement $choice
+ * @param AbstractNamedDBElement $choice
* @param Options|array $options
* @return array|string[]
*/
- public function generateChoiceAttr(AbstractStructuralDBElement $choice, $options): array
+ public function generateChoiceAttr(AbstractNamedDBElement $choice, $options): array
{
- $tmp = [];
-
- //Disable attribute if the choice is marked as not selectable
- if (($options['disable_not_selectable'] ?? false) && $choice->isNotSelectable()) {
- $tmp += ['disabled' => 'disabled'];
- }
-
- if ($choice instanceof AttachmentType) {
- $tmp += ['data-filetype_filter' => $choice->getFiletypeFilter()];
- }
-
- $level = $choice->getLevel();
- /** @var AbstractStructuralDBElement|null $parent */
- $parent = $options['subentities_of'] ?? null;
- if (null !== $parent) {
- $level -= $parent->getLevel() - 1;
- }
-
- $tmp += [
- 'data-level' => $level,
- 'data-parent' => $choice->getParent() ? $choice->getParent()->getFullPath() : null,
- 'data-path' => $choice->getFullPath('->'),
- 'data-image' => $choice->getMasterPictureAttachment() ? $this->attachmentURLGenerator->getThumbnailURL($choice->getMasterPictureAttachment(), 'thumbnail_xs') : null,
+ $tmp = [
+ 'data-level' => 0,
+ 'data-path' => $choice->getName(),
];
+ if ($choice instanceof AbstractStructuralDBElement) {
+ //Disable attribute if the choice is marked as not selectable
+ if (($options['disable_not_selectable'] ?? false) && $choice->isNotSelectable()) {
+ $tmp += ['disabled' => 'disabled'];
+ }
+
+ if ($choice instanceof AttachmentType) {
+ $tmp += ['data-filetype_filter' => $choice->getFiletypeFilter()];
+ }
+
+ $level = $choice->getLevel();
+ /** @var AbstractStructuralDBElement|null $parent */
+ $parent = $options['subentities_of'] ?? null;
+ if (null !== $parent) {
+ $level -= $parent->getLevel() - 1;
+ }
+
+ $tmp += [
+ 'data-level' => $level,
+ 'data-parent' => $choice->getParent() ? $choice->getParent()->getFullPath() : null,
+ 'data-path' => $choice->getFullPath('->'),
+ ];
+ }
+
+ if ($choice instanceof HasMasterAttachmentInterface) {
+ $tmp['data-image'] = $choice->getMasterPictureAttachment() ?
+ $this->attachmentURLGenerator->getThumbnailURL($choice->getMasterPictureAttachment(),
+ 'thumbnail_xs')
+ : null
+ ;
+ }
+
if ($choice instanceof AttachmentType && !empty($choice->getFiletypeFilter())) {
$tmp += ['data-filetype_filter' => $choice->getFiletypeFilter()];
}
@@ -112,20 +129,20 @@ class StructuralEntityChoiceHelper
/**
* Returns the choice label for the given AbstractStructuralDBElement.
- * @param AbstractStructuralDBElement $choice
+ * @param AbstractNamedDBElement $choice
* @return string
*/
- public function generateChoiceLabel(AbstractStructuralDBElement $choice): string
+ public function generateChoiceLabel(AbstractNamedDBElement $choice): string
{
return $choice->getName();
}
/**
* Returns the choice value for the given AbstractStructuralDBElement.
- * @param AbstractStructuralDBElement|null $element
+ * @param AbstractNamedDBElement|null $element
* @return string|int|null
*/
- public function generateChoiceValue(?AbstractStructuralDBElement $element)
+ public function generateChoiceValue(?AbstractNamedDBElement $element)
{
if ($element === null) {
return null;
@@ -138,18 +155,21 @@ class StructuralEntityChoiceHelper
* So please do not change this!
*/
if ($element->getID() === null) {
- //Must be the same as the separator in the choice_loader, otherwise this will not work!
- return $element->getFullPath('->');
+ if ($element instanceof AbstractStructuralDBElement) {
+ //Must be the same as the separator in the choice_loader, otherwise this will not work!
+ return $element->getFullPath('->');
+ }
+ return $element->getName();
}
return $element->getID();
}
/**
- * @param AbstractStructuralDBElement $element
+ * @param AbstractDBElement $element
* @return string|null
*/
- public function generateGroupBy(AbstractStructuralDBElement $element): ?string
+ public function generateGroupBy(AbstractDBElement $element): ?string
{
//Show entities that are not added to DB yet separately from other entities
if ($element->getID() === null) {
diff --git a/src/Form/Type/StructuralEntityType.php b/src/Form/Type/StructuralEntityType.php
index 9c65a7ef..b58caef7 100644
--- a/src/Form/Type/StructuralEntityType.php
+++ b/src/Form/Type/StructuralEntityType.php
@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace App\Form\Type;
use App\Entity\Attachments\AttachmentType;
+use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\AbstractStructuralDBElement;
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
use App\Form\Type\Helper\StructuralEntityChoiceLoader;
@@ -105,7 +106,7 @@ class StructuralEntityType extends AbstractType
'show_fullpath_in_subtext' => true, //When this is enabled, the full path will be shown in subtext
'subentities_of' => null, //Only show entities with the given parent class
'disable_not_selectable' => false, //Disable entries with not selectable property
- 'choice_value' => function (?AbstractStructuralDBElement $element) {
+ 'choice_value' => function (?AbstractNamedDBElement $element) {
return $this->choice_helper->generateChoiceValue($element);
}, //Use the element id as option value and for comparing items
'choice_loader' => function (Options $options) {
@@ -121,7 +122,7 @@ class StructuralEntityType extends AbstractType
return $this->choice_helper->generateChoiceAttr($choice, $options);
};
},
- 'group_by' => function (AbstractStructuralDBElement $element) {
+ 'group_by' => function (AbstractNamedDBElement $element) {
return $this->choice_helper->generateGroupBy($element);
},
'choice_translation_domain' => false, //Don't translate the entity names
diff --git a/src/Form/Type/UserSelectType.php b/src/Form/Type/UserSelectType.php
new file mode 100644
index 00000000..c9c0830c
--- /dev/null
+++ b/src/Form/Type/UserSelectType.php
@@ -0,0 +1,47 @@
+.
+ */
+
+namespace App\Form\Type;
+
+use App\Entity\UserSystem\User;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\OptionsResolver\Options;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class UserSelectType extends AbstractType
+{
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults([
+ 'class' => User::class,
+ 'choice_label' => function (Options $options) {
+ return function (User $choice, $key, $value) {
+ return $choice->getFullName(true);
+ };
+ },
+ ]);
+ }
+
+ public function getParent()
+ {
+ return StructuralEntityType::class;
+ }
+}
\ No newline at end of file
diff --git a/src/Repository/NamedDBElementRepository.php b/src/Repository/NamedDBElementRepository.php
index aa89453d..8387d47c 100644
--- a/src/Repository/NamedDBElementRepository.php
+++ b/src/Repository/NamedDBElementRepository.php
@@ -59,4 +59,14 @@ class NamedDBElementRepository extends DBElementRepository
return $result;
}
+
+ /**
+ * Returns the list of all nodes to use in a select box.
+ * @return AbstractNamedDBElement[]
+ */
+ public function toNodesList(): array
+ {
+ //All nodes are sorted by name
+ return $this->findBy([], ['name' => 'ASC']);
+ }
}
diff --git a/src/Services/Trees/NodesListBuilder.php b/src/Services/Trees/NodesListBuilder.php
index ff8240e0..a7b70793 100644
--- a/src/Services/Trees/NodesListBuilder.php
+++ b/src/Services/Trees/NodesListBuilder.php
@@ -46,7 +46,7 @@ class NodesListBuilder
}
/**
- * Gets a flattened hierachical tree. Useful for generating option lists.
+ * Gets a flattened hierarchical tree. Useful for generating option lists.
* In difference to the Repository Function, the results here are cached.
*
* @param string $class_name the class name of the entity you want to retrieve
@@ -66,6 +66,7 @@ class NodesListBuilder
$item->tag(['groups', 'tree_list', $this->keyGenerator->generateKey(), $secure_class_name]);
/** @var StructuralDBElementRepository $repo */
$repo = $this->em->getRepository($class_name);
+
return $repo->toNodesList($parent);
});
}
diff --git a/templates/admin/storelocation_admin.html.twig b/templates/admin/storelocation_admin.html.twig
index 5932b715..4741c02d 100644
--- a/templates/admin/storelocation_admin.html.twig
+++ b/templates/admin/storelocation_admin.html.twig
@@ -25,6 +25,8 @@
{{ form_row(form.is_full) }}
{{ form_row(form.limit_to_existing_parts) }}
{{ form_row(form.only_single_part) }}
+ {{ form_row(form.owner) }}
+ {{ form_row(form.part_owner_must_match) }}
{% endblock %}
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index fd9e8582..637e578a 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -11205,5 +11205,17 @@ Element 3
About Me
+
+
+ storelocation.owner.label
+ Owner
+
+
+
+
+ storelocation.part_owner_must_match.label
+ Part Lot owner must match storage location owner
+
+