diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java
index 079dd8a12..7c82638e7 100644
--- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java
+++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/BatteryField.java
@@ -10,6 +10,14 @@
 import com.powsybl.iidm.network.Battery;
 import com.powsybl.iidm.network.extensions.ActivePowerControl;
 import com.powsybl.iidm.network.extensions.ActivePowerControlAdder;
+import jakarta.validation.constraints.NotNull;
+import org.gridsuite.modification.server.dto.AttributeModification;
+import org.gridsuite.modification.server.dto.OperationType;
+import org.gridsuite.modification.server.modifications.ModificationUtils;
+
+import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFY_BATTERY_ERROR;
+import static org.gridsuite.modification.server.modifications.BatteryModification.modifyBatteryActiveLimitsAttributes;
+import static org.gridsuite.modification.server.modifications.BatteryModification.modifyBatterySetpointsAttributes;
 
 /**
  * @author Seddik Yengui <Seddik.yengui at rte-france.com>
@@ -34,16 +42,30 @@ public static Double getReferenceValue(Battery battery, String batteryField) {
         };
     }
 
-    public static void setNewValue(Battery battery, String batteryField, Double newValue) {
+    public static void setNewValue(Battery battery, String batteryField, @NotNull Double newValue) {
         BatteryField field = BatteryField.valueOf(batteryField);
+        final AttributeModification<Double> attributeModification = new AttributeModification<>(newValue, OperationType.SET);
         switch (field) {
-            case MINIMUM_ACTIVE_POWER -> battery.setMinP(newValue);
-            case MAXIMUM_ACTIVE_POWER -> battery.setMaxP(newValue);
-            case ACTIVE_POWER_SET_POINT -> battery.setTargetP(newValue);
-            case REACTIVE_POWER_SET_POINT -> battery.setTargetQ(newValue);
-            case DROOP -> battery.newExtension(ActivePowerControlAdder.class)
-                    .withDroop(newValue)
-                    .add();
+            case MINIMUM_ACTIVE_POWER ->
+                    modifyBatteryActiveLimitsAttributes(null, attributeModification, battery, null);
+            case MAXIMUM_ACTIVE_POWER ->
+                    modifyBatteryActiveLimitsAttributes(attributeModification, null, battery, null);
+            case ACTIVE_POWER_SET_POINT -> {
+                ModificationUtils.getInstance().checkActivePowerZeroOrBetweenMinAndMaxActivePower(
+                        attributeModification, null, null, battery.getMinP(),
+                        battery.getMaxP(), battery.getTargetP(), MODIFY_BATTERY_ERROR, "Battery '" + battery.getId() + "' : "
+                );
+                modifyBatterySetpointsAttributes(attributeModification, null, null, null, battery, null);
+            }
+            case REACTIVE_POWER_SET_POINT -> modifyBatterySetpointsAttributes(
+                    null, attributeModification, null, null, battery, null);
+            case DROOP -> {
+                ActivePowerControl<Battery> activePowerControl = battery.getExtension(ActivePowerControl.class);
+                ActivePowerControlAdder<Battery> activePowerControlAdder = battery.newExtension(ActivePowerControlAdder.class);
+                ModificationUtils.getInstance().modifyActivePowerControlAttributes(
+                        activePowerControl, activePowerControlAdder, null,
+                        new AttributeModification<>(newValue.floatValue(), OperationType.SET), null, null);
+            }
         }
     }
 }
diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java
index 7c864cbfd..d36390c58 100644
--- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java
+++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/GeneratorField.java
@@ -11,11 +11,15 @@
 import com.powsybl.iidm.network.extensions.ActivePowerControl;
 import com.powsybl.iidm.network.extensions.ActivePowerControlAdder;
 import com.powsybl.iidm.network.extensions.CoordinatedReactiveControl;
-import com.powsybl.iidm.network.extensions.CoordinatedReactiveControlAdder;
 import com.powsybl.iidm.network.extensions.GeneratorShortCircuit;
-import com.powsybl.iidm.network.extensions.GeneratorShortCircuitAdder;
 import com.powsybl.iidm.network.extensions.GeneratorStartup;
-import com.powsybl.iidm.network.extensions.GeneratorStartupAdder;
+import com.powsybl.network.store.iidm.impl.extensions.CoordinatedReactiveControlAdderImpl;
+import org.gridsuite.modification.server.dto.AttributeModification;
+import org.gridsuite.modification.server.dto.OperationType;
+import org.gridsuite.modification.server.modifications.ModificationUtils;
+
+import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFY_GENERATOR_ERROR;
+import static org.gridsuite.modification.server.modifications.GeneratorModification.*;
 
 /**
  * @author Seddik Yengui <Seddik.yengui at rte-france.com>
@@ -61,86 +65,42 @@ public static Double getReferenceValue(Generator generator, String generatorFiel
         };
     }
 
-    public static void setNewValue(Generator generator, String generatorField, Double newValue) {
+    public static void setNewValue(Generator generator, String generatorField, double newValue) {
         if (!Double.isNaN(newValue)) {
-            GeneratorStartup generatorStartup = generator.getExtension(GeneratorStartup.class);
-            GeneratorShortCircuit generatorShortCircuit = generator.getExtension(GeneratorShortCircuit.class);
             GeneratorField field = GeneratorField.valueOf(generatorField);
+            final AttributeModification<Double> attributeModification = new AttributeModification<>(newValue, OperationType.SET);
             switch (field) {
-                case MAXIMUM_ACTIVE_POWER -> generator.setMaxP(newValue);
-                case MINIMUM_ACTIVE_POWER -> generator.setMinP(newValue);
-                case ACTIVE_POWER_SET_POINT -> generator.setTargetP(newValue);
-                case RATED_NOMINAL_POWER -> generator.setRatedS(newValue);
-                case REACTIVE_POWER_SET_POINT -> generator.setTargetQ(newValue);
-                case VOLTAGE_SET_POINT -> generator.setTargetV(newValue);
-                case PLANNED_ACTIVE_POWER_SET_POINT -> {
-                    if (generatorStartup == null) {
-                        generator.newExtension(GeneratorStartupAdder.class)
-                                .withPlannedActivePowerSetpoint(newValue)
-                                .add();
-                    } else {
-                        generator.newExtension(GeneratorStartupAdder.class)
-                                .withMarginalCost(generatorStartup.getMarginalCost())
-                                .withPlannedActivePowerSetpoint(newValue)
-                                .withPlannedOutageRate(generatorStartup.getPlannedOutageRate())
-                                .withForcedOutageRate(generatorStartup.getForcedOutageRate())
-                                .add();
-                    }
-                }
-                case MARGINAL_COST -> {
-                    if (generatorStartup == null) {
-                        generator.newExtension(GeneratorStartupAdder.class)
-                                .withMarginalCost(newValue)
-                                .add();
-                    } else {
-                        generator.newExtension(GeneratorStartupAdder.class)
-                                .withMarginalCost(newValue)
-                                .withPlannedActivePowerSetpoint(generatorStartup.getPlannedActivePowerSetpoint())
-                                .withPlannedOutageRate(generatorStartup.getPlannedOutageRate())
-                                .withForcedOutageRate(generatorStartup.getForcedOutageRate())
-                                .add();
-                    }
-                }
-                case PLANNED_OUTAGE_RATE -> {
-                    if (generatorStartup == null) {
-                        generator.newExtension(GeneratorStartupAdder.class)
-                                .withPlannedOutageRate(newValue)
-                                .add();
-                    } else {
-                        generator.newExtension(GeneratorStartupAdder.class)
-                                .withMarginalCost(generatorStartup.getMarginalCost())
-                                .withPlannedActivePowerSetpoint(generatorStartup.getPlannedActivePowerSetpoint())
-                                .withPlannedOutageRate(newValue)
-                                .withForcedOutageRate(generatorStartup.getForcedOutageRate())
-                                .add();
-                    }
+                case MAXIMUM_ACTIVE_POWER -> modifyGeneratorActiveLimitsAttributes(
+                        attributeModification, null, null, generator, null);
+                case MINIMUM_ACTIVE_POWER -> modifyGeneratorActiveLimitsAttributes(null, attributeModification, null, generator, null);
+                case ACTIVE_POWER_SET_POINT -> {
+                    ModificationUtils.getInstance().checkActivePowerZeroOrBetweenMinAndMaxActivePower(
+                            attributeModification, null, null,
+                            generator.getMinP(), generator.getMaxP(), generator.getTargetP(),
+                            MODIFY_GENERATOR_ERROR, "Generator '" + generator.getId() + "' : "
+                    );
+                    generator.setTargetP(newValue);
                 }
-                case FORCED_OUTAGE_RATE -> {
-                    if (generatorStartup == null) {
-                        generator.newExtension(GeneratorStartupAdder.class)
-                                .withForcedOutageRate(newValue)
-                                .add();
-                    } else {
-                        generator.newExtension(GeneratorStartupAdder.class)
-                                .withMarginalCost(generatorStartup.getMarginalCost())
-                                .withPlannedActivePowerSetpoint(generatorStartup.getPlannedActivePowerSetpoint())
-                                .withPlannedOutageRate(generatorStartup.getForcedOutageRate())
-                                .withForcedOutageRate(newValue)
-                                .add();
-                    }
+                case RATED_NOMINAL_POWER -> modifyGeneratorActiveLimitsAttributes(null, null, attributeModification, generator, null);
+                case REACTIVE_POWER_SET_POINT -> modifyTargetQ(generator, attributeModification);
+                case VOLTAGE_SET_POINT -> modifyTargetV(generator, attributeModification);
+                case PLANNED_ACTIVE_POWER_SET_POINT ->
+                        modifyGeneratorStartUpAttributes(attributeModification, null, null, null, generator, null, null);
+                case MARGINAL_COST ->
+                        modifyGeneratorStartUpAttributes(null, attributeModification, null, null, generator, null, null);
+                case PLANNED_OUTAGE_RATE ->
+                        modifyGeneratorStartUpAttributes(null, null, attributeModification, null, generator, null, null);
+                case FORCED_OUTAGE_RATE ->
+                        modifyGeneratorStartUpAttributes(null, null, null, attributeModification, generator, null, null);
+                case DROOP -> {
+                    ActivePowerControl<Generator> activePowerControl = generator.getExtension(ActivePowerControl.class);
+                    ActivePowerControlAdder<Generator> activePowerControlAdder = generator.newExtension(ActivePowerControlAdder.class);
+                    ModificationUtils.getInstance().modifyActivePowerControlAttributes(activePowerControl, activePowerControlAdder, null,
+                            new AttributeModification<>((float) newValue, OperationType.SET), null, null);
                 }
-                case DROOP -> generator.newExtension(ActivePowerControlAdder.class)
-                        .withDroop(newValue)
-                        .add();
-                case TRANSIENT_REACTANCE -> generator.newExtension(GeneratorShortCircuitAdder.class)
-                        .withDirectTransX(newValue)
-                        .withStepUpTransformerX(generatorShortCircuit == null ? Double.NaN : generatorShortCircuit.getStepUpTransformerX())
-                        .add();
-                case STEP_UP_TRANSFORMER_REACTANCE -> generator.newExtension(GeneratorShortCircuitAdder.class)
-                        .withDirectTransX(generatorShortCircuit == null ? 0.0D : generatorShortCircuit.getDirectTransX())
-                        .withStepUpTransformerX(newValue)
-                        .add();
-                case Q_PERCENT -> generator.newExtension(CoordinatedReactiveControlAdder.class)
+                case TRANSIENT_REACTANCE -> modifyGeneratorShortCircuitAttributes(attributeModification, null, generator, null);
+                case STEP_UP_TRANSFORMER_REACTANCE -> modifyGeneratorShortCircuitAttributes(null, attributeModification, generator, null);
+                case Q_PERCENT -> generator.newExtension(CoordinatedReactiveControlAdderImpl.class)
                         .withQPercent(newValue)
                         .add();
             }
diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java
index 2743186a6..8c01d3f96 100644
--- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java
+++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/LoadField.java
@@ -8,6 +8,11 @@
 package org.gridsuite.modification.server.dto.formula.equipmentfield;
 
 import com.powsybl.iidm.network.Load;
+import org.gridsuite.modification.server.dto.AttributeModification;
+import org.gridsuite.modification.server.dto.OperationType;
+
+import static org.gridsuite.modification.server.modifications.LoadModification.modifyP0;
+import static org.gridsuite.modification.server.modifications.LoadModification.modifyQ0;
 
 /**
  * @author Seddik Yengui <Seddik.yengui at rte-france.com>
@@ -28,8 +33,8 @@ public static Double getReferenceValue(Load load, String loadField) {
     public static void setNewValue(Load load, String loadField, Double newValue) {
         LoadField field = LoadField.valueOf(loadField);
         switch (field) {
-            case ACTIVE_POWER -> load.setP0(newValue);
-            case REACTIVE_POWER -> load.setQ0(newValue);
+            case ACTIVE_POWER -> modifyP0(load, new AttributeModification<>(newValue, OperationType.SET), null);
+            case REACTIVE_POWER -> modifyQ0(load, new AttributeModification<>(newValue, OperationType.SET), null);
         }
     }
 }
diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java
index e155d4720..87dabb14a 100644
--- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java
+++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/ShuntCompensatorField.java
@@ -12,6 +12,11 @@
 import com.powsybl.iidm.network.ShuntCompensatorModelType;
 import com.powsybl.iidm.network.VoltageLevel;
 import org.gridsuite.modification.server.NetworkModificationException;
+import org.gridsuite.modification.server.dto.AttributeModification;
+import org.gridsuite.modification.server.dto.OperationType;
+import org.gridsuite.modification.server.dto.ShuntCompensatorType;
+
+import static org.gridsuite.modification.server.modifications.ShuntCompensatorModification.*;
 
 /**
  * @author Seddik Yengui <Seddik.yengui at rte-france.com>
@@ -42,19 +47,18 @@ public static void setNewValue(ShuntCompensator shuntCompensator, String shuntCo
         ShuntCompensatorLinearModel model = shuntCompensator.getModel(ShuntCompensatorLinearModel.class);
         ShuntCompensatorField field = ShuntCompensatorField.valueOf(shuntCompensatorField);
         VoltageLevel voltageLevel = shuntCompensator.getTerminal().getVoltageLevel();
+        var shuntCompensatorType = ShuntCompensatorType.REACTOR;
+        if (model != null && model.getBPerSection() > 0) {
+            shuntCompensatorType = ShuntCompensatorType.CAPACITOR;
+        }
         switch (field) {
-            case MAXIMUM_SECTION_COUNT -> {
-                int maximumSectionCount = newValue.intValue();
-                model.setBPerSection(model.getBPerSection() * shuntCompensator.getMaximumSectionCount() / maximumSectionCount);
-                model.setMaximumSectionCount(maximumSectionCount);
-            }
-            case SECTION_COUNT -> shuntCompensator.setSectionCount(newValue.intValue());
-            case MAXIMUM_SUSCEPTANCE -> model.setBPerSection(newValue / shuntCompensator.getMaximumSectionCount());
-            case MAXIMUM_Q_AT_NOMINAL_VOLTAGE -> {
-                double newQatNominalV = newValue / shuntCompensator.getMaximumSectionCount();
-                double newSusceptancePerSection = newQatNominalV / Math.pow(voltageLevel.getNominalV(), 2);
-                model.setBPerSection(newSusceptancePerSection);
-            }
+            case MAXIMUM_SECTION_COUNT -> modifyMaximumSectionCount(new AttributeModification<>(newValue.intValue(), OperationType.SET),
+                    null, null, null, shuntCompensator, model);
+            case SECTION_COUNT -> modifySectionCount(new AttributeModification<>(newValue.intValue(), OperationType.SET), null, shuntCompensator);
+            case MAXIMUM_SUSCEPTANCE -> modifyMaxSusceptance(new AttributeModification<>(newValue, OperationType.SET),
+                    shuntCompensator.getMaximumSectionCount(), null, model);
+            case MAXIMUM_Q_AT_NOMINAL_VOLTAGE -> modifyMaximumQAtNominalVoltage(new AttributeModification<>(newValue, OperationType.SET),
+                    voltageLevel, shuntCompensator.getMaximumSectionCount(), null, model, shuntCompensatorType);
         }
     }
 }
diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java
index e0f6d52df..6a13e93d6 100644
--- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java
+++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/TwoWindingsTransformerField.java
@@ -3,6 +3,9 @@
 import com.powsybl.iidm.network.PhaseTapChanger;
 import com.powsybl.iidm.network.RatioTapChanger;
 import com.powsybl.iidm.network.TwoWindingsTransformer;
+import org.gridsuite.modification.server.dto.AttributeModification;
+import org.gridsuite.modification.server.dto.OperationType;
+import static org.gridsuite.modification.server.modifications.TwoWindingsTransformerModification.*;
 
 public enum TwoWindingsTransformerField {
     R,
@@ -48,23 +51,33 @@ public static void setNewValue(TwoWindingsTransformer transformer, String twoWin
         TwoWindingsTransformerField field = TwoWindingsTransformerField.valueOf(twoWindingsTransformerField);
         final PhaseTapChanger phaseTapChanger = transformer.getPhaseTapChanger();
         final RatioTapChanger ratioTapChanger = transformer.getRatioTapChanger();
+        final PhaseTapChanger.RegulationMode regulationMode = phaseTapChanger != null ? phaseTapChanger.getRegulationMode() : null;
+        final AttributeModification<Double> attributeModification = new AttributeModification<>(newValue, OperationType.SET);
 
         switch (field) {
-            case R -> transformer.setR(newValue);
-            case X -> transformer.setX(newValue);
-            case G -> transformer.setG(newValue);
-            case B -> transformer.setB(newValue);
-            case RATED_U1 -> transformer.setRatedU1(newValue);
-            case RATED_U2 -> transformer.setRatedU2(newValue);
-            case RATED_S -> transformer.setRatedS(newValue);
-            case TARGET_V -> ratioTapChanger.setTargetV(newValue);
-            case RATIO_LOW_TAP_POSITION -> ratioTapChanger.setLowTapPosition(newValue.intValue());
-            case RATIO_TAP_POSITION -> ratioTapChanger.setTapPosition(newValue.intValue());
-            case RATIO_TARGET_DEADBAND -> ratioTapChanger.setTargetDeadband(newValue);
-            case REGULATION_VALUE -> phaseTapChanger.setRegulationValue(newValue);
-            case PHASE_LOW_TAP_POSITION -> phaseTapChanger.setLowTapPosition(newValue.intValue());
-            case PHASE_TAP_POSITION -> phaseTapChanger.setTapPosition(newValue.intValue());
-            case PHASE_TARGET_DEADBAND -> phaseTapChanger.setTargetDeadband(newValue);
+            case R -> modifyR(transformer, attributeModification, null);
+            case X -> modifyX(transformer, attributeModification, null);
+            case G -> modifyG(transformer, attributeModification, null);
+            case B -> modifyB(transformer, attributeModification, null);
+            case RATED_U1 -> modifyRatedU1(transformer, attributeModification, null);
+            case RATED_U2 -> modifyRatedU2(transformer, attributeModification, null);
+            case RATED_S -> modifyRatedS(transformer, attributeModification, null);
+            case TARGET_V -> modifyTargets(ratioTapChanger, null, true, attributeModification, null, null);
+            case RATIO_LOW_TAP_POSITION -> processTapChangerPositionsAndSteps(ratioTapChanger, null, true,
+                    new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null, null);
+            case RATIO_TAP_POSITION -> processTapChangerPositionsAndSteps(ratioTapChanger, null, true,
+                    null, new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null);
+            case RATIO_TARGET_DEADBAND -> modifyTargets(ratioTapChanger, null, true, null, attributeModification, null);
+            case REGULATION_VALUE -> processPhaseTapRegulation(
+                    phaseTapChanger, null, regulationMode, true, attributeModification, null, null
+            );
+            case PHASE_LOW_TAP_POSITION -> processTapChangerPositionsAndSteps(phaseTapChanger, null, true,
+                    new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null, null);
+            case PHASE_TAP_POSITION -> processTapChangerPositionsAndSteps(phaseTapChanger, null, true,
+                    null, new AttributeModification<>(newValue.intValue(), OperationType.SET), null, null);
+            case PHASE_TARGET_DEADBAND -> processPhaseTapRegulation(
+                    phaseTapChanger, null, null, true, null, attributeModification, null
+            );
         }
     }
 }
diff --git a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java
index a1fc1d644..69f366ad4 100644
--- a/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java
+++ b/src/main/java/org/gridsuite/modification/server/dto/formula/equipmentfield/VoltageLevelField.java
@@ -9,7 +9,10 @@
 
 import com.powsybl.iidm.network.VoltageLevel;
 import com.powsybl.iidm.network.extensions.IdentifiableShortCircuit;
-import com.powsybl.iidm.network.extensions.IdentifiableShortCircuitAdder;
+import org.gridsuite.modification.server.dto.AttributeModification;
+import org.gridsuite.modification.server.dto.OperationType;
+
+import static org.gridsuite.modification.server.modifications.VoltageLevelModification.*;
 
 /**
  * @author Seddik Yengui <Seddik.yengui at rte-france.com>
@@ -35,26 +38,15 @@ public static Double getReferenceValue(VoltageLevel voltageLevel, String voltage
     }
 
     public static void setNewValue(VoltageLevel voltageLevel, String voltageLevelField, Double newValue) {
-        IdentifiableShortCircuit<VoltageLevel> identifiableShortCircuit = voltageLevel.getExtension(IdentifiableShortCircuit.class);
         VoltageLevelField field = VoltageLevelField.valueOf(voltageLevelField);
         switch (field) {
-            case NOMINAL_VOLTAGE -> voltageLevel.setNominalV(newValue);
-            case LOW_VOLTAGE_LIMIT -> voltageLevel.setLowVoltageLimit(newValue);
-            case HIGH_VOLTAGE_LIMIT -> voltageLevel.setHighVoltageLimit(newValue);
-            case LOW_SHORT_CIRCUIT_CURRENT_LIMIT -> {
-                IdentifiableShortCircuitAdder<VoltageLevel> adder = voltageLevel.newExtension(IdentifiableShortCircuitAdder.class).withIpMin(newValue);
-                if (identifiableShortCircuit != null) {
-                    adder.withIpMax(identifiableShortCircuit.getIpMax());
-                }
-                adder.add();
-            }
-            case HIGH_SHORT_CIRCUIT_CURRENT_LIMIT -> {
-                IdentifiableShortCircuitAdder<VoltageLevel> adder = voltageLevel.newExtension(IdentifiableShortCircuitAdder.class).withIpMax(newValue);
-                if (identifiableShortCircuit != null) {
-                    adder.withIpMin(identifiableShortCircuit.getIpMin());
-                }
-                adder.add();
-            }
+            case NOMINAL_VOLTAGE -> modifyNominalV(voltageLevel, new AttributeModification<>(newValue, OperationType.SET), null);
+            case LOW_VOLTAGE_LIMIT -> modifLowVoltageLimit(voltageLevel, new AttributeModification<>(newValue, OperationType.SET), null);
+            case HIGH_VOLTAGE_LIMIT -> modifyHighVoltageLimit(voltageLevel, new AttributeModification<>(newValue, OperationType.SET), null);
+            case LOW_SHORT_CIRCUIT_CURRENT_LIMIT -> modifyVoltageLevelShortCircuit(
+                    new AttributeModification<>(newValue, OperationType.SET), null, null, voltageLevel);
+            case HIGH_SHORT_CIRCUIT_CURRENT_LIMIT -> modifyVoltageLevelShortCircuit(
+                    null, new AttributeModification<>(newValue, OperationType.SET), null, voltageLevel);
         }
     }
 }
diff --git a/src/main/java/org/gridsuite/modification/server/modifications/BatteryModification.java b/src/main/java/org/gridsuite/modification/server/modifications/BatteryModification.java
index 544be215a..15d9bd3ad 100644
--- a/src/main/java/org/gridsuite/modification/server/modifications/BatteryModification.java
+++ b/src/main/java/org/gridsuite/modification/server/modifications/BatteryModification.java
@@ -18,6 +18,7 @@
 import com.powsybl.iidm.network.extensions.ConnectablePosition;
 import com.powsybl.iidm.network.extensions.ConnectablePositionAdder;
 import org.gridsuite.modification.server.NetworkModificationException;
+import org.gridsuite.modification.server.dto.AttributeModification;
 import org.gridsuite.modification.server.dto.BatteryModificationInfos;
 import org.gridsuite.modification.server.dto.ReactiveCapabilityCurveModificationInfos;
 
@@ -86,17 +87,24 @@ private void modifyBattery(Battery battery, BatteryModificationInfos modificatio
         }
 
         modifyBatteryLimitsAttributes(modificationInfos, battery, subReportNode);
-        modifyBatterySetpointsAttributes(modificationInfos, battery, subReportNode);
+        modifyBatterySetpointsAttributes(
+                modificationInfos.getTargetP(), modificationInfos.getTargetQ(),
+                modificationInfos.getParticipate(), modificationInfos.getDroop(),
+                battery, subReportNode);
         modifyBatteryConnectivityAttributes(modificationInfos, battery, subReportNode);
         PropertiesUtils.applyProperties(battery, subReportNode, modificationInfos.getProperties(), "BatteryProperties");
     }
 
-    private void modifyBatterySetpointsAttributes(BatteryModificationInfos modificationInfos,
-                                                  Battery battery, ReportNode subReportNode) {
-        ReportNode reportActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setTargetP, battery::getTargetP, modificationInfos.getTargetP(), "Active power");
-        ReportNode reportReactivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setTargetQ, battery::getTargetQ, modificationInfos.getTargetQ(), "Reactive power");
+    public static void modifyBatterySetpointsAttributes(AttributeModification<Double> targetP,
+                                                        AttributeModification<Double> targetQ,
+                                                        AttributeModification<Boolean> participate,
+                                                        AttributeModification<Float> droop,
+                                                        Battery battery,
+                                                        ReportNode subReportNode) {
+        ReportNode reportActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setTargetP, battery::getTargetP, targetP, "Active power");
+        ReportNode reportReactivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setTargetQ, battery::getTargetQ, targetQ, "Reactive power");
         ReportNode subReporterSetpoints = null;
-        if (reportActivePower != null || reportReactivePower != null) {
+        if (subReportNode != null && (reportActivePower != null || reportReactivePower != null)) {
             subReporterSetpoints = subReportNode.newReportNode().withMessageTemplate(SETPOINTS, SETPOINTS).add();
             if (reportActivePower != null) {
                 insertReportNode(subReporterSetpoints, reportActivePower);
@@ -105,12 +113,12 @@ private void modifyBatterySetpointsAttributes(BatteryModificationInfos modificat
                 insertReportNode(subReporterSetpoints, reportReactivePower);
             }
         }
-        modifyBatteryActivePowerControlAttributes(modificationInfos, battery, subReportNode, subReporterSetpoints);
+        modifyBatteryActivePowerControlAttributes(participate, droop, battery, subReportNode, subReporterSetpoints);
     }
 
     private void modifyBatteryLimitsAttributes(BatteryModificationInfos modificationInfos,
                                                Battery battery, ReportNode subReportNode) {
-        ReportNode subReportNodeLimits = modifyBatteryActiveLimitsAttributes(modificationInfos, battery, subReportNode);
+        ReportNode subReportNodeLimits = modifyBatteryActiveLimitsAttributes(modificationInfos.getMaxP(), modificationInfos.getMinP(), battery, subReportNode);
         modifyBatteryReactiveLimitsAttributes(modificationInfos, battery, subReportNode, subReportNodeLimits);
     }
 
@@ -123,12 +131,13 @@ private void modifyBatteryReactiveCapabilityCurvePoints(BatteryModificationInfos
         ModificationUtils.getInstance().modifyReactiveCapabilityCurvePoints(points, modificationPoints, adder, subReportNode, subReportNodeLimits);
     }
 
-    private ReportNode modifyBatteryActiveLimitsAttributes(BatteryModificationInfos modificationInfos,
-                                                         Battery battery, ReportNode subReportNode) {
+    public static ReportNode modifyBatteryActiveLimitsAttributes(AttributeModification<Double> maxP,
+                                                                 AttributeModification<Double> minP,
+                                                                 Battery battery, ReportNode subReportNode) {
         ReportNode subReportNodeLimits = null;
-        ReportNode reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setMaxP, battery::getMaxP, modificationInfos.getMaxP(), "Max active power");
-        ReportNode reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setMinP, battery::getMinP, modificationInfos.getMinP(), "Min active power");
-        if (reportMaxActivePower != null || reportMinActivePower != null) {
+        ReportNode reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setMaxP, battery::getMaxP, maxP, "Max active power");
+        ReportNode reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(battery::setMinP, battery::getMinP, minP, "Min active power");
+        if (subReportNode != null && (reportMaxActivePower != null || reportMinActivePower != null)) {
             subReportNodeLimits = subReportNode.newReportNode().withMessageTemplate(LIMITS, LIMITS).add();
             ReportNode subReporterActiveLimits = subReportNodeLimits.newReportNode().withMessageTemplate(ACTIVE_LIMITS, ACTIVE_LIMITS).add();
             if (reportMaxActivePower != null) {
@@ -155,11 +164,14 @@ private void modifyBatteryReactiveLimitsAttributes(BatteryModificationInfos modi
         }
     }
 
-    private ReportNode modifyBatteryActivePowerControlAttributes(BatteryModificationInfos modificationInfos,
-                                                               Battery battery, ReportNode subReportNode, ReportNode subReportNodeSetpoints) {
+    public static ReportNode modifyBatteryActivePowerControlAttributes(AttributeModification<Boolean> participate,
+                                                                       AttributeModification<Float> droop,
+                                                                       Battery battery,
+                                                                       ReportNode subReportNode,
+                                                                       ReportNode subReportNodeSetpoints) {
         ActivePowerControl<Battery> activePowerControl = battery.getExtension(ActivePowerControl.class);
         ActivePowerControlAdder<Battery> activePowerControlAdder = battery.newExtension(ActivePowerControlAdder.class);
-        return ModificationUtils.getInstance().modifyActivePowerControlAttributes(activePowerControl, activePowerControlAdder, modificationInfos.getParticipate(), modificationInfos.getDroop(), subReportNode, subReportNodeSetpoints);
+        return ModificationUtils.getInstance().modifyActivePowerControlAttributes(activePowerControl, activePowerControlAdder, participate, droop, subReportNode, subReportNodeSetpoints);
     }
 
     private ReportNode modifyBatteryConnectivityAttributes(BatteryModificationInfos modificationInfos,
diff --git a/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java b/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java
index 75616c713..a1f119008 100644
--- a/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java
+++ b/src/main/java/org/gridsuite/modification/server/modifications/ByFormulaModification.java
@@ -98,7 +98,6 @@ public void apply(Network network, ReportNode subReportNode) {
                         .withUntypedValue(KEY_VALUE, equipmentCount)
                         .withSeverity(TypedValue.INFO_SEVERITY)
                         .add();
-                report(formulaSubReporter, formulaReports);
             } else {
                 if (equipmentNotModifiedCount == equipmentCount) {
                     createReport(subReportNode, "byFormulaModificationNone",
@@ -111,9 +110,9 @@ public void apply(Network network, ReportNode subReportNode) {
                             .withUntypedValue(KEY_NB_UNCHANGED, equipmentNotModifiedCount + equipmentNotFoundCount)
                             .withSeverity(TypedValue.WARN_SEVERITY)
                             .add();
-                    report(formulaSubReporter, formulaReports);
                 }
             }
+            report(formulaSubReporter, formulaReports);
         }
     }
 
@@ -267,7 +266,7 @@ private void applyFormula(Identifiable<?> identifiable,
             try {
                 final Double newValue = applyOperation(formulaInfos.getOperator(), value1, value2);
                 switch (identifiable.getType()) {
-                    case GENERATOR -> GeneratorField.setNewValue((Generator) identifiable, formulaInfos.getEditedField(), newValue);
+                    case GENERATOR -> GeneratorField.setNewValue((Generator) identifiable, formulaInfos.getEditedField(), newValue.doubleValue());
                     case BATTERY -> BatteryField.setNewValue((Battery) identifiable, formulaInfos.getEditedField(), newValue);
                     case SHUNT_COMPENSATOR -> ShuntCompensatorField.setNewValue((ShuntCompensator) identifiable, formulaInfos.getEditedField(), newValue);
                     case VOLTAGE_LEVEL -> VoltageLevelField.setNewValue((VoltageLevel) identifiable, formulaInfos.getEditedField(), newValue);
diff --git a/src/main/java/org/gridsuite/modification/server/modifications/GeneratorModification.java b/src/main/java/org/gridsuite/modification/server/modifications/GeneratorModification.java
index 03711328c..71a4508b9 100644
--- a/src/main/java/org/gridsuite/modification/server/modifications/GeneratorModification.java
+++ b/src/main/java/org/gridsuite/modification/server/modifications/GeneratorModification.java
@@ -92,53 +92,58 @@ private void modifyGenerator(Generator generator, GeneratorModificationInfos mod
 
         modifyGeneratorLimitsAttributes(modificationInfos, generator, subReportNode);
         modifyGeneratorSetpointsAttributes(modificationInfos, generator, subReportNode);
-        modifyGeneratorShortCircuitAttributes(modificationInfos, generator, subReportNode);
+        modifyGeneratorShortCircuitAttributes(modificationInfos.getDirectTransX(), modificationInfos.getStepUpTransformerX(), generator, subReportNode);
         modifyGeneratorStartUpAttributes(modificationInfos, generator, subReportNode);
         modifyGeneratorConnectivityAttributes(modificationInfos, generator, subReportNode);
         PropertiesUtils.applyProperties(generator, subReportNode, modificationInfos.getProperties(), "GeneratorProperties");
     }
 
-    private void modifyGeneratorShortCircuitAttributes(GeneratorModificationInfos modificationInfos,
-                                                       Generator generator, ReportNode subReportNode) {
+    public static void modifyGeneratorShortCircuitAttributes(AttributeModification<Double> directTransX,
+                                                             AttributeModification<Double> stepUpTransformerX,
+                                                             Generator generator,
+                                                             ReportNode subReportNode) {
         List<ReportNode> reports = new ArrayList<>();
         GeneratorShortCircuit generatorShortCircuit = generator.getExtension(GeneratorShortCircuit.class);
         Double oldTransientReactance = generatorShortCircuit != null ? generatorShortCircuit.getDirectTransX() : Double.NaN;
         Double oldStepUpTransformerReactance = generatorShortCircuit != null ? generatorShortCircuit.getStepUpTransformerX() : Double.NaN;
         // Either transient reactance or step-up transformer reactance are modified or
         // both
-        if (modificationInfos.getDirectTransX() != null
-                && modificationInfos.getStepUpTransformerX() != null) {
+        if (directTransX != null && stepUpTransformerX != null) {
             generator.newExtension(GeneratorShortCircuitAdder.class)
-                    .withDirectTransX(modificationInfos.getDirectTransX().getValue())
-                    .withStepUpTransformerX(modificationInfos.getStepUpTransformerX().getValue())
+                    .withDirectTransX(directTransX.getValue())
+                    .withStepUpTransformerX(stepUpTransformerX.getValue())
                     .add();
             reports.add(ModificationUtils.getInstance().buildModificationReport(
                     oldTransientReactance,
-                    modificationInfos.getDirectTransX().getValue(),
+                    directTransX.getValue(),
                     "Transient reactance"));
             reports.add(ModificationUtils.getInstance().buildModificationReport(
                     oldStepUpTransformerReactance,
-                    modificationInfos.getStepUpTransformerX().getValue(),
+                    stepUpTransformerX.getValue(),
                     "Transformer reactance"));
 
-        } else if (modificationInfos.getDirectTransX() != null) {
+        } else if (directTransX != null) {
             generator.newExtension(GeneratorShortCircuitAdder.class)
-                    .withDirectTransX(modificationInfos.getDirectTransX().getValue())
+                    .withStepUpTransformerX(oldStepUpTransformerReactance)
+                    .withDirectTransX(directTransX.getValue())
                     .add();
             reports.add(ModificationUtils.getInstance().buildModificationReport(
                     oldTransientReactance,
-                    modificationInfos.getDirectTransX().getValue(),
+                    directTransX.getValue(),
                     "Transient reactance"));
-        } else if (modificationInfos.getStepUpTransformerX() != null) {
+        } else if (stepUpTransformerX != null) {
             generator.newExtension(GeneratorShortCircuitAdder.class)
-                    .withStepUpTransformerX(modificationInfos.getStepUpTransformerX().getValue())
+                    .withStepUpTransformerX(stepUpTransformerX.getValue())
+                    .withDirectTransX(oldTransientReactance)
                     .add();
             reports.add(ModificationUtils.getInstance().buildModificationReport(
                     oldStepUpTransformerReactance,
-                    modificationInfos.getStepUpTransformerX().getValue(),
+                    stepUpTransformerX.getValue(),
                     "Transformer reactance"));
         }
-        ModificationUtils.getInstance().reportModifications(subReportNode, reports, "shortCircuitAttributesModified", "Short-circuit");
+        if (subReportNode != null) {
+            ModificationUtils.getInstance().reportModifications(subReportNode, reports, "shortCircuitAttributesModified", "Short-circuit");
+        }
     }
 
     private void modifyGeneratorReactiveCapabilityCurvePoints(GeneratorModificationInfos modificationInfos,
@@ -149,22 +154,25 @@ private void modifyGeneratorReactiveCapabilityCurvePoints(GeneratorModificationI
         ModificationUtils.getInstance().modifyReactiveCapabilityCurvePoints(points, modificationPoints, adder, subReportNode, subReportNodeLimits);
     }
 
-    private ReportNode modifyGeneratorActiveLimitsAttributes(GeneratorModificationInfos modificationInfos,
-                                                           Generator generator, ReportNode subReportNode) {
+    public static ReportNode modifyGeneratorActiveLimitsAttributes(AttributeModification<Double> maxP,
+                                                                   AttributeModification<Double> minP,
+                                                                   AttributeModification<Double> ratedS,
+                                                                   Generator generator,
+                                                                   ReportNode subReportNode) {
         ReportNode subReporterLimits = null;
         ReportNode reportMaxActivePower;
         ReportNode reportMinActivePower;
 
-        if (modificationInfos.getMaxP() != null && modificationInfos.getMaxP().getValue() > generator.getMinP()) {
-            reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMaxP, generator::getMaxP, modificationInfos.getMaxP(), "Max active power");
-            reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMinP, generator::getMinP, modificationInfos.getMinP(), "Min active power");
+        if (maxP != null && maxP.getValue() > generator.getMinP()) {
+            reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMaxP, generator::getMaxP, maxP, "Max active power");
+            reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMinP, generator::getMinP, minP, "Min active power");
 
         } else {
-            reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMinP, generator::getMinP, modificationInfos.getMinP(), "Min active power");
-            reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMaxP, generator::getMaxP, modificationInfos.getMaxP(), "Max active power");
+            reportMinActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMinP, generator::getMinP, minP, "Min active power");
+            reportMaxActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setMaxP, generator::getMaxP, maxP, "Max active power");
         }
-        ReportNode reportRatedNominalPower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setRatedS, generator::getRatedS, modificationInfos.getRatedS(), "Rated nominal power");
-        if (reportMaxActivePower != null || reportMinActivePower != null || reportRatedNominalPower != null) {
+        ReportNode reportRatedNominalPower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setRatedS, generator::getRatedS, ratedS, "Rated nominal power");
+        if (subReportNode != null && (reportMaxActivePower != null || reportMinActivePower != null || reportRatedNominalPower != null)) {
             subReporterLimits = subReportNode.newReportNode().withMessageTemplate(LIMITS, LIMITS).add();
             ReportNode subReporterActiveLimits = subReporterLimits.newReportNode().withMessageTemplate(ACTIVE_LIMITS, ACTIVE_LIMITS).add();
             if (reportMaxActivePower != null) {
@@ -208,30 +216,53 @@ private ReportNode modifyGeneratorActivePowerControlAttributes(GeneratorModifica
     private void modifyGeneratorStartUpAttributes(GeneratorModificationInfos modificationInfos, Generator generator,
                                                   ReportNode subReportNode) {
         List<ReportNode> reports = new ArrayList<>();
-        GeneratorStartup generatorStartup = generator.getExtension(GeneratorStartup.class);
+        modifyGeneratorStartUpAttributes(modificationInfos.getPlannedActivePowerSetPoint(),
+                modificationInfos.getMarginalCost(),
+                modificationInfos.getPlannedOutageRate(),
+                modificationInfos.getForcedOutageRate(),
+                generator,
+                subReportNode,
+                reports);
+    }
+
+    public static void modifyGeneratorStartUpAttributes(AttributeModification<Double> plannedActivePowerSetPoint,
+                                                        AttributeModification<Double> marginalCost,
+                                                        AttributeModification<Double> plannedOutageRate,
+                                                        AttributeModification<Double> forcedOutageRate,
+                                                        Generator generator,
+                                                        ReportNode subReportNode,
+                                                        List<ReportNode> reports) {
         GeneratorStartupAdder generatorStartupAdder = generator.newExtension(GeneratorStartupAdder.class);
-        boolean plannedActivePowerSetPointUpdated = addPlannedActivePowerSetPoint(modificationInfos, generatorStartupAdder, generatorStartup, reports);
-        boolean marginalCostUpdated = addMarginalCost(modificationInfos, generatorStartupAdder, generatorStartup, reports);
-        boolean plannedOutageRateUpdated = addPlannedOutageRate(modificationInfos, generatorStartupAdder, generatorStartup, reports);
-        boolean forcedOutageRateUpdated = addForcedOutageRate(modificationInfos, generatorStartupAdder, generatorStartup, reports);
+        GeneratorStartup generatorStartup = generator.getExtension(GeneratorStartup.class);
+        boolean plannedActivePowerSetPointUpdated = addPlannedActivePowerSetPoint(plannedActivePowerSetPoint,
+                generatorStartupAdder,
+                generatorStartup,
+                reports);
+        boolean marginalCostUpdated = addMarginalCost(marginalCost, generatorStartupAdder, generatorStartup, reports);
+        boolean plannedOutageRateUpdated = addPlannedOutageRate(plannedOutageRate, generatorStartupAdder, generatorStartup, reports);
+        boolean forcedOutageRateUpdated = addForcedOutageRate(forcedOutageRate, generatorStartupAdder, generatorStartup, reports);
 
         if (plannedActivePowerSetPointUpdated ||
                 marginalCostUpdated ||
                 plannedOutageRateUpdated ||
                 forcedOutageRateUpdated) {
             generatorStartupAdder.add();
-            ModificationUtils.getInstance().reportModifications(subReportNode, reports, "startUpAttributesModified", "Start up");
+            if (subReportNode != null) {
+                ModificationUtils.getInstance().reportModifications(subReportNode, reports, "startUpAttributesModified", "Start up");
+            }
         }
     }
 
-    private boolean addForcedOutageRate(GeneratorModificationInfos modificationInfos, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List<ReportNode> reports) {
+    private static boolean addForcedOutageRate(AttributeModification<Double> forcedOutageRate, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List<ReportNode> reports) {
         Double oldForcedOutageRate = generatorStartup != null ? generatorStartup.getForcedOutageRate() : Double.NaN;
-        if (modificationInfos.getForcedOutageRate() != null) {
+        if (forcedOutageRate != null) {
             generatorStartupAdder
-                    .withForcedOutageRate(modificationInfos.getForcedOutageRate().getValue());
-            reports.add(ModificationUtils.getInstance().buildModificationReport(oldForcedOutageRate,
-                    modificationInfos.getForcedOutageRate().getValue(),
-                    "Forced outage rate"));
+                    .withForcedOutageRate(forcedOutageRate.getValue());
+            if (reports != null) {
+                reports.add(ModificationUtils.getInstance().buildModificationReport(oldForcedOutageRate,
+                        forcedOutageRate.getValue(),
+                        "Forced outage rate"));
+            }
             return true;
         } else {
             generatorStartupAdder
@@ -240,14 +271,16 @@ private boolean addForcedOutageRate(GeneratorModificationInfos modificationInfos
         return false;
     }
 
-    private boolean addPlannedOutageRate(GeneratorModificationInfos modificationInfos, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List<ReportNode> reports) {
+    private static boolean addPlannedOutageRate(AttributeModification<Double> plannedOutageRate, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List<ReportNode> reports) {
         Double oldPlannedOutageRate = generatorStartup != null ? generatorStartup.getPlannedOutageRate() : Double.NaN;
-        if (modificationInfos.getPlannedOutageRate() != null) {
+        if (plannedOutageRate != null) {
             generatorStartupAdder
-                    .withPlannedOutageRate(modificationInfos.getPlannedOutageRate().getValue());
-            reports.add(ModificationUtils.getInstance().buildModificationReport(oldPlannedOutageRate,
-                    modificationInfos.getPlannedOutageRate().getValue(),
-                    "Planning outage rate"));
+                    .withPlannedOutageRate(plannedOutageRate.getValue());
+            if (reports != null) {
+                reports.add(ModificationUtils.getInstance().buildModificationReport(oldPlannedOutageRate,
+                        plannedOutageRate.getValue(),
+                        "Planning outage rate"));
+            }
             return true;
         } else {
             generatorStartupAdder
@@ -256,14 +289,16 @@ private boolean addPlannedOutageRate(GeneratorModificationInfos modificationInfo
         return false;
     }
 
-    private boolean addMarginalCost(GeneratorModificationInfos modificationInfos, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List<ReportNode> reports) {
+    private static boolean addMarginalCost(AttributeModification<Double> marginalCost, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List<ReportNode> reports) {
         Double oldMarginalCost = generatorStartup != null ? generatorStartup.getMarginalCost() : Double.NaN;
-        if (modificationInfos.getMarginalCost() != null) {
+        if (marginalCost != null) {
             generatorStartupAdder
-                    .withMarginalCost(modificationInfos.getMarginalCost().getValue());
-            reports.add(ModificationUtils.getInstance().buildModificationReport(oldMarginalCost,
-                    modificationInfos.getMarginalCost().getValue(),
-                    "Marginal cost"));
+                    .withMarginalCost(marginalCost.getValue());
+            if (reports != null) {
+                reports.add(ModificationUtils.getInstance().buildModificationReport(oldMarginalCost,
+                        marginalCost.getValue(),
+                        "Marginal cost"));
+            }
             return true;
         } else {
             generatorStartupAdder
@@ -272,14 +307,17 @@ private boolean addMarginalCost(GeneratorModificationInfos modificationInfos, Ge
         return false;
     }
 
-    private boolean addPlannedActivePowerSetPoint(GeneratorModificationInfos modificationInfos, GeneratorStartupAdder generatorStartupAdder, GeneratorStartup generatorStartup, List<ReportNode> reports) {
+    private static boolean addPlannedActivePowerSetPoint(AttributeModification<Double> plannedActivePowerSetPoint, GeneratorStartupAdder generatorStartupAdder,
+                                                  GeneratorStartup generatorStartup, List<ReportNode> reports) {
         Double oldPlannedActivePowerSetPoint = generatorStartup != null ? generatorStartup.getPlannedActivePowerSetpoint() : Double.NaN;
-        if (modificationInfos.getPlannedActivePowerSetPoint() != null) {
+        if (plannedActivePowerSetPoint != null) {
             generatorStartupAdder
-                    .withPlannedActivePowerSetpoint(modificationInfos.getPlannedActivePowerSetPoint().getValue());
-            reports.add(ModificationUtils.getInstance().buildModificationReport(oldPlannedActivePowerSetPoint,
-                    modificationInfos.getPlannedActivePowerSetPoint().getValue(),
-                    "Planning active power set point"));
+                    .withPlannedActivePowerSetpoint(plannedActivePowerSetPoint.getValue());
+            if (reports != null) {
+                reports.add(ModificationUtils.getInstance().buildModificationReport(oldPlannedActivePowerSetPoint,
+                        plannedActivePowerSetPoint.getValue(),
+                        "Planning active power set point"));
+            }
             return true;
         } else {
             generatorStartupAdder
@@ -339,15 +377,8 @@ private ReportNode modifyGeneratorVoltageRegulatorAttributes(GeneratorModificati
                                                                Generator generator, ReportNode subReportNode, ReportNode subReportNodeSetpoints) {
         List<ReportNode> voltageRegulationReports = new ArrayList<>();
 
-        ReportNode reportVoltageSetpoint = null;
-        if (modificationInfos.getTargetV() != null) {
-            if (modificationInfos.getTargetV().getOp() == OperationType.SET) {
-                reportVoltageSetpoint = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetV, generator::getTargetV,
-                    modificationInfos.getTargetV(), "Voltage");
-            } else {
-                reportVoltageSetpoint = ModificationUtils.getInstance().buildModificationReport(generator.getTargetV(), Double.NaN, "Voltage");
-            }
-        }
+        ReportNode reportVoltageSetpoint = modifyTargetV(generator, modificationInfos.getTargetV());
+
         ReportNode voltageRegulationOn = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setVoltageRegulatorOn, generator::isVoltageRegulatorOn,
                 modificationInfos.getVoltageRegulationOn(), "VoltageRegulationOn");
         if (voltageRegulationOn != null) {
@@ -392,17 +423,24 @@ private ReportNode modifyGeneratorVoltageRegulatorAttributes(GeneratorModificati
         return subReportNodeSetpoints2;
     }
 
-    private void modifyGeneratorSetpointsAttributes(GeneratorModificationInfos modificationInfos,
-                                                    Generator generator, ReportNode subReportNode) {
-        ReportNode reportActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetP, generator::getTargetP, modificationInfos.getTargetP(), "Active power");
-        ReportNode reportReactivePower = null;
-        if (modificationInfos.getTargetQ() != null) {
-            if (modificationInfos.getTargetQ().getOp() == OperationType.SET) {
-                reportReactivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetQ, generator::getTargetQ, modificationInfos.getTargetQ(), "Reactive power");
+    public static ReportNode modifyTargetV(Generator generator, AttributeModification<Double> modifTargetV) {
+        ReportNode reportVoltageSetpoint = null;
+        if (modifTargetV != null) {
+            if (modifTargetV.getOp() == OperationType.SET) {
+                reportVoltageSetpoint = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetV, generator::getTargetV,
+                        modifTargetV, "Voltage");
             } else {
-                reportReactivePower = ModificationUtils.getInstance().buildModificationReport(generator.getTargetQ(), Double.NaN, "Reactive power");
+                reportVoltageSetpoint = ModificationUtils.getInstance().buildModificationReport(generator.getTargetV(), Double.NaN, "Voltage");
             }
         }
+        return reportVoltageSetpoint;
+    }
+
+    private void modifyGeneratorSetpointsAttributes(GeneratorModificationInfos modificationInfos,
+                                                    Generator generator, ReportNode subReportNode) {
+        ReportNode reportActivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetP, generator::getTargetP, modificationInfos.getTargetP(), "Active power");
+
+        ReportNode reportReactivePower = modifyTargetQ(generator, modificationInfos.getTargetQ());
 
         ReportNode subReporterSetpoints = null;
         if (reportActivePower != null || reportReactivePower != null) {
@@ -418,9 +456,25 @@ private void modifyGeneratorSetpointsAttributes(GeneratorModificationInfos modif
         modifyGeneratorActivePowerControlAttributes(modificationInfos, generator, subReportNode, subReporterSetpoints);
     }
 
+    public static ReportNode modifyTargetQ(Generator generator, AttributeModification<Double> modifTargetQ) {
+        ReportNode reportReactivePower = null;
+        if (modifTargetQ != null) {
+            if (modifTargetQ.getOp() == OperationType.SET) {
+                reportReactivePower = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(generator::setTargetQ, generator::getTargetQ, modifTargetQ, "Target reactive power");
+            } else {
+                reportReactivePower = ModificationUtils.getInstance().buildModificationReport(generator.getTargetQ(), Double.NaN, "Target reactive power");
+            }
+        }
+        return reportReactivePower;
+    }
+
     private void modifyGeneratorLimitsAttributes(GeneratorModificationInfos modificationInfos,
                                                  Generator generator, ReportNode subReportNode) {
-        ReportNode subReportNodeLimits = modifyGeneratorActiveLimitsAttributes(modificationInfos, generator, subReportNode);
+        ReportNode subReportNodeLimits = modifyGeneratorActiveLimitsAttributes(modificationInfos.getMaxP(),
+                modificationInfos.getMinP(),
+                modificationInfos.getRatedS(),
+                generator,
+                subReportNode);
         modifyGeneratorReactiveLimitsAttributes(modificationInfos, generator, subReportNode, subReportNodeLimits);
     }
 
diff --git a/src/main/java/org/gridsuite/modification/server/modifications/LoadModification.java b/src/main/java/org/gridsuite/modification/server/modifications/LoadModification.java
index 019271d8e..3bbbb68c8 100644
--- a/src/main/java/org/gridsuite/modification/server/modifications/LoadModification.java
+++ b/src/main/java/org/gridsuite/modification/server/modifications/LoadModification.java
@@ -13,6 +13,7 @@
 import com.powsybl.iidm.network.extensions.ConnectablePosition;
 import com.powsybl.iidm.network.extensions.ConnectablePositionAdder;
 import org.gridsuite.modification.server.NetworkModificationException;
+import org.gridsuite.modification.server.dto.AttributeModification;
 import org.gridsuite.modification.server.dto.LoadModificationInfos;
 
 import static org.gridsuite.modification.server.NetworkModificationException.Type.LOAD_NOT_FOUND;
@@ -53,13 +54,21 @@ private void modifyLoad(Load load, ReportNode subReportNode) {
 
         ModificationUtils.getInstance().applyElementaryModifications(load::setName, () -> load.getOptionalName().orElse("No value"), modificationInfos.getEquipmentName(), subReportNode, "Name");
         ModificationUtils.getInstance().applyElementaryModifications(load::setLoadType, load::getLoadType, modificationInfos.getLoadType(), subReportNode, "Type");
-        ModificationUtils.getInstance().applyElementaryModifications(load::setP0, load::getP0, modificationInfos.getP0(), subReportNode, "Constant active power");
-        ModificationUtils.getInstance().applyElementaryModifications(load::setQ0, load::getQ0, modificationInfos.getQ0(), subReportNode, "Constant reactive power");
+        modifyP0(load, modificationInfos.getP0(), subReportNode);
+        modifyQ0(load, modificationInfos.getQ0(), subReportNode);
         modifyLoadConnectivityAttributes(modificationInfos, load, subReportNode);
         // properties
         PropertiesUtils.applyProperties(load, subReportNode, modificationInfos.getProperties(), "LoadProperties");
     }
 
+    public static void modifyQ0(Load load, AttributeModification<Double> q0, ReportNode subReportNode) {
+        ModificationUtils.getInstance().applyElementaryModifications(load::setQ0, load::getQ0, q0, subReportNode, "Constant reactive power");
+    }
+
+    public static void modifyP0(Load load, AttributeModification<Double> p0, ReportNode subReportNode) {
+        ModificationUtils.getInstance().applyElementaryModifications(load::setP0, load::getP0, p0, subReportNode, "Constant active power");
+    }
+
     private ReportNode modifyLoadConnectivityAttributes(LoadModificationInfos modificationInfos,
                                                         Load load, ReportNode subReportNode) {
         ConnectablePosition<Load> connectablePosition = load.getExtension(ConnectablePosition.class);
diff --git a/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java b/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java
index 92d4e588a..c2b94e850 100644
--- a/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java
+++ b/src/main/java/org/gridsuite/modification/server/modifications/ModificationUtils.java
@@ -509,7 +509,9 @@ public <T> void applyElementaryModifications(Consumer<T> setter, Supplier<T> get
             T newValue = modification.applyModification(oldValue);
             setter.accept(newValue);
 
-            insertReportNode(subReportNode, buildModificationReport(oldValue, newValue, fieldName));
+            if (subReportNode != null) {
+                insertReportNode(subReportNode, buildModificationReport(oldValue, newValue, fieldName));
+            }
         }
     }
 
@@ -1073,12 +1075,16 @@ private void modifyExistingActivePowerControl(ActivePowerControl<?> activePowerC
 
         Optional.ofNullable(participateInfo).ifPresent(info -> {
             activePowerControl.setParticipate(info.getValue());
-            reports.add(buildModificationReport(oldParticipate, info.getValue(), "Participate"));
+            if (reports != null) {
+                reports.add(buildModificationReport(oldParticipate, info.getValue(), "Participate"));
+            }
         });
 
         Optional.ofNullable(droopInfo).ifPresent(info -> {
             activePowerControl.setDroop(info.getValue());
-            reports.add(buildModificationReport(oldDroop, info.getValue(), "Droop"));
+            if (reports != null) {
+                reports.add(buildModificationReport(oldDroop, info.getValue(), "Droop"));
+            }
         });
     }
 
@@ -1088,22 +1094,22 @@ private void createNewActivePowerControl(ActivePowerControlAdder<?> adder,
                                              List<ReportNode> reports) {
         boolean participate = participateInfo != null ? participateInfo.getValue() : false;
         adder.withParticipate(participate);
-        if (participateInfo != null) {
+        if (participateInfo != null && reports != null) {
             reports.add(buildModificationReport(null, participate, "Participate"));
         }
         double droop = droopInfo != null ? droopInfo.getValue() : Double.NaN;
         adder.withDroop(droop);
-        if (droopInfo != null) {
+        if (droopInfo != null && reports != null) {
             reports.add(buildModificationReport(Double.NaN, droop, "Droop"));
         }
         adder.add();
     }
 
     public ReportNode modifyActivePowerControlAttributes(ActivePowerControl<?> activePowerControl,
-                                                       ActivePowerControlAdder<?> activePowerControlAdder,
-                                                       AttributeModification<Boolean> participateInfo,
-                                                       AttributeModification<Float> droopInfo,
-                                                        ReportNode subReportNode,
+                                                         ActivePowerControlAdder<?> activePowerControlAdder,
+                                                         AttributeModification<Boolean> participateInfo,
+                                                         AttributeModification<Float> droopInfo,
+                                                         ReportNode subReportNode,
                                                          ReportNode subReporterSetpoints) {
         List<ReportNode> reports = new ArrayList<>();
         if (activePowerControl != null) {
@@ -1111,13 +1117,15 @@ public ReportNode modifyActivePowerControlAttributes(ActivePowerControl<?> activ
         } else {
             createNewActivePowerControl(activePowerControlAdder, participateInfo, droopInfo, reports);
         }
-
-        ReportNode subReportNodeSetpoints2 = subReporterSetpoints;
-        if (subReporterSetpoints == null && !reports.isEmpty()) {
-            subReportNodeSetpoints2 = subReportNode.newReportNode().withMessageTemplate(SETPOINTS, SETPOINTS).add();
+        if (subReportNode != null) {
+            ReportNode subReportNodeSetpoints2 = subReporterSetpoints;
+            if (subReporterSetpoints == null && !reports.isEmpty()) {
+                subReportNodeSetpoints2 = subReportNode.newReportNode().withMessageTemplate(SETPOINTS, SETPOINTS).add();
+            }
+            reportModifications(subReportNodeSetpoints2, reports, "activePowerRegulationModified", "Active power regulation");
+            return subReportNodeSetpoints2;
         }
-        reportModifications(subReportNodeSetpoints2, reports, "activePowerRegulationModified", "Active power regulation");
-        return subReportNodeSetpoints2;
+        return null;
     }
 
     public void checkMaxQGreaterThanMinQ(
diff --git a/src/main/java/org/gridsuite/modification/server/modifications/ShuntCompensatorModification.java b/src/main/java/org/gridsuite/modification/server/modifications/ShuntCompensatorModification.java
index 25aaebe37..899ace841 100644
--- a/src/main/java/org/gridsuite/modification/server/modifications/ShuntCompensatorModification.java
+++ b/src/main/java/org/gridsuite/modification/server/modifications/ShuntCompensatorModification.java
@@ -13,6 +13,7 @@
 import com.powsybl.iidm.network.extensions.ConnectablePosition;
 import com.powsybl.iidm.network.extensions.ConnectablePositionAdder;
 import org.gridsuite.modification.server.NetworkModificationException;
+import org.gridsuite.modification.server.dto.AttributeModification;
 import org.gridsuite.modification.server.dto.ShuntCompensatorModificationInfos;
 import org.gridsuite.modification.server.dto.ShuntCompensatorType;
 
@@ -81,21 +82,30 @@ public void apply(Network network, ReportNode subReportNode) {
         PropertiesUtils.applyProperties(shuntCompensator, subReportNode, modificationInfos.getProperties(), "ShuntCompensatorProperties");
     }
 
-    private void modifyMaximumSectionCount(List<ReportNode> reports, ShuntCompensator shuntCompensator, ShuntCompensatorLinearModel model) {
-        if (modificationInfos.getMaximumSectionCount() != null) {
-            var maximumSectionCount = modificationInfos.getMaximumSectionCount().getValue();
-            if (modificationInfos.getMaxSusceptance() == null && modificationInfos.getMaxQAtNominalV() == null) {
+    public static void modifyMaximumSectionCount(AttributeModification<Integer> maximumSectionCountModif,
+                                                 AttributeModification<Double> maxSusceptance,
+                                                 AttributeModification<Double> maxQAtNominalV,
+                                                 List<ReportNode> reports,
+                                                 ShuntCompensator shuntCompensator,
+                                                 ShuntCompensatorLinearModel model) {
+        if (maximumSectionCountModif != null) {
+            var maximumSectionCount = maximumSectionCountModif.getValue();
+            if (maxSusceptance == null && maxQAtNominalV == null) {
                 model.setBPerSection(model.getBPerSection() * shuntCompensator.getMaximumSectionCount() / maximumSectionCount);
             }
-            reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensator.getMaximumSectionCount(), maximumSectionCount, "Maximum section count"));
+            if (reports != null) {
+                reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensator.getMaximumSectionCount(), maximumSectionCount, "Maximum section count"));
+            }
             model.setMaximumSectionCount(maximumSectionCount);
         }
     }
 
-    private void modifySectionCount(List<ReportNode> reports, ShuntCompensator shuntCompensator) {
-        if (modificationInfos.getSectionCount() != null) {
-            var newSectionCount = modificationInfos.getSectionCount().getValue();
-            reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensator.getSectionCount(), newSectionCount, "Section count"));
+    public static void modifySectionCount(AttributeModification<Integer> sectionCount, List<ReportNode> reports, ShuntCompensator shuntCompensator) {
+        if (sectionCount != null) {
+            var newSectionCount = sectionCount.getValue();
+            if (reports != null) {
+                reports.add(ModificationUtils.getInstance().buildModificationReport(shuntCompensator.getSectionCount(), newSectionCount, "Section count"));
+            }
             shuntCompensator.setSectionCount(newSectionCount);
         }
     }
@@ -106,7 +116,6 @@ private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompe
         var shuntCompensatorType = model.getBPerSection() > 0 ? ShuntCompensatorType.CAPACITOR : ShuntCompensatorType.REACTOR;
         double oldSusceptancePerSection = model.getBPerSection();
         double oldQAtNominalV = Math.abs(Math.pow(voltageLevel.getNominalV(), 2) * oldSusceptancePerSection);
-        double oldMaxSusceptance = oldSusceptancePerSection * shuntCompensator.getMaximumSectionCount();
         double oldMaxQAtNominalV = oldQAtNominalV * shuntCompensator.getMaximumSectionCount();
         double oldSwitchedOnSusceptance = oldSusceptancePerSection * shuntCompensator.getSectionCount();
         double oldSwitchedOnQAtNominalV = oldQAtNominalV * shuntCompensator.getSectionCount();
@@ -118,11 +127,17 @@ private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompe
         // due to cross validation between maximum section count and section count, we need to modify section count first
         // when maximum section count old value is greater than the new one
         if (modificationInfos.getMaximumSectionCount() != null && modificationInfos.getMaximumSectionCount().getValue() < shuntCompensator.getMaximumSectionCount()) {
-            modifySectionCount(reports, shuntCompensator);
-            modifyMaximumSectionCount(reports, shuntCompensator, model);
+            modifySectionCount(modificationInfos.getSectionCount(), reports, shuntCompensator);
+            modifyMaximumSectionCount(modificationInfos.getMaximumSectionCount(),
+                    modificationInfos.getMaxSusceptance(),
+                    modificationInfos.getMaxQAtNominalV(),
+                    reports, shuntCompensator, model);
         } else {
-            modifyMaximumSectionCount(reports, shuntCompensator, model);
-            modifySectionCount(reports, shuntCompensator);
+            modifyMaximumSectionCount(modificationInfos.getMaximumSectionCount(),
+                    modificationInfos.getMaxSusceptance(),
+                    modificationInfos.getMaxQAtNominalV(),
+                    reports, shuntCompensator, model);
+            modifySectionCount(modificationInfos.getSectionCount(), reports, shuntCompensator);
         }
 
         int maximumSectionCount = modificationInfos.getMaximumSectionCount() != null ? modificationInfos.getMaximumSectionCount().getValue() : shuntCompensator.getMaximumSectionCount();
@@ -140,22 +155,10 @@ private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompe
         }
 
         if (modificationInfos.getMaxQAtNominalV() != null) {
-            if (modificationInfos.getMaxQAtNominalV().getValue() < 0) {
-                throw new NetworkModificationException(NetworkModificationException.Type.MODIFY_SHUNT_COMPENSATOR_ERROR,
-                        "Qmax at nominal voltage should be greater or equal to 0");
-            }
-            double newQatNominalV = modificationInfos.getMaxQAtNominalV().getValue() / maximumSectionCount;
-            double newSusceptancePerSection = newQatNominalV / Math.pow(voltageLevel.getNominalV(), 2);
-            reports.add(ModificationUtils.getInstance().buildModificationReport(oldMaxQAtNominalV, modificationInfos.getMaxQAtNominalV().getValue(), "Qmax available at nominal voltage"));
-
-            model.setBPerSection(shuntCompensatorType == ShuntCompensatorType.CAPACITOR ? newSusceptancePerSection : -newSusceptancePerSection);
+            modifyMaximumQAtNominalVoltage(modificationInfos.getMaxQAtNominalV(), voltageLevel, maximumSectionCount, reports, model, shuntCompensatorType);
         }
-
         if (modificationInfos.getMaxSusceptance() != null) {
-            double newSusceptancePerSection = modificationInfos.getMaxSusceptance().getValue() / maximumSectionCount;
-            reports.add(ModificationUtils.getInstance().buildModificationReport(oldMaxSusceptance, modificationInfos.getMaxSusceptance().getValue(), "Maximal susceptance available"));
-
-            model.setBPerSection(newSusceptancePerSection);
+            modifyMaxSusceptance(modificationInfos.getMaxSusceptance(), maximumSectionCount, reports, model);
         }
 
         reportSwitchedOnAndPerSectionValues(reports, oldQAtNominalV, oldSwitchedOnQAtNominalV, oldSusceptancePerSection, oldSwitchedOnSusceptance, oldMaxQAtNominalV, sectionCount, maximumSectionCount);
@@ -163,6 +166,41 @@ private void applyModificationOnLinearModel(ReportNode subReportNode, ShuntCompe
         reports.forEach(report -> insertReportNode(subReportNode, report));
     }
 
+    public static void modifyMaxSusceptance(AttributeModification<Double> maxSusceptance,
+                                            int maximumSectionCount,
+                                            List<ReportNode> reports,
+                                            ShuntCompensatorLinearModel model) {
+        double newSusceptancePerSection = maxSusceptance.getValue() / maximumSectionCount;
+        if (reports != null) {
+            double oldSusceptancePerSection = model.getBPerSection();
+            double oldMaxSusceptance = oldSusceptancePerSection * maximumSectionCount;
+            reports.add(ModificationUtils.getInstance().buildModificationReport(oldMaxSusceptance, maxSusceptance.getValue(), "Maximal susceptance available"));
+        }
+        model.setBPerSection(newSusceptancePerSection);
+    }
+
+    public static void modifyMaximumQAtNominalVoltage(AttributeModification<Double> maxQAtNominalV,
+                                                       VoltageLevel voltageLevel,
+                                                       int maximumSectionCount,
+                                                       List<ReportNode> reports,
+                                                       ShuntCompensatorLinearModel model,
+                                                       ShuntCompensatorType shuntCompensatorType) {
+        if (maxQAtNominalV.getValue() < 0) {
+            throw new NetworkModificationException(NetworkModificationException.Type.MODIFY_SHUNT_COMPENSATOR_ERROR,
+                    "Qmax at nominal voltage should be greater or equal to 0");
+        }
+        double newQatNominalV = maxQAtNominalV.getValue() / maximumSectionCount;
+        double newSusceptancePerSection = newQatNominalV / Math.pow(voltageLevel.getNominalV(), 2);
+        if (reports != null) {
+            double oldSusceptancePerSection = model.getBPerSection();
+            double oldQAtNominalV = Math.abs(Math.pow(voltageLevel.getNominalV(), 2) * oldSusceptancePerSection);
+            double oldMaxQAtNominalV = oldQAtNominalV * maximumSectionCount;
+            reports.add(ModificationUtils.getInstance().buildModificationReport(oldMaxQAtNominalV, maxQAtNominalV.getValue(), "Qmax available at nominal voltage"));
+        }
+
+        model.setBPerSection(shuntCompensatorType == ShuntCompensatorType.CAPACITOR ? newSusceptancePerSection : -newSusceptancePerSection);
+    }
+
     private void reportSwitchedOnAndPerSectionValues(List<ReportNode> reports, double oldQAtNominalV, double oldSwitchedOnQAtNominalV, double oldSusceptancePerSection, double oldSwitchedOnSusceptance, double oldMaxQAtNominalV, int sectionCount, int maximumSectionCount) {
         if (modificationInfos.getMaxQAtNominalV() != null) {
             double newQatNominalV = modificationInfos.getMaxQAtNominalV().getValue() / maximumSectionCount;
diff --git a/src/main/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModification.java b/src/main/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModification.java
index 4a940d4cc..5fee968aa 100644
--- a/src/main/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModification.java
+++ b/src/main/java/org/gridsuite/modification/server/modifications/TwoWindingsTransformerModification.java
@@ -26,6 +26,7 @@ public class TwoWindingsTransformerModification extends AbstractBranchModificati
 
     private static final String RATIO_TAP_CHANGER_SUBREPORTER_DEFAULT_MESSAGE = "Ratio tap changer";
     private static final String PHASE_TAP_CHANGER_SUBREPORTER_DEFAULT_MESSAGE = "Phase tap changer";
+    public static final String MAGNETIZING_CONDUCTANCE_FIELD_NAME = "Magnetizing conductance";
 
     public TwoWindingsTransformerModification(TwoWindingsTransformerModificationInfos modificationInfos) {
         super(modificationInfos);
@@ -58,49 +59,111 @@ protected void modifyCharacteristics(Branch<?> branch, BranchModificationInfos b
         ReportNode characteristicsReporter = subReportNode.newReportNode().withMessageTemplate("characteristics", "Characteristics").add();
 
         // Branch specific fields
-        if (branchModificationInfos.getR() != null && branchModificationInfos.getR().getValue() != null) {
-            insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(twoWindingsTransformer.getR(),
-                    branchModificationInfos.getR().getValue(), "Series resistance", 1));
-            twoWindingsTransformer.setR(branchModificationInfos.getR().getValue());
-        }
-        if (branchModificationInfos.getX() != null && branchModificationInfos.getX().getValue() != null) {
-            insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(twoWindingsTransformer.getX(),
-                    branchModificationInfos.getX().getValue(), "Series reactance", 1));
-            twoWindingsTransformer.setX(branchModificationInfos.getX().getValue());
-        }
+        modifyR(twoWindingsTransformer, branchModificationInfos.getR(), characteristicsReporter);
+        modifyX(twoWindingsTransformer, branchModificationInfos.getX(), characteristicsReporter);
 
         // Transformer specific fields
         TwoWindingsTransformerModificationInfos twoWindingsTransformerModificationInfos = (TwoWindingsTransformerModificationInfos) branchModificationInfos;
-        if (twoWindingsTransformerModificationInfos.getG() != null && twoWindingsTransformerModificationInfos.getG().getValue() != null) {
-            // convert reported value from siemens to microsiemens
-            double oldMagnetizingConductanceToReport = twoWindingsTransformer.getG() * Math.pow(10, 6);
-            double newMagnetizingConductanceToReport = twoWindingsTransformerModificationInfos.getG().getValue() * Math.pow(10, 6);
-            insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(oldMagnetizingConductanceToReport,
-                    newMagnetizingConductanceToReport, "Magnetizing conductance", 1));
-            twoWindingsTransformer.setG(twoWindingsTransformerModificationInfos.getG().getValue());
+        modifyTransformerFields(twoWindingsTransformer,
+                twoWindingsTransformerModificationInfos.getG(),
+                twoWindingsTransformerModificationInfos.getB(),
+                twoWindingsTransformerModificationInfos.getRatedS(),
+                twoWindingsTransformerModificationInfos.getRatedU1(),
+                twoWindingsTransformerModificationInfos.getRatedU2(),
+                characteristicsReporter);
+    }
+
+    public static void modifyTransformerFields(TwoWindingsTransformer transformer,
+                                               AttributeModification<Double> modifG,
+                                               AttributeModification<Double> modifB,
+                                               AttributeModification<Double> modifRatedS,
+                                               AttributeModification<Double> modifRatedU1,
+                                               AttributeModification<Double> modifRatedU2,
+                                               ReportNode reportNode) {
+        modifyG(transformer, modifG, reportNode);
+        modifyB(transformer, modifB, reportNode);
+        modifyRatedS(transformer, modifRatedS, reportNode);
+        modifyRatedU1(transformer, modifRatedU1, reportNode);
+        modifyRatedU2(transformer, modifRatedU2, reportNode);
+    }
+
+    public static void modifyRatedU2(TwoWindingsTransformer transformer, AttributeModification<Double> modifRatedU2, ReportNode reportNode) {
+        if (modifRatedU2 != null && modifRatedU2.getValue() != null) {
+            if (reportNode != null) {
+                insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(transformer.getRatedU2(),
+                        modifRatedU2.getValue(), "Rated Voltage (Side 2)", 1));
+            }
+            transformer.setRatedU2(modifRatedU2.getValue());
         }
-        if (twoWindingsTransformerModificationInfos.getB() != null && twoWindingsTransformerModificationInfos.getB().getValue() != null) {
+    }
+
+    public static void modifyRatedU1(TwoWindingsTransformer transformer, AttributeModification<Double> modifRatedU1, ReportNode reportNode) {
+        if (modifRatedU1 != null && modifRatedU1.getValue() != null) {
+            if (reportNode != null) {
+                insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(transformer.getRatedU1(),
+                        modifRatedU1.getValue(), "Rated Voltage (Side 1)", 1));
+            }
+            transformer.setRatedU1(modifRatedU1.getValue());
+        }
+    }
+
+    public static void modifyRatedS(TwoWindingsTransformer transformer, AttributeModification<Double> modifRatedS, ReportNode reportNode) {
+        if (modifRatedS != null && modifRatedS.getValue() != null) {
+            if (reportNode != null) {
+                insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(transformer.getRatedS(),
+                                modifRatedS.getValue(), "Rated nominal power", 1));
+            }
+            transformer.setRatedS(modifRatedS.getValue());
+        }
+    }
+
+    public static void modifyB(TwoWindingsTransformer transformer, AttributeModification<Double> modifB, ReportNode reportNode) {
+        if (modifB != null && modifB.getValue() != null) {
             // convert reported value from siemens to microsiemens
-            double oldMagnetizingSusceptanceToReport = twoWindingsTransformer.getB() * Math.pow(10, 6);
-            double newMagnetizingSusceptanceToReport = twoWindingsTransformerModificationInfos.getB().getValue() * Math.pow(10, 6);
-            insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(oldMagnetizingSusceptanceToReport,
-                            newMagnetizingSusceptanceToReport, "Magnetizing susceptance", 1));
-            twoWindingsTransformer.setB(twoWindingsTransformerModificationInfos.getB().getValue());
+            if (reportNode != null) {
+                double oldMagnetizingSusceptanceToReport = transformer.getB() * Math.pow(10, 6);
+                double newMagnetizingSusceptanceToReport = modifB.getValue() * Math.pow(10, 6);
+                insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(oldMagnetizingSusceptanceToReport,
+                                newMagnetizingSusceptanceToReport, "Magnetizing susceptance", 1));
+            }
+            transformer.setB(modifB.getValue());
         }
-        if (twoWindingsTransformerModificationInfos.getRatedS() != null && twoWindingsTransformerModificationInfos.getRatedS().getValue() != null) {
-            insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(twoWindingsTransformer.getRatedS(),
-                            twoWindingsTransformerModificationInfos.getRatedS().getValue(), "Rated nominal power", 1));
-            twoWindingsTransformer.setRatedS(twoWindingsTransformerModificationInfos.getRatedS().getValue());
+    }
+
+    public static void modifyG(TwoWindingsTransformer transformer, AttributeModification<Double> modifG, ReportNode reportNode) {
+        if (modifG != null && modifG.getValue() != null) {
+            // convert reported value from siemens to microsiemens
+            if (reportNode != null) {
+                double oldMagnetizingConductanceToReport = transformer.getG() * Math.pow(10, 6);
+                double newMagnetizingConductanceToReport = modifG.getValue() * Math.pow(10, 6);
+                ReportNode gReportNode = ModificationUtils.getInstance().buildModificationReport(
+                        oldMagnetizingConductanceToReport,
+                        newMagnetizingConductanceToReport,
+                        MAGNETIZING_CONDUCTANCE_FIELD_NAME,
+                        1);
+                insertReportNode(reportNode, gReportNode);
+            }
+            transformer.setG(modifG.getValue());
         }
-        if (twoWindingsTransformerModificationInfos.getRatedU1() != null && twoWindingsTransformerModificationInfos.getRatedU1().getValue() != null) {
-            insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(twoWindingsTransformer.getRatedU1(),
-                    twoWindingsTransformerModificationInfos.getRatedU1().getValue(), "Rated Voltage (Side 1)", 1));
-            twoWindingsTransformer.setRatedU1(twoWindingsTransformerModificationInfos.getRatedU1().getValue());
+    }
+
+    public static void modifyX(TwoWindingsTransformer twt, AttributeModification<Double> modifX, ReportNode reportNode) {
+        if (modifX != null && modifX.getValue() != null) {
+            if (reportNode != null) {
+                insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(twt.getX(),
+                        modifX.getValue(), "Series reactance", 1));
+            }
+            twt.setX(modifX.getValue());
         }
-        if (twoWindingsTransformerModificationInfos.getRatedU2() != null && twoWindingsTransformerModificationInfos.getRatedU2().getValue() != null) {
-            insertReportNode(characteristicsReporter, ModificationUtils.getInstance().buildModificationReport(twoWindingsTransformer.getRatedU2(),
-                    twoWindingsTransformerModificationInfos.getRatedU2().getValue(), "Rated Voltage (Side 2)", 1));
-            twoWindingsTransformer.setRatedU2(twoWindingsTransformerModificationInfos.getRatedU2().getValue());
+    }
+
+    public static void modifyR(TwoWindingsTransformer twt, AttributeModification<Double> modifR, ReportNode reportNode) {
+        if (modifR != null && modifR.getValue() != null) {
+            if (reportNode != null) {
+                insertReportNode(reportNode, ModificationUtils.getInstance().buildModificationReport(twt.getR(),
+                        modifR.getValue(), "Series resistance", 1));
+            }
+            twt.setR(modifR.getValue());
         }
     }
 
@@ -152,8 +215,8 @@ private void processPhaseTapChanger(Network network,
             regulationMode = phaseTapChangerInfos.getRegulationMode().getValue();
         }
         if (!PhaseTapChanger.RegulationMode.FIXED_TAP.equals(regulationMode)) {
-            processPhaseTapRegulation(phaseTapChangerInfos, phaseTapChanger, phaseTapChangerAdder, regulationReports,
-                    regulationMode, isModification);
+            processPhaseTapRegulation(phaseTapChanger, phaseTapChangerAdder, regulationMode, isModification, phaseTapChangerInfos.getRegulationValue(), phaseTapChangerInfos.getTargetDeadband(), regulationReports
+            );
         }
 
         processRegulatingTerminal(phaseTapChangerInfos, phaseTapChanger, phaseTapChangerAdder, regulationReports,
@@ -161,8 +224,7 @@ private void processPhaseTapChanger(Network network,
                 twt, isModification);
 
         List<ReportNode> positionsAndStepsReports = new ArrayList<>();
-        processTapChangerPositionsAndSteps(phaseTapChangerInfos, phaseTapChanger, phaseTapChangerAdder, positionsAndStepsReports,
-                isModification);
+        processTapChangerPositionsAndSteps(phaseTapChanger, phaseTapChangerAdder, isModification, phaseTapChangerInfos.getLowTapPosition(), phaseTapChangerInfos.getTapPosition(), phaseTapChangerInfos.getSteps(), positionsAndStepsReports);
 
         if (!isModification) {
             phaseTapChangerAdder.add();
@@ -186,33 +248,36 @@ private void processPhaseTapChanger(Network network,
         }
     }
 
-    private void processPhaseTapRegulation(PhaseTapChangerModificationInfos phaseTapChangerInfos,
-            PhaseTapChanger phaseTapChanger,
-            PhaseTapChangerAdder phaseTapChangerAdder,
-            List<ReportNode> regulationReports,
-            PhaseTapChanger.RegulationMode regulationMode,
-            boolean isModification) {
+    public static void processPhaseTapRegulation(PhaseTapChanger phaseTapChanger,
+                                                 PhaseTapChangerAdder phaseTapChangerAdder,
+                                                 PhaseTapChanger.RegulationMode regulationMode,
+                                                 boolean isModification,
+                                                 AttributeModification<Double> modifyRegulationValue,
+                                                 AttributeModification<Double> modifyTargetDeadband,
+                                                 List<ReportNode> regulationReports) {
 
         if (regulationMode != null) {
-            ReportNode regulationReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
+            String fieldName = (regulationMode.equals(PhaseTapChanger.RegulationMode.CURRENT_LIMITER)) ? "Value" : "Flow set point";
+            ReportNode regulationValueReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
                     isModification ? phaseTapChanger::setRegulationValue
                             : phaseTapChangerAdder::setRegulationValue,
                     isModification ? phaseTapChanger::getRegulationValue : () -> null,
-                    phaseTapChangerInfos.getRegulationValue(),
-                    regulationMode.equals(PhaseTapChanger.RegulationMode.CURRENT_LIMITER) ? "Value" : "Flow set point",
+                    modifyRegulationValue,
+                    fieldName,
                     2);
-            if (regulationReport != null) {
-                regulationReports.add(regulationReport);
+            if (regulationReports != null && regulationValueReportNode != null) {
+                regulationReports.add(regulationValueReportNode);
             }
         }
 
-        ReportNode targetDeadbandReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
+        ReportNode targetDeadbandReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
                 isModification ? phaseTapChanger::setTargetDeadband
                         : phaseTapChangerAdder::setTargetDeadband,
                 isModification ? phaseTapChanger::getTargetDeadband : () -> null,
-                phaseTapChangerInfos.getTargetDeadband(), "Target deadband", 2);
-        if (targetDeadbandReport != null) {
-            regulationReports.add(targetDeadbandReport);
+                modifyTargetDeadband, "Target deadband", 2);
+
+        if (regulationReports != null && targetDeadbandReportNode != null) {
+            regulationReports.add(targetDeadbandReportNode);
         }
 
         if (isModification) {
@@ -246,8 +311,8 @@ private void processRatioTapChanger(Network network,
         processRatioVoltageRegulation(ratioTapChangerInfos, twt, ratioTapChanger, ratioTapChangerAdder, voltageRegulationReports, network,
                 isModification);
         List<ReportNode> positionsAndStepsReports = new ArrayList<>();
-        processTapChangerPositionsAndSteps(ratioTapChangerInfos, ratioTapChanger, ratioTapChangerAdder, positionsAndStepsReports,
-                isModification);
+        processTapChangerPositionsAndSteps(ratioTapChanger, ratioTapChangerAdder, isModification, ratioTapChangerInfos.getLowTapPosition(), ratioTapChangerInfos.getTapPosition(), ratioTapChangerInfos.getSteps(), positionsAndStepsReports
+        );
 
         if (!isModification) {
             ratioTapChangerAdder.add();
@@ -292,27 +357,33 @@ private void processRatioVoltageRegulation(RatioTapChangerModificationInfos rati
             List<ReportNode> voltageRegulationReports,
             Network network,
             boolean isModification) {
+        modifyTargets(ratioTapChanger, ratioTapChangerAdder, isModification, ratioTapChangerInfos.getTargetV(), ratioTapChangerInfos.getTargetDeadband(), voltageRegulationReports);
 
-        ReportNode targetVoltageReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
-                        isModification ? ratioTapChanger::setTargetV
-                                : ratioTapChangerAdder::setTargetV,
-                        isModification ? ratioTapChanger::getTargetV : () -> null,
-                        ratioTapChangerInfos.getTargetV(), "Target voltage", 2);
-        if (targetVoltageReport != null) {
-            voltageRegulationReports.add(targetVoltageReport);
-        }
+        processRegulatingTerminal(ratioTapChangerInfos, ratioTapChanger, ratioTapChangerAdder, voltageRegulationReports,
+                    network, twt, isModification);
+    }
+
+    public static void modifyTargets(RatioTapChanger ratioTapChanger, RatioTapChangerAdder ratioTapChangerAdder, boolean isModification, AttributeModification<Double> targetV, AttributeModification<Double> targetDeadband, List<ReportNode> voltageRegulationReports) {
+        ReportNode targetVoltageReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
+                isModification ? ratioTapChanger::setTargetV
+                        : ratioTapChangerAdder::setTargetV,
+                isModification ? ratioTapChanger::getTargetV : () -> null,
+                targetV, "Target voltage", 2);
 
-        ReportNode targetDeadbandReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
+        ReportNode targetDeadbandReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
                 isModification ? ratioTapChanger::setTargetDeadband
                         : ratioTapChangerAdder::setTargetDeadband,
                 isModification ? ratioTapChanger::getTargetDeadband : () -> null,
-                ratioTapChangerInfos.getTargetDeadband(), "Target deadband", 2);
-        if (targetDeadbandReport != null) {
-            voltageRegulationReports.add(targetDeadbandReport);
-        }
+                targetDeadband, "Target deadband", 2);
 
-        processRegulatingTerminal(ratioTapChangerInfos, ratioTapChanger, ratioTapChangerAdder, voltageRegulationReports,
-                    network, twt, isModification);
+        if (voltageRegulationReports != null) {
+            if (targetVoltageReportNode != null) {
+                voltageRegulationReports.add(targetVoltageReportNode);
+            }
+            if (targetDeadbandReportNode != null) {
+                voltageRegulationReports.add(targetDeadbandReportNode);
+            }
+        }
     }
 
     private void processRegulatingTerminal(TapChangerModificationInfos tapChangerModificationInfos,
@@ -369,35 +440,25 @@ private void setRegulatingTerminalInfos(TapChangerModificationInfos tapChangerMo
         tapChangerModificationInfos.setRegulatingTerminalType(new AttributeModification<>(terminal.getConnectable().getType().name(), OperationType.SET));
     }
 
-    private void processTapchangerSteps(List<ReportNode> tapChangerStepsReports,
-            TapChangerModificationInfos tapChangerModificationInfos,
-            TapChangerAdder<?, ?, ?, ?, ?, ?> tapChangerAdder,
-            TapChangerStepsReplacer<?, ?> tapChangerStepReplacer,
-            boolean isModification) {
-        tapChangerStepsReports.add(ReportNode.newRootReportNode()
-                .withMessageTemplate("tapChangerStepsModification", "            Taps were replaced by new ones below")
-                .withSeverity(TypedValue.INFO_SEVERITY)
-                .build());
-        for (TapChangerStepCreationInfos step : tapChangerModificationInfos.getSteps()) {
-            addStepAttributeReports(tapChangerStepsReports, step);
+    private static void processTapchangerSteps(List<ReportNode> tapChangerStepsReports,
+                                        TapChangerAdder<?, ?, ?, ?, ?, ?> tapChangerAdder,
+                                        TapChangerStepsReplacer<?, ?> tapChangerStepReplacer,
+                                        boolean isModification,
+                                        List<TapChangerStepCreationInfos> modifSteps) {
+        if (tapChangerStepsReports != null) {
+            tapChangerStepsReports.add(ReportNode.newRootReportNode()
+                    .withMessageTemplate("tapChangerStepsModification", "            Taps were replaced by new ones below")
+                    .withSeverity(TypedValue.INFO_SEVERITY)
+                    .build());
+        }
+        for (TapChangerStepCreationInfos step : modifSteps) {
+            if (tapChangerStepsReports != null) {
+                addStepAttributeReports(tapChangerStepsReports, step);
+            }
             if (tapChangerStepReplacer instanceof RatioTapChangerStepsReplacer || tapChangerAdder instanceof RatioTapChangerAdder) {
-                if (isModification) {
-                    tapChangerStepReplacer.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG())
-                            .setB(step.getB()).setRho(step.getRho()).endStep();
-                } else {
-                    tapChangerAdder.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG())
-                            .setB(step.getB()).setRho(step.getRho()).endStep();
-                }
+                processRatioTapChangerStep(tapChangerAdder, tapChangerStepReplacer, isModification, step);
             } else {
-                addStepAttributeReport(tapChangerStepsReports, "newStepAlpha" + step.getAlpha(),
-                        "                Shift angle : ${alpha}", "alpha", String.valueOf(step.getAlpha()));
-                if (isModification) {
-                    ((PhaseTapChangerStepsReplacer) tapChangerStepReplacer).beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG())
-                            .setB(step.getB()).setRho(step.getRho()).setAlpha(step.getAlpha()).endStep();
-                } else {
-                    ((PhaseTapChangerAdder) tapChangerAdder).beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG())
-                            .setB(step.getB()).setRho(step.getRho()).setAlpha(step.getAlpha()).endStep();
-                }
+                processPhaseTapChangerStep(tapChangerStepsReports, (PhaseTapChangerAdder) tapChangerAdder, (PhaseTapChangerStepsReplacer) tapChangerStepReplacer, isModification, step);
             }
         }
         if (isModification) {
@@ -405,7 +466,31 @@ private void processTapchangerSteps(List<ReportNode> tapChangerStepsReports,
         }
     }
 
-    private void addStepAttributeReports(List<ReportNode> tapChangerStepsReports, TapChangerStepCreationInfos step) {
+    private static void processPhaseTapChangerStep(List<ReportNode> tapChangerStepsReports, PhaseTapChangerAdder tapChangerAdder, PhaseTapChangerStepsReplacer tapChangerStepReplacer, boolean isModification, TapChangerStepCreationInfos step) {
+        if (tapChangerStepsReports != null) {
+            addStepAttributeReport(tapChangerStepsReports, "newStepAlpha" + step.getAlpha(),
+                    "                Shift angle : ${alpha}", "alpha", String.valueOf(step.getAlpha()));
+        }
+        if (isModification) {
+            tapChangerStepReplacer.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG())
+                    .setB(step.getB()).setRho(step.getRho()).setAlpha(step.getAlpha()).endStep();
+        } else {
+            tapChangerAdder.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG())
+                    .setB(step.getB()).setRho(step.getRho()).setAlpha(step.getAlpha()).endStep();
+        }
+    }
+
+    private static void processRatioTapChangerStep(TapChangerAdder<?, ?, ?, ?, ?, ?> tapChangerAdder, TapChangerStepsReplacer<?, ?> tapChangerStepReplacer, boolean isModification, TapChangerStepCreationInfos step) {
+        if (isModification) {
+            tapChangerStepReplacer.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG())
+                    .setB(step.getB()).setRho(step.getRho()).endStep();
+        } else {
+            tapChangerAdder.beginStep().setR(step.getR()).setX(step.getX()).setG(step.getG())
+                    .setB(step.getB()).setRho(step.getRho()).endStep();
+        }
+    }
+
+    private static void addStepAttributeReports(List<ReportNode> tapChangerStepsReports, TapChangerStepCreationInfos step) {
         addStepAttributeReport(tapChangerStepsReports, "newStepIndex" + step.getIndex(),
                 "            Tap (${index})", "index", String.valueOf(step.getIndex()));
         addStepAttributeReport(tapChangerStepsReports, "newStepResistance" + step.getR(),
@@ -420,41 +505,48 @@ private void addStepAttributeReports(List<ReportNode> tapChangerStepsReports, Ta
                 "                Ratio : ${rho}", "rho", String.valueOf(step.getRho()));
     }
 
-    private void processTapChangerPositionsAndSteps(TapChangerModificationInfos tapChangerModificationInfos,
-            TapChanger<?, ?, ?, ?> tapChanger,
-            TapChangerAdder<?, ?, ?, ?, ?, ?> tapChangerAdder,
-            List<ReportNode> tapChangerReports,
-            boolean isModification) {
-        ReportNode lowTapPositionReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
+    public static void processTapChangerPositionsAndSteps(TapChanger<?, ?, ?, ?> tapChanger,
+                                                   TapChangerAdder<?, ?, ?, ?, ?, ?> tapChangerAdder,
+                                                   boolean isModification,
+                                                   AttributeModification<Integer> modifyLowTapPosition,
+                                                   AttributeModification<Integer> modifyTapPosition,
+                                                   List<TapChangerStepCreationInfos> modifySteps,
+                                                   List<ReportNode> tapChangerReports) {
+        ReportNode lowTapPositionReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
                 isModification ? tapChanger::setLowTapPosition
                         : tapChangerAdder::setLowTapPosition,
                 isModification ? tapChanger::getLowTapPosition : () -> null,
-                tapChangerModificationInfos.getLowTapPosition(), "Low tap position", 2);
-        if (lowTapPositionReport != null) {
-            tapChangerReports.add(lowTapPositionReport);
-        }
+                modifyLowTapPosition, "Low tap position", 2);
 
-        ReportNode tapPositionReport = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
+        ReportNode tapPositionReportNode = ModificationUtils.getInstance().applyElementaryModificationsAndReturnReport(
                 isModification ? tapChanger::setTapPosition
                         : tapChangerAdder::setTapPosition,
                 isModification ? tapChanger::getTapPosition : () -> null,
-                tapChangerModificationInfos.getTapPosition(), "Tap position", 2);
-        if (tapPositionReport != null) {
-            tapChangerReports.add(tapPositionReport);
+                modifyTapPosition, "Tap position", 2);
+
+        if (tapChangerReports != null) {
+            if (lowTapPositionReportNode != null) {
+                tapChangerReports.add(lowTapPositionReportNode);
+            }
+            if (tapPositionReportNode != null) {
+                tapChangerReports.add(tapPositionReportNode);
+            }
         }
 
         // Add steps
-        if (tapChangerModificationInfos.getSteps() != null) {
-            tapChangerReports.add(ReportNode.newRootReportNode()
-                    .withMessageTemplate("tapsModification", "        Taps")
-                    .withSeverity(TypedValue.INFO_SEVERITY)
-                    .build());
-            processTapchangerSteps(tapChangerReports, tapChangerModificationInfos,
-                    tapChangerAdder, isModification ? tapChanger.stepsReplacer() : null, isModification);
+        if (modifySteps != null) {
+            if (tapChangerReports != null) {
+                tapChangerReports.add(ReportNode.newRootReportNode()
+                        .withMessageTemplate("tapsModification", "        Taps")
+                        .withSeverity(TypedValue.INFO_SEVERITY)
+                        .build());
+            }
+            processTapchangerSteps(tapChangerReports,
+                    tapChangerAdder, isModification ? tapChanger.stepsReplacer() : null, isModification, modifySteps);
         }
     }
 
-    private void addStepAttributeReport(List<ReportNode> tapChangerStepsReports, String key, String defaultMessage,
+    private static void addStepAttributeReport(List<ReportNode> tapChangerStepsReports, String key, String defaultMessage,
             String valueKey, String value) {
         tapChangerStepsReports.add(ReportNode.newRootReportNode()
                 .withMessageTemplate(key, defaultMessage)
diff --git a/src/main/java/org/gridsuite/modification/server/modifications/VoltageLevelModification.java b/src/main/java/org/gridsuite/modification/server/modifications/VoltageLevelModification.java
index 7bbd83e8b..0fb9eebc3 100644
--- a/src/main/java/org/gridsuite/modification/server/modifications/VoltageLevelModification.java
+++ b/src/main/java/org/gridsuite/modification/server/modifications/VoltageLevelModification.java
@@ -13,7 +13,9 @@
 import com.powsybl.iidm.network.extensions.IdentifiableShortCircuit;
 import com.powsybl.iidm.network.extensions.IdentifiableShortCircuitAdder;
 import org.gridsuite.modification.server.NetworkModificationException;
+import org.gridsuite.modification.server.dto.AttributeModification;
 import org.gridsuite.modification.server.dto.VoltageLevelModificationInfos;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -84,52 +86,79 @@ public void apply(Network network, ReportNode subReportNode) {
                 .add();
 
         ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setName, () -> voltageLevel.getOptionalName().orElse("No value"), modificationInfos.getEquipmentName(), subReportNode, "Name");
-        ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setNominalV, voltageLevel::getNominalV, modificationInfos.getNominalV(), subReportNode, "Nominal voltage");
-        ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setLowVoltageLimit, voltageLevel::getLowVoltageLimit, modificationInfos.getLowVoltageLimit(), subReportNode, "Low voltage limit");
-        ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setHighVoltageLimit, voltageLevel::getHighVoltageLimit, modificationInfos.getHighVoltageLimit(), subReportNode, "High voltage limit");
+        modifyNominalV(voltageLevel, modificationInfos.getNominalV(), subReportNode);
+        modifLowVoltageLimit(voltageLevel, modificationInfos.getLowVoltageLimit(), subReportNode);
+        modifyHighVoltageLimit(voltageLevel, modificationInfos.getHighVoltageLimit(), subReportNode);
 
-        modifyVoltageLevelShortCircuit(subReportNode, voltageLevel);
+        modifyVoltageLevelShortCircuit(modificationInfos.getIpMin(), modificationInfos.getIpMax(), subReportNode, voltageLevel);
         PropertiesUtils.applyProperties(voltageLevel, subReportNode, modificationInfos.getProperties(), "VlProperties");
     }
 
-    private void modifyVoltageLevelShortCircuit(ReportNode subReportNode, VoltageLevel voltageLevel) {
-        if (modificationInfos.getIpMin() != null || modificationInfos.getIpMax() != null) {
-            List<ReportNode> reports = new ArrayList<>();
-            IdentifiableShortCircuit<VoltageLevel> identifiableShortCircuit = voltageLevel.getExtension(IdentifiableShortCircuit.class);
-            IdentifiableShortCircuitAdder<VoltageLevel> identifiableShortCircuitAdder = voltageLevel.newExtension(IdentifiableShortCircuitAdder.class);
-            var oldIpMin = identifiableShortCircuit == null ? null : identifiableShortCircuit.getIpMin();
-            var oldIpMax = identifiableShortCircuit == null ? null : identifiableShortCircuit.getIpMax();
+    public static void modifyHighVoltageLimit(VoltageLevel voltageLevel, AttributeModification<Double> highVoltageLimit, ReportNode subReportNode) {
+        ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setHighVoltageLimit, voltageLevel::getHighVoltageLimit, highVoltageLimit, subReportNode, "High voltage limit");
+    }
 
-            if (modificationInfos.getIpMin() != null) {
-                var newIpMin = modificationInfos.getIpMin().getValue();
+    public static void modifLowVoltageLimit(VoltageLevel voltageLevel, AttributeModification<Double> lowVoltageLimit, ReportNode subReportNode) {
+        ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setLowVoltageLimit, voltageLevel::getLowVoltageLimit, lowVoltageLimit, subReportNode, "Low voltage limit");
+    }
 
-                identifiableShortCircuitAdder.withIpMin(newIpMin);
+    public static void modifyNominalV(VoltageLevel voltageLevel, AttributeModification<Double> modifNominalV, ReportNode subReportNode) {
+        ModificationUtils.getInstance().applyElementaryModifications(voltageLevel::setNominalV, voltageLevel::getNominalV, modifNominalV, subReportNode, "Nominal voltage");
+    }
 
-                //convert to kA to report it like the user set it.
-                var oldIpMinToReport = oldIpMin != null ? oldIpMin * 0.001 : null;
-                var newIpMinToReport = newIpMin * 0.001;
+    public static void modifyVoltageLevelShortCircuit(AttributeModification<Double> ipMin,
+                                                      AttributeModification<Double> ipMax,
+                                                      ReportNode subReportNode,
+                                                      VoltageLevel voltageLevel) {
+        if (ipMin == null && ipMax == null) {
+            return;
+        }
 
-                reports.add(ModificationUtils.getInstance()
-                        .buildModificationReport(oldIpMinToReport, newIpMinToReport, "Low short circuit current limit"));
-            } else if (oldIpMin != null) {
-                identifiableShortCircuitAdder.withIpMin(oldIpMin);
-            }
+        List<ReportNode> reports = new ArrayList<>();
+        IdentifiableShortCircuitAdder<VoltageLevel> identifiableShortCircuitAdder = voltageLevel.newExtension(IdentifiableShortCircuitAdder.class);
+        Double oldIpMin = null;
+        Double oldIpMax = null;
+        IdentifiableShortCircuit<VoltageLevel> identifiableShortCircuit = voltageLevel.getExtension(IdentifiableShortCircuit.class);
+        if (identifiableShortCircuit != null) {
+            oldIpMin = identifiableShortCircuit.getIpMin();
+            oldIpMax = identifiableShortCircuit.getIpMax();
+        }
 
-            if (modificationInfos.getIpMax() != null) {
-                var newIpMax = modificationInfos.getIpMax().getValue();
-                identifiableShortCircuitAdder.withIpMax(newIpMax);
-
-                //Convert to kA to report it like the user set it.
-                var oldIpMaxToReport = oldIpMax != null ? oldIpMax * 0.001 : null;
-                var newIpMaxToReport = newIpMax * 0.001;
-                reports.add(ModificationUtils.getInstance()
-                        .buildModificationReport(oldIpMaxToReport, newIpMaxToReport, "High short circuit current limit"));
-            } else if (oldIpMax != null) {
-                identifiableShortCircuitAdder.withIpMax(oldIpMax);
-            }
+        if (ipMin != null) {
+            var newIpMin = ipMin.getValue();
 
-            identifiableShortCircuitAdder.add();
+            identifiableShortCircuitAdder.withIpMin(newIpMin);
+
+            //convert to kA to report it like the user set it.
+            var oldIpMinToReport = convertToKiloAmps(oldIpMin);
+            var newIpMinToReport = convertToKiloAmps(newIpMin);
+            reports.add(ModificationUtils.getInstance()
+                    .buildModificationReport(oldIpMinToReport, newIpMinToReport, "Low short circuit current limit"));
+        } else if (oldIpMin != null) {
+            identifiableShortCircuitAdder.withIpMin(oldIpMin);
+        }
+
+        if (ipMax != null) {
+            var newIpMax = ipMax.getValue();
+            identifiableShortCircuitAdder.withIpMax(newIpMax);
+
+            //Convert to kA to report it like the user set it.
+            var oldIpMaxToReport = convertToKiloAmps(oldIpMax);
+            var newIpMaxToReport = convertToKiloAmps(newIpMax);
+            reports.add(ModificationUtils.getInstance()
+                    .buildModificationReport(oldIpMaxToReport, newIpMaxToReport, "High short circuit current limit"));
+        } else if (oldIpMax != null) {
+            identifiableShortCircuitAdder.withIpMax(oldIpMax);
+        }
+
+        identifiableShortCircuitAdder.add();
+        if (subReportNode != null) {
             reports.forEach(report -> insertReportNode(subReportNode, report));
         }
     }
+
+    private static Double convertToKiloAmps(Double value) {
+        return (value != null) ? value * 0.001 : null;
+    }
 }
+
diff --git a/src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java b/src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java
index 9c3a4d38a..ae5b98b1b 100644
--- a/src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java
+++ b/src/test/java/org/gridsuite/modification/server/modifications/GeneratorByFormulaModificationTest.java
@@ -299,7 +299,7 @@ protected void assertAfterNetworkModificationCreation() {
         assertNotNull(generatorStartup1);
         assertEquals(50, generator1.getTargetP(), 0);
         assertEquals(15, generatorStartup1.getMarginalCost(), 0);
-        assertEquals(55, generatorStartup1.getPlannedOutageRate(), 0);
+        assertEquals(2.5, generatorStartup1.getPlannedOutageRate(), 0);
         assertEquals(1100, generatorStartup1.getForcedOutageRate(), 0);
         assertEquals(50, generatorStartup1.getPlannedActivePowerSetpoint(), 0);
         assertEquals(502, generator1.getMaxP(), 0);
@@ -310,7 +310,7 @@ protected void assertAfterNetworkModificationCreation() {
         assertNotNull(generatorStartup2);
         assertEquals(100, generator2.getTargetP(), 0);
         assertEquals(15, generatorStartup2.getMarginalCost(), 0);
-        assertEquals(55, generatorStartup2.getPlannedOutageRate(), 0);
+        assertEquals(2.5, generatorStartup2.getPlannedOutageRate(), 0);
         assertEquals(1100, generatorStartup2.getForcedOutageRate(), 0);
         assertEquals(50, generatorStartup2.getPlannedActivePowerSetpoint(), 0);
         assertEquals(2002, generator2.getMaxP(), 0);