1122 lines
17 KiB
JavaScript
1122 lines
17 KiB
JavaScript
export default {
|
|
ALL_VALUE: "__ALL__",
|
|
|
|
CORE_COLUMNS: [
|
|
"Vorgang",
|
|
"Name",
|
|
"Vorname",
|
|
"E-Mail",
|
|
"Email",
|
|
"Geb.-Datum",
|
|
"Zus_Wunsch",
|
|
"Skipassnummer"
|
|
],
|
|
|
|
getWorkbook() {
|
|
const file = Dateiupload.files?.[0];
|
|
|
|
if (!file) {
|
|
return [];
|
|
}
|
|
|
|
const rawData = file.data;
|
|
|
|
if (
|
|
rawData === null ||
|
|
rawData === undefined ||
|
|
rawData === ""
|
|
) {
|
|
return [];
|
|
}
|
|
|
|
if (typeof rawData === "string") {
|
|
try {
|
|
return JSON.parse(rawData);
|
|
} catch (error) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
return rawData;
|
|
},
|
|
|
|
getSheetRows() {
|
|
const workbook = this.getWorkbook();
|
|
|
|
if (
|
|
!Array.isArray(workbook) ||
|
|
workbook.length === 0
|
|
) {
|
|
return [];
|
|
}
|
|
|
|
/*
|
|
* Appsmith liefert Excel-Dateien meist so:
|
|
*
|
|
* [
|
|
* {
|
|
* name: "!Leistungsliste",
|
|
* data: [
|
|
* ["Vorgang", "Name", "Vorname"],
|
|
* ["98555", "Statz", "Hannah"]
|
|
* ]
|
|
* }
|
|
* ]
|
|
*/
|
|
if (
|
|
workbook[0] !== null &&
|
|
typeof workbook[0] === "object" &&
|
|
!Array.isArray(workbook[0]) &&
|
|
Array.isArray(workbook[0].data)
|
|
) {
|
|
const preferredSheet =
|
|
workbook.find(sheet =>
|
|
String(sheet?.name ?? "")
|
|
.toLowerCase()
|
|
.includes("leistungsliste")
|
|
);
|
|
|
|
const selectedSheet =
|
|
preferredSheet ?? workbook[0];
|
|
|
|
return Array.isArray(selectedSheet?.data)
|
|
? selectedSheet.data
|
|
: [];
|
|
}
|
|
|
|
/*
|
|
* Alternativ können die Zeilen direkt geliefert werden.
|
|
*/
|
|
return workbook;
|
|
},
|
|
|
|
createUniqueHeaders(headerRow) {
|
|
const usedHeaders = {};
|
|
|
|
return headerRow.map((value, index) => {
|
|
let header = String(value ?? "")
|
|
.replace(/\s+/g, " ")
|
|
.trim();
|
|
|
|
if (!header) {
|
|
header = `Spalte_${index + 1}`;
|
|
}
|
|
|
|
usedHeaders[header] =
|
|
(usedHeaders[header] ?? 0) + 1;
|
|
|
|
if (usedHeaders[header] > 1) {
|
|
return `${header}_${usedHeaders[header]}`;
|
|
}
|
|
|
|
return header;
|
|
});
|
|
},
|
|
|
|
rowsAsObjects() {
|
|
const rows = this.getSheetRows();
|
|
|
|
if (
|
|
!Array.isArray(rows) ||
|
|
rows.length === 0
|
|
) {
|
|
return [];
|
|
}
|
|
|
|
/*
|
|
* Daten liegen bereits als Objekte vor.
|
|
*/
|
|
if (
|
|
rows[0] !== null &&
|
|
typeof rows[0] === "object" &&
|
|
!Array.isArray(rows[0])
|
|
) {
|
|
return rows.filter(row =>
|
|
Object.values(row).some(value =>
|
|
String(value ?? "").trim() !== ""
|
|
)
|
|
);
|
|
}
|
|
|
|
/*
|
|
* Daten liegen als Zeilen-Arrays vor.
|
|
* Erste Zeile wird als Überschrift verwendet.
|
|
*/
|
|
if (!Array.isArray(rows[0])) {
|
|
return [];
|
|
}
|
|
|
|
const headers =
|
|
this.createUniqueHeaders(rows[0]);
|
|
|
|
return rows
|
|
.slice(1)
|
|
.filter(row =>
|
|
Array.isArray(row) &&
|
|
row.some(value =>
|
|
String(value ?? "").trim() !== ""
|
|
)
|
|
)
|
|
.map(row => {
|
|
const result = {};
|
|
|
|
headers.forEach((header, index) => {
|
|
result[header] = row[index] ?? "";
|
|
});
|
|
|
|
return result;
|
|
});
|
|
},
|
|
|
|
cleanText(value) {
|
|
return String(value ?? "").trim();
|
|
},
|
|
|
|
quantity(value, fallback = 0) {
|
|
const number = Number(value);
|
|
|
|
if (!Number.isFinite(number)) {
|
|
return Math.max(
|
|
0,
|
|
Math.trunc(Number(fallback) || 0)
|
|
);
|
|
}
|
|
|
|
return Math.max(
|
|
0,
|
|
Math.trunc(number)
|
|
);
|
|
},
|
|
|
|
isBooked(value) {
|
|
const normalized = String(value ?? "")
|
|
.trim()
|
|
.toLowerCase();
|
|
|
|
const emptyValues = [
|
|
"",
|
|
"0",
|
|
"false",
|
|
"nein",
|
|
"no",
|
|
"n",
|
|
"null",
|
|
"undefined",
|
|
"-"
|
|
];
|
|
|
|
return !emptyValues.includes(normalized);
|
|
},
|
|
|
|
formatExcelDate(value) {
|
|
if (
|
|
value === null ||
|
|
value === undefined ||
|
|
value === ""
|
|
) {
|
|
return "";
|
|
}
|
|
|
|
const numericValue = Number(value);
|
|
|
|
/*
|
|
* Excel-Datumswerte sind fortlaufende Nummern.
|
|
* Beispiel: 41495 wird zu einem echten Datum.
|
|
*/
|
|
if (
|
|
Number.isFinite(numericValue) &&
|
|
numericValue > 20000 &&
|
|
numericValue < 100000
|
|
) {
|
|
const milliseconds =
|
|
Math.round(
|
|
(numericValue - 25569) *
|
|
86400 *
|
|
1000
|
|
);
|
|
|
|
const date = new Date(milliseconds);
|
|
|
|
if (!Number.isNaN(date.getTime())) {
|
|
const day = String(
|
|
date.getUTCDate()
|
|
).padStart(2, "0");
|
|
|
|
const month = String(
|
|
date.getUTCMonth() + 1
|
|
).padStart(2, "0");
|
|
|
|
const year =
|
|
date.getUTCFullYear();
|
|
|
|
return `${day}.${month}.${year}`;
|
|
}
|
|
}
|
|
|
|
return this.cleanText(value);
|
|
},
|
|
|
|
getServiceColumns() {
|
|
const rows = this.rowsAsObjects();
|
|
|
|
if (rows.length === 0) {
|
|
return [];
|
|
}
|
|
|
|
return Object.keys(rows[0])
|
|
.filter(column =>
|
|
!this.CORE_COLUMNS.includes(column)
|
|
)
|
|
.filter(column =>
|
|
!column.startsWith("Spalte_")
|
|
);
|
|
},
|
|
|
|
getSavedState() {
|
|
const state =
|
|
appsmith.store?.checkinState;
|
|
|
|
if (
|
|
state !== null &&
|
|
typeof state === "object" &&
|
|
!Array.isArray(state)
|
|
) {
|
|
return state;
|
|
}
|
|
|
|
return {};
|
|
},
|
|
|
|
createPersonId(rawRow, index) {
|
|
const vorgang =
|
|
this.cleanText(rawRow["Vorgang"]);
|
|
|
|
const name =
|
|
this.cleanText(rawRow["Name"]);
|
|
|
|
const vorname =
|
|
this.cleanText(rawRow["Vorname"]);
|
|
|
|
const email =
|
|
this.cleanText(
|
|
rawRow["E-Mail"] ??
|
|
rawRow["Email"]
|
|
);
|
|
|
|
const gebDatum =
|
|
this.cleanText(rawRow["Geb.-Datum"]);
|
|
|
|
return [
|
|
vorgang,
|
|
name,
|
|
vorname,
|
|
email,
|
|
gebDatum,
|
|
index
|
|
]
|
|
.join("|")
|
|
.toLowerCase()
|
|
.replace(/\s+/g, "_");
|
|
},
|
|
|
|
internalRows() {
|
|
const rawRows =
|
|
this.rowsAsObjects();
|
|
|
|
const serviceColumns =
|
|
this.getServiceColumns();
|
|
|
|
const savedState =
|
|
this.getSavedState();
|
|
|
|
return rawRows.map((rawRow, index) => {
|
|
const id =
|
|
this.createPersonId(rawRow, index);
|
|
|
|
const state =
|
|
savedState[id] ?? {};
|
|
|
|
const bookedServices =
|
|
serviceColumns.filter(column =>
|
|
this.isBooked(rawRow[column])
|
|
);
|
|
|
|
return {
|
|
id,
|
|
|
|
vorgang:
|
|
this.cleanText(
|
|
rawRow["Vorgang"]
|
|
),
|
|
|
|
name:
|
|
this.cleanText(
|
|
rawRow["Name"]
|
|
),
|
|
|
|
vorname:
|
|
this.cleanText(
|
|
rawRow["Vorname"]
|
|
),
|
|
|
|
email:
|
|
this.cleanText(
|
|
rawRow["E-Mail"] ??
|
|
rawRow["Email"]
|
|
),
|
|
|
|
gebDatum:
|
|
this.formatExcelDate(
|
|
rawRow["Geb.-Datum"]
|
|
),
|
|
|
|
zimmer:
|
|
state.zimmer ??
|
|
this.cleanText(
|
|
rawRow["Zus_Wunsch"]
|
|
),
|
|
|
|
schluessel:
|
|
this.quantity(
|
|
state.schluessel,
|
|
0
|
|
),
|
|
|
|
schluesselRetour:
|
|
this.quantity(
|
|
state.schluesselRetour,
|
|
0
|
|
),
|
|
|
|
leistungenListe:
|
|
bookedServices,
|
|
|
|
leistungen:
|
|
bookedServices.join(" · "),
|
|
|
|
skipassnummer:
|
|
state.skipassnummer ??
|
|
this.cleanText(
|
|
rawRow["Skipassnummer"]
|
|
),
|
|
|
|
notiz:
|
|
state.notiz ?? "",
|
|
|
|
stirnlampe:
|
|
this.quantity(
|
|
state.stirnlampe,
|
|
0
|
|
),
|
|
|
|
stirnlampeRetour:
|
|
this.quantity(
|
|
state.stirnlampeRetour,
|
|
0
|
|
),
|
|
|
|
nachbuchungen:
|
|
Array.isArray(
|
|
state.nachbuchungen
|
|
)
|
|
? state.nachbuchungen
|
|
: [],
|
|
|
|
status:
|
|
state.status ?? "offen",
|
|
|
|
reiseStatus:
|
|
state.reiseStatus ?? "aktiv",
|
|
|
|
checkedIn:
|
|
Boolean(
|
|
state.checkedIn ??
|
|
false
|
|
),
|
|
|
|
checkedInAt:
|
|
state.checkedInAt ?? "",
|
|
|
|
checkedInBy:
|
|
state.checkedInBy ?? ""
|
|
};
|
|
});
|
|
},
|
|
|
|
vorgangOptions() {
|
|
const vorgaenge = [
|
|
...new Set(
|
|
this.internalRows()
|
|
.map(row => row.vorgang)
|
|
.filter(Boolean)
|
|
)
|
|
].sort((a, b) =>
|
|
a.localeCompare(
|
|
b,
|
|
"de",
|
|
{
|
|
numeric: true
|
|
}
|
|
)
|
|
);
|
|
|
|
return [
|
|
{
|
|
label: "Alle Gruppen",
|
|
value: this.ALL_VALUE
|
|
},
|
|
...vorgaenge.map(vorgang => ({
|
|
label: vorgang,
|
|
value: vorgang
|
|
}))
|
|
];
|
|
},
|
|
|
|
leistungOptions() {
|
|
const services = [
|
|
...new Set(
|
|
this.internalRows()
|
|
.flatMap(row =>
|
|
row.leistungenListe ?? []
|
|
)
|
|
.filter(Boolean)
|
|
)
|
|
].sort((a, b) =>
|
|
a.localeCompare(b, "de")
|
|
);
|
|
|
|
return [
|
|
{
|
|
label: "Alle Leistungen",
|
|
value: this.ALL_VALUE
|
|
},
|
|
...services.map(service => ({
|
|
label: service,
|
|
value: service
|
|
}))
|
|
];
|
|
},
|
|
|
|
filteredInternalRows() {
|
|
let rows = [
|
|
...this.internalRows()
|
|
];
|
|
|
|
const uploadAktiv =
|
|
DatenquelleTabs.selectedTab ===
|
|
"Liste hochladen";
|
|
|
|
/*
|
|
* Suche
|
|
*/
|
|
const searchText =
|
|
this.cleanText(
|
|
uploadAktiv
|
|
? inpSucheUpload.text
|
|
: inpSuche.text
|
|
).toLowerCase();
|
|
|
|
if (searchText) {
|
|
rows = rows.filter(row => {
|
|
const searchableText = [
|
|
row.vorgang,
|
|
row.name,
|
|
row.vorname,
|
|
row.email,
|
|
row.gebDatum,
|
|
row.zimmer,
|
|
row.skipassnummer,
|
|
row.leistungen
|
|
]
|
|
.join(" ")
|
|
.toLowerCase();
|
|
|
|
return searchableText.includes(
|
|
searchText
|
|
);
|
|
});
|
|
}
|
|
|
|
/*
|
|
* Vorgangs-/Gruppenfilter
|
|
*/
|
|
const selectedVorgang =
|
|
(
|
|
uploadAktiv
|
|
? selVorgangUpload.selectedOptionValue
|
|
: selVorgang.selectedOptionValue
|
|
) ||
|
|
this.ALL_VALUE;
|
|
|
|
if (
|
|
selectedVorgang !==
|
|
this.ALL_VALUE
|
|
) {
|
|
rows = rows.filter(row =>
|
|
row.vorgang ===
|
|
String(selectedVorgang)
|
|
);
|
|
}
|
|
|
|
/*
|
|
* Check-in-Filter
|
|
*/
|
|
const selectedCheckin =
|
|
(
|
|
uploadAktiv
|
|
? selCheckinUpload.selectedOptionValue
|
|
: selCheckin.selectedOptionValue
|
|
) ||
|
|
this.ALL_VALUE;
|
|
|
|
if (
|
|
selectedCheckin === "checked"
|
|
) {
|
|
rows = rows.filter(row =>
|
|
row.checkedIn === true
|
|
);
|
|
}
|
|
|
|
if (
|
|
selectedCheckin === "pending"
|
|
) {
|
|
rows = rows.filter(row =>
|
|
row.checkedIn === false
|
|
);
|
|
}
|
|
|
|
/*
|
|
* Reisestatusfilter
|
|
*/
|
|
const selectedReiseStatus =
|
|
(
|
|
uploadAktiv
|
|
? selReiseStatusUpload.selectedOptionValue
|
|
: selReiseStatus.selectedOptionValue
|
|
) ||
|
|
this.ALL_VALUE;
|
|
|
|
if (
|
|
selectedReiseStatus !==
|
|
this.ALL_VALUE
|
|
) {
|
|
rows = rows.filter(row =>
|
|
row.reiseStatus ===
|
|
selectedReiseStatus
|
|
);
|
|
}
|
|
|
|
/*
|
|
* Leistungsfilter
|
|
*/
|
|
const selectedLeistung =
|
|
(
|
|
uploadAktiv
|
|
? selLeistungUpload.selectedOptionValue
|
|
: selLeistung.selectedOptionValue
|
|
) ||
|
|
this.ALL_VALUE;
|
|
|
|
if (
|
|
selectedLeistung !==
|
|
this.ALL_VALUE
|
|
) {
|
|
rows = rows.filter(row =>
|
|
row.leistungenListe.includes(
|
|
selectedLeistung
|
|
)
|
|
);
|
|
}
|
|
|
|
return rows;
|
|
},
|
|
|
|
filteredRows() {
|
|
return this.filteredInternalRows()
|
|
.map(row => ({
|
|
id:
|
|
row.id,
|
|
|
|
Vorgang:
|
|
row.vorgang,
|
|
|
|
Name:
|
|
row.name,
|
|
|
|
Vorname:
|
|
row.vorname,
|
|
|
|
"E-Mail":
|
|
row.email,
|
|
|
|
"Geb.-Datum":
|
|
row.gebDatum,
|
|
|
|
Zimmer:
|
|
row.zimmer,
|
|
|
|
Schlüssel:
|
|
row.schluessel,
|
|
|
|
"Schlüssel retour":
|
|
row.schluesselRetour,
|
|
|
|
"Skipass / Leistungen":
|
|
row.leistungen,
|
|
|
|
Skipassnummer:
|
|
row.skipassnummer,
|
|
|
|
Notiz:
|
|
row.notiz,
|
|
|
|
Stirnlampe:
|
|
row.stirnlampe,
|
|
|
|
"Stirnlampe retour":
|
|
row.stirnlampeRetour,
|
|
|
|
Nachbuchungen:
|
|
row.nachbuchungen.length,
|
|
|
|
Status:
|
|
row.status,
|
|
|
|
Reisestatus:
|
|
row.reiseStatus,
|
|
|
|
Eingecheckt:
|
|
row.checkedIn,
|
|
|
|
"Check-in Zeitpunkt":
|
|
row.checkedInAt,
|
|
|
|
"Check-in Benutzer":
|
|
row.checkedInBy
|
|
}));
|
|
},
|
|
|
|
stats() {
|
|
const rows =
|
|
this.internalRows();
|
|
|
|
return {
|
|
gesamt:
|
|
rows.length,
|
|
|
|
eingecheckt:
|
|
rows.filter(row =>
|
|
row.checkedIn === true
|
|
).length,
|
|
|
|
ausstehend:
|
|
rows.filter(row =>
|
|
row.checkedIn === false
|
|
).length,
|
|
|
|
gruppen:
|
|
new Set(
|
|
rows
|
|
.map(row => row.vorgang)
|
|
.filter(Boolean)
|
|
).size
|
|
};
|
|
},
|
|
|
|
async savePersonState(
|
|
personId,
|
|
changes
|
|
) {
|
|
if (!personId) {
|
|
showAlert(
|
|
"Teilnehmer-ID fehlt.",
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
const currentState = {
|
|
...this.getSavedState()
|
|
};
|
|
|
|
currentState[personId] = {
|
|
...(currentState[personId] ?? {}),
|
|
...changes,
|
|
|
|
updatedAt:
|
|
new Date().toISOString(),
|
|
|
|
updatedBy:
|
|
appsmith.user?.email ||
|
|
"lokaler Benutzer"
|
|
};
|
|
|
|
await storeValue(
|
|
"checkinState",
|
|
currentState,
|
|
true
|
|
);
|
|
|
|
return true;
|
|
},
|
|
|
|
async toggleCheckin(tableRow) {
|
|
if (!tableRow?.id) {
|
|
showAlert(
|
|
"Teilnehmer konnte nicht ermittelt werden.",
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
const gespeicherterStatus =
|
|
this.getSavedState()[tableRow.id] || {};
|
|
|
|
const aktuellEingecheckt =
|
|
gespeicherterStatus.checkedIn === true ||
|
|
tableRow.Eingecheckt === true ||
|
|
tableRow.checkedIn === true;
|
|
|
|
const newCheckedIn =
|
|
!aktuellEingecheckt;
|
|
|
|
await this.savePersonState(
|
|
tableRow.id,
|
|
{
|
|
checkedIn:
|
|
newCheckedIn,
|
|
|
|
checkedInAt:
|
|
newCheckedIn
|
|
? new Date().toISOString()
|
|
: "",
|
|
|
|
checkedInBy:
|
|
newCheckedIn
|
|
? (
|
|
appsmith.user?.email ||
|
|
"lokaler Benutzer"
|
|
)
|
|
: ""
|
|
}
|
|
);
|
|
|
|
const vorname =
|
|
tableRow.Vorname ||
|
|
tableRow.vorname ||
|
|
"";
|
|
|
|
const name =
|
|
tableRow.Name ||
|
|
tableRow.name ||
|
|
"";
|
|
|
|
showAlert(
|
|
newCheckedIn
|
|
? `${vorname} ${name} wurde eingecheckt.`
|
|
: `Check-in von ${vorname} ${name} wurde aufgehoben.`,
|
|
newCheckedIn
|
|
? "success"
|
|
: "warning"
|
|
);
|
|
|
|
return true;
|
|
},
|
|
|
|
async saveUpdatedRow(updatedRow) {
|
|
if (!updatedRow?.id) {
|
|
showAlert(
|
|
"Die bearbeitete Person konnte nicht ermittelt werden.",
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
const person =
|
|
this.internalRows().find(row =>
|
|
row.id === updatedRow.id
|
|
);
|
|
|
|
if (!person) {
|
|
showAlert(
|
|
"Teilnehmer wurde nicht gefunden.",
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
const schluesselValue =
|
|
this.quantity(
|
|
updatedRow["Schlüssel"],
|
|
person.schluessel
|
|
);
|
|
|
|
const schluesselRetourValue =
|
|
this.quantity(
|
|
updatedRow["Schlüssel retour"],
|
|
person.schluesselRetour
|
|
);
|
|
|
|
const stirnlampeValue =
|
|
this.quantity(
|
|
updatedRow["Stirnlampe"],
|
|
person.stirnlampe
|
|
);
|
|
|
|
const stirnlampeRetourValue =
|
|
this.quantity(
|
|
updatedRow["Stirnlampe retour"],
|
|
person.stirnlampeRetour
|
|
);
|
|
|
|
if (
|
|
schluesselRetourValue >
|
|
schluesselValue
|
|
) {
|
|
showAlert(
|
|
"Es können nicht mehr Schlüssel zurückgegeben als ausgegeben werden.",
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (
|
|
stirnlampeRetourValue >
|
|
stirnlampeValue
|
|
) {
|
|
showAlert(
|
|
"Es können nicht mehr Stirnlampen zurückgegeben als ausgegeben werden.",
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
await this.savePersonState(
|
|
person.id,
|
|
{
|
|
zimmer:
|
|
this.cleanText(
|
|
updatedRow["Zimmer"] ??
|
|
person.zimmer
|
|
),
|
|
|
|
schluessel:
|
|
schluesselValue,
|
|
|
|
schluesselRetour:
|
|
schluesselRetourValue,
|
|
|
|
skipassnummer:
|
|
this.cleanText(
|
|
updatedRow["Skipassnummer"] ??
|
|
person.skipassnummer
|
|
),
|
|
|
|
notiz:
|
|
this.cleanText(
|
|
updatedRow["Notiz"] ??
|
|
person.notiz
|
|
),
|
|
|
|
stirnlampe:
|
|
stirnlampeValue,
|
|
|
|
stirnlampeRetour:
|
|
stirnlampeRetourValue,
|
|
|
|
status:
|
|
this.cleanText(
|
|
updatedRow["Status"] ??
|
|
person.status
|
|
),
|
|
|
|
reiseStatus:
|
|
this.cleanText(
|
|
updatedRow["Reisestatus"] ??
|
|
person.reiseStatus
|
|
)
|
|
}
|
|
);
|
|
|
|
showAlert(
|
|
"Änderungen gespeichert.",
|
|
"success"
|
|
);
|
|
|
|
return true;
|
|
},
|
|
|
|
async saveAusgabe(
|
|
personId,
|
|
schluessel,
|
|
stirnlampe
|
|
) {
|
|
const person =
|
|
this.internalRows().find(row =>
|
|
row.id === personId
|
|
);
|
|
|
|
if (!person) {
|
|
showAlert(
|
|
"Teilnehmer wurde nicht gefunden.",
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
const schluesselValue =
|
|
this.quantity(schluessel, 0);
|
|
|
|
const stirnlampeValue =
|
|
this.quantity(stirnlampe, 0);
|
|
|
|
if (
|
|
person.schluesselRetour >
|
|
schluesselValue
|
|
) {
|
|
showAlert(
|
|
"Die ausgegebene Schlüsselmenge darf nicht kleiner als die bereits erfasste Rückgabe sein.",
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (
|
|
person.stirnlampeRetour >
|
|
stirnlampeValue
|
|
) {
|
|
showAlert(
|
|
"Die ausgegebene Stirnlampenmenge darf nicht kleiner als die bereits erfasste Rückgabe sein.",
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
await this.savePersonState(
|
|
person.id,
|
|
{
|
|
schluessel:
|
|
schluesselValue,
|
|
|
|
stirnlampe:
|
|
stirnlampeValue
|
|
}
|
|
);
|
|
|
|
showAlert(
|
|
`Ausgabe für ${person.vorname} ${person.name} gespeichert.`,
|
|
"success"
|
|
);
|
|
|
|
return true;
|
|
},
|
|
|
|
async saveRueckgabe(
|
|
personId,
|
|
schluesselRetour,
|
|
stirnlampeRetour
|
|
) {
|
|
const person =
|
|
this.internalRows().find(row =>
|
|
row.id === personId
|
|
);
|
|
|
|
if (!person) {
|
|
showAlert(
|
|
"Teilnehmer wurde nicht gefunden.",
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
const schluesselRetourValue =
|
|
this.quantity(
|
|
schluesselRetour,
|
|
person.schluesselRetour
|
|
);
|
|
|
|
const stirnlampeRetourValue =
|
|
this.quantity(
|
|
stirnlampeRetour,
|
|
person.stirnlampeRetour
|
|
);
|
|
|
|
if (
|
|
schluesselRetourValue >
|
|
person.schluessel
|
|
) {
|
|
showAlert(
|
|
`Maximal ${person.schluessel} Schlüssel können zurückgegeben werden.`,
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (
|
|
stirnlampeRetourValue >
|
|
person.stirnlampe
|
|
) {
|
|
showAlert(
|
|
`Maximal ${person.stirnlampe} Stirnlampen können zurückgegeben werden.`,
|
|
"error"
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
await this.savePersonState(
|
|
person.id,
|
|
{
|
|
schluesselRetour:
|
|
schluesselRetourValue,
|
|
|
|
stirnlampeRetour:
|
|
stirnlampeRetourValue,
|
|
|
|
rueckgabeAt:
|
|
new Date().toISOString(),
|
|
|
|
rueckgabeBy:
|
|
appsmith.user?.email ||
|
|
"lokaler Benutzer"
|
|
}
|
|
);
|
|
|
|
showAlert(
|
|
`Rückgabe für ${person.vorname} ${person.name} gespeichert.`,
|
|
"success"
|
|
);
|
|
|
|
return true;
|
|
},
|
|
|
|
async resetCheckinState() {
|
|
await removeValue(
|
|
"checkinState"
|
|
);
|
|
|
|
showAlert(
|
|
"Gespeicherte Check-in-Daten wurden zurückgesetzt.",
|
|
"success"
|
|
);
|
|
|
|
return true;
|
|
},
|
|
|
|
async checkinButtonClick() {
|
|
return await this.toggleCheckin(
|
|
Teilnehmer.triggeredRow
|
|
);
|
|
}
|
|
}; |