rework internal order system
This commit is contained in:
@@ -208,6 +208,20 @@ class AusruestungsanfrageController {
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Users (for "order on behalf of" autocomplete)
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
async getAllUsers(_req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const users = await ausruestungsanfrageService.getAllUsers();
|
||||
res.status(200).json({ success: true, data: users });
|
||||
} catch (error) {
|
||||
logger.error('AusruestungsanfrageController.getAllUsers error', { error });
|
||||
res.status(500).json({ success: false, message: 'Benutzer konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Requests
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -251,11 +265,12 @@ class AusruestungsanfrageController {
|
||||
|
||||
async createRequest(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { items, notizen, bezeichnung, fuer_benutzer_id } = req.body as {
|
||||
const { items, notizen, bezeichnung, fuer_benutzer_id, fuer_benutzer_name } = req.body as {
|
||||
items?: { artikel_id?: number; bezeichnung: string; menge: number; notizen?: string; eigenschaften?: { eigenschaft_id: number; wert: string }[] }[];
|
||||
notizen?: string;
|
||||
bezeichnung?: string;
|
||||
fuer_benutzer_id?: string;
|
||||
fuer_benutzer_name?: string;
|
||||
};
|
||||
|
||||
if (!items || items.length === 0) {
|
||||
@@ -276,6 +291,7 @@ class AusruestungsanfrageController {
|
||||
|
||||
// Determine anfrager: self or on behalf of another user
|
||||
let anfragerId = req.user!.id;
|
||||
let storedFuerBenutzerName: string | undefined;
|
||||
if (fuer_benutzer_id && fuer_benutzer_id !== req.user!.id) {
|
||||
const groups = req.user?.groups ?? [];
|
||||
const canOrderForUser = groups.includes('dashboard_admin') || permissionService.hasPermission(groups, 'ausruestungsanfrage:order_for_user');
|
||||
@@ -284,9 +300,18 @@ class AusruestungsanfrageController {
|
||||
return;
|
||||
}
|
||||
anfragerId = fuer_benutzer_id;
|
||||
} else if (fuer_benutzer_name && !fuer_benutzer_id) {
|
||||
// Custom name for user not in system — keep anfrager_id as current user
|
||||
const groups = req.user?.groups ?? [];
|
||||
const canOrderForUser = groups.includes('dashboard_admin') || permissionService.hasPermission(groups, 'ausruestungsanfrage:order_for_user');
|
||||
if (!canOrderForUser) {
|
||||
res.status(403).json({ success: false, message: 'Keine Berechtigung für Bestellung im Auftrag' });
|
||||
return;
|
||||
}
|
||||
storedFuerBenutzerName = fuer_benutzer_name;
|
||||
}
|
||||
|
||||
const request = await ausruestungsanfrageService.createRequest(anfragerId, items, notizen, bezeichnung);
|
||||
const request = await ausruestungsanfrageService.createRequest(anfragerId, items, notizen, bezeichnung, storedFuerBenutzerName);
|
||||
res.status(201).json({ success: true, data: request });
|
||||
} catch (error) {
|
||||
logger.error('AusruestungsanfrageController.createRequest error', { error });
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Add fuer_benutzer_name column for custom names (users not in system)
|
||||
ALTER TABLE ausruestung_anfragen ADD COLUMN IF NOT EXISTS fuer_benutzer_name TEXT;
|
||||
@@ -32,6 +32,12 @@ router.delete('/eigenschaften/:eigenschaftId', authenticate, requirePermission('
|
||||
// Legacy text-based categories
|
||||
router.get('/categories', authenticate, requirePermission('ausruestungsanfrage:view'), ausruestungsanfrageController.getCategories.bind(ausruestungsanfrageController));
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Users (for "order on behalf of" autocomplete)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
router.get('/users', authenticate, requirePermission('ausruestungsanfrage:order_for_user'), ausruestungsanfrageController.getAllUsers.bind(ausruestungsanfrageController));
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Overview
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -266,6 +266,20 @@ async function deleteArtikelEigenschaft(id: number) {
|
||||
await pool.query('DELETE FROM ausruestung_artikel_eigenschaften WHERE id = $1', [id]);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Users (for "order on behalf of" autocomplete)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
async function getAllUsers() {
|
||||
const result = await pool.query(
|
||||
`SELECT id, COALESCE(given_name || ' ' || family_name, name) AS name
|
||||
FROM users
|
||||
WHERE is_active = true
|
||||
ORDER BY name`,
|
||||
);
|
||||
return result.rows;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Requests (ausruestung_anfragen)
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -288,6 +302,7 @@ async function getRequests(filters?: { status?: string; anfrager_id?: string })
|
||||
`SELECT a.*,
|
||||
COALESCE(u.given_name || ' ' || u.family_name, u.name) AS anfrager_name,
|
||||
COALESCE(u2.given_name || ' ' || u2.family_name, u2.name) AS bearbeitet_von_name,
|
||||
a.fuer_benutzer_name,
|
||||
(SELECT COUNT(*)::int FROM ausruestung_anfrage_positionen p WHERE p.anfrage_id = a.id) AS positionen_count,
|
||||
(SELECT COUNT(*)::int FROM ausruestung_anfrage_positionen p WHERE p.anfrage_id = a.id AND p.geliefert) AS geliefert_count
|
||||
FROM ausruestung_anfragen a
|
||||
@@ -316,7 +331,8 @@ async function getRequestById(id: number) {
|
||||
const reqResult = await pool.query(
|
||||
`SELECT a.*,
|
||||
COALESCE(u.given_name || ' ' || u.family_name, u.name) AS anfrager_name,
|
||||
COALESCE(u2.given_name || ' ' || u2.family_name, u2.name) AS bearbeitet_von_name
|
||||
COALESCE(u2.given_name || ' ' || u2.family_name, u2.name) AS bearbeitet_von_name,
|
||||
a.fuer_benutzer_name
|
||||
FROM ausruestung_anfragen a
|
||||
LEFT JOIN users u ON u.id = a.anfrager_id
|
||||
LEFT JOIN users u2 ON u2.id = a.bearbeitet_von
|
||||
@@ -388,6 +404,7 @@ async function createRequest(
|
||||
items: { artikel_id?: number; bezeichnung: string; menge: number; notizen?: string; eigenschaften?: { eigenschaft_id: number; wert: string }[] }[],
|
||||
notizen?: string,
|
||||
bezeichnung?: string,
|
||||
fuerBenutzerName?: string,
|
||||
) {
|
||||
const client = await pool.connect();
|
||||
try {
|
||||
@@ -407,20 +424,20 @@ async function createRequest(
|
||||
);
|
||||
const nextNr = maxResult.rows[0].next_nr;
|
||||
const anfrageResult = await client.query(
|
||||
`INSERT INTO ausruestung_anfragen (anfrager_id, notizen, bezeichnung, bestell_nummer, bestell_jahr)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
`INSERT INTO ausruestung_anfragen (anfrager_id, notizen, bezeichnung, bestell_nummer, bestell_jahr, fuer_benutzer_name)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
RETURNING *`,
|
||||
[userId, notizen || null, bezeichnung || null, nextNr, currentYear],
|
||||
[userId, notizen || null, bezeichnung || null, nextNr, currentYear, fuerBenutzerName || null],
|
||||
);
|
||||
await client.query('RELEASE SAVEPOINT sp_bestell_nr');
|
||||
anfrage = anfrageResult.rows[0];
|
||||
} catch {
|
||||
await client.query('ROLLBACK TO SAVEPOINT sp_bestell_nr');
|
||||
const anfrageResult = await client.query(
|
||||
`INSERT INTO ausruestung_anfragen (anfrager_id, notizen, bezeichnung)
|
||||
VALUES ($1, $2, $3)
|
||||
`INSERT INTO ausruestung_anfragen (anfrager_id, notizen, bezeichnung, fuer_benutzer_name)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING *`,
|
||||
[userId, notizen || null, bezeichnung || null],
|
||||
[userId, notizen || null, bezeichnung || null, fuerBenutzerName || null],
|
||||
);
|
||||
anfrage = anfrageResult.rows[0];
|
||||
}
|
||||
@@ -752,6 +769,7 @@ async function getWidgetOverview() {
|
||||
}
|
||||
|
||||
export default {
|
||||
getAllUsers,
|
||||
getKategorien,
|
||||
createKategorie,
|
||||
updateKategorie,
|
||||
|
||||
Reference in New Issue
Block a user