Moved getParts() and getPartsCount() to a repository (instead of a class method).

This commit is contained in:
Jan Böhmer 2020-05-16 20:53:35 +02:00
parent 350f1bb979
commit 14adb77a97
24 changed files with 421 additions and 71 deletions

View file

@ -45,6 +45,7 @@ namespace App\Controller\AdminPages;
use App\DataTables\LogDataTable; use App\DataTables\LogDataTable;
use App\Entity\Base\AbstractNamedDBElement; use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\AbstractStructuralDBElement; use App\Entity\Base\AbstractStructuralDBElement;
use App\Entity\Base\PartsContainingRepositoryInterface;
use App\Entity\LabelSystem\LabelProfile; use App\Entity\LabelSystem\LabelProfile;
use App\Entity\UserSystem\User; use App\Entity\UserSystem\User;
use App\Events\SecurityEvent; use App\Events\SecurityEvent;
@ -52,6 +53,7 @@ use App\Events\SecurityEvents;
use App\Exceptions\AttachmentDownloadException; use App\Exceptions\AttachmentDownloadException;
use App\Form\AdminPages\ImportType; use App\Form\AdminPages\ImportType;
use App\Form\AdminPages\MassCreationForm; use App\Form\AdminPages\MassCreationForm;
use App\Repository\AbstractPartsContainingRepository;
use App\Services\Attachments\AttachmentSubmitHandler; use App\Services\Attachments\AttachmentSubmitHandler;
use App\Services\EntityExporter; use App\Services\EntityExporter;
use App\Services\EntityImporter; use App\Services\EntityImporter;
@ -100,11 +102,13 @@ abstract class BaseAdminController extends AbstractController
protected $labelGenerator; protected $labelGenerator;
protected $barcodeExampleGenerator; protected $barcodeExampleGenerator;
protected $entityManager;
public function __construct(TranslatorInterface $translator, UserPasswordEncoderInterface $passwordEncoder, public function __construct(TranslatorInterface $translator, UserPasswordEncoderInterface $passwordEncoder,
AttachmentSubmitHandler $attachmentSubmitHandler, AttachmentSubmitHandler $attachmentSubmitHandler,
EventCommentHelper $commentHelper, HistoryHelper $historyHelper, TimeTravel $timeTravel, EventCommentHelper $commentHelper, HistoryHelper $historyHelper, TimeTravel $timeTravel,
DataTableFactory $dataTableFactory, EventDispatcherInterface $eventDispatcher, BarcodeExampleElementsGenerator $barcodeExampleGenerator, DataTableFactory $dataTableFactory, EventDispatcherInterface $eventDispatcher, BarcodeExampleElementsGenerator $barcodeExampleGenerator,
LabelGenerator $labelGenerator) LabelGenerator $labelGenerator, EntityManagerInterface $entityManager)
{ {
if ('' === $this->entity_class || '' === $this->form_class || '' === $this->twig_template || '' === $this->route_base) { if ('' === $this->entity_class || '' === $this->form_class || '' === $this->twig_template || '' === $this->route_base) {
throw new InvalidArgumentException('You have to override the $entity_class, $form_class, $route_base and $twig_template value in your subclasss!'); throw new InvalidArgumentException('You have to override the $entity_class, $form_class, $route_base and $twig_template value in your subclasss!');
@ -128,6 +132,7 @@ abstract class BaseAdminController extends AbstractController
$this->eventDispatcher = $eventDispatcher; $this->eventDispatcher = $eventDispatcher;
$this->barcodeExampleGenerator = $barcodeExampleGenerator; $this->barcodeExampleGenerator = $barcodeExampleGenerator;
$this->labelGenerator = $labelGenerator; $this->labelGenerator = $labelGenerator;
$this->entityManager = $entityManager;
} }
protected function _edit(AbstractNamedDBElement $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response protected function _edit(AbstractNamedDBElement $entity, Request $request, EntityManagerInterface $em, ?string $timestamp = null): Response
@ -237,6 +242,10 @@ abstract class BaseAdminController extends AbstractController
$pdf_data = $this->labelGenerator->generateLabel($entity->getOptions(), $example); $pdf_data = $this->labelGenerator->generateLabel($entity->getOptions(), $example);
} }
/** @var AbstractPartsContainingRepository $repo */
$repo = $this->entityManager->getRepository($this->entity_class);
return $this->render($this->twig_template, [ return $this->render($this->twig_template, [
'entity' => $entity, 'entity' => $entity,
'form' => $form->createView(), 'form' => $form->createView(),
@ -244,6 +253,7 @@ abstract class BaseAdminController extends AbstractController
'datatable' => $table, 'datatable' => $table,
'pdf_data' => $pdf_data ?? null, 'pdf_data' => $pdf_data ?? null,
'timeTravel' => $timeTravel_timestamp, 'timeTravel' => $timeTravel_timestamp,
'repo' => $repo,
]); ]);
} }
@ -357,6 +367,7 @@ abstract class BaseAdminController extends AbstractController
$em->flush(); $em->flush();
} }
return $this->render($this->twig_template, [ return $this->render($this->twig_template, [
'entity' => $new_entity, 'entity' => $new_entity,
'form' => $form->createView(), 'form' => $form->createView(),

View file

@ -48,6 +48,7 @@ use App\Entity\Parts\Footprint;
use App\Entity\Parts\Manufacturer; use App\Entity\Parts\Manufacturer;
use App\Entity\Parts\Storelocation; use App\Entity\Parts\Storelocation;
use App\Entity\Parts\Supplier; use App\Entity\Parts\Supplier;
use Doctrine\ORM\EntityManagerInterface;
use Omines\DataTablesBundle\DataTableFactory; use Omines\DataTablesBundle\DataTableFactory;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
@ -57,6 +58,13 @@ use Symfony\Component\Routing\Annotation\Route;
class PartListsController extends AbstractController class PartListsController extends AbstractController
{ {
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
/** /**
* @Route("/category/{id}/parts", name="part_list_category") * @Route("/category/{id}/parts", name="part_list_category")
* *
@ -74,6 +82,7 @@ class PartListsController extends AbstractController
return $this->render('Parts/lists/category_list.html.twig', [ return $this->render('Parts/lists/category_list.html.twig', [
'datatable' => $table, 'datatable' => $table,
'entity' => $category, 'entity' => $category,
'repo' => $this->entityManager->getRepository(Category::class),
]); ]);
} }
@ -94,6 +103,7 @@ class PartListsController extends AbstractController
return $this->render('Parts/lists/footprint_list.html.twig', [ return $this->render('Parts/lists/footprint_list.html.twig', [
'datatable' => $table, 'datatable' => $table,
'entity' => $footprint, 'entity' => $footprint,
'repo' => $this->entityManager->getRepository(Footprint::class),
]); ]);
} }
@ -114,6 +124,7 @@ class PartListsController extends AbstractController
return $this->render('Parts/lists/manufacturer_list.html.twig', [ return $this->render('Parts/lists/manufacturer_list.html.twig', [
'datatable' => $table, 'datatable' => $table,
'entity' => $manufacturer, 'entity' => $manufacturer,
'repo' => $this->entityManager->getRepository(Manufacturer::class),
]); ]);
} }
@ -134,6 +145,7 @@ class PartListsController extends AbstractController
return $this->render('Parts/lists/store_location_list.html.twig', [ return $this->render('Parts/lists/store_location_list.html.twig', [
'datatable' => $table, 'datatable' => $table,
'entity' => $storelocation, 'entity' => $storelocation,
'repo' => $this->entityManager->getRepository(Storelocation::class),
]); ]);
} }
@ -154,6 +166,7 @@ class PartListsController extends AbstractController
return $this->render('Parts/lists/supplier_list.html.twig', [ return $this->render('Parts/lists/supplier_list.html.twig', [
'datatable' => $table, 'datatable' => $table,
'entity' => $supplier, 'entity' => $supplier,
'repo' => $this->entityManager->getRepository(Supplier::class),
]); ]);
} }

View file

@ -30,28 +30,9 @@ use Doctrine\ORM\Mapping as ORM;
/** /**
* Class PartsContainingDBElement. * Class PartsContainingDBElement.
* *
* @ORM\MappedSuperclass() * @ORM\MappedSuperclass(repositoryClass="App\Repository\AbstractPartsContainingRepository")
*/ */
abstract class AbstractPartsContainingDBElement extends AbstractStructuralDBElement abstract class AbstractPartsContainingDBElement extends AbstractStructuralDBElement
{ {
/**
* @var Part[]|Collection
*/
protected $parts;
public function __construct()
{
parent::__construct();
$this->parts = new ArrayCollection();
}
/**
* Returns the parts associated with this element.
*
* @return Collection|Part[]
*/
public function getParts(): Collection
{
return $this->parts;
}
} }

View file

@ -0,0 +1,43 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Entity\Base;
use App\Entity\Parts\Part;
use Doctrine\Common\Collections\Collection;
interface PartsContainingRepositoryInterface
{
/**
* Returns all parts associated with this element.
* @param object $element The element for which the parts should be determined.
* @param array $order_by The order of the parts. Format ['name' => 'ASC']
* @return Part[]
*/
public function getParts(object $element, array $order_by = ['name' => 'ASC']): array;
/**
* Gets the count of the parts associated with this element.
* @param object $element The element for which the parts should be determined.
* @return int
*/
public function getPartsCount(object $element): int;
}

View file

@ -32,7 +32,7 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class AttachmentType. * Class AttachmentType.
* *
* @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository") * @ORM\Entity(repositoryClass="App\Repository\Parts\CategoryRepository")
* @ORM\Table(name="`categories`") * @ORM\Table(name="`categories`")
*/ */
class Category extends AbstractPartsContainingDBElement class Category extends AbstractPartsContainingDBElement
@ -49,11 +49,6 @@ class Category extends AbstractPartsContainingDBElement
*/ */
protected $parent; protected $parent;
/**
* @ORM\OneToMany(targetEntity="Part", mappedBy="category", fetch="EXTRA_LAZY")
*/
protected $parts;
/** /**
* @var string * @var string
* @ORM\Column(type="text") * @ORM\Column(type="text")

View file

@ -60,7 +60,7 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class Footprint. * Class Footprint.
* *
* @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository") * @ORM\Entity(repositoryClass="App\Repository\Parts\FootprintRepository")
* @ORM\Table("`footprints`") * @ORM\Table("`footprints`")
*/ */
class Footprint extends AbstractPartsContainingDBElement class Footprint extends AbstractPartsContainingDBElement
@ -77,10 +77,6 @@ class Footprint extends AbstractPartsContainingDBElement
*/ */
protected $children; protected $children;
/**
* @ORM\OneToMany(targetEntity="Part", mappedBy="footprint", fetch="EXTRA_LAZY")
*/
protected $parts;
/** /**
* @var Collection<int, FootprintAttachment> * @var Collection<int, FootprintAttachment>
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\FootprintAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\OneToMany(targetEntity="App\Entity\Attachments\FootprintAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)

View file

@ -60,7 +60,7 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class Manufacturer. * Class Manufacturer.
* *
* @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository") * @ORM\Entity(repositoryClass="App\Repository\Parts\ManufacturerRepository")
* @ORM\Table("`manufacturers`") * @ORM\Table("`manufacturers`")
*/ */
class Manufacturer extends AbstractCompany class Manufacturer extends AbstractCompany
@ -77,10 +77,6 @@ class Manufacturer extends AbstractCompany
*/ */
protected $children; protected $children;
/**
* @ORM\OneToMany(targetEntity="Part", mappedBy="manufacturer", fetch="EXTRA_LAZY")
*/
protected $parts;
/** /**
* @var Collection<int, ManufacturerAttachment> * @var Collection<int, ManufacturerAttachment>
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)

View file

@ -54,7 +54,7 @@ use Symfony\Component\Validator\Constraints as Assert;
* This unit represents the unit in which the amount of parts in stock are measured. * This unit represents the unit in which the amount of parts in stock are measured.
* This could be something like N, grams, meters, etc... * This could be something like N, grams, meters, etc...
* *
* @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository") * @ORM\Entity(repositoryClass="App\Repository\Parts\MeasurementUnitRepository")
* @ORM\Table(name="`measurement_units`") * @ORM\Table(name="`measurement_units`")
* @UniqueEntity("unit") * @UniqueEntity("unit")
*/ */
@ -94,10 +94,6 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
*/ */
protected $parent; protected $parent;
/**
* @ORM\OneToMany(targetEntity="Part", mappedBy="partUnit", fetch="EXTRA_LAZY")
*/
protected $parts;
/** /**
* @var Collection<int, MeasurementUnitAttachment> * @var Collection<int, MeasurementUnitAttachment>
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\MeasurementUnitAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\OneToMany(targetEntity="App\Entity\Attachments\MeasurementUnitAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)

View file

@ -114,7 +114,7 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface, Named
/** /**
* @var Part The part that is stored in this lot * @var Part The part that is stored in this lot
* @ORM\ManyToOne(targetEntity="Part", inversedBy="partLots") * @ORM\ManyToOne(targetEntity="Part")
* @ORM\JoinColumn(name="id_part", referencedColumnName="id", nullable=false, onDelete="CASCADE") * @ORM\JoinColumn(name="id_part", referencedColumnName="id", nullable=false, onDelete="CASCADE")
* @Assert\NotNull() * @Assert\NotNull()
*/ */

View file

@ -79,7 +79,7 @@ trait BasicPropertyTrait
/** /**
* @var Category The category this part belongs too (e.g. Resistors). Use tags, for more complex grouping. * @var Category The category this part belongs too (e.g. Resistors). Use tags, for more complex grouping.
* Every part must have a category. * Every part must have a category.
* @ORM\ManyToOne(targetEntity="Category", inversedBy="parts") * @ORM\ManyToOne(targetEntity="Category")
* @ORM\JoinColumn(name="id_category", referencedColumnName="id", nullable=false) * @ORM\JoinColumn(name="id_category", referencedColumnName="id", nullable=false)
* @ColumnSecurity(prefix="category", type="App\Entity\Parts\Category") * @ColumnSecurity(prefix="category", type="App\Entity\Parts\Category")
* @Selectable() * @Selectable()
@ -88,7 +88,7 @@ trait BasicPropertyTrait
/** /**
* @var Footprint|null The footprint of this part (e.g. DIP8) * @var Footprint|null The footprint of this part (e.g. DIP8)
* @ORM\ManyToOne(targetEntity="Footprint", inversedBy="parts") * @ORM\ManyToOne(targetEntity="Footprint")
* @ORM\JoinColumn(name="id_footprint", referencedColumnName="id") * @ORM\JoinColumn(name="id_footprint", referencedColumnName="id")
* @ColumnSecurity(prefix="footprint", type="App\Entity\Parts\Footprint") * @ColumnSecurity(prefix="footprint", type="App\Entity\Parts\Footprint")
* @Selectable() * @Selectable()

View file

@ -72,7 +72,7 @@ trait InstockTrait
/** /**
* @var ?MeasurementUnit the unit in which the part's amount is measured * @var ?MeasurementUnit the unit in which the part's amount is measured
* @ORM\ManyToOne(targetEntity="MeasurementUnit", inversedBy="parts") * @ORM\ManyToOne(targetEntity="MeasurementUnit")
* @ORM\JoinColumn(name="id_part_unit", referencedColumnName="id", nullable=true) * @ORM\JoinColumn(name="id_part_unit", referencedColumnName="id", nullable=true)
* @ColumnSecurity(type="object", prefix="unit") * @ColumnSecurity(type="object", prefix="unit")
*/ */

View file

@ -54,7 +54,7 @@ trait ManufacturerTrait
{ {
/** /**
* @var Manufacturer|null The manufacturer of this part * @var Manufacturer|null The manufacturer of this part
* @ORM\ManyToOne(targetEntity="Manufacturer", inversedBy="parts") * @ORM\ManyToOne(targetEntity="Manufacturer")
* @ORM\JoinColumn(name="id_manufacturer", referencedColumnName="id") * @ORM\JoinColumn(name="id_manufacturer", referencedColumnName="id")
* @ColumnSecurity(prefix="manufacturer", type="App\Entity\Parts\Manufacturer") * @ColumnSecurity(prefix="manufacturer", type="App\Entity\Parts\Manufacturer")
* @Selectable() * @Selectable()

View file

@ -60,7 +60,7 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class Store location. * Class Store location.
* *
* @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository") * @ORM\Entity(repositoryClass="App\Repository\Parts\StorelocationRepository")
* @ORM\Table("`storelocations`") * @ORM\Table("`storelocations`")
*/ */
class Storelocation extends AbstractPartsContainingDBElement class Storelocation extends AbstractPartsContainingDBElement
@ -84,15 +84,6 @@ class Storelocation extends AbstractPartsContainingDBElement
*/ */
protected $storage_type; protected $storage_type;
/**
* @ORM\ManyToMany(targetEntity="Part", fetch="EXTRA_LAZY")
* @ORM\JoinTable(name="part_lots",
* joinColumns={@ORM\JoinColumn(name="id_store_location", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="id_part", referencedColumnName="id")}
* )
*/
protected $parts;
/** @var Collection<int, StorelocationParameter> /** @var Collection<int, StorelocationParameter>
* @ORM\OneToMany(targetEntity="App\Entity\Parameters\StorelocationParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\OneToMany(targetEntity="App\Entity\Parameters\StorelocationParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"}) * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})

View file

@ -62,7 +62,7 @@ use Symfony\Component\Validator\Constraints as Assert;
/** /**
* Class Supplier. * Class Supplier.
* *
* @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository") * @ORM\Entity(repositoryClass="App\Repository\Parts\SupplierRepository")
* @ORM\Table("`suppliers`") * @ORM\Table("`suppliers`")
*/ */
class Supplier extends AbstractCompany class Supplier extends AbstractCompany
@ -100,15 +100,6 @@ class Supplier extends AbstractCompany
*/ */
protected $shipping_costs; protected $shipping_costs;
/**
* @ORM\ManyToMany(targetEntity="Part", fetch="EXTRA_LAZY")
* @ORM\JoinTable(name="orderdetails",
* joinColumns={@ORM\JoinColumn(name="id_supplier", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="part_id", referencedColumnName="id")}
* )
*/
protected $parts;
/** /**
* @var Collection<int, SupplierAttachment> * @var Collection<int, SupplierAttachment>
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\SupplierAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\OneToMany(targetEntity="App\Entity\Attachments\SupplierAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)

View file

@ -0,0 +1,70 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Repository;
use App\Entity\Base\AbstractPartsContainingDBElement;
use App\Entity\Base\PartsContainingRepositoryInterface;
use App\Entity\Parts\Part;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
abstract class AbstractPartsContainingRepository extends StructuralDBElementRepository
implements PartsContainingRepositoryInterface
{
/**
* Returns all parts associated with this element.
* @param AbstractPartsContainingDBElement $element The element for which the parts should be determined.
* @param array $order_by The order of the parts. Format ['name' => 'ASC']
* @return Part[]
*/
abstract public function getParts(object $element, array $order_by = ['name' => 'ASC']): array;
/**
* Gets the count of the parts associated with this element.
* @param AbstractPartsContainingDBElement $element The element for which the parts should be determined.
* @return int
*/
abstract public function getPartsCount(object $element): int;
protected function getPartsByField(object $element, array $order_by, string $field_name): array
{
if (!$element instanceof AbstractPartsContainingDBElement) {
throw new \InvalidArgumentException('$element must be an instance of AbstractPartContainingDBElement!');
}
$repo = $this->getEntityManager()->getRepository(Part::class);
return $repo->findBy([$field_name => $element], $order_by);
}
protected function getPartsCountByField(object $element, string $field_name): int
{
if (!$element instanceof AbstractPartsContainingDBElement) {
throw new \InvalidArgumentException('$element must be an instance of AbstractPartContainingDBElement!');
}
$repo = $this->getEntityManager()->getRepository(Part::class);
return $repo->count([$field_name => $element]);
}
}

View file

@ -0,0 +1,37 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Repository\Parts;
use App\Repository\AbstractPartsContainingRepository;
class CategoryRepository extends AbstractPartsContainingRepository
{
public function getParts(object $element, array $order_by = ['name' => 'ASC']): array
{
return $this->getPartsByField($element, $order_by, 'category');
}
public function getPartsCount(object $element): int
{
return $this->getPartsCountByField($element, 'category');
}
}

View file

@ -0,0 +1,36 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Repository\Parts;
use App\Repository\AbstractPartsContainingRepository;
class FootprintRepository extends AbstractPartsContainingRepository
{
public function getParts(object $element, array $order_by = ['name' => 'ASC']): array
{
return $this->getPartsByField($element, $order_by, 'footprint');
}
public function getPartsCount(object $element): int
{
return $this->getPartsCountByField($element, 'footprint');
}
}

View file

@ -0,0 +1,37 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Repository\Parts;
use App\Repository\AbstractPartsContainingRepository;
class ManufacturerRepository extends AbstractPartsContainingRepository
{
public function getParts(object $element, array $order_by = ['name' => 'ASC']): array
{
return $this->getPartsByField($element, $order_by, 'manufacturer');
}
public function getPartsCount(object $element): int
{
return $this->getPartsCountByField($element, 'manufacturer');
}
}

View file

@ -0,0 +1,37 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Repository\Parts;
use App\Repository\AbstractPartsContainingRepository;
class MeasurementUnitRepository extends AbstractPartsContainingRepository
{
public function getParts(object $element, array $order_by = ['name' => 'ASC']): array
{
return $this->getPartsByField($element, $order_by, 'partUnit');
}
public function getPartsCount(object $element): int
{
return $this->getPartsCountByField($element, 'partUnit');
}
}

View file

@ -0,0 +1,59 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Repository\Parts;
use App\Entity\Parts\Part;
use App\Repository\AbstractPartsContainingRepository;
use Doctrine\ORM\QueryBuilder;
class StorelocationRepository extends AbstractPartsContainingRepository
{
public function getParts(object $element, array $order_by = ['name' => 'ASC']): array
{
$qb = new QueryBuilder($this->getEntityManager());
$qb->select('part')
->from(Part::class, 'part')
->leftJoin('part.partLots', 'lots')
->where('lots.storage_location = ?1')
->setParameter(1, $element);
foreach ($order_by as $field => $order) {
$qb->addOrderBy('part.' . $field, $order);
}
return $qb->getQuery()->getResult();
}
public function getPartsCount(object $element): int
{
$qb = new QueryBuilder($this->getEntityManager());
$qb->select('COUNT(part.id)')
->from(Part::class, 'part')
->leftJoin('part.partLots', 'lots')
->where('lots.storage_location = ?1')
->setParameter(1, $element);
return (int) $qb->getQuery()->getSingleScalarResult();
}
}

View file

@ -0,0 +1,59 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Repository\Parts;
use App\Entity\Parts\Part;
use App\Repository\AbstractPartsContainingRepository;
use Doctrine\ORM\QueryBuilder;
class SupplierRepository extends AbstractPartsContainingRepository
{
public function getParts(object $element, array $order_by = ['name' => 'ASC']): array
{
$qb = new QueryBuilder($this->getEntityManager());
$qb->select('part')
->from(Part::class, 'part')
->leftJoin('part.orderdetails', 'orderdetail')
->where('orderdetail.supplier = ?1')
->setParameter(1, $element);
foreach ($order_by as $field => $order) {
$qb->addOrderBy('part.' . $field, $order);
}
return $qb->getQuery()->getResult();
}
public function getPartsCount(object $element): int
{
$qb = new QueryBuilder($this->getEntityManager());
$qb->select('COUNT(part.id)')
->from(Part::class, 'part')
->leftJoin('part.orderdetails', 'orderdetail')
->where('orderdetail.supplier = ?1')
->setParameter(1, $element);
return (int) $qb->getQuery()->getSingleScalarResult();
}
}

View file

@ -43,6 +43,7 @@ declare(strict_types=1);
namespace App\Validator\Constraints; namespace App\Validator\Constraints;
use App\Entity\Parts\PartLot; use App\Entity\Parts\PartLot;
use App\Entity\Parts\Storelocation;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\Exception\UnexpectedTypeException; use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraint;
@ -75,7 +76,8 @@ class ValidPartLotValidator extends ConstraintValidator
//We can only validate the values if we know the storelocation //We can only validate the values if we know the storelocation
if ($value->getStorageLocation()) { if ($value->getStorageLocation()) {
$parts = $value->getStorageLocation()->getParts(); $repo = $this->em->getRepository(Storelocation::class);
$parts = $repo->getParts($value);
//Check for isFull() attribute //Check for isFull() attribute
if ($value->getStorageLocation()->isFull()) { if ($value->getStorageLocation()->isFull()) {

View file

@ -38,8 +38,8 @@
<label class="col-form-label col-md-3">{% trans %}entity.info.parts_count{% endtrans %}</label> <label class="col-form-label col-md-3">{% trans %}entity.info.parts_count{% endtrans %}</label>
<div class="col-md-9"> <div class="col-md-9">
<p class="form-control-static"> <p class="form-control-static">
{% if entity.id and entity.parts is defined %} {% if entity.id and repo.partsCount is defined %}
{{ entity.parts | length }} {{ repo.partsCount(entity) }}
{% else %} {% else %}
- -
{% endif %} {% endif %}

View file

@ -94,7 +94,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-4">{% trans %}entity.info.parent{% endtrans %}:</label> <label class="col-sm-4">{% trans %}entity.info.parent{% endtrans %}:</label>
<span class="col-sm form-control-static">{{ entity.parts | length }}</span> <span class="col-sm form-control-static">{{ repo.partsCount(entity) }}</span>
</div> </div>
</div> </div>
</div> </div>