partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

PartService.php (6254B)


      1 <?php
      2 
      3 namespace PartKeepr\PartBundle\Services;
      4 
      5 use Doctrine\ORM\EntityManager;
      6 use PartKeepr\DoctrineReflectionBundle\Filter\Filter;
      7 use PartKeepr\DoctrineReflectionBundle\Services\FilterService;
      8 use PartKeepr\PartBundle\Entity\Part;
      9 use PartKeepr\PartBundle\Entity\PartParameter;
     10 use PartKeepr\PartBundle\Exceptions\NotAMetaPartException;
     11 
     12 class PartService
     13 {
     14     /**
     15      * The maximum number of parts allowed.
     16      *
     17      * @var int|bool
     18      */
     19     private $partLimit;
     20 
     21     /**
     22      * Whether to check if the internal part number is unique or not.
     23      *
     24      * @var bool
     25      */
     26     private $checkInternalPartNumberUniqueness;
     27 
     28     /**
     29      * @var EntityManager
     30      */
     31     private $entityManager;
     32 
     33     /**
     34      * @var FilterService
     35      */
     36     private $filterService;
     37 
     38     public function __construct(
     39         EntityManager $entityManager,
     40         FilterService $filterService,
     41         $partLimit = false,
     42         $checkInternalPartNumberUniqueness = false
     43     ) {
     44         $this->entityManager = $entityManager;
     45         $this->filterService = $filterService;
     46         $this->partLimit = $partLimit;
     47         $this->checkInternalPartNumberUniqueness = $checkInternalPartNumberUniqueness;
     48     }
     49 
     50     /**
     51      * Returns the number of parts present in the system.
     52      *
     53      * @return mixed
     54      */
     55     public function getPartCount()
     56     {
     57         $dql = 'SELECT COUNT(p) FROM PartKeepr\\PartBundle\\Entity\\Part p';
     58         $query = $this->entityManager->createQuery($dql);
     59 
     60         return $query->getSingleScalarResult();
     61     }
     62 
     63     /**
     64      * Checks if the given internal part number is unique.
     65      *
     66      * @param string    $internalPartNumber The internal part number to checkl
     67      * @param Part|null $part               An optional part to exclude within the check
     68      *
     69      * @return bool
     70      */
     71     public function isInternalPartNumberUnique($internalPartNumber, Part $part = null)
     72     {
     73         if (!$this->checkInternalPartNumberUniqueness) {
     74             return true;
     75         }
     76 
     77         /**
     78          * Empty internal part numbers aren't checked. If you want to require an internal part number, set the
     79          * field internalPartNumber to mandatory.
     80          */
     81         if ($internalPartNumber == "") {
     82             return true;
     83         }
     84 
     85         $dql = 'SELECT COUNT(p) FROM PartKeepr\\PartBundle\\Entity\\Part p WHERE p.internalPartNumber = :internalPartNumber';
     86 
     87         if ($part !== null) {
     88             $dql .= " AND p.id != :partId";
     89         }
     90 
     91         $query = $this->entityManager->createQuery($dql)->setParameter('internalPartNumber', $internalPartNumber);
     92 
     93         if ($part !== null) {
     94             $query->setParameter('partId', $part->getId());
     95         }
     96 
     97         return $query->getSingleScalarResult() == 0 ? true : false;
     98     }
     99 
    100     /**
    101      * Checks if the amount of parts is exceeded.
    102      *
    103      * @return bool
    104      */
    105     public function checkPartLimit()
    106     {
    107         if ($this->partLimit !== false && $this->partLimit != "-1") {
    108             if ($this->getPartCount() >= $this->partLimit) {
    109                 return true;
    110             }
    111         }
    112 
    113         return false;
    114     }
    115 
    116     /**
    117      * Returns the matching parts for a given meta part.
    118      *
    119      * @param Part $metaPart
    120      *
    121      * @return Part[]
    122      */
    123     public function getMatchingMetaParts(Part $metaPart)
    124     {
    125         $paramCount = 0;
    126         $paramPrefix = ":param";
    127         $results = [];
    128 
    129         if (!$metaPart->isMetaPart()) {
    130             throw new NotAMetaPartException();
    131         }
    132 
    133         foreach ($metaPart->getMetaPartParameterCriterias() as $metaPartParameterCriteria) {
    134             $qb = $this->entityManager->createQueryBuilder();
    135             $qb->select("p.id AS id")
    136                 ->from("PartKeeprPartBundle:PartParameter", "pp")
    137                 ->join("pp.part", "p")
    138                 ->where("1=1");
    139 
    140             $filter = new Filter();
    141             $filter->setOperator($metaPartParameterCriteria->getOperator());
    142             $filter->setProperty("name");
    143 
    144             switch ($metaPartParameterCriteria->getValueType()) {
    145                 case PartParameter::VALUE_TYPE_NUMERIC:
    146                     $expr = $this->filterService->getExpressionForFilter(
    147                         $filter,
    148                         "pp.normalizedValue",
    149                         $paramPrefix.$paramCount
    150                     );
    151 
    152                     $qb->setParameter($paramPrefix.$paramCount, $metaPartParameterCriteria->getNormalizedValue());
    153                     $paramCount++;
    154                     break;
    155                 case PartParameter::VALUE_TYPE_STRING:
    156                     $expr = $this->filterService->getExpressionForFilter(
    157                         $filter,
    158                         "pp.stringValue",
    159                         $paramPrefix.$paramCount
    160                     );
    161                     $qb->setParameter($paramPrefix.$paramCount, $metaPartParameterCriteria->getStringValue());
    162                     $paramCount++;
    163                     break;
    164                 default:
    165                     throw new \InvalidArgumentException("Unknown value type");
    166             }
    167 
    168             $expr2 = $qb->expr()->eq("pp.name", $paramPrefix.$paramCount);
    169             $qb->setParameter($paramPrefix.$paramCount, $metaPartParameterCriteria->getPartParameterName());
    170 
    171             $qb->andWhere(
    172                 $qb->expr()->andX($expr, $expr2)
    173             );
    174 
    175             $result = [];
    176             foreach ($qb->getQuery()->getScalarResult() as $partId) {
    177                 $result[] = $partId["id"];
    178             }
    179 
    180             $results[] = $result;
    181         }
    182 
    183         if (count($results) > 1) {
    184             $result = call_user_func_array("array_intersect", $results);
    185         } else {
    186             if (count($results) === 1) {
    187                 $result = $results[0];
    188             } else {
    189                 $result = [];
    190             }
    191         }
    192 
    193         if (count($result) > 0) {
    194             $qb = $this->entityManager->createQueryBuilder();
    195             $qb->select("p")->from("PartKeeprPartBundle:Part", "p")
    196                 ->where(
    197                     $qb->expr()->in("p.id", ":result")
    198                 );
    199 
    200             $qb->setParameter(":result", $result);
    201 
    202             return $qb->getQuery()->getResult();
    203         } else {
    204             return [];
    205         }
    206     }
    207 }