Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions app/Repositories/Summit/DoctrineSummitAttendeeTicketRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,12 @@ private function requiredAliases(?Filter $filter, ?Order $order): array
$need['b'] = $need['bt'] = $need['bf'] = $need['bt_bf'] = true;
}

if ($has('has_badge_prints') || $ord('badge_prints_count')) {
// filters use SIZE(b.prints): DQL SIZE() needs a collection path, not the joined prt alias
if ($has('has_badge_prints') || $has('badge_prints_count')) {
$need['b'] = true;
}

if ($ord('badge_prints_count')) {
$need['b'] = $need['prt'] = true;
}

Expand Down Expand Up @@ -380,15 +385,15 @@ protected function getFilterMappings()
'has_badge_prints' => new DoctrineSwitchFilterMapping([
'1' => new DoctrineCaseFilterMapping(
'true',
"SIZE(prt) > 0"
"SIZE(b.prints) > 0"
),
'0' => new DoctrineCaseFilterMapping(
'false',
"SIZE(prt) = 0"
"SIZE(b.prints) = 0"
),
]
),
'badge_prints_count' => 'SIZE(prt) :operator :value',
'badge_prints_count' => 'SIZE(b.prints) :operator :value',
'exclude_is_printable_free_unassigned' => new DoctrineSwitchFilterMapping([
'1' => new DoctrineCaseFilterMapping(
'true',
Expand Down Expand Up @@ -757,7 +762,9 @@ public function getAllByPage(PagingInfo $paging_info, Filter $filter = null, Ord

$start = time();
Log::debug(sprintf('DoctrineSummitAttendeeTicketRepository::getAllByPage'));
$total = $this->getFastCount($filter, $order);
// the total does not depend on the order; aggregate orders (badge_prints_count, refunded_amount,
// final_amount_adjusted) add GROUP BY e.id, which breaks the single scalar COUNT
$total = $this->getFastCount($filter);
$ids = $this->getAllIdsByPage($paging_info, $filter, $order);
$query = $this->getEntityManager()->createQueryBuilder()
->select('e, a, o, tt, pc, b, bt, a_c, m')
Expand Down
122 changes: 122 additions & 0 deletions tests/oauth2/OAuth2SummitTicketsApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,128 @@ public function testGetAllTicketsWithoutPromoCode()
return $tickets;
}

/**
* badge_prints_count filter maps to SIZE(prt), so the badge/prints joins must be added
* for the filter too (not only for the order), otherwise the count query fails with
* a DQL semantical error on the undefined prt alias.
Comment on lines +1039 to +1041
*/
public function testGetAllTicketsByBadgePrintsCount()
{
foreach ([
['badge_prints_count>1'],
['badge_prints_count==3,badge_prints_count==4,badge_prints_count==5'],
['badge_prints_count==0'],
] as $filter) {
$params = [
'id' => self::$summit->getId(),
'page' => 1,
'per_page' => 10,
'filter' => $filter,
'order' => '+id'
];

$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];

$response = $this->action(
"GET",
"OAuth2SummitTicketApiController@getAllBySummit",
$params,
[],
[],
[],
$headers
);

$content = $response->getContent();
$this->assertResponseStatus(200);
$tickets = json_decode($content);
$this->assertTrue(!is_null($tickets));
}
}

/**
* Orders backed by aggregates add GROUP BY e.id; the total count must not inherit it,
* otherwise COUNT(DISTINCT e.id) yields one row per ticket (or none) and the request 500s.
*/
public function testGetAllTicketsOrderedByAggregates()
{
foreach ([
[[], '-badge_prints_count'],
[['badge_prints_count>=1'], '-badge_prints_count'],
[[], '+refunded_amount'],
[[], '-final_amount_adjusted'],
] as [$filter, $order]) {
$params = [
'id' => self::$summit->getId(),
'page' => 1,
'per_page' => 10,
'filter' => $filter,
'order' => $order
];

$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];

$response = $this->action(
"GET",
"OAuth2SummitTicketApiController@getAllBySummit",
$params,
[],
[],
[],
$headers
);

$content = $response->getContent();
$this->assertResponseStatus(200);
$tickets = json_decode($content);
$this->assertTrue(!is_null($tickets));
if (empty($filter)) {
$this->assertGreaterThan(1, $tickets->total);
$this->assertCount(min(10, $tickets->total), $tickets->data);
}
}
}

public function testGetAllTicketsByHasBadgePrints()
{
$params = [
'id' => self::$summit->getId(),
'page' => 1,
'per_page' => 10,
'filter' => [
'has_badge_prints==1',
],
'order' => '+id'
];

$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];

$response = $this->action(
"GET",
"OAuth2SummitTicketApiController@getAllBySummit",
$params,
[],
[],
[],
$headers
);

$content = $response->getContent();
$this->assertResponseStatus(200);
$tickets = json_decode($content);
$this->assertTrue(!is_null($tickets));
return $tickets;
}

public function testGetAttendeeBadge()
{
// Use the testCreateAttendeeBadge helper to ensure a badge exists
Expand Down
Loading