From e081585fd9e93fdc86c9bbba8fb872ed0e1a13ab Mon Sep 17 00:00:00 2001 From: Sosthene Date: Wed, 27 Aug 2025 17:35:15 +0200 Subject: [PATCH] Heavy refactoring of importData --- src/common/Api/LeCoffreApi/sdk/ImportData.ts | 226 +++++++++++++++---- 1 file changed, 178 insertions(+), 48 deletions(-) diff --git a/src/common/Api/LeCoffreApi/sdk/ImportData.ts b/src/common/Api/LeCoffreApi/sdk/ImportData.ts index eb7b00c8..9fa35f98 100644 --- a/src/common/Api/LeCoffreApi/sdk/ImportData.ts +++ b/src/common/Api/LeCoffreApi/sdk/ImportData.ts @@ -8,6 +8,9 @@ import RuleService from './RuleService'; import RuleGroupService from './RuleGroupService'; import RoleService from './RoleService'; import OfficeRoleService from './OfficeRoleService'; +import { DEFAULT_VALIDATOR_ID } from '@Front/Config/AppConstants'; + +const mandatoryRoles = ['Notaire', 'Collaborateur']; /** * Type pour le callback de progression @@ -85,9 +88,13 @@ export default class ImportData { // Exécuter l'étape et stocker le résultat si nécessaire const result = await step.function(stepProgressCallback, results); - if (result) { + if (result !== undefined) { results.push(result); + } else { + // Push empty array to maintain consistent indexing + results.push([]); } + console.log(`Step ${i} (${step.name}): ${result?.length || 0} items`); } if (!await this.isDone()) { @@ -122,7 +129,7 @@ export default class ImportData { const roles: any = { demiurge: { - members: [...[ownerId], validatorId], + members: [ownerId], validation_rules: [], storages: [] }, @@ -172,6 +179,7 @@ export default class ImportData { } private static async importRules(onProgress?: (progress: number, description?: string) => void): Promise { + console.log('Importing rules'); const rules: any[] = []; const INIT_PROGRESS = 0; @@ -201,10 +209,14 @@ export default class ImportData { const existingRules: any[] = (await RuleService.getRules()).map((process: any) => process.processData); const filteredRules: any[] = result.data.filter((rule: any) => !existingRules.some((existingRule: any) => existingRule.uid === rule.uid)); + if (filteredRules.length === 0) { + console.debug('All rules already imported'); + } + const totalFilteredRules = filteredRules.length; for (let i = 0; i < totalFilteredRules; i++) { - const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; - rules.push((await RuleService.createRule(filteredRules[i], validatorId)).processData); + console.log(`Adding rule ${filteredRules[i].name}`); + rules.push((await RuleService.createRule(filteredRules[i], DEFAULT_VALIDATOR_ID)).processData); const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS; const ruleProgressIncrement = progressRange / (totalFilteredRules * totalPages); @@ -225,6 +237,7 @@ export default class ImportData { } private static async importRuleGroups(onProgress?: (progress: number, description?: string) => void): Promise { + console.log('Importing rule groups'); const ruleGroups: any[] = []; const INIT_PROGRESS = 0; @@ -256,8 +269,8 @@ export default class ImportData { const totalFilteredRuleGroups = filteredRuleGroups.length; for (let i = 0; i < totalFilteredRuleGroups; i++) { - const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; - ruleGroups.push((await RuleGroupService.createRuleGroup(filteredRuleGroups[i], validatorId)).processData); + console.log(`Adding rule group ${filteredRuleGroups[i].name}`); + ruleGroups.push((await RuleGroupService.createRuleGroup(filteredRuleGroups[i], DEFAULT_VALIDATOR_ID)).processData); const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS; const ruleProgressIncrement = progressRange / (totalFilteredRuleGroups * totalPages); @@ -278,6 +291,7 @@ export default class ImportData { } private static async importRoles(onProgress?: (progress: number, description?: string) => void): Promise { + console.log('Importing roles'); // Constantes de progression - pourraient être paramétrées const INIT_PROGRESS = 0; const FETCH_PROGRESS = 30; @@ -309,10 +323,14 @@ export default class ImportData { onProgress?.(FETCH_PROGRESS, 'Récupération des rôles existants'); const roles: any[] = processes.map((process: any) => process.processData); if (roles.length === 0) { + const defaultRolesNames: string[] = defaultRoles.map((role: any) => role.name); const totalRoles = defaultRoles.length; for (let i = 0; i < totalRoles; i++) { - const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; - roles.push((await RoleService.createRole(defaultRoles[i], validatorId)).processData); + if (!defaultRolesNames.includes(roles[i].name)) { + roles.push((await RoleService.createRole(defaultRoles[i], DEFAULT_VALIDATOR_ID)).processData); + } else { + console.log(`Role ${defaultRoles[i].name} already exists`); + } // Progression dynamique pendant la création des rôles const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS; @@ -326,54 +344,166 @@ export default class ImportData { }); } + private static async importDefaultRoles(officeUid: string, ruleGroups: any[], onProgress?: (progress: number, description?: string) => void): Promise { + console.log('Importing default roles'); + let officeRoles: any[] = []; + + const CREATE_START_PROGRESS = 60; + const CREATE_END_PROGRESS = 90; + + onProgress?.(CREATE_START_PROGRESS, 'Création des rôles par défaut'); + + // Prepare the collaborator rules from rule groups + const collaboratorRules: any[] = ruleGroups + .map((ruleGroup: any) => ruleGroup.rules || []) + .reduce((acc: any, curr: any) => [...acc, ...curr], []) + .map((rule: any) => ({ uid: rule.uid })); + + console.log(`Found ${collaboratorRules.length} collaborator rules from ${ruleGroups.length} rule groups`); + + // Get fresh list of existing roles (including ones we just created) + const updatedExistingRoles = await OfficeRoleService.getOfficeRoles(); + const existingRoles = updatedExistingRoles + .map((role: any) => role.processData) + .filter((roleData: any) => roleData.office?.uid === officeUid); + + const existingRoleNames = existingRoles.map((role: any) => role.name); + + const missingMandatoryRoles = mandatoryRoles.filter(roleName => + !existingRoleNames.includes(roleName) + ); + + console.log(`Found ${existingRoleNames.length} existing roles, ${missingMandatoryRoles.length} mandatory roles missing`); + + if (missingMandatoryRoles.length === 0) { + onProgress?.(CREATE_END_PROGRESS, 'Tous les rôles obligatoires existent déjà'); + return officeRoles; + } + + for (let i = 0; i < missingMandatoryRoles.length; i++) { + const roleName = missingMandatoryRoles[i]; + const fallbackRole = { + name: roleName, + office: { uid: officeUid }, + // Only Notaire gets rules, Collaborateur gets none + ...(roleName === 'Notaire' && { rules: collaboratorRules }) + }; + + console.log(`Creating missing mandatory role: ${roleName}`); + + officeRoles.push((await OfficeRoleService.createOfficeRole(fallbackRole, DEFAULT_VALIDATOR_ID)).processData); + + const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS; + const progress = CREATE_START_PROGRESS + ((i + 1) / missingMandatoryRoles.length) * progressRange; + onProgress?.(progress, `Création rôle obligatoire ${i + 1}/${missingMandatoryRoles.length} - ${roleName}`); + } + + return officeRoles; + } + private static async importOfficeRoles(office: any, ruleGroups: any[], onProgress?: (progress: number, description?: string) => void): Promise { - // Constantes de progression - pourraient être paramétrées + console.log('Importing office roles'); + let officeRoles: any[] = []; + const officeUid = office.processData?.uid; + if (!officeUid) { + console.error('Office UID is not set'); + return officeRoles; + } + console.log(`Processing ${ruleGroups.length} rule groups for office ${officeUid}`); + const INIT_PROGRESS = 0; const FETCH_PROGRESS = 30; - const CREATE_START_PROGRESS = FETCH_PROGRESS; const CREATE_END_PROGRESS = 90; const FINAL_PROGRESS = 100; - onProgress?.(INIT_PROGRESS, 'Initialisation'); - return await new Promise((resolve: (roles: any[]) => void) => { - const collaboratorRules: any[] = ruleGroups - .map((ruleGroup: any) => ruleGroup.rules) - .reduce((acc: any, curr: any) => [...acc, ...curr], []) - .map((rule: any) => ({ uid: rule.uid })); - const defaultOfficeRoles: any[] = [ - { - name: 'Notaire', - office: { - uid: office.uid - }, - rules: collaboratorRules - }, - { - name: 'Collaborateur', - office: { - uid: office.uid - } - } - ]; - OfficeRoleService.getOfficeRoles().then(async (processes: any[]) => { - onProgress?.(FETCH_PROGRESS, 'Récupération des rôles d\'office existants'); - const officeRoles: any[] = processes.map((process: any) => process.processData); - if (officeRoles.length === 0) { - const totalOfficeRoles = defaultOfficeRoles.length; - for (let i = 0; i < totalOfficeRoles; i++) { - const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; - officeRoles.push((await OfficeRoleService.createOfficeRole(defaultOfficeRoles[i], validatorId)).processData); + let page = 1; + let limit = 10; + let totalPages = 1; - // Progression dynamique pendant la création des rôles d'office - const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS; - const progress = CREATE_START_PROGRESS + ((i + 1) / totalOfficeRoles) * progressRange; - onProgress?.(progress, `Création du rôle d'office ${i + 1}/${totalOfficeRoles} : ${defaultOfficeRoles[i].name}`); - } - } - onProgress?.(FINAL_PROGRESS, 'Importation des rôles d\'office terminée'); - resolve(officeRoles); - }); + onProgress?.(FETCH_PROGRESS, 'Récupération des rôles d\'office existants'); + let result = await DatabaseService.getTableData('office_roles', page, limit); + if (result && result.success && result.pagination) { + totalPages = result.pagination.totalPages || 1; + } + + const FETCH_PAGE_PROGRESS_START = FETCH_PROGRESS; + const FETCH_PAGE_PROGRESS_END = 60; + const CREATE_START_PROGRESS = 60; + + // Collect all office roles for this office from all pages + const allOfficeRolesForThisOffice: any[] = []; + while (result && result.success) { + const fetchPageProgress = FETCH_PAGE_PROGRESS_START + ((page / totalPages) * (FETCH_PAGE_PROGRESS_END - FETCH_PAGE_PROGRESS_START)); + onProgress?.(fetchPageProgress, `Page ${page}/${totalPages} : Récupération des rôles d'office`); + + // Collect office roles for this office from current page + const officeRolesFromPage = result.data.filter((officeRole: any) => + officeRole.office?.uid === officeUid + ); + allOfficeRolesForThisOffice.push(...officeRolesFromPage); + + if (!result.pagination.hasNextPage) { + break; + } + page++; + result = await DatabaseService.getTableData('office_roles', page, limit); + } + + console.log(`Found ${allOfficeRolesForThisOffice.length} office roles in database for this office`); + + if (allOfficeRolesForThisOffice.length === 0) { + console.log('No office roles found in database, creating defaults'); + return await this.importDefaultRoles(officeUid, ruleGroups, onProgress); + } + + // Get all existing office role processes (to avoid duplicates) + const existingOfficeRoles: any[] = await OfficeRoleService.getOfficeRoles(); + const existingOfficeRoleUids = existingOfficeRoles.map((existingRole: any) => + existingRole.processData.uid + ); + + console.log(`Found ${existingOfficeRoles.length} existing office role processes`); + + // Import all office roles found in database (if not already imported) + const dbRolesToImport = allOfficeRolesForThisOffice.filter((dbRole: any) => + !existingOfficeRoleUids.includes(dbRole.uid) + ); + + console.log(`Importing ${dbRolesToImport.length} new office roles from database`); + + for (let i = 0; i < dbRolesToImport.length; i++) { + const roleData = dbRolesToImport[i]; + + // Ensure office UID is set correctly + if (!roleData.office) { + roleData.office = { uid: officeUid }; + } else if (!roleData.office.uid) { + roleData.office.uid = officeUid; + } + + console.log(`Importing office role: ${roleData.name}`); + + officeRoles.push((await OfficeRoleService.createOfficeRole(roleData, DEFAULT_VALIDATOR_ID)).processData); + + const progressRange = (CREATE_END_PROGRESS - CREATE_START_PROGRESS) * 0.7; // 70% for db imports + const progress = CREATE_START_PROGRESS + ((i + 1) / dbRolesToImport.length) * progressRange; + onProgress?.(progress, `Import base de données ${i + 1}/${dbRolesToImport.length} - ${roleData.name}`); + } + + // Now check for mandatory roles and create any missing ones + const mandatoryRolesProgress = CREATE_START_PROGRESS + (CREATE_END_PROGRESS - CREATE_START_PROGRESS) * 0.7; + onProgress?.(mandatoryRolesProgress, 'Vérification des rôles obligatoires'); + + const defaultRolesCreated = await this.importDefaultRoles(officeUid, ruleGroups, (subProgress, description) => { + // Map sub-progress to remaining 20% of total progress + const mappedProgress = mandatoryRolesProgress + (subProgress - 60) * 0.3 / 30; // Scale 60-90 to remaining 30% + onProgress?.(mappedProgress, description); }); + + officeRoles.push(...defaultRolesCreated); + + onProgress?.(FINAL_PROGRESS, 'Importation des rôles d\'office terminée'); + return officeRoles; } }