EN · DE · RU · FR · ES

#653: V7_0_0_6__MigrateEmployeeAndCarryVacationDays.java

projectforge-business/src/main/java/org/projectforge/flyway/dbmigration/V7_0_0_6__MigrateEmployeeAndCarryVacationDays.java Type : Java · Rôle : Composant · Source : projectforge-business/src/main/java/org/projectforge/flyway/dbmigration/V7_0_0_6__MigrateEmployeeAndCarryVacationDays.java 157 lignes · 115 code · 29 commentaires · 13 vides
Script de migration de base de données Flyway. Fait partie de la chaîne de migration versionnée qui fait évoluer le schéma de base de données de ProjectForge.

Structure du code

Paquetage : org.projectforge.flyway.dbmigration

Classes : V7_0_0_6__MigrateEmployeeAndCarryVacationDays

Étend : BaseJavaMigration

Méthodes (4) : migrate, migrateEmployeesCarryVacationDays, migrateEmployeeTable, ensureMidnigt

Champs (1) : log

Importations : 19 paquetages

Code source (abrégé)

package org.projectforge.flyway.dbmigration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.projectforge.framework.time.PFDateTimeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
import org.springframework.jdbc.support.rowset.SqlRowSet;

import javax.sql.DataSource;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Year;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Depuis la version 7 de ProjectForge, les jours de congés restants sont gérés dans une nouvelle table
 * au lieu d'être traités comme un attribut de l'employé (sans information sur l'année).
 */
public class V7_0_0_6__MigrateEmployeeAndCarryVacationDays extends BaseJavaMigration {
  private static Logger log = LoggerFactory.getLogger(V7_0_0_6__MigrateEmployeeAndCarryVacationDays.class);

  @Override
  public void migrate(Context context) {
    DataSource ds = new SingleConnectionDataSource(context.getConnection(), true);
    migrateEmployeesCarryVacationDays(ds);
    migrateEmployeeTable(ds);
  }

  private void migrateEmployeesCarryVacationDays(DataSource ds) {
    log.info("Tentative de migration des jours de congés reportés des employés depuis l'année précédente, si cette fonctionnalité est utilisée.");
    JdbcTemplate jdbc = new JdbcTemplate(ds);

    // Après l'installation de la version 7 (snapshot), le cronjob de mise à jour annuelle des jours de congés restants a échoué
    // en raison d'un bug dans EmployeeAttrDO.parent (Kotlin-NPE)
    // On récupère donc l'année d'installation :
    int release7InstalledOnYear = Year.now().getValue();
    try {
      Timestamp release7InstalledOn = jdbc.queryForObject("select installed_on from t_flyway_schema_version where version='7.0.0'", Timestamp.class);
      release7InstalledOnYear = LocalDateTime.ofInstant(release7InstalledOn.toInstant(), PFDateTimeUtils.ZONE_UTC).getYear();
    } catch (Exception ex) {
      // OK, la base de données semble vide.
    }

    SqlRowSet rs = jdbc.queryForRowSet("select p.modifiedat as modifiedat,p.value as value,e.pk as pk,e.tenant_id as tenant from t_fibu_employee_attr as p inner join t_fibu_employee as e on p.parent=e.pk where propertyname = 'previousyearleave' order by pk");
    int counter = 0;
    Date now = new Date();
    SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(ds).withTableName("t_employee_vacation_remaining");
    while (rs.next()) {
      ++counter;
      Timestamp modifiedat = rs.getTimestamp("modifiedat");
      Integer employeeId = rs.getInt("pk");
      Integer tenantId = rs.getInt("tenant");
      BigDecimal value = rs.getBigDecimal("value");
      int year = LocalDateTime.ofInstant(modifiedat.toInstant(), ZoneId.of("UTC")).getYear();
      if (year > release7InstalledOnYear) {
        year = release7InstalledOnYear; // Les congés ont été modifiés, mais l'attribut 'previousyearleave' n'est pas de l'année en cours.
      }
      Map<String, Object> parameters = new HashMap<String, Object>();
      parameters.put("pk", counter);
      parameters.put("deleted", false);
      parameters.put("created", now);
      parameters.put("last_update", now);
      parameters.put("tenant_id", tenantId);
      parameters.put("employee_id", employeeId);
      parameters.put("year", year);
      parameters.put("carry_vacation_days_from_previous_year", value);
      simpleJdbcInsert.execute(parameters);
    }
    if (counter > 0) {
      log.info("Nombre d'entrées migrées avec succès : " + counter);
    } else {
      log.info("Aucune entrée de congés trouvée à migrer (OK, si la fonctionnalité de congés n'était pas utilisée.)");
    }
  }

  private void migrateEmployeeTable(DataSource ds) {
    JdbcTemplate jdbc = new JdbcTemplate(ds);
    String defaultTimeZoneString = null;
    try {
      defaultTimeZoneString = jdbc.queryForObject("select stringvalue from t_configuration where parameter = 'timezone'", String.class);
    } catch (Exception ex) {
      // OK, la base de données semble vide.
    }
    ZoneId zoneId;
    if (defaultTimeZoneString == null) {
      zoneId = ZoneId.systemDefault();
    } else {
      zoneId = ZoneId.of(defaultTimeZoneString);
      int counter = 0;
      log.info("Migration des champs de timestamp de la table des employés.");
      SqlRowSet rs = jdbc.queryForRowSet("select pk, eintritt, austritt, birthday from t_fibu_employee");
      while (rs.next()) {
        ++counter;
        Integer pk = rs.getInt("pk");
        Timestamp eintrittOrig = rs.getTimestamp("eintritt");
        Timestamp austrittOrg = rs.getTimestamp("austritt");
        Timestamp birtdayOrig = rs.getTimestamp("birthday");

        LocalDate birthday = ensureMidnigt(birtdayOrig, ZoneId.of("UTC")); // Les anniversaires étaient stockés en UTC
        LocalDate eintritt = ensureMidnigt(eintrittOrig, zoneId);
        LocalDate austritt = ensureMidnigt(austrittOrg, zoneId);

        jdbc.update("update t_fibu_employee set birthday=?, eintritt=?, austritt=? where pk=?", birthday, eintritt, austritt, pk);
      }
      if (counter > 0) {
        log.info("Nombre d'employés migrés avec succès : " + counter);
      } else {
        log.info("Aucune entrée d'employé trouvée à migrer (OK, si les employés ne sont pas utilisés.)");
      }
    }
  }

// ... (tronqué, 134 lignes au total)

Historique Git

868d6abb7 2025 -> 2026
63081666f En-têtes des fichiers source : 2024 -> 2025.
b6092df09 Copyright 2023 -> 2024
ab45d51fa Copyright 2001-2022 -> 2001-2023.
5f7ef41b8 Copyright 2021 -> 2022