diff --git a/backend/services/falukantService.js b/backend/services/falukantService.js index a790f17..f154331 100644 --- a/backend/services/falukantService.js +++ b/backend/services/falukantService.js @@ -2223,26 +2223,64 @@ class FalukantService extends BaseService { async generateProposals(falukantUserId, regionId) { try { - const threeWeeksAgo = new Date(Date.now() - 21 * 24 * 60 * 60 * 1000); + const twentyOneDaysAgo = new Date(Date.now() - 21 * 24 * 60 * 60 * 1000); + const relevantRegionIds = await this.getRegionAndParentIds(regionId); + + const employerCharacter = await FalukantCharacter.findOne({ + where: { userId: falukantUserId }, + attributes: ['id'] + }); + const excludeCharacterId = employerCharacter?.id ?? null; + const proposalCount = Math.floor(Math.random() * 3) + 3; + const usedCharacterIds = new Set(); + for (let i = 0; i < proposalCount; i++) { - const directorCharacter = await FalukantCharacter.findOne({ - where: { - regionId, - createdAt: { [Op.lt]: threeWeeksAgo }, - }, + const buildWhere = (includeMinAge = true) => { + const w = { + regionId: { [Op.in]: relevantRegionIds }, + }; + if (includeMinAge) w.birthdate = { [Op.lte]: twentyOneDaysAgo }; + if (usedCharacterIds.size > 0) w.id = { [Op.notIn]: Array.from(usedCharacterIds) }; + if (excludeCharacterId) { + w[Op.or] = [ + { userId: null }, + { userId: { [Op.ne]: falukantUserId } } + ]; + } + return w; + }; + + let directorCharacter = await FalukantCharacter.findOne({ + where: buildWhere(true), // birthdate <= 21 Tage her = mind. 21 Tage alt include: [ { model: TitleOfNobility, as: 'nobleTitle', attributes: ['level'], + required: true }, ], order: sequelize.literal('RANDOM()'), }); + if (!directorCharacter) { + directorCharacter = await FalukantCharacter.findOne({ + where: buildWhere(false), // Fallback ohne Altersfilter + include: [ + { + model: TitleOfNobility, + as: 'nobleTitle', + attributes: ['level'], + required: true + }, + ], + order: sequelize.literal('RANDOM()'), + }); + } if (!directorCharacter) { throw new Error('No directors available for the region'); } + usedCharacterIds.add(directorCharacter.id); const avgKnowledge = await this.calculateAverageKnowledge(directorCharacter.id); const proposedIncome = Math.round( directorCharacter.nobleTitle.level * Math.pow(1.231, avgKnowledge / 1.5)