Added an menu to show some simple statistics.

This commit is contained in:
Jan Böhmer 2020-02-10 23:26:45 +01:00
parent 15957203af
commit f79975832a
7 changed files with 454 additions and 4 deletions

View file

@ -0,0 +1,44 @@
<?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 General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
namespace App\Controller;
use App\Services\StatisticsHelper;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class StatisticsController extends AbstractController
{
/**
* @Route("/statistics", name="statistics_view")
* @return Response
*/
public function showStatistics(StatisticsHelper $helper): Response
{
$this->denyAccessUnlessGranted('@tools.statistics');
return $this->render('/Statistics/statistics.html.twig', [
'helper' => $helper,
]);
}
}

View file

@ -33,7 +33,7 @@ use LogicException;
/**
* Class Attachment.
*
* @ORM\Entity
* @ORM\Entity(repositoryClass="App\Repository\AttachmentRepository")
* @ORM\Table(name="`attachments`")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="class_name", type="string")

View file

@ -0,0 +1,80 @@
<?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 General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
namespace App\Repository;
use Doctrine\ORM\EntityRepository;
class AttachmentRepository extends EntityRepository
{
/**
* Gets the count of all private/secure attachments.
* @return int
*/
public function getPrivateAttachmentsCount(): int
{
$qb = $this->createQueryBuilder('attachment');
$qb->select('COUNT(attachment)')
->where('attachment.path LIKE :like');
$qb->setParameter('like', '\\%SECURE\\%%');
$query = $qb->getQuery();
return (int) $query->getSingleScalarResult();
}
/**
* Gets the count of all external attachments (attachments only containing an URL)
* @return int
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getExternalAttachments(): int
{
$qb = $this->createQueryBuilder('attachment');
$qb->select('COUNT(attachment)')
->where('attachment.path LIKE :http')
->orWhere('attachment.path LIKE :https');
$qb->setParameter('http', 'http://%');
$qb->setParameter('https', 'https://%');
$query = $qb->getQuery();
return (int) $query->getSingleScalarResult();
}
/**
* Gets the count of all attachments where an user uploaded an file.
* @return int
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getUserUploadedAttachments(): int
{
$qb = $this->createQueryBuilder('attachment');
$qb->select('COUNT(attachment)')
->where('attachment.path LIKE :base')
->orWhere('attachment.path LIKE :media')
->orWhere('attachment.path LIKE :secure');
$qb->setParameter('secure', '\\%SECURE\\%%');
$qb->setParameter('base', '\\%BASE\\%%');
$qb->setParameter('media', '\\%MEDIA\\%%');
$query = $qb->getQuery();
return (int) $query->getSingleScalarResult();
}
}

View file

@ -24,9 +24,45 @@ declare(strict_types=1);
namespace App\Repository;
use App\Entity\Parts\PartLot;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
class PartRepository extends EntityRepository
{
//TODO
/**
* Gets the summed up instock of all parts (only parts without an measurent unit)
* @return string
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getPartsInstockSum(): string
{
$qb = new QueryBuilder($this->getEntityManager());
$qb->select('SUM(part_lot.amount)')
->from(PartLot::class, 'part_lot')
->leftJoin('part_lot.part', 'part')
->where('part.partUnit IS NULL');
$query = $qb->getQuery();
return $query->getSingleScalarResult();
}
/**
* Gets the number of parts that has price informations.
* @return int
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getPartsCountWithPrice(): int
{
$qb = $this->createQueryBuilder('part');
$qb->select('COUNT(part)')
->innerJoin('part.orderdetails', 'orderdetail')
->innerJoin('orderdetail.pricedetails', 'pricedetail')
->where('pricedetail.price > 0.0');
$query = $qb->getQuery();
return (int) $query->getSingleScalarResult();
}
}

View file

@ -0,0 +1,149 @@
<?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 General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
namespace App\Services;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Devices\Device;
use App\Entity\Parts\Category;
use App\Entity\Parts\Footprint;
use App\Entity\Parts\Manufacturer;
use App\Entity\Parts\MeasurementUnit;
use App\Entity\Parts\Part;
use App\Entity\Parts\Storelocation;
use App\Entity\Parts\Supplier;
use App\Entity\PriceInformations\Currency;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
class StatisticsHelper
{
protected $em;
protected $part_repo;
protected $attachment_repo;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
$this->part_repo = $this->em->getRepository(Part::class);
$this->attachment_repo = $this->em->getRepository(Attachment::class);
}
/**
* Returns the count of distinct parts
*/
public function getDistinctPartsCount(): int
{
return $this->part_repo->count([]);
}
/**
* Returns the summed instocked over all parts (only parts without a measurement unit)
* @return string
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getPartsInstockSum(): string
{
return $this->part_repo->getPartsInstockSum();
}
/**
* Returns the number of all parts which have price informations
* @return int
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getPartsCountWithPrice(): int
{
return $this->part_repo->getPartsCountWithPrice();
}
/**
* Returns the number of datastructures for the given type.
* @param string $type
* @return int
*/
public function getDataStructuresCount(string $type): int
{
$arr = [
'attachment_type' => AttachmentType::class,
'category' => Category::class,
'device' => Device::class,
'footprint' => Footprint::class,
'manufacturer' => Manufacturer::class,
'measurement_unit' => MeasurementUnit::class,
'storelocation' => Storelocation::class,
'supplier' => Supplier::class,
'currency' => Currency::class,
];
if (!isset($arr[$type])) {
throw new \InvalidArgumentException('No count for the given type available!');
}
/** @var EntityRepository $repo */
$repo = $this->em->getRepository($arr[$type]);
return $repo->count([]);
}
/**
* Gets the count of all attachments.
* @return int
*/
public function getAttachmentsCount(): int
{
return $this->attachment_repo->count([]);
}
/**
* Gets the count of all private/secure attachments
* @return int
*/
public function getPrivateAttachmentsCount(): int
{
return $this->attachment_repo->getPrivateAttachmentsCount();
}
/**
* Gets the count of all external (only containing an URL) attachments
* @return int
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getExternalAttachmentsCount(): int
{
return $this->attachment_repo->getExternalAttachments();
}
/**
* Gets the count of all attachments where the user uploaded an file.
* @return int
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function getUserUploadedAttachmentsCount(): int
{
return $this->attachment_repo->getUserUploadedAttachments();
}
}

View file

@ -58,8 +58,8 @@ class ToolsTreeBuilder
protected $security;
public function __construct(TranslatorInterface $translator, UrlGeneratorInterface $urlGenerator,
TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator,
Security $security)
TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator,
Security $security)
{
$this->translator = $translator;
$this->urlGenerator = $urlGenerator;
@ -187,6 +187,13 @@ class ToolsTreeBuilder
);
}
if ($this->security->isGranted('@tools.statistics')) {
$show_nodes[] = new TreeViewNode(
$this->translator->trans('tree.tools.show.statistics'),
$this->urlGenerator->generate('statistics_view')
);
}
return $show_nodes;
}