Overview

This documentation describes the migration process from the legacy salesperson management to the new system based on Salesperson Set ID. The migration is necessary to transition from a redundant data model to a normalized one, with significant benefits in terms of disk space and performance.

Migration Activation

The migration process consists of two phases:

Phase 1 (Optional but Recommended for Large Data Volumes): Pre-calculation via Job Queue

  • Gradually calculates the “Salesperson Set ID” values in advance
  • Can run during normal working hours with minimal user impact
  • Significantly reduces the time required for Phase 2

Phase 2 (Required): Final migration via Eos Admin Library (EAL) feature flag activation

  • Completes the migration to the new data model
  • Executes the final data structure switch

Important:

  • The migration is considered complete only when the entire process initiated by the EAL feature flag activation finishes successfully.
  • The migration is performed per company: each company in the environment requires independent migration.
  • It is the consultant’s responsibility to thoroughly test the migration in a non-production environment before executing it in production.

Differences Between Legacy System and New System

Legacy System

In the legacy system, salesperson management (roles and salesperson) was replicated for each individual entity managed by the Commissions app (CMS):

┌─────────────────────────────────────────────────────────────────────┐
│                        LEGACY SYSTEM                                │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Customer "CUST001"                                                 │
│    └── EOS Add. Salesperson/Purchaser                               │
│          ├── Role: AGENT1, Salesperson: SP001                       │
│          └── Role: AGENT2, Salesperson: SP002                       │
│                                                                     │
│  Sales Header "INV-0001"                                            │
│    └── EOS Add. Salesperson/Purchaser                               │
│          ├── Role: AGENT1, Salesperson: SP001  ◄── DUPLICATE        │
│          └── Role: AGENT2, Salesperson: SP002  ◄── DUPLICATE        │
│                                                                     │
│  Sales Line "INV-0001, Line 10000"                                  │
│    └── EOS Add. Salesperson/Purchaser                               │
│          ├── Role: AGENT1, Salesperson: SP001  ◄── DUPLICATE        │
│          └── Role: AGENT2, Salesperson: SP002  ◄── DUPLICATE        │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Legacy system issues:

  • Data redundancy: the same set of roles/salespersons is stored N times
  • High disk space: exponential storage growth
  • Degraded performance: slow queries on tables with millions of records
  • Complex maintenance: updates requiring changes across multiple records

New System (Dimension-like)

The new system adopts an approach similar to Business Central’s dimension management. Each unique combination of roles and salespersons is assigned a unique integer ID (Salesperson Set ID). Entities managed by CMS store only this ID.

┌────────────────────────────────────────────────────────────────────┐
│                        NEW SYSTEM                                  │
├────────────────────────────────────────────────────────────────────┤
│                                                                    │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │  EOS010 Role-Salesperson Sets (normalized table)             │  │
│  │  ┌────┬────────────┬─────────────────┐                       │  │
│  │  │ ID │ Salesp.Role│ Salesperson Code│                       │  │
│  │  ├────┼────────────┼─────────────────┤                       │  │
│  │  │ 1  │ AGENT1     │ SP001           │                       │  │
│  │  │ 2  │ AGENT2     │ SP002           │                       │  │
│  │  │... │ ...        │ ...             │                       │  │
│  │  └────┴────────────┴─────────────────┘                       │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                    │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │  EOS010 Salesperson Set Entry (unique combinations)          │  │
│  │  ┌──────────────────┬──────────────────────────┐             │  │
│  │  │ Salesperson Set  │ Role-Salesperson Set ID  │             │  │
│  │  │       ID         │  (references table above)│             │  │
│  │  ├──────────────────┼──────────────────────────┤             │  │
│  │  │ 100              │ 1 (AGENT1/SP001)         │             │  │
│  │  │ 100              │ 2 (AGENT2/SP002)         │             │  │
│  │  │ 101              │ 1 (AGENT1/SP001)         │             │  │
│  │  │ 101              │ 5 (AGENT3/SP003)         │             │  │
│  │  └──────────────────┴──────────────────────────┘             │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                    │
│  Customer "CUST001"                                                │
│    └── EOS Salesperson Set ID = 100  ◄── JUST ONE INTEGER!         │
│                                                                    │
│  Sales Header "INV-0001"                                           │
│    └── EOS Salesperson Set ID = 100  ◄── SAME ID = SAME SET        │
│                                                                    │
│  Sales Line "INV-0001, Line 10000"                                 │
│    └── EOS Salesperson Set ID = 100  ◄── NO REDUNDANCY             │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

