> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Migration notes 6.0

This page explains the changes required to migrate to the stated version
of Atoti Sign-Off.

## Migrate to 6.0.1

Upgrading from version 6.0.0 See [Atoti Sign-Off 6.0.1 Release Notes](../../release-notes#601).

### Headline announcement

* **Persisting full scope paths**: Full scope paths are persisted to the JPA layer to allow handling of scopes with slicing and non-slicing hierarchies.
* **Customized sign-off status feed**: The sign-off status feed member for “in review” representation can be customized on the application server.

### Using full scope paths in persisted data

Older versions of Atoti Sign-Off did not include the full scope path for definitions that were saved to the JPA layer. As of this version, full scope paths
will be used. For example, if you have a definition on the slicing `Book` level, the old path would look like:

```
[Booking].[Books].[Book]=[BS_MGT_FX]
```

The new path will look like:

```
[Booking].[Books].[Book]=[AllMember].[BS_MGT_FX]
```

To migrate scope paths created before Atoti Sign-Off `6.1.0`, we have added a migration endpoint. The reason for adding an endpoint rather than a
script is that we need to connect with the application server to get the full scope path.

<Info>
  You only need to run the migration if you are using persisted data as your golden source of Atoti Sign-Off data. If you are using files as your golden source
  of data then you do not need to run the migration.
</Info>

To run the migration, do the following:

1. Start your application server.
2. Start Atoti Sign-Off with the `6.0.1-migration` Spring profile to include the endpoint and override default validation.
3. Run the migration endpoint. You can do this via Swagger by executing the POST request at `<base URL>/sign-off/rest/v2/migrate/sign-off-definition-scopes`.
   The
   migration endpoint retrieves the full scope paths from the application server and updates the definitions if necessary.
4. Restart the application server and Atoti Sign-Off as normal (without the `6.0.1-migration` profile) to view your updated definitions and proceed as normal.

### Configuration properties

#### Properties added

##### [signoff-activeviam](../../../user-ref/properties/config-properties/signoff-activeviam)

| Property Name                                                 | Comment                                         | Value                |
| ------------------------------------------------------------- | ----------------------------------------------- | -------------------- |
| `sign-off.application.settings.feed-member-coordinate.member` | Defines the members for the Sign-Off hierarchy. | `[TOTAL REVIEWABLE]` |

### Configuration

#### Configuration properties

##### Properties added

[signoff-activeviam module](../../../user-ref/properties/config-properties/signoff-activeviam)

| Property                                                  | Default value | Description                                                                             |
| --------------------------------------------------------- | ------------- | --------------------------------------------------------------------------------------- |
| `sign-off.workflow.approver-can-be-same-as-previous-user` | `false`       | When enabled, the approving user can be the same as the previous user in the workflow.  |
| `sign-off.application.overlapping-scopes.allowed`         | `false`       | True if users are allowed to create definitions on overlapping scopes, false otherwise. |

#### Configuration files

##### Files modified

###### RestApiProperties.java

Updated properties:

| Key              | Comment                    | New Value                        | Old Value           |
| ---------------- | -------------------------- | -------------------------------- | ------------------- |
| `statusEndpoint` | Updated the default value. | `/activeviam/pivot/rest/v9/ping` | `/sign-off/enabled` |

###### [UI settings](../../../dev/dev-ui-config/ui-settings)

Updated properties:

| Key                           | Comment                                             | New Value  | Old Value                                                                                   |
| ----------------------------- | --------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------- |
| `availableApplicationServers` | Cube-specific module settings are no longer needed. | `string[]` | `{[serverName: string]: {[cubeName: string ]: {// Cube-specific module settings go here}}}` |

Deleted properties:

| Key                                         | Comment                                                                                      |
| ------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `filteredApplicationCubes`                  | This is fetched from the server and set in `application.yml`.                                |
| `adjustmentCommentLevel`                    | Used by dashboard widgets that have been removed.                                            |
| `adjustmentFiltersLevel`                    | Used by dashboard widgets that have been removed.                                            |
| `adjustmentIdLevel`                         | Used by dashboard widgets that have been removed.                                            |
| `adjustmentInputLevel`                      | Used by dashboard widgets that have been removed.                                            |
| `adjustmentLiveFromLevel`                   | Used by dashboard widgets that have been removed.                                            |
| `adjustmentLiveToLevel`                     | Used by dashboard widgets that have been removed.                                            |
| `adjustmentReasonLevel`                     | Used by dashboard widgets that have been removed.                                            |
| `adjustmentsServerNameLevel`                | Used by dashboard widgets that have been removed.                                            |
| `adjustmentStatusLevel`                     | Used by dashboard widgets that have been removed.                                            |
| `adjustmentsWorkflowStatusLevel`            | Used by dashboard widgets that have been removed.                                            |
| `adjustmentTypeLevel`                       | Used by dashboard widgets that have been removed.                                            |
| `adjustmentUserLevel`                       | Used by dashboard widgets that have been removed.                                            |
| `adjustmentValidFromLevel`                  | Used by dashboard widgets that have been removed.                                            |
| `adjustmentValidToLevel`                    | Used by dashboard widgets that have been removed.                                            |
| `adjustmentCubeSettings`                    | Used by dashboard widgets that have been removed.                                            |
| `allowedStatusForArchive`                   | Allowed actions are now fetched dynamically from the server.                                 |
| `allowedStatusForDelete`                    | Allowed actions are now fetched dynamically from the server.                                 |
| `allowedStatusForEdit`                      | Allowed actions are now fetched dynamically from the server.                                 |
| `allowedStatusForPublish`                   | Allowed actions are now fetched dynamically from the server.                                 |
| `areWorkflowButtonsHidden`                  | Allowed actions are now fetched dynamically from the server.                                 |
| `availableRoles`                            | This is fetched from the server and set in `application.yml`. See `sign-off.workflow.roles`. |
| `failedStatuses`                            | Used by dashboard widgets that have been removed.                                            |
| `fields`                                    | This is fetched from the server and set in `application.yml`.                                |
| `isValidFromFieldDisabledForAdjustments`    | This is always disabled.                                                                     |
| `signOffButtonInformation`                  | This is fetched from the server and set in `application.yml`. See `workflow.configuration`.  |
| `signOffInstanceAsOfDateDimensionName`      | Used by dashboard widgets that have been removed.                                            |
| `signOffInstanceAsOfDateHierarchyName`      | Used by dashboard widgets that have been removed.                                            |
| `signOffInstanceAsOfDateLevelName`          | Used by dashboard widgets that have been removed.                                            |
| `signOffInstanceKeyDimensionName`           | Used by dashboard widgets that have been removed.                                            |
| `signOffInstanceKeyHierarchyName`           | Used by dashboard widgets that have been removed.                                            |
| `signOffInstanceStatusDimensionName`        | Used by dashboard widgets that have been removed.                                            |
| `signOffInstanceStatusHierarchyName`        | Used by dashboard widgets that have been removed.                                            |
| `signOffInstanceStatusLevelName`            | Used by dashboard widgets that have been removed.                                            |
| `signOffRoleActionMap`                      | Allowed actions are now fetched dynamically from the server.                                 |
| `signOffStatusProgress`                     | Used by dashboard widgets that have been removed.                                            |
| `signOffWorkFlowMap`                        | This is fetched from the server and set in `application.yml`. See `workflow.configuration`.  |
| `startDailyProgressStatus`                  | Used by dashboard widgets that have been removed.                                            |
| `taskDefinitionCategoryDimensionName`       | Used by dashboard widgets that have been removed.                                            |
| `taskDefinitionCategoryHierarchyName`       | Used by dashboard widgets that have been removed.                                            |
| `taskDefinitionCubeName`                    | Used by dashboard widgets that have been removed.                                            |
| `taskDefinitionNameDimensionName`           | Used by dashboard widgets that have been removed.                                            |
| `taskDefinitionNameHierarchyName`           | Used by dashboard widgets that have been removed.                                            |
| `taskDefinitionWorkflowStatusDimensionName` | Used by dashboard widgets that have been removed.                                            |
| `taskDefinitionWorkflowStatusHierarchyName` | Used by dashboard widgets that have been removed.                                            |
| `taskInstanceCubeName`                      | Used by dashboard widgets that have been removed.                                            |

###### [application.yml](../../../user-ref/properties/property-files/application-yml)

New properties:

| Property Name                                                            | Comment                                                                                                                                                                     | Value                                    |
| ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| activiti.datasource.properties.hibernate.default\_schema                 | The default schema used by the Activiti datasource.                                                                                                                         | sign-off                                 |
| application.datasource.properties.hibernate.default\_schema              | The default schema used by the Application datasource.                                                                                                                      | sign-off                                 |
| application.rest-apis.MR.mdx-endpoint                                    | A rest endpoint that can be called to execute MDX queries on the server. (MR)                                                                                               | /activeviam/pivot/rest/v9/cube/query/mdx |
| application.rest-apis.MR.cubes.Var-ES Cube.as-of-date-level              | The full level used to determine the As-Of-Date of the `VAR-ES Cube` on the server. (MR).                                                                                   | \[Dates].\[Date].\[AsOfDate]             |
| application.rest-apis.MR.cubes.VaR-ES Summary Cube.as-of-date-level      | The full level used to determine the As-Of-Date of the `VaR-ES Summary Cube` on the server. (MR).                                                                           | \[Dates].\[Date].\[AsOfDate]             |
| application.rest-apis.MR.cubes.Sensitivity Cube.as-of-date-level         | The full level used to determine the As-Of-Date of the `Sensitivity Cube` on the server. (MR).                                                                              | \[Dates].\[Date].\[AsOfDate]             |
| application.rest-apis.MR.cubes.Sensitivity Summary Cube.as-of-date-level | The full level used to determine the As-Of-Date of the `Sensitivity Summary Cube` on the server. (MR).                                                                      | \[Dates].\[Date].\[AsOfDate]             |
| application.rest-apis.MR.cubes.PLCube.as-of-date-level                   | The full level used to determine the As-Of-Date of the `PLCube` on the server. (MR).                                                                                        | \[Dates].\[Date].\[AsOfDate]             |
| application.rest-apis.MR.cubes.PL Summary Cube.as-of-date-level          | The full level used to determine the As-Of-Date of the `PL Summary Cube` on the server. (MR).                                                                               | \[Dates].\[Date].\[AsOfDate]             |
| application.rest-apis.MR.cubes.MRCombinedCube.as-of-date-level           | The full level used to determine the As-Of-Date of the `MRCombinedCube` on the server. (MR).                                                                                | \[Dates].\[Date].\[AsOfDate]             |
| application.rest-apis.FRTB.mdx-endpoint                                  | A rest endpoint that can be called to execute MDX queries on the server. (FRTB)                                                                                             | /activeviam/pivot/rest/v9/cube/query/mdx |
| audit-log.datasource.properties.hibernate.default\_schema                | The default schema used by the Activiti History datasource.                                                                                                                 | sign-off                                 |
| spring.h2.console.enabled                                                | When set to `true`, the [H2 console](https://www.h2database.com/html/quickstart.html) is available. This is useful for investigating JDBC connections. Disabled by default. | `false`                                  |
| spring.application.name                                                  | Spring property for the application name. Used by the notification service to identify the source server for each notification.                                             | Atoti Sign-Off                           |
| spring.activiti.database-schema                                          | The schema used by the Activiti databases.                                                                                                                                  | sign-off                                 |
| sign-off.workflow\.roles                                                 | The list of roles for workflow participants                                                                                                                                 | USERS,MANAGERS                           |

Updated properties:

| Old Property Name            | New Property Name                 | Comment                                                | New Value                                                                                                     | Old Value                                                               |
| ---------------------------- | --------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `activiti.datasource.url`    | `activiti.datasource.url`         | The URL of the Activiti datasource.                    | `jdbc:h2:file:./sign-off-activiti;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS "sign-off";`             | `jdbc:h2:file:./sign-off-activiti;DB_CLOSE_DELAY=-1`                    |
| `application.datasource.url` | `application.datasource.url`      | The URL of the Application datasource.                 | `jdbc:h2:file:./application-sign-off;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS "sign-off";`          | `jdbc:h2:file:./application-sign-off;DB_CLOSE_DELAY=-1`                 |
| `audit-log.datasource.url`   | `audit-log.datasource.url`        | The URL of the Audit Log datasource.                   | `jdbc:h2:file:./audit-log;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS "sign-off";`                     | `jdbc:h2:file:./audit-log;DB_CLOSE_DELAY=-1`                            |
| `workflow-types`             | `sign-off.workflow.configuration` | Describes the workflows as a pair of key and approvers | e.g. `[{"dummy-workflow": {"key": "sign-off-process-instance.dummy-workflow", "participants": "approvers"}}]` | e.g. `[{"dummy-workflow": "sign-off-process-instance.dummy-workflow"}]` |

### Datastores

#### Modified stores

| Modification | Store                                                                              | Field      | Type           | Description                                          |
| ------------ | ---------------------------------------------------------------------------------- | ---------- | -------------- | ---------------------------------------------------- |
| Deleted      | [SignOffProcessDefinition](../../../user-ref/datastore/signoff-process-definition) | `MEASURES` | list of string | This column has been removed because it is not used. |

### Other changes

#### Spring Boot compliance

Atoti Sign-Off now aligns more closely with Spring Boot best practices in our aim to move towards using [Spring Boot Starters](https://docs.spring.io/spring-boot/reference/features/developing-auto-configuration.html#features.developing-auto-configuration.custom-starter)
to ease migrations.

##### Configuration properties

Atoti Sign-Off now uses [Spring Configuration Properties](https://docs.spring.io/spring-boot/how-to/properties-and-configuration.) to help externalize
configurations for users. You can see a full list of the provided properties in the [Configuration Properties](../../../user-ref/properties/config-properties) section.

#### Adjustments `locations` and `input` fields

These two adjustment fields are now `List`s instead of `Set`s. This impacts the following classes and services that may affect your implementation:

Workflow-related:

* `SignOffProcessInstanceWorkflowService.java`
* `AuditableAdjustmentDefinitionDTO.java`
* `AdjustmentExecutionDTO.java`

JPA-related:

* `AdjustmentsDefinitionEntity.java`
* `AdjustmentsFiltersConverter.java`
* `AdjustmentsInputConverter.java`
* `IAdjustmentDefinition.java`
* `AdjustmentExecutionEntity.java`
* `IAdjustmentExecution.java`

#### Status manager service

The `ISignOffWorkflowStatusManager` lets you implement a service to define the statuses that relate to specific categories.
Current methods with a default implementation in `DefaultSignOffWorkflowStatusManager` are:

* `getLiveDefinitionStatuses()`: returns a list of definition status considered live.
* `getPendingApprovalTaskStatuses()`: returns a list of task status considered pending.

#### Workflow task actions

A unique way is now used to execute common workflow task actions (e.g. approve, reject, request approval …) and custom actions.
It allows greater flexibility and easier extension of current set of actions.
To extend the task actions, see [Adding Custom Workflow Tasks](../../../dev/dev-extensions/custom-workflows/custom-workflow-actions).

### Using Atoti Sign-Off with older solutions

Atoti Sign-Off 6.0 is a major upgrade but can be compatible with older solutions with some adjustments.
This section guides you through the steps to make your solution compatible with Atoti Sign-Off 6.0.

We shall include sample changes specific to Atoti Market Risk version 5.4.2 and Atoti FRTB 5.3.4, but the general steps apply to any server that connects with Atoti Sign-Off.

#### Steps to use Atoti Sign-Off

The steps to use Atoti Sign-Off are the same as in the [Getting started](../../../dev/dev-getting-started#connecting-atoti-sign-off-to-your-application-server) guide. Note that depending on the Atoti Server version of the solution you are running with Atoti Sign-Off,
you may need to update the property `application.rest-apis.<server>.mdx-endpoint` in your `application.yml` file.

If your Atoti Server version runs with a different version of the API than the default set in Atoti Sign-Off (`/activeviam/pivot/rest/v9/cube/query/mdx`) for Atoti Server 6.1,
you will need to update this property.
See the [Atoti Server API documentation](https://docs.activeviam.com/products/atoti/server/6.1.4/docs/rest-api/rest-apis-overview/#atoti--database) for the correct version.

###### Connecting with Atoti Market Risk 5.4.2 & Atoti FRTB 5.3.4

With Atoti Market Risk 5.4.2 and Atoti FRTB 5.3.4, which runs with Atoti Server `6.0`, you need to update this property in Atoti Sign-Off:

```
application.rest-apis.MR.mdx-endpoint=/activeviam/pivot/rest/v8/cube/query/mdx
```

#### Steps to use the Atoti Solution

##### Migrate adjustments services

For UI compatibility, `adjustments-services` version `4.1` or higher is required.
See [Adjustments Services 4.1](https://docs.activeviam.com/products/modules/adjustments-services/4.1/online-help/release/migrate-4.1.).

You will need to:

1. Update your dependency artifact’s `groupId` and `version` to `com.activeviam.solutions` and `4.1.0` respectively.
2. Update your code to use a `List` in `AdjustmentRequestDTO` and `SupportedAdjustmentDTO` when setting your`filters` and `input`.
3. Update your code to replace use of `NamedValueDTO`s from dependencies (e.g. `com.activeviam.apps:shared` also known as the common library).

###### Connecting Atoti Market Risk 5.4.2 & Atoti FRTB 5.3.4

In Atoti Market Risk 5.4.2 and Atoti FRTB 5.3.4, the dependency `com.activeviam.apps:shared` is using version `2.0.6-AS6.0`
and `2.0.3-AS6.0` respectively which depend on `adjustments-services` version `4.0.0`.
Your code may call methods in dependencies that use `NamedValueDTO` which has changed in `adjustments-services` version `4.1.0`.

You should replace calls to `ExecutionFunctionalComponents::parseInput` with calls to a local method to your project to complete its purpose.

<Accordion title="ExecutionFunctionalComponents::parseInput">
  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  public static AdjustmentInputParser parseInput() {
      return (req, def) -> {
          Map<String, Object> inputMap = new HashMap<>();
          req.getInput().forEach(
                  input -> {
                      String name = input.getName();
                      String value = input.getValue();
                      IParser<Object> parser = Registry.getPluginValue(IParser.class, def.typeOf(name));
                      inputMap.put(name, parser == null ? value : parser.parse(value));
                  }
          );
          return inputMap;
      };
  }
  ```
</Accordion>

**Atoti Market Risk 5.4.2**

You may place this method in `ExecutionFunctionalComponentsConfig` for instance.
Then you should replace the calls to `ExecutionFunctionalComponents.java::parseInput` with it in:

* `AdjustmentsExecutionVaRConfig`
* `AdjustmentsExecutionPnLConfig`
* `AdjustmentsExecutionSensiConfig`

**Atoti FRTB 5.3.4**

You may place this method in `AdjustmentExecutionConfig` for instance and make it static.
Then you should replace the calls to `ExecutionFunctionalComponents::parseInput` with it in this same class.

##### Migrate Sign-Off API

To ensure that the API contract between the Atoti solution and Atoti Sign-Off is respected,
check that the Sign-Off API is upgraded to the version required by your Atoti Sign-Off version. You can find the correct version in the [Dependency versions](../../release-notes#dependency-versions) section of the Release notes.

For Atoti Sign-Off 6.0.0 you need to upgrade to `4.2.0`.
See [Sign-Off API 4.2](https://docs.activeviam.com/products/modules/signoff-api/4.2/online-help/release/migrate-4.2.).

You will need to:

1. Update your dependency artifact’s `groupId`, `artifact` and `version` to `com.activeviam.solutions.signoff-api`, `signoff-api-lib` and `4.2.0` respectively.
2. Implement the `ISignOffRestService::enabled` method. This method is used to let Atoti Sign-Off know that the server is up and running.
3. Remove calls to `getMeasures` in `SignOffProcessInstanceExportDTO`: The `measures` field has been removed in Sign-Off API `4.2.0`.

###### Connecting with Atoti Market Risk 5.4.2 & Atoti FRTB 5.3.4

In Atoti Market Risk 5.4.2 and Atoti FRTB 5.3.4, you may remove calls to the `getMeasures` method in the `SignOffProcessInstanceExportDTO` class by extending the `SignOffService` with a `CustomSignOffService` class.

<Accordion title="CustomSignOffService">
  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  @Slf4j
  public class CustomSignOffService extends SignOffService {
      public CustomSignOffService(IActivePivotManager manager, ILocalDataExtractionService dataExtractionService,
              ISignOffServiceParams serviceParams) {
          super(manager, dataExtractionService, serviceParams);
      }

      /**
       * Export the data related to the instance following the DEE templates
       *
       * @param instance The sign-off task definition that needs to be exported
       * @return The list of export names with the associated task ID
       */
      @Override
      public Map<String, String> export(SignOffProcessInstanceExportDTO instance) {
          validateRequest(instance);

          try {
              if (log.isInfoEnabled()) {
                  log.info("[EXPORT][SERVICE] Received \"export\" call for {} for definition {}.", JacksonSerializer.serialize(instance),
                          JacksonSerializer.serialize(instance));
              }
          } catch (SerializerException e) {
              log.error("[EXPORT][SERVICE] Error serializing object", e);
          }

          IMultiVersionActivePivot pivot = manager.getActivePivots().get(instance.getDomain());
          if (pivot == null) {
              throw new BadRequestException("[EXPORT][SERVICE] Requested an export on the " + instance.getDomain() + " cube, which does not exist.");
          }

          List<IDeeOrder> templates = getTemplates(instance.getDomain());

          List<IDeeOrder> orders = new ArrayList<>();
          for (var template : templates) {
              orders.add(adjustDeeOrderToInstance(template, instance));
          }

          IDeeOrder order = new CompositeDeeOrder(orders);
          List<String> taskIds = dataExtractionService.submitLocalTask(order);

          Map<String, String> deeTasks = new HashMap<>();
          for (int i = 0; i < taskIds.size(); i++) {
              deeTasks.put(orders.get(i).getName(), taskIds.get(i));
          }
          return deeTasks;
      }

      /**
       * Get all the templates need to fulfill an export request
       *
       * @param domain   the selected cube
       * @return A list of export templates
       */
      protected List<IDeeOrder> getTemplates(String domain) {
          List<String> templatesName = serviceParams.getDomainTemplates(domain, List.of());
          if (templatesName == null) {
              return List.of();
          }
          return templatesName.stream().map(deeTemplates::get).filter(Objects::nonNull).map(DeeOrderStr::getDeeOrder).toList();
      }

      /**
       * Check that all the parameters are provided on the request
       *
       * @param instance The request
       * @throws BadRequestException when the request is not well filled
       */
      @Override
      protected void validateRequest(SignOffProcessInstanceExportDTO instance) {
          if (instance == null) {
              throw new BadRequestException("[EXPORT][SERVICE] DTO not provided.");
          }

          String domain = instance.getDomain();
          if (domain == null) {
              throw new BadRequestException("[EXPORT][SERVICE] The export request is missing a domain (cube).");
          }

          if (instance.getFilters() == null) {
              throw new BadRequestException("[EXPORT][SERVICE] The export request is missing filters.");
          }

          if (instance.getAsOfDate() == null) {
              throw new BadRequestException("[EXPORT][SERVICE] The export request is missing an as-of date.");
          }
      }
  }
  ```
</Accordion>

Alongside with an adapted `SignOffServiceConfig`.

<Accordion title="SignOffServiceConfig">
  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  @Configuration
  public class SignOffServiceConfig {

      protected final CommonSignOffHierarchyProperties commonSignOffHierarchyProperties;

      protected final SignOffProperties signOffProperties;

      /**
       * The configuration property used to define the folder in which the DEE templates used for
       * the export of the sign-off are defined
       */
      public static final String EXPORT_TEMPLATE_FOLDER_PROP = "data.extraction.templates.base.dir.path";

      protected final String signOffDataExtractionTemplatesBaseDirPath;

      public SignOffServiceConfig(
              @Value("${" + EXPORT_TEMPLATE_FOLDER_PROP + "}") String signOffDataExtractionTemplatesBaseDirPath,
              CommonSignOffHierarchyProperties commonSignOffHierarchyProperties,
              SignOffProperties signOffProperties) {
          this.signOffDataExtractionTemplatesBaseDirPath = signOffDataExtractionTemplatesBaseDirPath;
          this.commonSignOffHierarchyProperties = commonSignOffHierarchyProperties;
          this.signOffProperties = signOffProperties;
      }

      @Bean
      public ISignOffService signOffService(IActivePivotManager manager, ILocalDataExtractionService dataExtractionService,
              @Qualifier(SP_QUALIFIER__TEMPLATES) Map<String, SignOffProperties.ExportFilenamesMdxTemplate> templatesFileName) {
          return new CustomSignOffService(manager, dataExtractionService, getSignOffServiceParams(templatesFileName));
      }

      @Bean
      @ConditionalOnVectorizedSensitivity
      @Deprecated(since = "5.4.0", forRemoval = true)
      @Qualifier(SP_QUALIFIER__TEMPLATES)
      protected Map<String, SignOffProperties.ExportFilenamesMdxTemplate> scalarTemplate() {
          return signOffProperties.getExtractionTemplates();
      }

      @Bean
      @ConditionalOnScalarSensitivity
      @Qualifier(SP_QUALIFIER__TEMPLATES)
      protected Map<String, SignOffProperties.ExportFilenamesMdxTemplate> vectorisedTemplate() {
          return signOffProperties.getExtractionTemplatesScalar();
      }

      protected ISignOffServiceParams getSignOffServiceParams(Map<String, SignOffProperties.ExportFilenamesMdxTemplate> templatesFileName) {
          Map<IPair<String, Set<String>>, List<String>> cubeToTemplates = new HashMap<>();
          for (var templatesFileNameValue : templatesFileName.values()) {
              var cubeName = templatesFileNameValue.getCubeName();
              Set<String> measuresAsSet = templatesFileNameValue.getMeasures();
              List<String> exportFileNames = templatesFileNameValue.getExportFileNames();
              cubeToTemplates.put(new Pair<>(cubeName, measuresAsSet), exportFileNames);
          }

          Map<String, LevelIdentifier> dateLevels = signOffProperties.getDateHierarchies();
          Map<String, LevelIdentifier> taskLevels = signOffProperties.getTaskLevels();

          return new ISignOffServiceParams() {
              @Override public String getKpiMdxTemplate() {
                  return signOffProperties.getExportFilenamesMdxTemplate();
              }

              @Override public List<String> getDomainTemplates(String domain, List<String> measures) {
                  Set<String> templates = new HashSet<>();
                  templates.addAll(cubeToTemplates.getOrDefault(new Pair<>(domain, null), List.of()));
                  templates.addAll(cubeToTemplates.getOrDefault(new Pair<>(DOMAIN_DEFAULT, null), List.of()));
                  return new ArrayList<>(templates);
              }

              @Override public String getSignOffDataExtractionTemplatesBaseDirPath() {
                  return signOffDataExtractionTemplatesBaseDirPath;
              }

              @Override public LevelIdentifier getDateLevel(String domain) {
                  return dateLevels.getOrDefault(domain, dateLevels.get(DOMAIN_DEFAULT));
              }

              @Override public LevelIdentifier getSignOffLevel(String domain) {
                  return taskLevels.getOrDefault(domain, taskLevels.get(DOMAIN_DEFAULT));
              }

              @Override public String getReviewableMember() {
                  return commonSignOffHierarchyProperties.getLevelMembers().get(1);
              }
          };
      }
  }
  ```
</Accordion>

These changes will be used in the Atoti Market Risk solution when it is upgraded to be compatible with Atoti Sign-Off `6.0.x`.
