Add church office requirements validation in FalukantService: Implement checks for prerequisite office types when determining available positions, enhancing the application process for church offices based on user qualifications.

This commit is contained in:
Torsten Schulz (local)
2026-01-28 16:52:44 +01:00
parent f102069f5a
commit 8e20fbd24d

View File

@@ -51,6 +51,7 @@ import Election from '../models/falukant/data/election.js';
import ChurchOffice from '../models/falukant/data/church_office.js'; import ChurchOffice from '../models/falukant/data/church_office.js';
import ChurchOfficeType from '../models/falukant/type/church_office_type.js'; import ChurchOfficeType from '../models/falukant/type/church_office_type.js';
import ChurchApplication from '../models/falukant/data/church_application.js'; import ChurchApplication from '../models/falukant/data/church_application.js';
import ChurchOfficeRequirement from '../models/falukant/predefine/church_office_requirement.js';
import PoliticalOfficeType from '../models/falukant/type/political_office_type.js'; import PoliticalOfficeType from '../models/falukant/type/political_office_type.js';
import Candidate from '../models/falukant/data/candidate.js'; import Candidate from '../models/falukant/data/candidate.js';
import Vote from '../models/falukant/data/vote.js'; import Vote from '../models/falukant/data/vote.js';
@@ -4103,7 +4104,8 @@ class FalukantService extends BaseService {
history: matchingHistory, history: matchingHistory,
alreadyApplied alreadyApplied
}; };
}); })
.filter(election => !election.alreadyApplied); // Nur Positionen ohne bestehende Bewerbung
return result; return result;
} }
@@ -4955,17 +4957,70 @@ class FalukantService extends BaseService {
return []; return [];
} }
// Prüfe welche Kirchenämter der Charakter bereits innehat
const heldOffices = await ChurchOffice.findAll({
where: { characterId: character.id },
include: [
{
model: ChurchOfficeType,
as: 'type',
attributes: ['id']
}
]
});
const heldOfficeTypeIds = heldOffices.map(o => o.type.id);
// Prüfe welche Bewerbungen bereits existieren
const existingApplications = await ChurchApplication.findAll({
where: {
characterId: character.id,
status: 'pending'
},
attributes: ['officeTypeId', 'regionId']
});
const appliedPositions = new Set(
existingApplications.map(a => `${a.officeTypeId}-${a.regionId}`)
);
// Alle relevanten Regionen (Region + Eltern) laden // Alle relevanten Regionen (Region + Eltern) laden
const relevantRegionIds = await this.getRegionAndParentIds(character.regionId); const relevantRegionIds = await this.getRegionAndParentIds(character.regionId);
// Alle Kirchenamt-Typen laden // Alle Kirchenamt-Typen mit Voraussetzungen laden
const officeTypes = await ChurchOfficeType.findAll({ const officeTypes = await ChurchOfficeType.findAll({
include: [
{
model: ChurchOfficeRequirement,
as: 'requirements',
required: false
}
],
order: [['hierarchyLevel', 'ASC']] order: [['hierarchyLevel', 'ASC']]
}); });
const availablePositions = []; const availablePositions = [];
for (const officeType of officeTypes) { for (const officeType of officeTypes) {
// Prüfe Voraussetzungen: Hat der User bereits das erforderliche niedrigere Amt?
const requirement = officeType.requirements?.[0];
if (requirement && requirement.prerequisiteOfficeTypeId) {
// Prüfe ob der User das erforderliche Amt innehat
if (!heldOfficeTypeIds.includes(requirement.prerequisiteOfficeTypeId)) {
continue; // Voraussetzung nicht erfüllt
}
} else if (requirement && requirement.prerequisiteOfficeTypeId === null) {
// Keine Voraussetzung = Einstiegsposition, OK
} else if (heldOfficeTypeIds.length === 0) {
// Wenn keine Voraussetzung definiert ist, aber User hat noch kein Amt, nur Einstiegspositionen zeigen
if (officeType.hierarchyLevel > 0) {
continue;
}
}
// Prüfe ob der User bereits dieses Amt innehat
if (heldOfficeTypeIds.includes(officeType.id)) {
continue; // User hat bereits dieses Amt
}
// Finde den RegionType für diesen officeType // Finde den RegionType für diesen officeType
const regionType = await RegionType.findOne({ const regionType = await RegionType.findOne({
where: { labelTr: officeType.regionType } where: { labelTr: officeType.regionType }
@@ -4982,6 +5037,24 @@ class FalukantService extends BaseService {
}); });
for (const region of regions) { for (const region of regions) {
// Prüfe ob bereits eine Bewerbung für diese Position existiert
const applicationKey = `${officeType.id}-${region.id}`;
if (appliedPositions.has(applicationKey)) {
continue; // Bereits beworben
}
// Prüfe ob der User bereits dieses Amt in dieser Region innehat
const hasOfficeInRegion = await ChurchOffice.findOne({
where: {
characterId: character.id,
officeTypeId: officeType.id,
regionId: region.id
}
});
if (hasOfficeInRegion) {
continue; // User hat bereits dieses Amt in dieser Region
}
// Zähle besetzte Positionen dieses Typs in dieser Region // Zähle besetzte Positionen dieses Typs in dieser Region
const occupiedCount = await ChurchOffice.count({ const occupiedCount = await ChurchOffice.count({
where: { where: {