Expected benefits of the new system:

  • Significant reduction in disk space: from N records per entity to 1 integer field
  • Improved processing speed: queries on integer indexes typically more performant
  • More responsive user interface: faster lookups and filters
  • Better maintainability: normalized structure with simplified maintenance

Note: Actual performance improvements may vary depending on the specific environment and data volume.

Objects involved in migration

The migration affects the following tables (identified by their respective Database IDs):

Database IDTableTypeNotes
18CustomerMasterIncludes Ship-to Address (222)
222Ship-to AddressMasterProcessed together with Customer
36Sales HeaderDocumentIncludes Sales Line (37)
37Sales LineDocumentProcessed together with Header
112Sales Invoice HeaderPostedIncludes Sales Invoice Line (113)
113Sales Invoice LinePostedProcessed together with Header
114Sales Cr.Memo HeaderPostedIncludes Sales Cr.Memo Line (115)
115Sales Cr.Memo LinePostedProcessed together with Header
5107Sales Header ArchiveArchiveIncludes Sales Line Archive (5108)
5108Sales Line ArchiveArchiveProcessed together with Header

Migration Codeunits

Codeunit “EOS010 SalesP Upgrade” (ID: 18008321)

This codeunit executes the complete and synchronous migration of all data. It is designed to be executed once in a controlled environment.

Main Characteristics

CharacteristicDescription
ExecutionSynchronous, blocking
ScopePer company (each company is migrated separately)
DurationCan take hours depending on company data volume
TransactionSingle transaction with automatic rollback in case of error

Execution Flow

  1. Checking Environment

    • Verifies interferences with other apps
    • Checks for missing roles/salespersons
    • Verifies unknown tables
  2. Data Upgrade

    • Verifies modify permissions
    • Creates Role-Salesperson combinations
    • Migrates active document data
    • Migrates archived data
    • Updates sales networks
  3. Data Verification

    • Verifies migrated data integrity

When to Use

  • ✅ Initial migration in test environment
  • ✅ Production environment with downtime possibility
  • ✅ Small/medium-sized databases
  • ⚠️ Note: The codeunit is executed automatically when activating the EAL feature flag, it cannot be executed manually via code
  • DO NOT activate the feature flag in production environment without downtime
  • DO NOT activate the feature flag on large databases without planning

Codeunit “EOS010 SalesP JobQueue Upg” (ID: 18008325)

This codeunit executes incremental and asynchronous migration via Job Queue. It is designed for production environments where downtime is not possible.

Main Characteristics

CharacteristicDescription
ExecutionAsynchronous via Job Queue
ScopePer company (each Job Queue works on a specific company)
Single execution durationMaximum 10 minutes per execution
BehaviorResumes from where it left off
CommitProgressive commits for each document/entity
ConfigurationRecommended to configure via page “EOS010 Salesp Upgrade Status” using action Setup Job Queue
Typical UseGradual migration in production

Operation and Purpose

The activity executed via job queue allows to calculate the “Salesperson Set ID” value on all supported tables in advance, thus speeding up the final upgrade when the feature flag is activated.

Important: The Job Queue operates on the current company data. If you have multiple companies in the environment, you need to configure a separate Job Queue Entry for each company.

Recommended Scheduling:

  • The job queue should be scheduled in a time window with few or no users, for example during night hours
  • To avoid exceeding the time window, it is designed to execute for a maximum of 10 minutes at a time
  • Automatically stops after 10 minutes and resumes at the next scheduled execution

