From d67e93064c61187851ed8d41e2b00bce54f598f1 Mon Sep 17 00:00:00 2001 From: Marcel Diegelmann Date: Thu, 12 Feb 2026 12:46:59 +0100 Subject: [PATCH] =?UTF-8?q?Statistik-Bereich=20um=20Tab=20f=C3=BCr=20Proje?= =?UTF-8?q?kte/Baugruppen=20erweitern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/statistics_assembly_controller.js | 45 +++++++++++++ src/Controller/StatisticsController.php | 32 ++++++++++ src/Services/Tools/StatisticsHelper.php | 26 ++++++++ .../tools/statistics/statistics.html.twig | 64 ++++++++++++++++++- translations/messages.cs.xlf | 42 ++++++++++++ translations/messages.da.xlf | 42 ++++++++++++ translations/messages.de.xlf | 42 ++++++++++++ translations/messages.el.xlf | 42 ++++++++++++ translations/messages.en.xlf | 42 ++++++++++++ translations/messages.es.xlf | 42 ++++++++++++ translations/messages.fr.xlf | 42 ++++++++++++ translations/messages.hu.xlf | 42 ++++++++++++ translations/messages.it.xlf | 42 ++++++++++++ translations/messages.ja.xlf | 42 ++++++++++++ translations/messages.nl.xlf | 42 ++++++++++++ translations/messages.pl.xlf | 42 ++++++++++++ translations/messages.ru.xlf | 42 ++++++++++++ translations/messages.zh.xlf | 42 ++++++++++++ 18 files changed, 754 insertions(+), 1 deletion(-) create mode 100644 assets/controllers/pages/statistics_assembly_controller.js diff --git a/assets/controllers/pages/statistics_assembly_controller.js b/assets/controllers/pages/statistics_assembly_controller.js new file mode 100644 index 00000000..b20ef3b3 --- /dev/null +++ b/assets/controllers/pages/statistics_assembly_controller.js @@ -0,0 +1,45 @@ +import { Controller } from '@hotwired/stimulus'; + +export default class extends Controller { + static values = { + url: String, + confirmMsg: String, + successMsg: String, + errorMsg: String + } + + static targets = ["count"] + + async cleanup(event) { + event.preventDefault(); + + if (!confirm(this.confirmMsgValue)) { + return; + } + + try { + const response = await fetch(this.urlValue, { + method: 'POST', + headers: { + 'X-Requested-With': 'XMLHttpRequest' + } + }); + + if (response.ok) { + const data = await response.json(); + alert(this.successMsgValue.replace('%count%', data.count)); + // Update the count displayed in the UI + if (this.hasCountTarget) { + this.countTarget.innerText = '0'; + } + // Reload page to reflect changes if needed, or just let the user see 0 + window.location.reload(); + } else { + alert(this.errorMsgValue); + } + } catch (error) { + console.error('Cleanup failed:', error); + alert(this.errorMsgValue); + } + } +} diff --git a/src/Controller/StatisticsController.php b/src/Controller/StatisticsController.php index 67c29781..e3b378f1 100644 --- a/src/Controller/StatisticsController.php +++ b/src/Controller/StatisticsController.php @@ -42,7 +42,10 @@ declare(strict_types=1); namespace App\Controller; use App\Services\Tools\StatisticsHelper; +use App\Entity\AssemblySystem\AssemblyBOMEntry; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; @@ -57,4 +60,33 @@ class StatisticsController extends AbstractController 'helper' => $helper, ]); } + + #[Route(path: '/statistics/cleanup-assembly-bom-entries', name: 'statistics_cleanup_assembly_bom_entries', methods: ['POST'])] + public function cleanupAssemblyBOMEntries(EntityManagerInterface $em): JsonResponse + { + $this->denyAccessUnlessGranted('@tools.statistics'); + + $qb = $em->createQueryBuilder(); + $qb->select('be', 'IDENTITY(be.part) AS part_id') + ->from(AssemblyBOMEntry::class, 'be') + ->leftJoin('be.part', 'p') + ->where('be.part IS NOT NULL') + ->andWhere('p.id IS NULL'); + + $results = $qb->getQuery()->getResult(); + $count = count($results); + + foreach ($results as $result) { + /** @var AssemblyBOMEntry $entry */ + $entry = $result[0]; + $part_id = $result['part_id'] ?? 'unknown'; + + $entry->setPart(null); + $entry->setName(sprintf('part-id=%s not found', $part_id)); + } + + $em->flush(); + + return new JsonResponse(['success' => true, 'count' => $count]); + } } diff --git a/src/Services/Tools/StatisticsHelper.php b/src/Services/Tools/StatisticsHelper.php index 00bb05c9..a3da3fde 100644 --- a/src/Services/Tools/StatisticsHelper.php +++ b/src/Services/Tools/StatisticsHelper.php @@ -41,8 +41,10 @@ declare(strict_types=1); namespace App\Services\Tools; +use App\Entity\AssemblySystem\AssemblyBOMEntry; use App\Entity\Attachments\Attachment; use App\Entity\Attachments\AttachmentType; +use App\Entity\AssemblySystem\Assembly; use App\Entity\ProjectSystem\Project; use App\Entity\Parts\Category; use App\Entity\Parts\Footprint; @@ -79,6 +81,14 @@ class StatisticsHelper return $this->part_repo->count([]); } + /** + * Returns the count of distinct projects. + */ + public function getDistinctProjectsCount(): int + { + return $this->em->getRepository(Project::class)->count([]); + } + /** * Returns the summed instocked over all parts (only parts without a measurement unit). * @@ -116,6 +126,7 @@ class StatisticsHelper 'storelocation' => StorageLocation::class, 'supplier' => Supplier::class, 'currency' => Currency::class, + 'assembly' => Assembly::class, ]; if (!isset($arr[$type])) { @@ -164,4 +175,19 @@ class StatisticsHelper { return $this->attachment_repo->getUserUploadedAttachments(); } + + /** + * Returns the count of BOM entries which point to a non-existent part ID. + */ + public function getInvalidPartBOMEntriesCount(): int + { + $qb = $this->em->createQueryBuilder(); + $qb->select('COUNT(be.id)') + ->from(AssemblyBOMEntry::class, 'be') + ->leftJoin('be.part', 'p') + ->where('be.part IS NOT NULL') + ->andWhere('p.id IS NULL'); + + return (int) $qb->getQuery()->getSingleScalarResult(); + } } diff --git a/templates/tools/statistics/statistics.html.twig b/templates/tools/statistics/statistics.html.twig index 1f488439..ed817cbe 100644 --- a/templates/tools/statistics/statistics.html.twig +++ b/templates/tools/statistics/statistics.html.twig @@ -14,6 +14,16 @@ {% trans %}statistics.parts{% endtrans %} + +