chore: code cleanup

This commit is contained in:
Björn Fromme
2025-08-21 14:20:43 +02:00
parent c4e28818e0
commit e36009008c
273 changed files with 547 additions and 531 deletions
+4 -4
View File
@@ -5,7 +5,6 @@ namespace App\Service\Assignment;
use App\Entity\Assignment;
use App\Model\TimelineItem;
use Carbon\CarbonPeriod;
use function Symfony\Component\String\b;
/**
* Service for processing assignments into timeline visualization data.
@@ -20,6 +19,7 @@ class TimelineService
* distributing them across multiple rows to avoid date overlaps.
*
* @param Assignment[] $assignments Array of assignments to process
*
* @return array Multi-dimensional array: [hotelCode][rowIndex][itemKey] => TimelineItem
*/
public function preprocess(array $assignments): array
@@ -46,14 +46,14 @@ class TimelineService
// Handle assignments with no dispositions - create items for all available slots
if (0 === $dispositionsCount) {
$item = TimelineItem::fromAssignment($assignment);
for ($i = 1; $i <= $assignment->getAvailableDispositions(); $i++) {
for ($i = 1; $i <= $assignment->getAvailableDispositions(); ++$i) {
$this->addItem($rows[$hotelCode], $item);
}
} else {
// Create items for remaining vacant slots if any
if ($dispositionsCount < $dispositionsAvailable) {
$item = TimelineItem::fromAssignment($assignment);
for ($i = 1; $i <= $dispositionsAvailable - $dispositionsCount; $i++) {
for ($i = 1; $i <= $dispositionsAvailable - $dispositionsCount; ++$i) {
$this->addItem($rows[$hotelCode], $item);
}
}
@@ -73,7 +73,7 @@ class TimelineService
* Finds the first available row where the item doesn't overlap with existing items,
* or creates a new row if necessary.
*
* @param array $rows Reference to the rows array for a specific hotel
* @param array $rows Reference to the rows array for a specific hotel
* @param TimelineItem $item The timeline item to add
*/
private function addItem(array &$rows, TimelineItem $item): void
+1 -2
View File
@@ -3,7 +3,6 @@
namespace App\Service\Common;
use App\Model\AbstractFilterDto;
use App\Model\AssignmentFilterDto;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -16,7 +15,7 @@ abstract class AbstractFilterHandler
public function __construct(
protected readonly RequestStack $requestStack,
protected readonly EntityManagerInterface $entityManager
protected readonly EntityManagerInterface $entityManager,
) {
}
@@ -57,7 +57,7 @@ class ApplicationFilterHandler extends AbstractFilterHandler
protected function saveFilterSettings(AbstractFilterDto $filterDto): void
{
/** @var ApplicationFilterDto $filterDto */
/* @var ApplicationFilterDto $filterDto */
$this->getSession()->set($this->namespace, [
'id' => $filterDto->getId(),
'date_from' => $filterDto->getDateFrom(),
@@ -57,7 +57,7 @@ class AssignmentFilterHandler extends AbstractFilterHandler
protected function saveFilterSettings(AbstractFilterDto $filterDto): void
{
/** @var AssignmentFilterDto $filterDto */
/* @var AssignmentFilterDto $filterDto */
$this->getSession()->set($this->namespace, [
'id' => $filterDto->getId(),
'date_from' => $filterDto->getDateFrom(),
@@ -29,9 +29,9 @@ class DestinationFilterHandler extends AbstractFilterHandler
protected function saveFilterSettings(AbstractFilterDto $filterDto): void
{
/** @var DestinationFilterDto $filterDto */
/* @var DestinationFilterDto $filterDto */
$this->getSession()->set($this->namespace, [
'hotels' => $filterDto->getHotels(),
]);
}
}
}
+1 -1
View File
@@ -57,7 +57,7 @@ class DocumentFilterHandler extends AbstractFilterHandler
protected function saveFilterSettings(AbstractFilterDto $filterDto): void
{
/** @var DocumentFilterDto $filterDto */
/* @var DocumentFilterDto $filterDto */
$this->getSession()->set($this->namespace, [
'teamer_id' => $filterDto->getTeamer()?->getId(),
'type' => $filterDto->getType(),
+1 -1
View File
@@ -36,7 +36,7 @@ class FeedbackFilterHandler extends AbstractFilterHandler
protected function saveFilterSettings(AbstractFilterDto $filterDto): void
{
/** @var FeedbackFilterDto $filterDto */
/* @var FeedbackFilterDto $filterDto */
$this->getSession()->set($this->namespace, [
'name' => $filterDto->getName(),
'date_from' => $filterDto->getDateFrom(),
+2 -1
View File
@@ -9,7 +9,8 @@ use Spatie\IcalendarGenerator\Components\Event;
class IcsGenerator
{
public function __construct(private readonly Disposition $disposition)
{}
{
}
public function generate(): string
{
+1 -1
View File
@@ -42,7 +42,7 @@ class TeamerFilterHandler extends AbstractFilterHandler
protected function saveFilterSettings(AbstractFilterDto $filterDto): void
{
/** @var TeamerFilterDto $filterDto */
/* @var TeamerFilterDto $filterDto */
$this->getSession()->set($this->namespace, [
'name' => $filterDto->getName(),
'available_at' => $filterDto->getAvailableAt(),
+1 -1
View File
@@ -51,7 +51,7 @@ class TimelineFilterHandler extends AbstractFilterHandler
protected function saveFilterSettings(AbstractFilterDto $filterDto): void
{
/** @var TimelineFilterDto $filterDto */
/* @var TimelineFilterDto $filterDto */
$this->getSession()->set($this->namespace, [
'date_from' => $filterDto->getDateFrom(),
'date_to' => $filterDto->getDateTo(),
@@ -15,7 +15,7 @@ class DispositionReminderService
public function __construct(
private readonly DispositionRepository $dispositionRepository,
private readonly Mailer $mailer,
private readonly LoggerInterface $logger
private readonly LoggerInterface $logger,
) {
}
@@ -10,7 +10,7 @@ class DispositionStatusService
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly LoggerInterface $logger
private readonly LoggerInterface $logger,
) {
}
@@ -38,4 +38,4 @@ class DispositionStatusService
return $message;
}
}
}
+2 -2
View File
@@ -17,7 +17,7 @@ class FeedbackReminderService
private readonly HotelDataProvider $hotelDataProvider,
private readonly UserRepository $userRepository,
private readonly Mailer $mailer,
private readonly LoggerInterface $logger
private readonly LoggerInterface $logger,
) {
}
@@ -88,4 +88,4 @@ class FeedbackReminderService
return 'Sent feedback reminders to '.count($hotelManagers).' hotel managers';
}
}
}
+2 -3
View File
@@ -10,7 +10,7 @@ class FlushLogsService
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly LoggerInterface $logger
private readonly LoggerInterface $logger,
) {
}
@@ -35,5 +35,4 @@ class FlushLogsService
return [$success, $message];
}
}
}
+3 -4
View File
@@ -8,14 +8,13 @@ use App\Entity\Upload;
use App\Repository\DispositionRepository;
use Doctrine\ORM\Query\Expr\Join;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
class UploadReminderService
{
public function __construct(
private readonly DispositionRepository $dispositionRepository,
private readonly Mailer $mailer,
private readonly LoggerInterface $logger
private readonly LoggerInterface $logger,
) {
}
@@ -92,7 +91,7 @@ class UploadReminderService
->where($qb->expr()->andX(
$qb->expr()->isNull('document'),
$qb->expr()->orX(
// Due date can be determined by assignment's date which potentially overrides destination date
// Due date can be determined by assignment's date which potentially overrides destination date
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateTo'),
$qb->expr()->eq('assignment.dateTo', ':dateTo')
@@ -132,4 +131,4 @@ class UploadReminderService
return $message;
}
}
}
+6 -6
View File
@@ -27,25 +27,25 @@ class ContractRenderer extends AbstractPdfRenderer
// Current date
$date = (new \DateTimeImmutable())->format('d.m.Y');
$pdf->Text(164,43, $pdf->encodeString($date));
$pdf->Text(164, 43, $pdf->encodeString($date));
// Name
$pdf->Text(45,67.75, $pdf->encodeString($teamer));
$pdf->Text(45, 67.75, $pdf->encodeString($teamer));
// Address
$pdf->Text(45,77.75, $pdf->encodeString($teamer->getAddress()));
$pdf->Text(45, 77.75, $pdf->encodeString($teamer->getAddress()));
// Jobprofile
$pdf->Text(21,104.5, $pdf->encodeString($assignment->getJobProfile()->getName()));
$pdf->Text(21, 104.5, $pdf->encodeString($assignment->getJobProfile()->getName()));
// Period
$dateFrom = $assignment->getEffectivePeriod()->start->format('d.m.Y');
$dateTo = $assignment->getEffectivePeriod()->end->format('d.m.Y');
$period = sprintf('%s - %s', $dateFrom, $dateTo);
$pdf->Text(57,113, $period);
$pdf->Text(57, 113, $period);
// Destination
$pdf->Text(57,121.5, $pdf->encodeString(sprintf('%s, %s', $destination->getProduct(), $destination->getHotel())));
$pdf->Text(57, 121.5, $pdf->encodeString(sprintf('%s, %s', $destination->getProduct(), $destination->getHotel())));
// Set pointer to last page to include all
$pdf->setPage($numberOfPages);
+3 -3
View File
@@ -39,19 +39,19 @@ class InvoiceApprover extends AbstractPdfRenderer
// Cost unit job profile
if (null !== $costUnit = $assignment->getJobProfile()->getCostUnit()) {
$pdf->SetFont('Arial', '', 11);
$pdf->Text(20,20, $pdf->encodeString('Kostenstelle 1: '.$costUnit));
$pdf->Text(20, 20, $pdf->encodeString('Kostenstelle 1: '.$costUnit));
}
// Cost unit destination/hotel
if (null !== $costUnit = $assignment->getDestination()->getCostUnit()) {
$pdf->SetFont('Arial', '', 11);
$pdf->Text(20,25, $pdf->encodeString('Kostenstelle 2: '.$costUnit));
$pdf->Text(20, 25, $pdf->encodeString('Kostenstelle 2: '.$costUnit));
}
// Approval
$pdf->SetFont('Arial', '', 11);
$pdf->SetTextColor(0, 128, 0);
$pdf->Text(20,30, $pdf->encodeString('geprüft: '.$invoice->getApprovedBy()));
$pdf->Text(20, 30, $pdf->encodeString('geprüft: '.$invoice->getApprovedBy()));
$this->createBackup($filepath);
+9 -11
View File
@@ -3,7 +3,6 @@
namespace App\Service\Pdf;
use App\Entity\Disposition;
use App\Entity\Upload;
class InvoiceRenderer extends AbstractPdfRenderer
{
@@ -26,33 +25,32 @@ class InvoiceRenderer extends AbstractPdfRenderer
$assignment = $disposition->getAssignment();
// Name
$pdf->Text(135,28.5, $pdf->encodeString($teamer->getFullName()));
$pdf->Text(135, 28.5, $pdf->encodeString($teamer->getFullName()));
// Address
$address = $teamer->getAddress();
$pdf->Text(135,39, $pdf->encodeString($address->getStreet()));
$pdf->Text(135,51, $pdf->encodeString($address->getPostCode(). ' '.$address->getCity()));
$pdf->Text(135, 39, $pdf->encodeString($address->getStreet()));
$pdf->Text(135, 51, $pdf->encodeString($address->getPostCode().' '.$address->getCity()));
// Tax ID
$pdf->Text(144,62, $pdf->encodeString($teamer->getTaxId() ?? '-'));
$pdf->Text(144, 62, $pdf->encodeString($teamer->getTaxId() ?? '-'));
// Invoice number
$pdf->SetFont('Arial', '', 12);
$number = $assignment->getEffectivePeriod()->start->format('d/m/Y');
$pdf->Text(85,116, $number);
$pdf->Text(85, 116, $number);
$pdf->SetFont('Arial', '', 10);
// Bank account
$bankAccount = $teamer->getBankAccount();
$pdf->Text(36,233.5, $pdf->encodeString($bankAccount->getIban() ?? '-'));
$pdf->Text(36,241, $pdf->encodeString($bankAccount->getBic() ?? '-'));
$pdf->Text(36,248.5, $pdf->encodeString($bankAccount->getBank() ?? '-'));
$pdf->Text(36, 233.5, $pdf->encodeString($bankAccount->getIban() ?? '-'));
$pdf->Text(36, 241, $pdf->encodeString($bankAccount->getBic() ?? '-'));
$pdf->Text(36, 248.5, $pdf->encodeString($bankAccount->getBank() ?? '-'));
// Current date
$date = (new \DateTimeImmutable())->format('d.m.Y');
$pdf->Text(38,264, $pdf->encodeString($date));
$pdf->Text(38, 264, $pdf->encodeString($date));
return $pdf;
}
+13 -13
View File
@@ -85,7 +85,7 @@ class Pdf extends Fpdi
* maintaining its aspect ratio. An optional title can be added at the top.
*
* @param string $sourceFile Path to the image file to display
* @param string $pageTitle Optional title text to display at the top of the page
* @param string $pageTitle Optional title text to display at the top of the page
*/
public function appendImage(string $sourceFile, string $pageTitle = ''): void
{
@@ -113,18 +113,18 @@ class Pdf extends Fpdi
* while maintaining aspect ratio, then positions it in the center. Handles
* image loading errors gracefully by displaying an error message.
*
* @param string $imgPath Path to the image file
* @param int $x X-coordinate of the container's top-left corner
* @param int $y Y-coordinate of the container's top-left corner
* @param int $containerWidth Width of the container area
* @param int $containerHeight Height of the container area
* @param string $imgPath Path to the image file
* @param int $x X-coordinate of the container's top-left corner
* @param int $y Y-coordinate of the container's top-left corner
* @param int $containerWidth Width of the container area
* @param int $containerHeight Height of the container area
*/
public function centerImage(
string $imgPath,
int $x = 0,
int $y = 0,
int $containerWidth = self::A4_WIDTH,
int $containerHeight = self::A4_HEIGHT
int $containerHeight = self::A4_HEIGHT,
): void {
[$width, $height] = $this->resizeToFit($imgPath, $containerWidth, $containerHeight);
@@ -151,7 +151,7 @@ class Pdf extends Fpdi
*/
protected function pixelsToMm($val): int
{
return (int) (round($val * $this::MM_IN_INCH / self::DPI));
return (int) round($val * $this::MM_IN_INCH / self::DPI);
}
/**
@@ -163,7 +163,7 @@ class Pdf extends Fpdi
*/
protected function mmToPixels($val): int
{
return (int) (round($this::DPI * $val / $this::MM_IN_INCH));
return (int) round($this::DPI * $val / $this::MM_IN_INCH);
}
/**
@@ -173,16 +173,16 @@ class Pdf extends Fpdi
* size that fits within the maximum width and height while preserving the
* aspect ratio. Returns dimensions in millimeters for PDF placement.
*
* @param string $imgPath Path to the image file
* @param int $maxWidth Maximum allowed width in millimeters
* @param int $maxHeight Maximum allowed height in millimeters
* @param string $imgPath Path to the image file
* @param int $maxWidth Maximum allowed width in millimeters
* @param int $maxHeight Maximum allowed height in millimeters
*
* @return array Array containing [width, height] in millimeters
*/
protected function resizeToFit(
string $imgPath,
int $maxWidth = self::A4_WIDTH,
int $maxHeight = self::A4_HEIGHT
int $maxHeight = self::A4_HEIGHT,
): array {
[$width, $height] = getimagesize($imgPath);
$widthScale = $this->mmToPixels($maxWidth) / $width;
+2 -2
View File
@@ -39,7 +39,7 @@ class Sanitizer
if (null === $targetFilepath) {
$parts = pathinfo($inputFilepath);
$targetFilepath = sprintf('%s/%s.%s', $parts['dirname'], $parts['filename'], $parts['extension']);
$targetFilepath = sprintf('%s/%s.%s', $parts['dirname'], $parts['filename'], $parts['extension']);
}
if ('pdf' !== pathinfo($inputFilepath, PATHINFO_EXTENSION)) {
@@ -61,7 +61,7 @@ class Sanitizer
$filesystem->remove($inputFilepath);
$inputFilepath = $pdfFilepath;
$targetFilepath.= '.pdf';
$targetFilepath .= '.pdf';
}
$command = [
+2 -2
View File
@@ -18,7 +18,7 @@ class AvailabilityProcessor
* ...
* ],
* ],
* ]
* ].
*/
public function groupRecords(array $records): array
{
@@ -43,4 +43,4 @@ class AvailabilityProcessor
return $availabilities;
}
}
}
+1 -1
View File
@@ -40,4 +40,4 @@ class PickupResolver
return false;
}
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ class DownloadNamer
{
public function nameForTeamer(Upload $upload, Teamer $teamer): string
{
$pattern = match($upload->getType()) {
$pattern = match ($upload->getType()) {
Upload::TYPE_INVOICE => 'hn-%d-%s-%s.pdf',
Upload::TYPE_CONTRACT => 'hv-%d-%s-%s.pdf',
default => null,
+4 -4
View File
@@ -11,7 +11,6 @@ use Psr\Log\LoggerInterface;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\RequestStack;
use function Symfony\Component\String\s;
class UploadHandler
{
@@ -22,7 +21,7 @@ class UploadHandler
private readonly OrphanageManager $orphanageManager,
private readonly Sanitizer $sanitizer,
private readonly LoggerInterface $logger,
private readonly string $projectDir
private readonly string $projectDir,
) {
}
@@ -121,11 +120,12 @@ class UploadHandler
;
}
public function getUploadFilepath(Upload $upload): string
public function getUploadFilepath(Upload $upload, bool $absolute = true): string
{
$folder = substr($upload->getFilename(), 0, 1);
$relativePath = sprintf('uploads/%s/%s/%s', $upload->getType(), $folder, $upload->getFilename());
return sprintf('%s/uploads/%s/%s/%s', $this->projectDir, $upload->getType(), $folder, $upload->getFilename());
return true === $absolute ? sprintf('%s/%s', $this->projectDir, $relativePath) : $relativePath;
}
public function getTempUploadFilepath(UploadDto $uploadDto, string $uploadSessionId): string