Change Management: Any record that was already processed by the job queue, if modified by a user, will be automatically recalculated at the next Job Queue execution.

Important Note: The update activity via job queue is optional and serves exclusively to speed up the final migration. The actual migration is completed only with the activation of the EAL feature flag.

Job Queue Entry Configuration

The Parameter String of the Job Queue Entry defines which tables to process:

18|36|112|114|5107
ValueProcessed Table
18Customer + Ship-to Address
36Sales Header + Sales Line
112Sales Invoice Header + Lines
114Sales Cr.Memo Header + Lines
5107Sales Header Archive + Lines

Note: Accepted separators are | (pipe) and , (comma).

Execution Flow

┌──────────────────────────────────────────────────────────────────┐
│                    Job Queue Entry Start                         │
└──────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────────┐
│  Check: CommissionsSetup."Enable SalesP. JobQueue Upg." = TRUE   │
└──────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────────┐
│  Parse Parameter String → Table ID List                          │
└──────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────────┐
│  CreateAllRoleSalespersons() + Commit                            │
└──────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────────┐
│  For each TableID in List:                                       │
│    ├── Check: (CurrentDateTime - StartDateTime) > 10 min?        │
│    │     └── YES → Exit                                          │
│    └── NO → Process Table                                        │
│              ├── Filter: "Upgrade Status" = "To Calculate"       │
│              ├── Get Salespersons → Calculate Set ID             │
│              ├── Update Record with Set ID                       │
│              ├── Set Status = "Valued"                           │
│              └── Commit                                          │
└──────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────────┐
│  Next Job Queue Execution → Resumes from unprocessed records     │
└──────────────────────────────────────────────────────────────────┘

Understanding the Two-Phase Approach

The migration can be executed in two ways:

Single-Phase Approach (Small to Medium Databases):

  • Direct activation of the EAL feature flag
  • Suitable for test environments and smaller production databases
  • Requires a maintenance window proportional to data volume

Two-Phase Approach (Large Databases - RECOMMENDED):

  • Phase 1: Optional pre-calculation via Job Queue (days/weeks)
  • Phase 2: Feature flag activation (minutes/hours)
  • Minimizes production downtime
  • Distributes system load over time

Scenario 1: Small to Medium Database (Single-Phase)

  1. Test Environment First: Always test the complete procedure in a non-production environment
  2. Open the Salesperson Upgrade Status (CMS) page
  3. Use Calculate Status to assess current data volume and expected migration time
  4. Plan an appropriate maintenance window
  5. Activate the feature flag in Eos Admin Library (EAL)
  6. Monitor completion via status page
  7. Review log for any issues
  8. Verify application functionality post-migration

Purpose: This phase pre-calculates “Salesperson Set ID” values to minimize Phase 2 duration.

Setup Steps:

  1. Test First: Execute this procedure in a test environment to estimate timing
  2. Open the EOS010 Salesp Upgrade Status page
  3. Enable the Enable Salesperson Job Queue Upgrade flag
  4. Click the Setup Job Queue action to create a pre-configured Job Queue Entry
  5. Customize the Job Queue Entry scheduling:
    • Recommended: Schedule during low-usage periods (e.g., night-time)
    • Set appropriate recurrence (e.g., hourly)
    • Each execution runs for a maximum of 10 minutes
  6. Set the Job Queue Entry to Ready status
  7. Monitor progress regularly via Calculate Status
  8. Allow the Job Queue to run until completion percentage is sufficiently high (typically > 90-95%)

Duration: This phase may run for days or weeks depending on data volume and scheduling frequency.

Phase 2: Final Migration via Feature Flag Activation (Required)

Timing: Execute during a planned maintenance window.

Steps:

  1. Verify Phase 1 completion percentage (if Phase 1 was executed)
  2. Plan a maintenance window appropriate to remaining data volume
  3. Disable the Job Queue (if running) to avoid conflicts
  4. Activate the feature flag in Eos Admin Library (EAL)
  5. Monitor the migration process via status page
  6. Review the detailed log upon completion
  7. Perform post-migration verification and testing
  8. Remove or disable Job Queue Entry if no longer needed

