fix(sync): add Sachbearbeiter to dienstgrad constraint; add catalog browser dialog for external order position
This commit is contained in:
@@ -61,7 +61,7 @@ class MemberController {
|
||||
status: normalizeArray(statusParam) as any,
|
||||
dienstgrad: normalizeArray(dienstgradParam) as any,
|
||||
page: page ? parseInt(page, 10) || 1 : 1,
|
||||
pageSize: pageSize ? Math.min(parseInt(pageSize, 10) || 25, 100) : 25,
|
||||
pageSize: pageSize ? (parseInt(pageSize, 10) === 0 ? 0 : Math.min(parseInt(pageSize, 10) || 25, 100)) : 25,
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
-- Migration 088: Add 'Sachbearbeiter' to mitglieder_profile dienstgrad CHECK constraint.
|
||||
-- 'SB' is a valid FDISK Dienstgrad abbreviation that was missing from the allowed list,
|
||||
-- causing the FDISK sync to fail when a member's current rank is Sachbearbeiter.
|
||||
|
||||
ALTER TABLE mitglieder_profile
|
||||
DROP CONSTRAINT IF EXISTS mitglieder_profile_dienstgrad_check;
|
||||
|
||||
ALTER TABLE mitglieder_profile
|
||||
ADD CONSTRAINT mitglieder_profile_dienstgrad_check
|
||||
CHECK (dienstgrad IS NULL OR dienstgrad IN (
|
||||
-- Standard Dienstgrade
|
||||
'Feuerwehranwärter',
|
||||
'Jugendfeuerwehrmann',
|
||||
'Probefeuerwehrmann',
|
||||
'Feuerwehrmann',
|
||||
'Feuerwehrfrau',
|
||||
'Oberfeuerwehrmann',
|
||||
'Oberfeuerwehrfrau',
|
||||
'Hauptfeuerwehrmann',
|
||||
'Hauptfeuerwehrfrau',
|
||||
'Löschmeister',
|
||||
'Oberlöschmeister',
|
||||
'Hauptlöschmeister',
|
||||
'Brandmeister',
|
||||
'Oberbrandmeister',
|
||||
'Hauptbrandmeister',
|
||||
'Brandinspektor',
|
||||
'Oberbrandinspektor',
|
||||
'Brandoberinspektor',
|
||||
'Brandamtmann',
|
||||
'Verwaltungsmeister',
|
||||
'Oberverwaltungsmeister',
|
||||
'Hauptverwaltungsmeister',
|
||||
'Verwalter',
|
||||
'Sachbearbeiter',
|
||||
-- Ehrendienstgrade
|
||||
'Ehren-Feuerwehrmann',
|
||||
'Ehren-Feuerwehrfrau',
|
||||
'Ehren-Oberfeuerwehrmann',
|
||||
'Ehren-Oberfeuerwehrfrau',
|
||||
'Ehren-Hauptfeuerwehrmann',
|
||||
'Ehren-Hauptfeuerwehrfrau',
|
||||
'Ehren-Löschmeister',
|
||||
'Ehren-Oberlöschmeister',
|
||||
'Ehren-Hauptlöschmeister',
|
||||
'Ehren-Brandmeister',
|
||||
'Ehren-Oberbrandmeister',
|
||||
'Ehren-Hauptbrandmeister',
|
||||
'Ehren-Brandinspektor',
|
||||
'Ehren-Oberbrandinspektor',
|
||||
'Ehren-Brandoberinspektor',
|
||||
'Ehren-Brandamtmann',
|
||||
'Ehren-Verwaltungsmeister',
|
||||
'Ehren-Oberverwaltungsmeister',
|
||||
'Ehren-Hauptverwaltungsmeister',
|
||||
'Ehren-Verwalter'
|
||||
));
|
||||
@@ -163,31 +163,57 @@ class MemberService {
|
||||
}
|
||||
|
||||
const whereClause = `WHERE ${conditions.join(' AND ')}`;
|
||||
const offset = (page - 1) * pageSize;
|
||||
const fetchAll = pageSize === 0;
|
||||
|
||||
const dataQuery = `
|
||||
SELECT
|
||||
u.id,
|
||||
u.name,
|
||||
u.given_name,
|
||||
u.family_name,
|
||||
u.email,
|
||||
u.profile_picture_url,
|
||||
u.is_active,
|
||||
mp.id AS profile_id,
|
||||
mp.fdisk_standesbuch_nr,
|
||||
mp.dienstgrad,
|
||||
mp.funktion,
|
||||
mp.status,
|
||||
mp.eintrittsdatum,
|
||||
mp.telefon_mobil
|
||||
FROM users u
|
||||
LEFT JOIN mitglieder_profile mp ON mp.user_id = u.id
|
||||
${whereClause}
|
||||
ORDER BY u.family_name ASC NULLS LAST, u.given_name ASC NULLS LAST
|
||||
LIMIT $${paramIdx} OFFSET $${paramIdx + 1}
|
||||
`;
|
||||
values.push(pageSize, offset);
|
||||
let dataQuery: string;
|
||||
if (fetchAll) {
|
||||
dataQuery = `
|
||||
SELECT
|
||||
u.id,
|
||||
u.name,
|
||||
u.given_name,
|
||||
u.family_name,
|
||||
u.email,
|
||||
u.profile_picture_url,
|
||||
u.is_active,
|
||||
mp.id AS profile_id,
|
||||
mp.fdisk_standesbuch_nr,
|
||||
mp.dienstgrad,
|
||||
mp.funktion,
|
||||
mp.status,
|
||||
mp.eintrittsdatum,
|
||||
mp.telefon_mobil
|
||||
FROM users u
|
||||
LEFT JOIN mitglieder_profile mp ON mp.user_id = u.id
|
||||
${whereClause}
|
||||
ORDER BY u.family_name ASC NULLS LAST, u.given_name ASC NULLS LAST
|
||||
`;
|
||||
} else {
|
||||
const offset = (page - 1) * pageSize;
|
||||
dataQuery = `
|
||||
SELECT
|
||||
u.id,
|
||||
u.name,
|
||||
u.given_name,
|
||||
u.family_name,
|
||||
u.email,
|
||||
u.profile_picture_url,
|
||||
u.is_active,
|
||||
mp.id AS profile_id,
|
||||
mp.fdisk_standesbuch_nr,
|
||||
mp.dienstgrad,
|
||||
mp.funktion,
|
||||
mp.status,
|
||||
mp.eintrittsdatum,
|
||||
mp.telefon_mobil
|
||||
FROM users u
|
||||
LEFT JOIN mitglieder_profile mp ON mp.user_id = u.id
|
||||
${whereClause}
|
||||
ORDER BY u.family_name ASC NULLS LAST, u.given_name ASC NULLS LAST
|
||||
LIMIT $${paramIdx} OFFSET $${paramIdx + 1}
|
||||
`;
|
||||
values.push(pageSize, offset);
|
||||
}
|
||||
|
||||
const countQuery = `
|
||||
SELECT COUNT(*)::INTEGER AS total
|
||||
@@ -196,9 +222,11 @@ class MemberService {
|
||||
${whereClause}
|
||||
`;
|
||||
|
||||
const countValues = fetchAll ? values : values.slice(0, values.length - 2);
|
||||
|
||||
const [dataResult, countResult] = await Promise.all([
|
||||
pool.query(dataQuery, values),
|
||||
pool.query(countQuery, values.slice(0, values.length - 2)), // exclude LIMIT/OFFSET
|
||||
pool.query(countQuery, countValues),
|
||||
]);
|
||||
|
||||
const items: MemberListItem[] = dataResult.rows.map((row) => ({
|
||||
|
||||
Reference in New Issue
Block a user