feat: soft-delete for teamer accounts

addresses #869dv9br3
This commit is contained in:
Björn Fromme
2026-08-11 12:26:13 +02:00
parent 388ecf9603
commit d654ce77fb
45 changed files with 1151 additions and 7 deletions
+10 -1
View File
@@ -41,7 +41,12 @@ class AvailabilityRepository extends ServiceEntityRepository
if (false === $custom) {
$qb->andWhere($qb->expr()->isNull('availability.owner'));
} else {
$qb->andWhere($qb->expr()->isNotNull('availability.owner'));
$qb
->andWhere($qb->expr()->isNotNull('availability.owner'))
// a deleted teamer takes no further assignments, so their own
// availabilities must no longer be offered for disposition
->andWhere($qb->expr()->isNull('teamer.deletedAt'))
;
}
return $qb->getQuery();
@@ -49,6 +54,10 @@ class AvailabilityRepository extends ServiceEntityRepository
public function getSelectableForTeamer(Teamer $teamer): array
{
if (true === $teamer->isDeleted()) {
return [];
}
$qb = $this->createQueryBuilder('availability');
return $qb
+9 -1
View File
@@ -106,7 +106,14 @@ class TeamerRepository extends ServiceEntityRepository
;
}
if (false === $filterDto->isIncludeInactive()) {
if (false === $filterDto->isIncludeDeleted()) {
$qb->andWhere($qb->expr()->isNull('teamer.deletedAt'));
}
// a deleted teamer never logs in again and would always count as inactive, so
// asking for them has to lift this filter - otherwise they could not be found
// again to be restored
if (false === $filterDto->isIncludeInactive() && false === $filterDto->isIncludeDeleted()) {
$qb
->andWhere($qb->expr()->gte('user.lastLoginAt', ':lastLoginThreshold'))
->setParameter('lastLoginThreshold', new \DateTimeImmutable($this->teamerInactivePeriod))
@@ -125,6 +132,7 @@ class TeamerRepository extends ServiceEntityRepository
$qb->expr()->like('teamer.lastName', ':search'),
$qb->expr()->like('teamer.firstName', ':search'),
))
->andWhere($qb->expr()->isNull('teamer.deletedAt'))
->orderBy('teamer.lastName', 'ASC')
->addOrderBy('teamer.firstName', 'ASC')
->setParameter('search', '%'.$this->escapeLikeWildcards($search).'%')
+5
View File
@@ -52,6 +52,9 @@ class UserRepository extends ServiceEntityRepository
));
return $qb
// andWhere after a chain of orWhere yields "(... OR ...) AND ...", so this
// narrows the whole list rather than widening it by one more alternative
->andWhere($qb->expr()->isNull('u.deletedAt'))
->orderBy('u.lastName', 'ASC')
->getQuery()
->getResult()
@@ -82,6 +85,7 @@ class UserRepository extends ServiceEntityRepository
return $qb
->andWhere('JSON_CONTAINS(user.roles, :role) = 1')
->andWhere($qb->expr()->isNull('user.deletedAt'))
->setParameter('role', json_encode($role))
->getQuery()
->getResult()
@@ -98,6 +102,7 @@ class UserRepository extends ServiceEntityRepository
$qb->expr()->like('user.firstName', ':search'),
))
->andWhere('JSON_CONTAINS(user.roles, :role) = 1')
->andWhere($qb->expr()->isNull('user.deletedAt'))
->orderBy('user.lastName', 'ASC')
->addOrderBy('user.firstName', 'ASC')
->setParameter('search', '%'.$this->escapeLikeWildcards($search).'%')