feat: remove obsolete date range override

This commit is contained in:
2026-08-31 16:56:36 +02:00
parent 86c5d23181
commit 127ced4378
42 changed files with 152 additions and 353 deletions
@@ -36,7 +36,7 @@ class IndexController extends AbstractController
$request->query->getInt('page', 1),
$request->query->getInt('limit', 50),
[
'defaultSortFieldName' => 'assignment.dateFrom',
'defaultSortFieldName' => 'destination.dateFrom',
'defaultSortDirection' => 'asc',
]
);
@@ -37,7 +37,7 @@ class IndexController extends AbstractController
$request->query->getInt('page', 1),
9,
[
'defaultSortFieldName' => 'assignment.dateFrom',
'defaultSortFieldName' => 'destination.dateFrom',
'defaultSortDirection' => 'asc',
]
);
@@ -37,7 +37,7 @@ class IndexController extends AbstractController
$request->query->getInt('page', 1),
9,
[
'defaultSortFieldName' => 'assignment.dateFrom',
'defaultSortFieldName' => 'destination.dateFrom',
'defaultSortDirection' => 'asc',
]
);
@@ -35,8 +35,8 @@ class IcsController extends AbstractController
$filename = sprintf(
'Einteilung_%s_%s-%s.ics',
$jobProfile->getName(),
$assignment->getEffectivePeriod()->start->format('d.m.Y'),
$assignment->getEffectivePeriod()->end->format('d.m.Y')
$destination->getDateFrom()->format('d.m.Y'),
$destination->getDateTo()->format('d.m.Y')
);
$slugger = new AsciiSlugger();
$filename = $slugger->slug($filename);
@@ -37,7 +37,7 @@ class RecentController extends AbstractController
$request->query->getInt('page', 1),
9,
[
'defaultSortFieldName' => 'assignment.dateFrom',
'defaultSortFieldName' => 'destination.dateFrom',
'defaultSortDirection' => 'asc',
]
);
@@ -37,7 +37,7 @@ class UpcomingController extends AbstractController
$request->query->getInt('page', 1),
9,
[
'defaultSortFieldName' => 'assignment.dateFrom',
'defaultSortFieldName' => 'destination.dateFrom',
'defaultSortDirection' => 'asc',
]
);
-70
View File
@@ -6,7 +6,6 @@ use App\Entity\Traits\BlameableEntity;
use App\Entity\Traits\SoftDeletableEntity;
use App\Entity\Traits\TimestampableEntity;
use App\Repository\AssignmentRepository;
use Carbon\CarbonPeriodImmutable;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
@@ -64,13 +63,6 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
#[ORM\Column]
private bool $skipFormalities = false;
#[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)]
private ?\DateTimeImmutable $dateFrom = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)]
#[Assert\GreaterThan(propertyPath: 'dateFrom', message: 'Das Enddatum muss nach dem Beginndatum liegen')]
private ?\DateTimeImmutable $dateTo = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)]
private ?\DateTimeImmutable $pickupDate = null;
@@ -133,8 +125,6 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
->setAvailableDispositions($assignment->getAvailableDispositions())
->setShowAvailableDispositions($assignment->isShowAvailableDispositions())
->setSkipFormalities($assignment->isSkipFormalities())
->setDateFrom($assignment->getDateFrom())
->setDateTo($assignment->getDateTo())
->setPickupDate($assignment->getPickupDate())
->setPickup($assignment->getPickup())
->setBenefits($assignment->getBenefits())
@@ -266,66 +256,6 @@ class Assignment implements BlameableEntityInterface, TimestampableEntityInterfa
return $this;
}
public function getDateFrom(): ?\DateTimeImmutable
{
return $this->dateFrom;
}
public function setDateFrom(?\DateTimeImmutable $dateFrom): static
{
$this->dateFrom = $dateFrom;
return $this;
}
public function getDateTo(): ?\DateTimeImmutable
{
return $this->dateTo;
}
public function setDateTo(?\DateTimeImmutable $dateTo): static
{
$this->dateTo = $dateTo;
return $this;
}
/**
* Immutable on purpose: a plain CarbonPeriod hands out mutable Carbon instances, so a caller
* deriving one date from another - `$end = $period->getEndDate(); $end->addDays(14)` - moves
* the original as well and silently collapses its own period. CarbonPeriodImmutable yields
* CarbonImmutable from start, end and getEndDate(), which makes that mistake impossible.
*/
public function getEffectivePeriod(): ?CarbonPeriodImmutable
{
if (null !== $destination = $this->getDestination()) {
$dateFrom = $this->getDateFrom() ?? $destination->getDateFrom();
$dateTo = $this->getDateTo() ?? $destination->getDateTo();
return new CarbonPeriodImmutable($dateFrom, $dateTo);
}
return null;
}
public function getEffectiveDateFrom(): ?\DateTimeImmutable
{
if (null !== $effectivePeriod = $this->getEffectivePeriod()) {
return $effectivePeriod->start->toDateTimeImmutable();
}
return null;
}
public function getEffectiveDateTo(): ?\DateTimeImmutable
{
if (null !== $effectivePeriod = $this->getEffectivePeriod()) {
return $effectivePeriod->end->toDateTimeImmutable();
}
return null;
}
public function getEffectivePickupDate(): ?\DateTimeImmutable
{
if (null !== $this->pickupDate) {
+3 -5
View File
@@ -246,9 +246,8 @@ class Disposition implements BlameableEntityInterface, TimestampableEntityInterf
}
$assignment = $this->getAssignment();
$assignmentPeriod = $assignment->getEffectivePeriod();
$dueDateFrom = $this->getCreatedAt()->modify(sprintf('+%d days', $deadlineDays));
$dueDateTo = $assignmentPeriod->end->modify('-1 day');
$dueDateTo = $assignment->getDestination()->getDateTo()->modify('-1 day');
// A short-notice assignment can end before the normal $deadlineDays window would even
// start. Left uncapped, dueDateFrom >= dueDateTo makes isStarted() and isEnded() equal
@@ -297,9 +296,8 @@ class Disposition implements BlameableEntityInterface, TimestampableEntityInterf
}
$assignment = $this->getAssignment();
$assignmentPeriod = $assignment->getEffectivePeriod();
$dueDateFrom = $assignmentPeriod->getEndDate();
$dueDateTo = $dueDateFrom->addDays($deadlineDays);
$dueDateFrom = $assignment->getDestination()->getDateTo();
$dueDateTo = $dueDateFrom->modify(sprintf('+%d days', $deadlineDays));
$period = CarbonPeriodImmutable::create($dueDateFrom, $dueDateTo);
+2 -2
View File
@@ -98,8 +98,8 @@ class Feedback implements BlameableEntityInterface, TimestampableEntityInterface
$instance
->setAssignment($assignment)
->setAssignmentDateFrom($assignment->getEffectiveDateFrom())
->setAssignmentDateTo($assignment->getEffectiveDateTo())
->setAssignmentDateFrom($destination->getDateFrom())
->setAssignmentDateTo($destination->getDateTo())
->setDestinationName($destination->getProduct())
->setHotel($destination->getHotel())
->setHotelCode($destination->getHotelCode())
@@ -75,14 +75,13 @@ class DispositionWorkflowGuardSubscriber implements EventSubscriberInterface
/** @var Disposition $disposition */
$disposition = $event->getSubject();
$assignment = $disposition->getAssignment();
$assignmentPeriod = $assignment->getEffectivePeriod();
$today = new \DateTimeImmutable();
$dueDateFrom = $disposition
->getCreatedAt()
->modify(sprintf('+%d days', $this->contractUploadDeadlineDays))
;
$dueDateTo = $assignmentPeriod->end->modify('-1 day');
$dueDateTo = $assignment->getDestination()->getDateTo()->modify('-1 day');
// Block upload if deadline has passed
if ($dueDateTo < $today) {
@@ -6,6 +6,7 @@ use App\Entity\Upload;
use App\Event\ApplicationDeletedEvent;
use App\Event\DocumentConfirmedEvent;
use App\Repository\ApplicationRepository;
use Carbon\CarbonPeriodImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
@@ -37,10 +38,12 @@ class InvalidateApplicationsListener
return;
}
if (null === $period = $disposition->getAssignment()->getEffectivePeriod()) {
if (null === $destination = $disposition->getAssignment()->getDestination()) {
return;
}
$period = new CarbonPeriodImmutable($destination->getDateFrom(), $destination->getDateTo());
$applications = $this->applicationRepository->findOverlappingForTeamer($teamer, $period);
if (0 === count($applications)) {
@@ -55,8 +58,8 @@ class InvalidateApplicationsListener
'teamer' => $teamer->getUuid(),
'teamer_name' => (string) $teamer,
'destination' => $assignment->getDestination()->getHotelCode(),
'date_from' => $assignment->getEffectiveDateFrom()->format('Y-m-d'),
'date_to' => $assignment->getEffectiveDateTo()->format('Y-m-d'),
'date_from' => $assignment->getDestination()->getDateFrom()->format('Y-m-d'),
'date_to' => $assignment->getDestination()->getDateTo()->format('Y-m-d'),
]);
$this->entityManager->remove($application);
}
-8
View File
@@ -79,14 +79,6 @@ class AssignmentType extends AbstractType
'rows' => 3,
],
])
// ->add('dateFrom', DatepickerType::class, [
// 'label' => 'abweichender Einsatztermin von',
// 'required' => false,
// ])
// ->add('dateTo', DatepickerType::class, [
// 'label' => 'abweichender Einsatztermin bis',
// 'required' => false,
// ])
// ->add('pickupDate', DatepickerType::class, [
// 'label' => 'abweichender Zustieg bei Busbegleitung',
// 'required' => false,
+5 -25
View File
@@ -163,12 +163,10 @@ class ApplicationRepository extends ServiceEntityRepository
}
/**
* Finds all applications of a teamer whose effective assignment period overlaps the given period.
* Finds all applications of a teamer whose assignment period overlaps the given period.
*
* The effective period of an assignment is its own date range, falling back to the date range of
* its destination whenever the assignment does not override it - the query mirrors
* {@see Assignment::getEffectivePeriod()}. Boundaries count as an overlap: a teamer cannot end one
* assignment on the same day another one begins.
* The assignment period is the date range of its destination. Boundaries count as an
* overlap: a teamer cannot end one assignment on the same day another one begins.
*
* @return array<Application>
*/
@@ -193,26 +191,8 @@ class ApplicationRepository extends ServiceEntityRepository
$qb->expr()->neq('assignment.status', ':assignment_called_off'),
$qb->expr()->isNull('assignment.deletedAt'),
$qb->expr()->isNull('destination.deletedAt'),
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNull('assignment.dateFrom'),
$qb->expr()->lte('destination.dateFrom', ':dateTo')
),
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateFrom'),
$qb->expr()->lte('assignment.dateFrom', ':dateTo')
)
),
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNull('assignment.dateTo'),
$qb->expr()->gte('destination.dateTo', ':dateFrom')
),
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateTo'),
$qb->expr()->gte('assignment.dateTo', ':dateFrom')
)
)
$qb->expr()->lte('destination.dateFrom', ':dateTo'),
$qb->expr()->gte('destination.dateTo', ':dateFrom')
))
->setParameter('teamer', $teamer)
->setParameter('application_rejected', Application::STATUS_REJECTED)
+2 -14
View File
@@ -73,13 +73,7 @@ class AssignmentRepository extends ServiceEntityRepository
->innerJoin('assignment.destination', 'destination')
->innerJoin('assignment.jobProfile', 'job_profile')
->where($qb->expr()->andX(
$qb->expr()->orX(
$qb->expr()->gt('destination.dateFrom', ':now'),
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateFrom'),
$qb->expr()->gt('assignment.dateFrom', ':now')
)
),
$qb->expr()->gt('destination.dateFrom', ':now'),
$qb->expr()->isNull('assignment.deletedAt'),
$qb->expr()->notIn('assignment.status', ':status'),
$qb->expr()->in('assignment.id', $availableAssignmentsIds)
@@ -399,13 +393,7 @@ class AssignmentRepository extends ServiceEntityRepository
)
->innerJoin('assignment.destination', 'destination')
->where($qb->expr()->andX(
$qb->expr()->orX(
$qb->expr()->gt('destination.dateFrom', ':now'),
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateFrom'),
$qb->expr()->gt('assignment.dateFrom', ':now')
)
),
$qb->expr()->gt('destination.dateFrom', ':now'),
$qb->expr()->notIn('assignment.status', ':status'),
$qb->expr()->isNull('assignment.deletedAt')
))
+12 -84
View File
@@ -11,7 +11,6 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\Expr\Comparison;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\Query\Expr\Orx;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
@@ -43,16 +42,7 @@ class DispositionRepository extends ServiceEntityRepository
$qb->expr()->eq('disposition.teamer', ':teamer'),
$qb->expr()->neq('assignment.status', ':assignmentStatus'),
$qb->expr()->neq('disposition.status', ':dispositionStatus'),
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNull('assignment.dateTo'),
$qb->expr()->gte('destination.dateTo', ':date')
),
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateTo'),
$qb->expr()->gte('assignment.dateTo', ':date')
)
)
$qb->expr()->gte('destination.dateTo', ':date')
))
->setParameter('teamer', $teamer)
->setParameter('assignmentStatus', Assignment::STATUS_CALLED_OFF)
@@ -85,16 +75,7 @@ class DispositionRepository extends ServiceEntityRepository
$qb->expr()->eq('disposition.teamer', ':teamer'),
$qb->expr()->neq('assignment.status', ':assignmentStatus'),
$qb->expr()->neq('disposition.status', ':dispositionStatus'),
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNull('assignment.dateTo'),
$qb->expr()->lte('destination.dateTo', ':date')
),
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateTo'),
$qb->expr()->lte('assignment.dateTo', ':date')
)
)
$qb->expr()->lte('destination.dateTo', ':date')
))
->setParameter('teamer', $teamer)
->setParameter('assignmentStatus', Assignment::STATUS_CALLED_OFF)
@@ -145,12 +126,12 @@ class DispositionRepository extends ServiceEntityRepository
}
/**
* The effective start date of every non-called-off disposition of a teamer, one row
* each, for the per-season tally in the info modal.
* The start date of every non-called-off disposition of a teamer, one row each, for the
* per-season tally in the info modal.
*
* Same teamer/called-off filtering as findRecentDispositionsByTeamer(), but unbounded
* and stripped to the one date it needs: assignment.dateFrom falling back to the
* destination's, the season convention shared with SeasonPeriodFilter.
* and stripped to the one date it needs: the destination's start, the season convention
* shared with SeasonPeriodFilter.
*
* @return array<int, array{seasonDate: string}>
*/
@@ -159,7 +140,7 @@ class DispositionRepository extends ServiceEntityRepository
$qb = $this->createQueryBuilder('disposition');
return $qb
->select('COALESCE(assignment.dateFrom, destination.dateFrom) AS seasonDate')
->select('destination.dateFrom AS seasonDate')
->innerJoin('disposition.assignment', 'assignment')
->innerJoin('assignment.destination', 'destination')
->where($qb->expr()->andX(
@@ -242,13 +223,7 @@ class DispositionRepository extends ServiceEntityRepository
->leftJoin('disposition.feedback', 'feedback')
->where($qb->expr()->andX(
$qb->expr()->notIn('assignment.status', ':status'),
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateTo'),
$qb->expr()->lte('assignment.dateTo', ':dateTo')
),
$qb->expr()->lte('destination.dateTo', ':dateTo')
),
$qb->expr()->lte('destination.dateTo', ':dateTo'),
$qb->expr()->isNull('feedback'),
$this->excludesSkipFormalities($qb)
))
@@ -302,13 +277,7 @@ class DispositionRepository extends ServiceEntityRepository
->innerJoin('assignment.destination', 'destination')
->where($qb->expr()->andX(
$qb->expr()->in('disposition.status', ':status'),
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateTo'),
$qb->expr()->lte('assignment.dateTo', ':dateTo')
),
$qb->expr()->lte('destination.dateTo', ':dateTo')
)
$qb->expr()->lte('destination.dateTo', ':dateTo')
))
->setParameter('status', [
Disposition::STATUS_NEW,
@@ -529,10 +498,10 @@ class DispositionRepository extends ServiceEntityRepository
$normalDay = $qb->expr()->andX(
$qb->expr()->gte('disposition.createdAt', ':dayStart'),
$qb->expr()->lt('disposition.createdAt', ':dayEnd'),
$this->effectiveDateToGreaterThan($qb, ':tomorrow'),
$qb->expr()->gt('destination.dateTo', ':tomorrow'),
);
$shortNoticeDay = $qb->expr()->andX(
$this->effectiveDateToEquals($qb, ':tomorrow'),
$qb->expr()->eq('destination.dateTo', ':tomorrow'),
$qb->expr()->gte('disposition.createdAt', ':dayStart'),
);
@@ -599,7 +568,7 @@ class DispositionRepository extends ServiceEntityRepository
// in CronCommand, so a skip-formalities placement is still `confirmed` here and
// would slip past the status filter on the day after the assignment ends.
$this->excludesSkipFormalities($qb),
$this->effectiveDateToEquals($qb, ':endDate'),
$qb->expr()->eq('destination.dateTo', ':endDate'),
))
->setParameter('documentType', Upload::TYPE_INVOICE)
->setParameter('dispositionStatus', [Disposition::STATUS_CALLED_OFF, Disposition::STATUS_COMPLETED])
@@ -611,30 +580,6 @@ class DispositionRepository extends ServiceEntityRepository
;
}
/**
* Compares the assignment's end date against $parameter, falling back to the destination's
* when the assignment does not override it.
*
* The fallback is guarded on both sides - without the isNull() on the second branch an
* assignment that moves the end date into the future would still match on the
* destination's date. Kept in one place because the per-assignment date override is due to
* be removed (docs/remove-assignment-date-override.md), and this then collapses to a plain
* comparison on destination.dateTo.
*/
private function effectiveDateToEquals(QueryBuilder $qb, string $parameter): Orx
{
return $qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateTo'),
$qb->expr()->eq('assignment.dateTo', $parameter)
),
$qb->expr()->andX(
$qb->expr()->isNull('assignment.dateTo'),
$qb->expr()->eq('destination.dateTo', $parameter)
),
);
}
/**
* Restricts a query to assignments that still run the contract, invoice and feedback process.
*
@@ -653,23 +598,6 @@ class DispositionRepository extends ServiceEntityRepository
return $qb->expr()->eq('assignment.skipFormalities', ':skipFormalities');
}
/**
* Same fallback as effectiveDateToEquals(), but for "later than $parameter".
*/
private function effectiveDateToGreaterThan(QueryBuilder $qb, string $parameter): Orx
{
return $qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateTo'),
$qb->expr()->gt('assignment.dateTo', $parameter)
),
$qb->expr()->andX(
$qb->expr()->isNull('assignment.dateTo'),
$qb->expr()->gt('destination.dateTo', $parameter)
),
);
}
/**
* Dispositions whose contract upload period has run out, for the admin dashboard.
*
+8 -28
View File
@@ -5,15 +5,14 @@ namespace App\Repository\Filter;
use Doctrine\ORM\QueryBuilder;
/**
* Narrows a query to the season an assignment runs in.
* Narrows a query to the season an assignment runs in, which is the date range of its
* destination.
*
* The season is assignment.dateFrom/dateTo falling back to the destination's, mirroring
* Assignment::getEffectivePeriod(), which DQL cannot call. Every statistics screen means
* this by a date range, so it lives in one place: three repositories carrying the same
* expression by hand is three chances for "a season" to come to mean something slightly
* different on one screen than on the one beside it.
* Kept in one place because every statistics screen means the same thing by "a season":
* the expression carried by hand in each repository is one more chance for it to come to
* mean something slightly different on one screen than on the one beside it.
*
* Both aliases must already be joined by the caller - this only adds the conditions.
* The destination alias must already be joined by the caller - this only adds the conditions.
*/
final class SeasonPeriodFilter
{
@@ -21,37 +20,18 @@ final class SeasonPeriodFilter
QueryBuilder $qb,
?\DateTimeImmutable $dateFrom,
?\DateTimeImmutable $dateTo,
string $assignmentAlias = 'assignment',
string $destinationAlias = 'destination',
): void {
if (null !== $dateFrom) {
$qb
->andWhere($qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNotNull($assignmentAlias.'.dateFrom'),
$qb->expr()->gte($assignmentAlias.'.dateFrom', ':dateFrom')
),
$qb->expr()->andX(
$qb->expr()->isNull($assignmentAlias.'.dateFrom'),
$qb->expr()->gte($destinationAlias.'.dateFrom', ':dateFrom')
)
))
->andWhere($qb->expr()->gte($destinationAlias.'.dateFrom', ':dateFrom'))
->setParameter('dateFrom', $dateFrom)
;
}
if (null !== $dateTo) {
$qb
->andWhere($qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNotNull($assignmentAlias.'.dateTo'),
$qb->expr()->lte($assignmentAlias.'.dateTo', ':dateTo')
),
$qb->expr()->andX(
$qb->expr()->isNull($assignmentAlias.'.dateTo'),
$qb->expr()->lte($destinationAlias.'.dateTo', ':dateTo')
)
))
->andWhere($qb->expr()->lte($destinationAlias.'.dateTo', ':dateTo'))
->setParameter('dateTo', $dateTo)
;
}
+4 -2
View File
@@ -21,9 +21,11 @@ class IcsGenerator
$label = sprintf('E&P: Einteilung als %s', $assignment->getJobProfile()->getName());
$address = sprintf("%s\n%s", $assignment->getDestination()->getProduct(), $assignment->getDestination()->getHotel());
$destination = $assignment->getDestination();
$event = Event::create($label)
->startsAt($assignment->getEffectivePeriod()->start)
->endsAt($assignment->getEffectivePeriod()->end->modify('+1 day'))
->startsAt($destination->getDateFrom())
->endsAt($destination->getDateTo()->modify('+1 day'))
->address($address)
->description($label)
;
+2 -2
View File
@@ -39,8 +39,8 @@ class ContractRenderer extends AbstractPdfRenderer
$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');
$dateFrom = $destination->getDateFrom()->format('d.m.Y');
$dateTo = $destination->getDateTo()->format('d.m.Y');
$period = sprintf('%s - %s', $dateFrom, $dateTo);
$pdf->Text(57, 113, $period);
+1 -1
View File
@@ -37,7 +37,7 @@ class InvoiceRenderer extends AbstractPdfRenderer
// Invoice number
$pdf->SetFont('Arial', '', 12);
$date = $assignment->getEffectivePeriod()->start->format('d/m/Y');
$date = $assignment->getDestination()->getDateFrom()->format('d/m/Y');
$suffix = $assignment->getId();
$number = sprintf('%s-%05d', $date, $suffix);
$pdf->Text(85, 116, $number);
@@ -37,12 +37,12 @@ class ApplicationValidator extends ConstraintValidator
return;
}
if (null === $period = $application->getAssignment()->getEffectivePeriod()) {
if (null === $destination = $application->getAssignment()->getDestination()) {
return;
}
$applicationDateFrom = $period->start->toDateTimeImmutable();
$applicationDateTo = $period->end->toDateTimeImmutable();
$applicationDateFrom = $destination->getDateFrom();
$applicationDateTo = $destination->getDateTo();
$qb = $this
->dispositionRepository
@@ -62,26 +62,8 @@ class ApplicationValidator extends ConstraintValidator
$qb->expr()->neq('assignment.status', ':assignment_called_off'),
$qb->expr()->isNull('assignment.deletedAt'),
$qb->expr()->isNull('destination.deletedAt'),
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNull('assignment.dateFrom'),
$qb->expr()->lte('destination.dateFrom', ':application_date_to')
),
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateFrom'),
$qb->expr()->lte('assignment.dateFrom', ':application_date_to')
)
),
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->isNull('assignment.dateTo'),
$qb->expr()->gte('destination.dateTo', ':application_date_from')
),
$qb->expr()->andX(
$qb->expr()->isNotNull('assignment.dateTo'),
$qb->expr()->gte('assignment.dateTo', ':application_date_from')
)
)
$qb->expr()->lte('destination.dateFrom', ':application_date_to'),
$qb->expr()->gte('destination.dateTo', ':application_date_from')
))
->setParameter('teamer', $teamer)
->setParameter('disposition_called_off', Disposition::STATUS_CALLED_OFF)