diff --git a/src/Controller/PartController.php b/src/Controller/PartController.php index 96403729..4f34a4c6 100644 --- a/src/Controller/PartController.php +++ b/src/Controller/PartController.php @@ -82,7 +82,7 @@ class PartController extends AbstractController return $this->render('Parts/edit/edit_part_info.html.twig', [ 'part' => $part, - 'form_main' => $form->createView(), + 'form' => $form->createView(), ]); } diff --git a/src/Entity/Parts/Part.php b/src/Entity/Parts/Part.php index 93d6123a..df4b794c 100644 --- a/src/Entity/Parts/Part.php +++ b/src/Entity/Parts/Part.php @@ -179,7 +179,8 @@ class Part extends AttachmentContainingDBElement /** * @var ?PartLot[] - * @ORM\OneToMany(targetEntity="PartLot", mappedBy="part") + * @ORM\OneToMany(targetEntity="PartLot", mappedBy="part", cascade={"persist", "remove"}, orphanRemoval=true) + * @Assert\Valid() */ protected $partLots; @@ -593,6 +594,18 @@ class Part extends AttachmentContainingDBElement return $this->partLots; } + public function addPartLot(PartLot $lot): Part + { + $lot->setPart($this); + $this->partLots->add($lot); + return $this; + } + + public function removePartLot(PartLot $lot): Part + { + $this->partLots->removeElement($lot); + return $this; + } /** * Returns the assigned manufacturer product number (MPN) for this part. diff --git a/src/Entity/Parts/PartLot.php b/src/Entity/Parts/PartLot.php index 636ac1e8..6d9bdb2c 100644 --- a/src/Entity/Parts/PartLot.php +++ b/src/Entity/Parts/PartLot.php @@ -56,13 +56,13 @@ class PartLot extends DBElement * @var string A short description about this lot, shown in table * @ORM\Column(type="text") */ - protected $description; + protected $description = ""; /** * @var string A comment stored with this lot. * @ORM\Column(type="text") */ - protected $comment; + protected $comment = ""; /** * @var ?\DateTime Set a time until when the lot must be used. @@ -90,21 +90,21 @@ class PartLot extends DBElement * @var bool If this is set to true, the instock amount is marked as not known * @ORM\Column(type="boolean") */ - protected $instock_unknown; + protected $instock_unknown = false; /** * @var float For continuos sizes (length, volume, etc.) the instock is saved here. * @ORM\Column(type="float") - * @Assert\Positive() + * @Assert\PositiveOrZero() */ - protected $amount; + protected $amount = 0; /** * @var boolean Determines if this lot was manually marked for refilling. * @ORM\Column(type="boolean") */ - protected $needs_refill; + protected $needs_refill = false; /** * Returns the ID as an string, defined by the element class. @@ -198,7 +198,7 @@ class PartLot extends DBElement * Gets the storage locatiion, where this part lot is stored. * @return Storelocation The store location where this part is stored */ - public function getStorageLocation(): Storelocation + public function getStorageLocation(): ?Storelocation { return $this->storage_location; } @@ -260,7 +260,7 @@ class PartLot extends DBElement */ public function getAmount(): float { - if (!$this->part->useFloatAmount()) { + if ($this->part instanceof Part && !$this->part->useFloatAmount()) { return round($this->amount); } return (float) $this->amount; @@ -269,6 +269,7 @@ class PartLot extends DBElement public function setAmount(float $new_amount): PartLot { $this->amount = $new_amount; + return $this; } diff --git a/src/Form/Part/PartBaseType.php b/src/Form/Part/PartBaseType.php index 83435f4b..ad8fe5bf 100644 --- a/src/Form/Part/PartBaseType.php +++ b/src/Form/Part/PartBaseType.php @@ -43,6 +43,7 @@ use FOS\CKEditorBundle\Form\Type\CKEditorType; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; +use Symfony\Component\Form\Extension\Core\Type\CollectionType; use Symfony\Component\Form\Extension\Core\Type\NumberType; use Symfony\Component\Form\Extension\Core\Type\UrlType; use Symfony\Component\Form\FormBuilderInterface; @@ -119,14 +120,18 @@ class PartBaseType extends AbstractType ->add('favorite', CheckboxType::class, ['label_attr'=> ['class' => 'checkbox-custom'], 'required' => false, 'label' => 'part.edit.is_favorite']); + //Part Lots section + $builder->add('partLots', CollectionType::class, [ + 'entry_type' => PartLotType::class, + 'allow_add' => true, 'allow_delete' => true, + 'label' => false, + 'by_reference' => false + ]); + $builder //Buttons - ->add('save1', SubmitType::class, ['label' => 'part.edit.save']) - ->add('reset1', ResetType::class, ['label' => 'part.edit.reset']) - ->add('save2', SubmitType::class, ['label' => 'part.edit.save']) - ->add('reset2', ResetType::class, ['label' => 'part.edit.reset']) - ->add('save3', SubmitType::class, ['label' => 'part.edit.save']) - ->add('reset3', ResetType::class, ['label' => 'part.edit.reset']); + ->add('save', SubmitType::class, ['label' => 'part.edit.save']) + ->add('reset', ResetType::class, ['label' => 'part.edit.reset']); } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Form/Part/PartLotType.php b/src/Form/Part/PartLotType.php new file mode 100644 index 00000000..d012f7f0 --- /dev/null +++ b/src/Form/Part/PartLotType.php @@ -0,0 +1,90 @@ +add('description', TextType::class, ['label' => 'part_lot.edit.description', + 'required' => false, 'empty_data' => "", 'attr' => ['class' => 'form-control-sm']]); + + $builder->add('storage_location', StructuralEntityType::class, ['class' => Storelocation::class, + 'label' => 'part_lot.edit.location', + 'disable_not_selectable' => true, 'attr' => ['class' => 'form-control-sm']]); + + $builder->add('amount',NumberType::class, [ 'html5' => true, + 'label' => 'part_lot.edit.amount', + 'attr' => ['class' => 'form-control-sm', 'min' => 0, 'step' => 'any'] + ]); + $builder->add('instock_unknown', CheckboxType::class, ['required' => false, + 'label' => 'part_lot.edit.instock_unknown', + 'attr' => ['class' => 'form-control-sm'], + 'label_attr'=> ['class' => 'checkbox-custom']]); + $builder->add('needs_refill', CheckboxType::class, ['label_attr'=> ['class' => 'checkbox-custom'], + 'label' => 'part_lot.edit.needs_refill', + 'attr' => ['class' => 'form-control-sm'], + 'required' => false]); + $builder->add('expirationDate', DateTimeType::class, [ + 'label' => 'part_lot.edit.expiration_date', + 'attr' => [], + 'required' => false]); + + $builder->add('comment', TextType::class, ['label' => 'part_lot.edit.comment', + 'label' => 'part_lot.edit.comment', + 'attr' => ['class' => 'form-control-sm'], + 'required' => false, 'empty_data' => ""]); + } + + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => PartLot::class, + ]); + } +} \ No newline at end of file diff --git a/templates/Parts/edit/_lots.html.twig b/templates/Parts/edit/_lots.html.twig new file mode 100644 index 00000000..4ec4f5a3 --- /dev/null +++ b/templates/Parts/edit/_lots.html.twig @@ -0,0 +1,60 @@ +{% set delete_btn %} + +{% endset %} + + + + + {% for lot in form.partLots %} + + + + + {% endfor %} + +
+ {{ form_widget(lot) }} + + {{ delete_btn }} +
+ + + + \ No newline at end of file diff --git a/templates/Parts/edit/_main.html.twig b/templates/Parts/edit/_main.html.twig index 687f3dbf..00ba6ebc 100644 --- a/templates/Parts/edit/_main.html.twig +++ b/templates/Parts/edit/_main.html.twig @@ -1,13 +1,11 @@ -{{ form_row(form_main.name) }} -{{ form_row(form_main.description) }} -{{ form_row(form_main.category) }} -{{ form_row(form_main.tags) }} -{{ form_row(form_main.minAmount) }} -{{ form_row(form_main.partUnit)}} +{{ form_row(form.name) }} +{{ form_row(form.description) }} +{{ form_row(form.category) }} +{{ form_row(form.tags) }} +{{ form_row(form.minAmount) }} +{{ form_row(form.partUnit)}} -{{ form_row(form_main.footprint) }} +{{ form_row(form.footprint) }} -{{ form_row(form_main.comment) }} +{{ form_row(form.comment) }} -{{ form_row(form_main.save1) }} -{{ form_row(form_main.reset1) }} \ No newline at end of file diff --git a/templates/Parts/edit/_manufacturer.html.twig b/templates/Parts/edit/_manufacturer.html.twig index efe1f515..c25080d8 100644 --- a/templates/Parts/edit/_manufacturer.html.twig +++ b/templates/Parts/edit/_manufacturer.html.twig @@ -1,6 +1,3 @@ -{{ form_row(form_main.manufacturer) }} -{{ form_row(form_main.manufacturer_product_number) }} -{{ form_row(form_main.manufacturer_product_url)}} - -{{ form_row(form_main.save2) }} -{{ form_row(form_main.reset2) }} \ No newline at end of file +{{ form_row(form.manufacturer) }} +{{ form_row(form.manufacturer_product_number) }} +{{ form_row(form.manufacturer_product_url)}} \ No newline at end of file diff --git a/templates/Parts/edit/_options.html.twig b/templates/Parts/edit/_options.html.twig index 56c1ca7a..db4abc1c 100644 --- a/templates/Parts/edit/_options.html.twig +++ b/templates/Parts/edit/_options.html.twig @@ -1,5 +1,2 @@ -{{ form_row(form_main.needsReview) }} -{{ form_row(form_main.favorite) }} - -{{ form_row(form_main.save3) }} -{{ form_row(form_main.reset3) }} \ No newline at end of file +{{ form_row(form.needsReview) }} +{{ form_row(form.favorite) }} \ No newline at end of file diff --git a/templates/Parts/edit/edit_part_info.html.twig b/templates/Parts/edit/edit_part_info.html.twig index 6ae1bdd6..6ea076d0 100644 --- a/templates/Parts/edit/edit_part_info.html.twig +++ b/templates/Parts/edit/edit_part_info.html.twig @@ -17,18 +17,34 @@ + {{ form_start(form) }}
- {{ form_start(form_main) }} +
{% include "Parts/edit/_main.html.twig" %}
@@ -38,8 +54,14 @@
{% include "Parts/edit/_options.html.twig" %}
- {{ form_end(form_main) }} +
+ {% include "Parts/edit/_lots.html.twig" %} +
+
+ {{ form_row(form.save) }} + {{ form_row(form.reset) }} + {{ form_end(form) }} {% endblock %} \ No newline at end of file diff --git a/templates/Parts/edit/new_part.html.twig b/templates/Parts/edit/new_part.html.twig index 2d67795f..7cd490af 100644 --- a/templates/Parts/edit/new_part.html.twig +++ b/templates/Parts/edit/new_part.html.twig @@ -1,4 +1,4 @@ -{% extends "Parts/edit_part_info.html.twig" %} +{% extends "Parts/edit/edit_part_info.html.twig" %} {% block card_border %}border-success{% endblock %} {% block card_type %}bg-success text-white{% endblock %}