feat(persoenliche-ausruestung): add quantity field and article-grouped replacement flow in order dialog

This commit is contained in:
Matthias Hochmeister
2026-04-24 12:36:28 +02:00
parent 9410441ce2
commit 4ec719ad0a
15 changed files with 263 additions and 96 deletions

View File

@@ -573,6 +573,7 @@ class AusruestungsanfrageController {
groesse?: string;
kategorie?: string;
eigenschaften?: Array<{ eigenschaft_id?: number; name: string; wert: string }>;
replacedItemIds?: string[];
}>;
};

View File

@@ -34,6 +34,7 @@ const CreateSchema = z.object({
anschaffung_datum: isoDate.optional(),
zustand: ZustandEnum.optional(),
notizen: z.string().max(2000).optional(),
menge: z.number().int().min(1).default(1).optional(),
eigenschaften: z.array(EigenschaftInput).optional(),
});
@@ -49,6 +50,7 @@ const UpdateSchema = z.object({
anschaffung_datum: isoDate.nullable().optional(),
zustand: ZustandEnum.optional(),
notizen: z.string().max(2000).nullable().optional(),
menge: z.number().int().min(1).nullable().optional(),
eigenschaften: z.array(EigenschaftInput).nullable().optional(),
});

View File

@@ -0,0 +1 @@
ALTER TABLE persoenliche_ausruestung ADD COLUMN IF NOT EXISTS menge INT NOT NULL DEFAULT 1;

View File

@@ -1007,6 +1007,7 @@ interface AssignmentInput {
groesse?: string;
kategorie?: string;
eigenschaften?: { eigenschaft_id?: number; name: string; wert: string }[];
replacedItemIds?: string[];
}
async function assignDeliveredItems(
@@ -1033,7 +1034,7 @@ async function assignDeliveredItems(
for (const a of assignments) {
// Load position details
const posResult = await client.query(
'SELECT bezeichnung, artikel_id FROM ausruestung_anfrage_positionen WHERE id = $1 AND anfrage_id = $2',
'SELECT bezeichnung, artikel_id, menge FROM ausruestung_anfrage_positionen WHERE id = $1 AND anfrage_id = $2',
[a.positionId, anfrageId],
);
if (posResult.rows.length === 0) continue;
@@ -1088,8 +1089,8 @@ async function assignDeliveredItems(
const insertResult = await client.query(
`INSERT INTO persoenliche_ausruestung (
bezeichnung, kategorie, groesse, user_id, benutzer_name,
anfrage_id, anfrage_position_id, artikel_id, erstellt_von
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
anfrage_id, anfrage_position_id, artikel_id, menge, erstellt_von
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING id`,
[
pos.bezeichnung,
@@ -1100,6 +1101,7 @@ async function assignDeliveredItems(
anfrageId,
a.positionId,
pos.artikel_id ?? null,
pos.menge ?? 1,
requestingUserId,
],
);
@@ -1146,6 +1148,15 @@ async function assignDeliveredItems(
);
}
if (a.replacedItemIds && a.replacedItemIds.length > 0) {
await client.query(
`UPDATE persoenliche_ausruestung
SET geloescht_am = NOW()
WHERE id = ANY($1::uuid[]) AND geloescht_am IS NULL`,
[a.replacedItemIds],
);
}
assigned++;
}

View File

@@ -19,6 +19,7 @@ interface CreatePersonalEquipmentData {
anschaffung_datum?: string;
zustand?: string;
notizen?: string;
menge?: number;
eigenschaften?: { eigenschaft_id?: number | null; name: string; wert: string }[];
}
@@ -34,6 +35,7 @@ interface UpdatePersonalEquipmentData {
anschaffung_datum?: string | null;
zustand?: string;
notizen?: string | null;
menge?: number | null;
eigenschaften?: { eigenschaft_id?: number | null; name: string; wert: string }[] | null;
}
@@ -154,8 +156,8 @@ async function create(data: CreatePersonalEquipmentData, requestingUserId: strin
`INSERT INTO persoenliche_ausruestung (
bezeichnung, kategorie, artikel_id, user_id, benutzer_name,
groesse, seriennummer, inventarnummer, anschaffung_datum,
zustand, notizen, erstellt_von
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)
zustand, notizen, menge, erstellt_von
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13)
RETURNING *`,
[
data.bezeichnung,
@@ -169,6 +171,7 @@ async function create(data: CreatePersonalEquipmentData, requestingUserId: strin
data.anschaffung_datum ?? null,
data.zustand ?? 'gut',
data.notizen ?? null,
data.menge ?? 1,
requestingUserId,
],
);
@@ -214,6 +217,7 @@ async function update(id: string, data: UpdatePersonalEquipmentData) {
if (data.anschaffung_datum !== undefined) addField('anschaffung_datum', data.anschaffung_datum);
if (data.zustand !== undefined) addField('zustand', data.zustand);
if (data.notizen !== undefined) addField('notizen', data.notizen);
if (data.menge !== undefined) addField('menge', data.menge ?? 1);
if (fields.length === 0 && data.eigenschaften === undefined) {
throw new Error('No fields to update');