update
This commit is contained in:
@@ -23,6 +23,7 @@ router.patch('/:id', authenticate, requirePermission('bookings:write'), bookingC
|
|||||||
|
|
||||||
// Soft-cancel (sets abgesagt=TRUE)
|
// Soft-cancel (sets abgesagt=TRUE)
|
||||||
router.delete('/:id', authenticate, requirePermission('bookings:write'), bookingController.cancel.bind(bookingController));
|
router.delete('/:id', authenticate, requirePermission('bookings:write'), bookingController.cancel.bind(bookingController));
|
||||||
|
router.patch('/:id/cancel', authenticate, requirePermission('bookings:write'), bookingController.cancel.bind(bookingController));
|
||||||
|
|
||||||
// Hard-delete (admin only)
|
// Hard-delete (admin only)
|
||||||
router.delete('/:id/force', authenticate, requirePermission('bookings:delete'), bookingController.hardDelete.bind(bookingController));
|
router.delete('/:id/force', authenticate, requirePermission('bookings:delete'), bookingController.hardDelete.bind(bookingController));
|
||||||
|
|||||||
@@ -277,7 +277,8 @@ function FahrzeugBuchungen() {
|
|||||||
setDetailBooking(null);
|
setDetailBooking(null);
|
||||||
loadData();
|
loadData();
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const msg = e instanceof Error ? e.message : 'Fehler beim Stornieren';
|
const axiosErr = e as { response?: { data?: { message?: string } }; message?: string };
|
||||||
|
const msg = axiosErr?.response?.data?.message || (e instanceof Error ? e.message : 'Fehler beim Stornieren');
|
||||||
notification.showError(msg);
|
notification.showError(msg);
|
||||||
} finally {
|
} finally {
|
||||||
setCancelLoading(false);
|
setCancelLoading(false);
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export const bookingApi = {
|
|||||||
|
|
||||||
cancel(id: string, abgesagt_grund: string): Promise<void> {
|
cancel(id: string, abgesagt_grund: string): Promise<void> {
|
||||||
return api
|
return api
|
||||||
.delete(`/api/bookings/${id}`, { data: { abgesagt_grund } })
|
.patch(`/api/bookings/${id}/cancel`, { abgesagt_grund })
|
||||||
.then(() => undefined);
|
.then(() => undefined);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -905,11 +905,21 @@ async function scrapeMemberFahrgenehmigungen(
|
|||||||
const pageData = await frame.evaluate(() => {
|
const pageData = await frame.evaluate(() => {
|
||||||
const extractCellValue = (cell: Element): string => {
|
const extractCellValue = (cell: Element): string => {
|
||||||
const input = cell.querySelector('input[type="text"], input:not([type])') as HTMLInputElement | null;
|
const input = cell.querySelector('input[type="text"], input:not([type])') as HTMLInputElement | null;
|
||||||
if (input) return input.value?.trim() ?? '';
|
if (input && input.value?.trim()) return input.value.trim();
|
||||||
const sel = cell.querySelector('select') as HTMLSelectElement | null;
|
const sel = cell.querySelector('select') as HTMLSelectElement | null;
|
||||||
if (sel) {
|
if (sel) {
|
||||||
const opt = sel.options[sel.selectedIndex];
|
const idx = sel.selectedIndex;
|
||||||
return (opt?.text || opt?.value || '').trim();
|
if (idx >= 0 && sel.options[idx]) {
|
||||||
|
const t = (sel.options[idx].text || sel.options[idx].value || '').trim();
|
||||||
|
if (t) return t;
|
||||||
|
}
|
||||||
|
if (sel.value?.trim()) return sel.value.trim();
|
||||||
|
const selectedOpt = sel.querySelector('option[selected]') as HTMLOptionElement | null;
|
||||||
|
if (selectedOpt) {
|
||||||
|
const t = (selectedOpt.text || selectedOpt.value || '').trim();
|
||||||
|
if (t) return t;
|
||||||
|
}
|
||||||
|
// fall through to textContent if select is empty
|
||||||
}
|
}
|
||||||
const anchor = cell.querySelector('a');
|
const anchor = cell.querySelector('a');
|
||||||
const atitle = anchor?.getAttribute('title')?.trim();
|
const atitle = anchor?.getAttribute('title')?.trim();
|
||||||
|
|||||||
Reference in New Issue
Block a user