add linking between internal and external orders
This commit is contained in:
@@ -507,6 +507,30 @@ class AusruestungsanfrageController {
|
||||
}
|
||||
}
|
||||
|
||||
async createOrders(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const anfrageId = Number(req.params.id);
|
||||
const { orders } = req.body as {
|
||||
orders: Array<{
|
||||
lieferant_id: number;
|
||||
bezeichnung: string;
|
||||
positionen: Array<{ position_id: number; bezeichnung: string; menge: number; einheit?: string; notizen?: string }>;
|
||||
}>;
|
||||
};
|
||||
|
||||
if (!orders || orders.length === 0) {
|
||||
res.status(400).json({ success: false, message: 'Mindestens eine Bestellung ist erforderlich' });
|
||||
return;
|
||||
}
|
||||
|
||||
const created = await ausruestungsanfrageService.createOrdersFromRequest(anfrageId, orders, req.user!.id);
|
||||
res.status(201).json({ success: true, data: { created_bestellungen: created } });
|
||||
} catch (error) {
|
||||
logger.error('AusruestungsanfrageController.createOrders error', { error });
|
||||
res.status(500).json({ success: false, message: 'Bestellungen konnten nicht erstellt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Widget overview (lightweight, for dashboard widget)
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -69,5 +69,6 @@ router.patch('/positionen/:positionId/geliefert', authenticate, requirePermissio
|
||||
|
||||
router.post('/requests/:id/link', authenticate, requirePermission('ausruestungsanfrage:link_orders'), ausruestungsanfrageController.linkToOrder.bind(ausruestungsanfrageController));
|
||||
router.delete('/requests/:id/link/:bestellungId', authenticate, requirePermission('ausruestungsanfrage:link_orders'), ausruestungsanfrageController.unlinkFromOrder.bind(ausruestungsanfrageController));
|
||||
router.post('/requests/:id/create-orders', authenticate, requirePermission('ausruestungsanfrage:link_orders'), ausruestungsanfrageController.createOrders.bind(ausruestungsanfrageController));
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -716,6 +716,73 @@ async function getLinkedOrders(anfrageId: number) {
|
||||
return result.rows;
|
||||
}
|
||||
|
||||
async function createOrdersFromRequest(
|
||||
anfrageId: number,
|
||||
orders: Array<{
|
||||
lieferant_id: number;
|
||||
bezeichnung: string;
|
||||
positionen: Array<{ position_id: number; bezeichnung: string; menge: number; einheit?: string; notizen?: string }>;
|
||||
}>,
|
||||
userId: string,
|
||||
) {
|
||||
const client = await pool.connect();
|
||||
try {
|
||||
await client.query('BEGIN');
|
||||
|
||||
const createdBestellungen: Array<{ id: number; bezeichnung: string; lieferant_name: string }> = [];
|
||||
|
||||
for (const orderData of orders) {
|
||||
const nrResult = await client.query(
|
||||
`SELECT COALESCE(MAX(laufende_nummer), 0) + 1 AS next_nr
|
||||
FROM bestellungen
|
||||
WHERE EXTRACT(YEAR FROM erstellt_am) = EXTRACT(YEAR FROM NOW())`
|
||||
);
|
||||
const laufendeNummer = nrResult.rows[0].next_nr;
|
||||
|
||||
const bestellungResult = await client.query(
|
||||
`INSERT INTO bestellungen (bezeichnung, lieferant_id, status, laufende_nummer, erstellt_von)
|
||||
VALUES ($1, $2, 'wartet_auf_genehmigung', $3, $4)
|
||||
RETURNING id, bezeichnung`,
|
||||
[orderData.bezeichnung, orderData.lieferant_id, laufendeNummer, userId]
|
||||
);
|
||||
const bestellung = bestellungResult.rows[0];
|
||||
|
||||
for (const pos of orderData.positionen) {
|
||||
await client.query(
|
||||
`INSERT INTO bestellpositionen (bestellung_id, bezeichnung, menge, einheit, notizen)
|
||||
VALUES ($1, $2, $3, $4, $5)`,
|
||||
[bestellung.id, pos.bezeichnung, pos.menge, pos.einheit || 'Stk', pos.notizen || null]
|
||||
);
|
||||
}
|
||||
|
||||
await client.query(
|
||||
`INSERT INTO ausruestung_anfrage_bestellung (anfrage_id, bestellung_id)
|
||||
VALUES ($1, $2) ON CONFLICT DO NOTHING`,
|
||||
[anfrageId, bestellung.id]
|
||||
);
|
||||
|
||||
const vendorResult = await client.query('SELECT name FROM lieferanten WHERE id = $1', [orderData.lieferant_id]);
|
||||
const lieferantName = vendorResult.rows[0]?.name ?? '';
|
||||
|
||||
createdBestellungen.push({ id: bestellung.id, bezeichnung: bestellung.bezeichnung, lieferant_name: lieferantName });
|
||||
}
|
||||
|
||||
await client.query(
|
||||
`UPDATE ausruestung_anfragen SET status = 'bestellt', aktualisiert_am = NOW() WHERE id = $1`,
|
||||
[anfrageId]
|
||||
);
|
||||
|
||||
await client.query('COMMIT');
|
||||
return createdBestellungen;
|
||||
} catch (error) {
|
||||
await client.query('ROLLBACK');
|
||||
logger.error('AusruestungsanfrageService.createOrdersFromRequest failed', { error });
|
||||
throw new Error('Bestellungen konnten nicht erstellt werden');
|
||||
} finally {
|
||||
client.release();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Overview (aggregated)
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -795,6 +862,7 @@ export default {
|
||||
linkToOrder,
|
||||
unlinkFromOrder,
|
||||
getLinkedOrders,
|
||||
createOrdersFromRequest,
|
||||
getOverview,
|
||||
getWidgetOverview,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user