diff --git a/backend/models/falukant/data/director.js b/backend/models/falukant/data/director.js index cf6276e..ec427af 100644 --- a/backend/models/falukant/data/director.js +++ b/backend/models/falukant/data/director.js @@ -33,6 +33,10 @@ Director.init({ type: DataTypes.BOOLEAN, allowNull: false, defaultValue: true}, + autoAdjustIncome: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false}, lastSalaryPayout: { type: DataTypes.DATE, allowNull: false, diff --git a/backend/services/falukantService.js b/backend/services/falukantService.js index d5d56af..29aa355 100644 --- a/backend/services/falukantService.js +++ b/backend/services/falukantService.js @@ -3328,7 +3328,7 @@ class FalukantService extends BaseService { { model: RegionData, as: 'region', - attributes: ['name'] + attributes: ['id', 'name'] } ] }, @@ -3351,6 +3351,7 @@ class FalukantService extends BaseService { return { director: { id: director.id, + directorCharacterId: director.directorCharacterId, character: { name: `${director.character.definedFirstName.name} ${director.character.definedLastName.name}`, title: director.character.nobleTitle.labelTr, @@ -3366,6 +3367,8 @@ class FalukantService extends BaseService { mayProduce: director.mayProduce, maySell: director.maySell, mayStartTransport: director.mayStartTransport, + autoAdjustIncome: director.autoAdjustIncome, + regionId: director.character.region?.id || director.character.regionId || null, region: director.character.region?.name || null, wishedIncome, }, @@ -3420,7 +3423,7 @@ class FalukantService extends BaseService { ] }, ], - attributes: ['id', 'satisfaction', 'income'], + attributes: ['id', 'satisfaction', 'income', 'autoAdjustIncome'], }); return directors .filter(director => director.character != null) @@ -3436,10 +3439,13 @@ class FalukantService extends BaseService { ); return { id: director.id, + directorCharacterId: char.id, satisfaction: director.satisfaction, character: char, age: calcAge(char.birthdate), income: director.income, + autoAdjustIncome: director.autoAdjustIncome, + regionId: char.region?.id ?? null, region: char.region?.name ?? '', wishedIncome, }; @@ -3488,8 +3494,18 @@ class FalukantService extends BaseService { if (!director) { return null; } + const allowedKeys = new Set([ + 'mayProduce', + 'maySell', + 'mayStartTransport', + 'mayRepairVehicles', + 'autoAdjustIncome', + ]); + if (!allowedKeys.has(settingKey)) { + throw new Error('Invalid setting key'); + } const updateData = {}; - updateData[settingKey] = value || false; + updateData[settingKey] = !!value; await Director.update(updateData, { where: { @@ -8905,15 +8921,18 @@ async function enrichNotificationsWithCharacterNames(notifications) { where: { id: { [Op.in]: ids } }, include: [ { model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] }, - { model: FalukantPredefineLastname, as: 'definedLastName', attributes: ['name'] } + { model: FalukantPredefineLastname, as: 'definedLastName', attributes: ['name'] }, + { model: TitleOfNobility, as: 'nobleTitle', attributes: ['labelTr'] }, ], - attributes: ['id'] + attributes: ['id', 'gender'] }); for (const c of characters) { + const title = String(c.nobleTitle?.labelTr || '').trim(); const first = c.definedFirstName?.name || ''; const last = c.definedLastName?.name || ''; - const display = `${first} ${last}`.trim() || null; + const baseName = `${first} ${last}`.trim(); + const display = [title, baseName].filter(Boolean).join(' ').trim() || null; nameMap.set(Number(c.id), display || `#${c.id}`); } } diff --git a/backend/sql/add_director_auto_adjust_income.sql b/backend/sql/add_director_auto_adjust_income.sql new file mode 100644 index 0000000..e3796be --- /dev/null +++ b/backend/sql/add_director_auto_adjust_income.sql @@ -0,0 +1,15 @@ +-- Adds opt-in flag for automatic director salary adjustment (daemon-controlled) +-- Default is OFF for all existing and future directors. + +ALTER TABLE falukant_data.director + ADD COLUMN IF NOT EXISTS auto_adjust_income boolean; + +UPDATE falukant_data.director +SET auto_adjust_income = false +WHERE auto_adjust_income IS NULL; + +ALTER TABLE falukant_data.director + ALTER COLUMN auto_adjust_income SET DEFAULT false; + +ALTER TABLE falukant_data.director + ALTER COLUMN auto_adjust_income SET NOT NULL; diff --git a/frontend/src/components/falukant/DirectorInfo.vue b/frontend/src/components/falukant/DirectorInfo.vue index b0703f0..c8f17da 100644 --- a/frontend/src/components/falukant/DirectorInfo.vue +++ b/frontend/src/components/falukant/DirectorInfo.vue @@ -104,6 +104,14 @@ /> {{ $t('falukant.branch.director.starttransport') }} +
diff --git a/frontend/src/components/falukant/MessagesDialog.vue b/frontend/src/components/falukant/MessagesDialog.vue index 1f30c6e..2ed2f2d 100644 --- a/frontend/src/components/falukant/MessagesDialog.vue +++ b/frontend/src/components/falukant/MessagesDialog.vue @@ -427,7 +427,8 @@ export default { params.threshold_percent = base.threshold_percent; } const isDirectorResign = base.event === 'director_resignation_risk_high' - || (typeof base.tr === 'string' && base.tr.includes('director.resignation')); + || base.event === 'director_resigned' + || (typeof base.tr === 'string' && (base.tr.includes('director.resignation') || base.tr.includes('director.resigned'))); if (isDirectorResign) { params.directorName = params.characterName || base.character_name diff --git a/frontend/src/i18n/locales/ceb/falukant.json b/frontend/src/i18n/locales/ceb/falukant.json index c68bbce..6c532f6 100644 --- a/frontend/src/i18n/locales/ceb/falukant.json +++ b/frontend/src/i18n/locales/ceb/falukant.json @@ -35,7 +35,8 @@ "notify_election_created": "Giskedyul ang usa ka bag-ong eleksiyon.", "notify_office_filled": "Na puno ang usa ka politikal nga opisina.", "director": { - "resignation_risk_high": "Taas ang risgo nga mobiya ang direktor nga si {directorName}: risgo {risk_percent}% (threshold {threshold_percent}%). Karon nga satisfaction {satisfaction}." + "resignation_risk_high": "Taas ang risgo nga mobiya ang direktor nga si {directorName}: risgo {risk_percent}% (threshold {threshold_percent}%). Karon nga satisfaction {satisfaction}.", + "resigned": "Nibiya ang direktor nga si {directorName} (satisfaction {satisfaction}, resignation value {resignation_percent}%). Rehiyon: {regionName}." }, "director_death": "Namatay si {characterName} sa edad nga {ageYears}. Isip amo, kinahanglan kang magtudlo og bag-ong direktor.{regionLabel}{spouses}{children}{lovers}", "relationship_death": "Namatay si {characterName} sa edad nga {ageYears}.{regionLabel}{spouses}{children}{lovers}", @@ -467,6 +468,7 @@ "income": "Kita", "incomeUpdated": "Malampuson nga na-update ang sweldo.", "starttransport": "Makapagsugod og transport", + "autoAdjustIncome": "Awtomatikong i-adjust ang sweldo", "emptyTransport": { "title": "Transporte without products", "description": "Move vehicles gikan sa this sangang opisina ngadto sa another ngadto sa use them better.", diff --git a/frontend/src/i18n/locales/de/falukant.json b/frontend/src/i18n/locales/de/falukant.json index c01fdab..0e9b8c0 100644 --- a/frontend/src/i18n/locales/de/falukant.json +++ b/frontend/src/i18n/locales/de/falukant.json @@ -49,7 +49,8 @@ "notify_election_created": "Es wurde eine neue Wahl ausgeschrieben.", "notify_office_filled": "Ein politisches Amt wurde neu besetzt.", "director": { - "resignation_risk_high": "Hohe Kündigungsgefahr für den Direktor {directorName}: Risiko {risk_percent} % (Schwelle {threshold_percent} %). Zufriedenheit aktuell {satisfaction}." + "resignation_risk_high": "Hohe Kündigungsgefahr für den Direktor {directorName}: Risiko {risk_percent} % (Schwelle {threshold_percent} %). Zufriedenheit aktuell {satisfaction}.", + "resigned": "Direktor {directorName} hat gekündigt (Zufriedenheit {satisfaction}, Kündigungswert {resignation_percent} %). Region: {regionName}." }, "director_death": "{characterName} ist im Alter von {ageYears} Jahren verstorben. Als Arbeitgeber musst du die Direktion neu besetzen.{regionLabel}{spouses}{children}{lovers}", "relationship_death": "{characterName} ist im Alter von {ageYears} Jahren verstorben.{regionLabel}{spouses}{children}{lovers}", @@ -398,6 +399,7 @@ "produce": "Darf produzieren", "sell": "Darf verkaufen", "starttransport": "Darf Transporte veranlassen", + "autoAdjustIncome": "Gehalt automatisch anpassen", "emptyTransport": { "title": "Transport ohne Produkte", "description": "Bewege Transportmittel von dieser Niederlassung zu einer anderen, um sie besser zu nutzen.", diff --git a/frontend/src/i18n/locales/en/falukant.json b/frontend/src/i18n/locales/en/falukant.json index 8ef9ca6..cb4c042 100644 --- a/frontend/src/i18n/locales/en/falukant.json +++ b/frontend/src/i18n/locales/en/falukant.json @@ -35,7 +35,8 @@ "notify_election_created": "A new election has been scheduled.", "notify_office_filled": "A political office has been filled.", "director": { - "resignation_risk_high": "High resignation risk for director {directorName}: risk {risk_percent}% (threshold {threshold_percent}%). Current satisfaction {satisfaction}." + "resignation_risk_high": "High resignation risk for director {directorName}: risk {risk_percent}% (threshold {threshold_percent}%). Current satisfaction {satisfaction}.", + "resigned": "Director {directorName} resigned (satisfaction {satisfaction}, resignation value {resignation_percent}%). Region: {regionName}." }, "director_death": "{characterName} died at the age of {ageYears}. As employer you need to appoint a new director.{regionLabel}{spouses}{children}{lovers}", "relationship_death": "{characterName} died at the age of {ageYears}.{regionLabel}{spouses}{children}{lovers}", @@ -442,6 +443,7 @@ "income": "Income", "incomeUpdated": "Salary has been successfully updated.", "starttransport": "May start transports", + "autoAdjustIncome": "Automatically adjust salary", "emptyTransport": { "title": "Transport without products", "description": "Move vehicles from this branch to another to use them better.", diff --git a/frontend/src/i18n/locales/es/falukant.json b/frontend/src/i18n/locales/es/falukant.json index fcb7f01..18cb2b7 100644 --- a/frontend/src/i18n/locales/es/falukant.json +++ b/frontend/src/i18n/locales/es/falukant.json @@ -49,7 +49,8 @@ "notify_election_created": "Se ha convocado una nueva elección.", "notify_office_filled": "Se ha cubierto un cargo político.", "director": { - "resignation_risk_high": "Alto riesgo de renuncia del director {directorName}: riesgo {risk_percent}% (umbral {threshold_percent}%). Satisfacción actual {satisfaction}." + "resignation_risk_high": "Alto riesgo de renuncia del director {directorName}: riesgo {risk_percent}% (umbral {threshold_percent}%). Satisfacción actual {satisfaction}.", + "resigned": "El director {directorName} ha dimitido (satisfacción {satisfaction}, valor de dimisión {resignation_percent}%). Región: {regionName}." }, "director_death": "{characterName} ha fallecido a la edad de {ageYears} años. Como empleador debes nombrar un nuevo director.{regionLabel}{spouses}{children}{lovers}", "relationship_death": "{characterName} ha fallecido a la edad de {ageYears} años.{regionLabel}{spouses}{children}{lovers}", @@ -399,6 +400,7 @@ "produce": "Puede producir", "sell": "Puede vender", "starttransport": "Puede iniciar transportes", + "autoAdjustIncome": "Ajustar salario automáticamente", "emptyTransport": { "title": "Transporte sin productos", "description": "Mueve medios de transporte de esta sucursal a otra para aprovecharlos mejor.", diff --git a/frontend/src/i18n/locales/fr/falukant.json b/frontend/src/i18n/locales/fr/falukant.json index 326f87b..76633ed 100644 --- a/frontend/src/i18n/locales/fr/falukant.json +++ b/frontend/src/i18n/locales/fr/falukant.json @@ -49,7 +49,8 @@ "notify_election_created": "Une nouvelle élection a été déclenchée.", "notify_office_filled": "Une fonction politique a été pourvue.", "director": { - "resignation_risk_high": "Risque élevé de démission du directeur {directorName} : risque {risk_percent}% (seuil {threshold_percent}%). Satisfaction actuelle {satisfaction}." + "resignation_risk_high": "Risque élevé de démission du directeur {directorName} : risque {risk_percent}% (seuil {threshold_percent}%). Satisfaction actuelle {satisfaction}.", + "resigned": "Le directeur {directorName} a démissionné (satisfaction {satisfaction}, valeur de démission {resignation_percent} %). Région : {regionName}." }, "director_death": "{characterName} est décédé à l'âge de {ageYears}. En tant qu'employeur, vous devez remplir le conseil d'administration.{regionLabel}{spouses}{children}{lovers}", "relationship_death": "{characterName} est décédé à l'âge de {ageYears}.{regionLabel}{spouses}{children}{lovers}", @@ -397,6 +398,7 @@ "produce": "Peut produire", "sell": "Peut vendre", "starttransport": "Peut organiser le transport", + "autoAdjustIncome": "Ajuster automatiquement le salaire", "emptyTransport": { "title": "Transport sans produits", "description": "Déplacez le transport de cette branche à une autre pour en faire un meilleur usage.",