Expected Duration:

  • Without Phase 1: May take several hours depending on data volume
  • With Phase 1 completed: Typically completes in minutes to hours

Advantages of the Two-Phase Approach:

  • Significantly reduced maintenance window for Phase 2
  • Minimal user impact during Phase 1
  • User modifications during Phase 1 are automatically recalculated
  • Distributed system load over time

Scenario 3: Optimization with Multiple Job Queues (Advanced)

Table filters that can be applied to the job queue can be used to optimize the update based on user activity:

Low User Activity Tables (posted or archived documents):

  • Can be processed during user activity hours
  • Tables: 112 (Sales Invoice), 114 (Sales Cr.Memo), 5107 (Sales Archive)
  • Low impact on performance perceived by users

High User Activity Tables (active documents):

  • Must be processed during low-traffic time slots (e.g., night-time)
  • Tables: 36 (Sales Header), 37 (Sales Line)
  • Require time windows with few or no active users

Multiple Job Queue Configuration

It is possible to have multiple update job queues running concurrently as long as they work on different tables.

Configuration example:

Job Queue Entry #1 - Low activity tables (daytime hours):

Parameter String: 112|114|5107
Schedule: 08:00 - 18:00
Recurrence: every 30 minutes

Job Queue Entry #2 - High activity tables (night-time hours):

Parameter String: 18|36
Schedule: 22:00 - 06:00
Recurrence: every 15 minutes

Potential Benefits:

  • Optimizes resource utilization across 24 hours
  • Reduces impact on active users
  • May accelerate overall preparation
  • Provides scheduling flexibility

Important Considerations:

  • Ensure tables don’t overlap between different Job Queues
  • Monitor overall database load and performance
  • Customer tables (18) may require specific considerations based on your usage patterns
  • Test this configuration in a non-production environment before production use

Page “EOS010 Salesp Upgrade Status” (ID: 18008330)

Monitoring and management page for the upgrade process.

Layout

Setup Section

FieldDescription
Enable Salesperson Job Queue UpgradeEnables/disables Job Queue execution
SalesPerson DataUpdate DateDate/time of last execution
SalesPerson DataUpdate UserUser who executed the last upgrade
SalesPerson DataUpdate StatusStatus: In Progress, Completed, Error

Tip: Click on “SalesPerson DataUpdate Status” to download the detailed log.

Tables Section (Repeater)

ColumnDescription
TableTable name
Total RecordsTotal records in table
Processed RecordsRecords with Status = “Valued”
Progress %Completion percentage

Actions

Calculate Status

Calculates upgrade status for all tables. This operation can take significant time on large databases.

Setup Job Queue

Automatically creates a new Job Queue Entry (if it doesn’t already exist) configured to:

  • Execute codeunit EOS010 SalesP JobQueue Upg
  • Parameter String: 18|36|112|114|5107 (all tables)
  • Recurrence: every minute, every day
  • Maximum 3 retry attempts in case of error

Note: This action automatically creates and configures the Job Queue Entry with all the correct parameters, significantly simplifying the setup process.

Troubleshooting

Error “Enable SalesP. JobQueue Upg. must have a value”

Cause: The enable flag is not active.

Solution: Enable “Enable Salesperson Job Queue Upgrade” in the status page.

Degraded Performance During Execution

Cause: Migration competes with user operations.

Solution:

  1. Limit Job Queue time window to night hours
  2. Reduce number of tables processed per execution
  3. Increase interval between executions

Notes for Implementers

  1. Backup: Always perform a complete backup before starting the migration.

  2. Test: Always test the migration in a copy environment before production.

  3. Monitoring: During Job Queue migration, regularly monitor:

    • Disk space
    • Database performance
    • Job Queue Entry status
  4. Post-Migration: After completion:

    • Remove the Job Queue Entry
    • Verify application performance

EOS Labs -