diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index ccb9766a..5f98a59e 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -38,4 +38,5 @@ jobs: ssh: default tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:dev ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ gitea.sha }} \ No newline at end of file diff --git a/next.config.js b/next.config.js index 6a4eec96..f22a82d2 100644 --- a/next.config.js +++ b/next.config.js @@ -20,6 +20,7 @@ const nextConfig = { NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID, NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION, NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL, + NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL, }, serverRuntimeConfig: { @@ -36,6 +37,7 @@ const nextConfig = { NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID, NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION, NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL, + NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL, }, env: { @@ -52,6 +54,7 @@ const nextConfig = { NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID, NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION, NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL, + NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL, }, // webpack: config => { diff --git a/src/common/Api/LeCoffreApi/sdk/AbstractService.ts b/src/common/Api/LeCoffreApi/sdk/AbstractService.ts index 17ddeada..0f13b415 100644 --- a/src/common/Api/LeCoffreApi/sdk/AbstractService.ts +++ b/src/common/Api/LeCoffreApi/sdk/AbstractService.ts @@ -38,7 +38,7 @@ export default abstract class AbstractService { return null; } - const now = Date.now(); + const now: number = Date.now(); if ((now - item.timestamp) < this.CACHE_TTL) { return item.process; } @@ -48,7 +48,7 @@ export default abstract class AbstractService { protected static getItems(key: string): any[] { const list: any[] = JSON.parse(sessionStorage.getItem(key) || '[]'); - const now = Date.now(); + const now: number = Date.now(); const items: any[] = []; for (const item of list) { diff --git a/src/common/Api/LeCoffreApi/sdk/CollaboratorService.ts b/src/common/Api/LeCoffreApi/sdk/CollaboratorService.ts index 4737f7f4..0fe3d856 100644 --- a/src/common/Api/LeCoffreApi/sdk/CollaboratorService.ts +++ b/src/common/Api/LeCoffreApi/sdk/CollaboratorService.ts @@ -15,7 +15,7 @@ export default class CollaboratorService extends AbstractService { } public static createCollaborator(collaboratorData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/CustomerService.ts b/src/common/Api/LeCoffreApi/sdk/CustomerService.ts index 601cab38..2654f2a3 100644 --- a/src/common/Api/LeCoffreApi/sdk/CustomerService.ts +++ b/src/common/Api/LeCoffreApi/sdk/CustomerService.ts @@ -11,7 +11,7 @@ export default class CustomerService extends AbstractService { } public static createCustomer(customerData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/DatabaseService.ts b/src/common/Api/LeCoffreApi/sdk/DatabaseService.ts new file mode 100644 index 00000000..d8cbd83e --- /dev/null +++ b/src/common/Api/LeCoffreApi/sdk/DatabaseService.ts @@ -0,0 +1,52 @@ +import getConfig from 'next/config'; +const { publicRuntimeConfig } = getConfig(); + +export default class DatabaseService { + + // Empêcher l'instanciation de cette classe utilitaire + private constructor() { } + + /** + * Récupère les données d'une table avec pagination + * @param tableName Nom de la table à consulter + * @param page Numéro de page (commence à 1) + * @param limit Nombre d'éléments par page + * @returns Données de la table avec pagination + */ + public static async getTableData(tableName: string, page: number = 1, limit: number = 10): Promise { + // Vérification des paramètres + if (!tableName) { + throw new Error('Le nom de la table est requis'); + } + + // Validation du nom de la table (par sécurité) + const tableNameRegex = /^[a-zA-Z0-9_]+$/; + if (!tableNameRegex.test(tableName)) { + throw new Error('Nom de table invalide'); + } + + try { + // Construction de l'URL avec paramètres de pagination + const url = `${publicRuntimeConfig.NEXT_PUBLIC_API_URL}/db/${tableName}?page=${page}&limit=${limit}`; + + // Appel à l'API REST + const response = await fetch(url, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + const errorData = await response.json(); + throw new Error(errorData.message || 'Erreur lors de la récupération des données'); + } + + const data = await response.json(); + return data; + } catch (error) { + console.error('Erreur lors de l\'accès à la base de données:', error); + throw error; + } + } +} diff --git a/src/common/Api/LeCoffreApi/sdk/DeedTypeService.ts b/src/common/Api/LeCoffreApi/sdk/DeedTypeService.ts index e4efd224..b07dae69 100644 --- a/src/common/Api/LeCoffreApi/sdk/DeedTypeService.ts +++ b/src/common/Api/LeCoffreApi/sdk/DeedTypeService.ts @@ -13,7 +13,7 @@ export default class DeedTypeService extends AbstractService { } public static createDeedType(deedTypeData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), @@ -91,7 +91,8 @@ export default class DeedTypeService extends AbstractService { publicValues['uid'] && publicValues['utype'] && publicValues['utype'] === 'deedType' && - publicValues['isDeleted'] && publicValues['isDeleted'] === 'false' && + publicValues['isDeleted'] && + publicValues['isDeleted'] === 'false' && !items.map((item: any) => item.processData.uid).includes(publicValues['uid']) ).then(async (processes: any[]) => { if (processes.length === 0) { @@ -182,12 +183,12 @@ export default class DeedTypeService extends AbstractService { this.messageBus.notifyUpdate(process.processId, newStateId).then(() => { this.messageBus.validateState(process.processId, newStateId).then(() => { // Update cache - this.setItem('_deed_types_', processUpdated); + this.setItem('_deed_types_', process); resolve(); - }).catch(() => console.error('Failed to validate state')); - }).catch(() => console.error('Failed to notify update')); - }).catch(() => console.error('Failed to update')); + }).catch((error) => console.error('Failed to validate state', error)); + }).catch((error) => console.error('Failed to notify update', error)); + }).catch((error) => console.error('Failed to update', error)); }); } diff --git a/src/common/Api/LeCoffreApi/sdk/DocumentService.ts b/src/common/Api/LeCoffreApi/sdk/DocumentService.ts index f43b9be0..de36b38c 100644 --- a/src/common/Api/LeCoffreApi/sdk/DocumentService.ts +++ b/src/common/Api/LeCoffreApi/sdk/DocumentService.ts @@ -11,7 +11,7 @@ export default class DocumentService extends AbstractService { } public static createDocument(documentData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/DocumentTypeService.ts b/src/common/Api/LeCoffreApi/sdk/DocumentTypeService.ts index ef829988..2d3de4d2 100644 --- a/src/common/Api/LeCoffreApi/sdk/DocumentTypeService.ts +++ b/src/common/Api/LeCoffreApi/sdk/DocumentTypeService.ts @@ -11,7 +11,7 @@ export default class DocumentTypeService extends AbstractService { } public static createDocumentType(documentTypeData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/FileService.ts b/src/common/Api/LeCoffreApi/sdk/FileService.ts index 2212ed12..1a38e2c3 100644 --- a/src/common/Api/LeCoffreApi/sdk/FileService.ts +++ b/src/common/Api/LeCoffreApi/sdk/FileService.ts @@ -12,7 +12,7 @@ export default class FileService { private constructor() { } public static createFile(fileData: FileData, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/FolderService.ts b/src/common/Api/LeCoffreApi/sdk/FolderService.ts index a20be304..9413cc73 100644 --- a/src/common/Api/LeCoffreApi/sdk/FolderService.ts +++ b/src/common/Api/LeCoffreApi/sdk/FolderService.ts @@ -18,7 +18,7 @@ export default class FolderService extends AbstractService { } public static createFolder(folderData: any, stakeholdersId: string[], customersId: string[]): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/ImportData.ts b/src/common/Api/LeCoffreApi/sdk/ImportData.ts index 890663dc..eb7b00c8 100644 --- a/src/common/Api/LeCoffreApi/sdk/ImportData.ts +++ b/src/common/Api/LeCoffreApi/sdk/ImportData.ts @@ -3,6 +3,7 @@ import { v4 as uuidv4 } from 'uuid'; import User from 'src/sdk/User'; import MessageBus from 'src/sdk/MessageBus'; +import DatabaseService from './DatabaseService'; import RuleService from './RuleService'; import RuleGroupService from './RuleGroupService'; import RoleService from './RoleService'; @@ -36,8 +37,8 @@ export default class ImportData { }, { name: 'Groupes de règles', - function: async (progressCallback?: (subProgress: number, description?: string) => void, prevResults?: any[]) => - await this.importRuleGroups(prevResults![0], progressCallback) + function: async (progressCallback?: (subProgress: number, description?: string) => void) => + await this.importRuleGroups(progressCallback) }, { name: 'Rôles', @@ -104,7 +105,7 @@ export default class ImportData { } private static async done(validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), @@ -171,190 +172,109 @@ export default class ImportData { } private static async importRules(onProgress?: (progress: number, description?: string) => void): Promise { - // Constantes de progression - pourraient être paramétrées + const rules: any[] = []; + 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: (rules: any[]) => void) => { - const defaultRules: any[] = [ - // Actes et documents - { - name: "POST deeds", - label: "Créer un template de type d'acte", - namespace: "collaborator" - }, - { - name: "PUT deeds", - label: "Modifier un type d'acte", - namespace: "collaborator" - }, - { - name: "DELETE deeds", - label: "Supprimer des types d'actes", - namespace: "collaborator" - }, - { - name: "GET deed-types", - label: "Lecture des types d'actes", - namespace: "collaborator" - }, - { - name: "POST deed-types", - label: "Création des types d'actes", - namespace: "collaborator" - }, - { - name: "PUT deed-types", - label: "Modification des types d'actes", - namespace: "collaborator" - }, - { - name: "DELETE deed-types", - label: "Suppression des types d'actes", - namespace: "collaborator" - }, - { - name: "GET document-types", - label: "Lecture des types de documents", - namespace: "collaborator" - }, - { - name: "POST document-types", - label: "Création des types de documents", - namespace: "collaborator" - }, - { - name: "PUT document-types", - label: "Modification des types de documents", - namespace: "collaborator" - }, - { - name: "DELETE document-types", - label: "Suppression des types de documents", - namespace: "collaborator" - }, - // RIB - { - name: "GET rib", - label: "Lire le RIB de l'office", - namespace: "collaborator" - }, - { - name: "POST rib", - label: "Déposer le RIB de l'office", - namespace: "collaborator" - }, - { - name: "PUT rib", - label: "Editer le RIB de l'office", - namespace: "collaborator" - }, - { - name: "DELETE rib", - label: "Supprimer le RIB de l'office", - namespace: "collaborator" - }, - // Abonnements - { - name: "GET subscriptions", - label: "Récupérer les abonnements", - namespace: "collaborator" - }, - { - name: "POST subscriptions", - label: "Inviter un collaborateur à l'abonnement", - namespace: "collaborator" - }, - { - name: "PUT subscriptions", - label: "Modifier l'abonnement", - namespace: "collaborator" - }, - { - name: "GET stripe", - label: "Gérer l'abonnement de l'office", - namespace: "collaborator" - }, - { - name: "POST stripe", - label: "Payer un abonnement", - namespace: "collaborator" - } - ]; - RuleService.getRules().then(async (processes: any[]) => { - onProgress?.(FETCH_PROGRESS, 'Récupération des règles existantes'); - const rules: any[] = processes.map((process: any) => process.processData); - if (rules.length === 0) { - const totalRules = defaultRules.length; - for (let i = 0; i < totalRules; i++) { - const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; - rules.push((await RuleService.createRule(defaultRules[i], validatorId)).processData); - // Progression dynamique pendant la création des règles - const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS; - const progress = CREATE_START_PROGRESS + ((i + 1) / totalRules) * progressRange; - onProgress?.(progress, `Création de la règle ${i + 1}/${totalRules} : ${defaultRules[i].label}`); - } - } - onProgress?.(FINAL_PROGRESS, 'Importation des règles terminée'); - resolve(rules); - }); - }); + let page = 1; + let limit = 10; + let totalPages = 1; + + onProgress?.(FETCH_PROGRESS, 'Récupération des règles existantes'); + let result = await DatabaseService.getTableData('rules', 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; + + 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ègles`); + 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)); + + 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); + + const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS; + const ruleProgressIncrement = progressRange / (totalFilteredRules * totalPages); + const progress = CREATE_START_PROGRESS + ((page - 1) * totalFilteredRules + i + 1) * ruleProgressIncrement; + onProgress?.(progress, `Page ${page}/${totalPages} : Création de la règle ${i + 1}/${totalFilteredRules} - ${filteredRules[i].label}`); + } + + if (!result.pagination.hasNextPage) { + break; + } + page++; + + result = await DatabaseService.getTableData('rules', page, limit); + } + + onProgress?.(FINAL_PROGRESS, 'Importation des règles terminée'); + return rules; } - private static async importRuleGroups(rules: any[], onProgress?: (progress: number, description?: string) => void): Promise { - // Constantes de progression - pourraient être paramétrées + private static async importRuleGroups(onProgress?: (progress: number, description?: string) => void): Promise { + const ruleGroups: any[] = []; + 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: (ruleGroups: any[]) => void) => { - const defaultRuleGroups: any[] = [ - { - name: "Gestion des matrices d'actes et des documents", - rules: rules - .filter((rule: any) => rule.name.includes("deeds") || rule.name.includes("deed-types") || rule.name.includes("document-types")) - .map((rule: any) => ({ uid: rule.uid })) - }, - { - name: "Intégration du RIB", - rules: rules - .filter((rule: any) => rule.name.includes("rib")) - .map((rule: any) => ({ uid: rule.uid })) - }, - { - name: "Gestion de l'abonnement", - rules: rules - .filter((rule: any) => rule.name.includes("subscriptions") || rule.name.includes("stripe")) - .map((rule: any) => ({ uid: rule.uid })) - } - ]; - RuleGroupService.getRuleGroups().then(async (processes: any[]) => { - onProgress?.(FETCH_PROGRESS, 'Récupération des groupes de règles existants'); - const ruleGroups: any[] = processes.map((process: any) => process.processData); - if (ruleGroups.length === 0) { - const totalGroups = defaultRuleGroups.length; - for (let i = 0; i < totalGroups; i++) { - const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; - ruleGroups.push((await RuleGroupService.createRuleGroup(defaultRuleGroups[i], validatorId)).processData); - // Progression dynamique pendant la création des groupes de règles - const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS; - const progress = CREATE_START_PROGRESS + ((i + 1) / totalGroups) * progressRange; - onProgress?.(progress, `Création du groupe de règles ${i + 1}/${totalGroups} : ${defaultRuleGroups[i].name}`); - } - } - onProgress?.(FINAL_PROGRESS, 'Importation des groupes de règles terminée'); - resolve(ruleGroups); - }); - }); + let page = 1; + let limit = 10; + let totalPages = 1; + + onProgress?.(FETCH_PROGRESS, 'Récupération des groupes de règles existants'); + let result = await DatabaseService.getTableData('rules_groups', 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; + + 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 du groupe de règles`); + const existingRuleGroups: any[] = (await RuleGroupService.getRuleGroups()).map((process: any) => process.processData); + const filteredRuleGroups: any[] = result.data.filter((rule: any) => !existingRuleGroups.some((existingRule: any) => existingRule.uid === rule.uid)); + + 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); + + const progressRange = CREATE_END_PROGRESS - CREATE_START_PROGRESS; + const ruleProgressIncrement = progressRange / (totalFilteredRuleGroups * totalPages); + const progress = CREATE_START_PROGRESS + ((page - 1) * totalFilteredRuleGroups + i + 1) * ruleProgressIncrement; + onProgress?.(progress, `Page ${page}/${totalPages} : Création du groupe de règles ${i + 1}/${totalFilteredRuleGroups} - ${filteredRuleGroups[i].label}`); + } + + if (!result.pagination.hasNextPage) { + break; + } + page++; + + result = await DatabaseService.getTableData('rules_groups', page, limit); + } + + onProgress?.(FINAL_PROGRESS, 'Importation des groupes de règles terminée'); + return ruleGroups; } private static async importRoles(onProgress?: (progress: number, description?: string) => void): Promise { diff --git a/src/common/Api/LeCoffreApi/sdk/NoteService.ts b/src/common/Api/LeCoffreApi/sdk/NoteService.ts index afb1b7e7..bf7254ea 100644 --- a/src/common/Api/LeCoffreApi/sdk/NoteService.ts +++ b/src/common/Api/LeCoffreApi/sdk/NoteService.ts @@ -10,7 +10,7 @@ export default class NoteService { private constructor() { } public static createNote(noteData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/OfficeRibService.ts b/src/common/Api/LeCoffreApi/sdk/OfficeRibService.ts index e5b488ef..1e3cc802 100644 --- a/src/common/Api/LeCoffreApi/sdk/OfficeRibService.ts +++ b/src/common/Api/LeCoffreApi/sdk/OfficeRibService.ts @@ -12,7 +12,7 @@ export default class OfficeRibService { private constructor() { } public static createOfficeRib(fileData: FileData, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/OfficeRoleService.ts b/src/common/Api/LeCoffreApi/sdk/OfficeRoleService.ts index ef3c0bd9..a9aabc1d 100644 --- a/src/common/Api/LeCoffreApi/sdk/OfficeRoleService.ts +++ b/src/common/Api/LeCoffreApi/sdk/OfficeRoleService.ts @@ -14,7 +14,7 @@ export default class OfficeRoleService extends AbstractService { } public static createOfficeRole(roleData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/OfficeService.ts b/src/common/Api/LeCoffreApi/sdk/OfficeService.ts index a207d3bb..4b139c9f 100644 --- a/src/common/Api/LeCoffreApi/sdk/OfficeService.ts +++ b/src/common/Api/LeCoffreApi/sdk/OfficeService.ts @@ -11,7 +11,7 @@ export default class OfficeService extends AbstractService { } public static createOffice(officeData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/RoleService.ts b/src/common/Api/LeCoffreApi/sdk/RoleService.ts index 0572e393..6f21a627 100644 --- a/src/common/Api/LeCoffreApi/sdk/RoleService.ts +++ b/src/common/Api/LeCoffreApi/sdk/RoleService.ts @@ -11,7 +11,7 @@ export default class RoleService extends AbstractService { } public static createRole(roleData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/RuleGroupService.ts b/src/common/Api/LeCoffreApi/sdk/RuleGroupService.ts index 0619b95c..c0775cde 100644 --- a/src/common/Api/LeCoffreApi/sdk/RuleGroupService.ts +++ b/src/common/Api/LeCoffreApi/sdk/RuleGroupService.ts @@ -13,7 +13,7 @@ export default class RuleGroupService extends AbstractService { } public static createRuleGroup(ruleGroupData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/common/Api/LeCoffreApi/sdk/RuleService.ts b/src/common/Api/LeCoffreApi/sdk/RuleService.ts index a7d1cc1c..9fd9bb4d 100644 --- a/src/common/Api/LeCoffreApi/sdk/RuleService.ts +++ b/src/common/Api/LeCoffreApi/sdk/RuleService.ts @@ -11,7 +11,7 @@ export default class RuleService extends AbstractService { } public static createRule(ruleData: any, validatorId: string): Promise { - const ownerId = User.getInstance().getPairingId()!; + const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { uid: uuidv4(), diff --git a/src/front/Api/LeCoffreApi/Notary/Customers/Customers.ts b/src/front/Api/LeCoffreApi/Notary/Customers/Customers.ts index 36b113d8..a36c547b 100644 --- a/src/front/Api/LeCoffreApi/Notary/Customers/Customers.ts +++ b/src/front/Api/LeCoffreApi/Notary/Customers/Customers.ts @@ -88,15 +88,15 @@ export default class Customers extends BaseNotary { } } - public async sendReminder(uid: string, documentsUid: string[]): Promise { + public async sendReminder(office: any, customer: any): Promise { // TODO: review const baseBackUrl = 'http://localhost:8080';//variables.BACK_API_PROTOCOL + variables.BACK_API_HOST; - const url = new URL(`${baseBackUrl}/api/${uid}/send_reminder`); + const url = new URL(`${baseBackUrl}/api/send_reminder`); //const url = new URL(this.baseURl.concat(`/${uid}/send_reminder`)); try { - await this.postRequest(url, { email: 'ja.janin.anthony@gmail.com', documentsUid }); + await this.postRequest(url, { office, customer }); } catch (err) { this.onError(err); return Promise.reject(err); diff --git a/src/front/Components/Layouts/DeedTypes/DeedTypesCreate/index.tsx b/src/front/Components/Layouts/DeedTypes/DeedTypesCreate/index.tsx index c93c3507..c914ea78 100644 --- a/src/front/Components/Layouts/DeedTypes/DeedTypesCreate/index.tsx +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesCreate/index.tsx @@ -7,7 +7,6 @@ import Typography, { ETypo } from "@Front/Components/DesignSystem/Typography"; import DefaultDeedTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDeedTypeDashboard"; import { ToasterService } from "@Front/Components/DesignSystem/Toaster"; import Module from "@Front/Config/Module"; -import JwtService from "@Front/Services/JwtService/JwtService"; import { DeedType, Office } from "le-coffre-resources/dist/Admin"; import { useRouter } from "next/router"; import { useCallback, useState } from "react"; @@ -15,8 +14,10 @@ import { useCallback, useState } from "react"; import classes from "./classes.module.scss"; import { validateOrReject, ValidationError } from "class-validator"; -import DeedTypeService from "src/common/Api/LeCoffreApi/sdk/DeedTypeService"; +import UserStore from "@Front/Stores/UserStore"; + import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService"; +import DeedTypeService from "src/common/Api/LeCoffreApi/sdk/DeedTypeService"; type IProps = {}; export default function DeedTypesCreate(props: IProps) { @@ -28,8 +29,8 @@ export default function DeedTypesCreate(props: IProps) { const onSubmitHandler = useCallback( async (e: React.FormEvent | null, values: { [key: string]: string }) => { try { - // TODO: review - const officeId = 'demo_notary_office_id'; //JwtService.getInstance().decodeJwt()?.office_Id; + const user: any = UserStore.instance.getUser(); + const officeId: string = user.office.uid; const deedType = DeedType.hydrate({ name: values["name"], diff --git a/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/index.tsx b/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/index.tsx index d718768f..c05d984b 100644 --- a/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/index.tsx +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/index.tsx @@ -79,6 +79,7 @@ export default function DeedTypesInformations(props: IProps) { async function getDeedType() { if (!deedTypeUid) return; + setSelectedDocuments([]); DeedTypeService.getDeedTypeByUid(deedTypeUid as string).then((process: any) => { if (process) { const deedType: any = process.processData; @@ -99,6 +100,7 @@ export default function DeedTypesInformations(props: IProps) { } async function getDocuments() { + setAvailableDocuments([]); DocumentTypeService.getDocumentTypes().then((processes: any[]) => { if (processes.length) { const documents: any[] = processes.map((process: any) => process.processData); @@ -128,8 +130,8 @@ export default function DeedTypesInformations(props: IProps) { if (!document_types) { document_types = []; } - selectedDocuments.map((selectedDocument: any) => ({ uid: selectedDocument.id as string })) - .forEach((selectedDocument: any) => document_types.push(selectedDocument)); + selectedDocuments.map((selectedDocument: any) => selectedDocument.id as string) + .forEach((uid: any) => document_types.push(availableDocuments.find((document: any) => document.uid === uid))); // New data const newData: any = { diff --git a/src/front/Components/Layouts/Folder/FolderInformation/ClientView/ClientBox/index.tsx b/src/front/Components/Layouts/Folder/FolderInformation/ClientView/ClientBox/index.tsx index fd44a797..540b49aa 100644 --- a/src/front/Components/Layouts/Folder/FolderInformation/ClientView/ClientBox/index.tsx +++ b/src/front/Components/Layouts/Folder/FolderInformation/ClientView/ClientBox/index.tsx @@ -30,12 +30,6 @@ export default function ClientBox(props: IProps) { const { isOpen: isDeleteModalOpen, open: openDeleteModal, close: closeDeleteModal } = useOpenable(); const { isOpen: isErrorModalOpen, open: openErrorModal, close: closeErrorModal } = useOpenable(); - // TODO: review - const handleOpenConnectionLink = useCallback(() => { - const url = `http://localhost:3000/client-dashboard/${folderUid}/profile/${customer.uid}`; - alert(url); - }, [customer.uid, folderUid]); - const handleDelete = useCallback( (customerUid: string) => { LoaderService.getInstance().show(); @@ -100,15 +94,6 @@ export default function ClientBox(props: IProps) { )} -
- -
Numéro de téléphone diff --git a/src/front/Components/Layouts/Folder/FolderInformation/ClientView/DocumentTables/index.tsx b/src/front/Components/Layouts/Folder/FolderInformation/ClientView/DocumentTables/index.tsx index ec02f8f2..a140a18b 100644 --- a/src/front/Components/Layouts/Folder/FolderInformation/ClientView/DocumentTables/index.tsx +++ b/src/front/Components/Layouts/Folder/FolderInformation/ClientView/DocumentTables/index.tsx @@ -438,10 +438,11 @@ export default function DocumentTables(props: IProps) { ); const progress = useMemo(() => { - const total = askedDocuments.length + toValidateDocuments.length + validatedDocuments.length + refusedDocuments.length; + // Exclude refused documents from total - only count documents that are still in progress + const total = askedDocuments.length + toValidateDocuments.length + validatedDocuments.length; if (total === 0) return 0; return (validatedDocuments.length / total) * 100; - }, [askedDocuments.length, refusedDocuments.length, toValidateDocuments.length, validatedDocuments.length]); + }, [askedDocuments.length, toValidateDocuments.length, validatedDocuments.length]); if (documents.length === 0 && documentsNotary.length === 0) return ; diff --git a/src/front/Components/Layouts/Folder/FolderInformation/ClientView/EmailReminder/ReminderModal/index.tsx b/src/front/Components/Layouts/Folder/FolderInformation/ClientView/EmailReminder/ReminderModal/index.tsx index 58ed5d47..3dca73f1 100644 --- a/src/front/Components/Layouts/Folder/FolderInformation/ClientView/EmailReminder/ReminderModal/index.tsx +++ b/src/front/Components/Layouts/Folder/FolderInformation/ClientView/EmailReminder/ReminderModal/index.tsx @@ -11,6 +11,11 @@ import React, { useCallback, useMemo, useState } from "react"; import classes from "./classes.module.scss"; +import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService"; +import DocumentService from "src/common/Api/LeCoffreApi/sdk/DocumentService"; +import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService"; +import UserStore from "@Front/Stores/UserStore"; + type IProps = { isOpen: boolean; onClose?: () => void; @@ -23,9 +28,24 @@ export default function ReminderModal(props: IProps) { const [selectedOptions, setSelectedOptions] = useState([]); const [isAllSelected, setIsAllSelected] = useState(false); - const onRemind = useCallback(() => { + const onRemind = useCallback(async () => { + LoaderService.getInstance().show(); + + const documentUids: string[] = selectedOptions.map((option) => option.value) as string[]; + + const user: any = UserStore.instance.getUser(); + const _office: any = user.office; + + const _documents: any[] = []; + for (const documentUid of documentUids) { + _documents.push((await DocumentService.getDocumentByUid(documentUid)).processData); + } + const _customer = (await CustomerService.getCustomerByUid(customer.uid!)).processData; + + LoaderService.getInstance().hide(); + Customers.getInstance() - .sendReminder(customer.uid!, selectedOptions.map((option) => option.value) as string[]) + .sendReminder(_office, _customer) .then(onRemindSuccess) .then(() => ToasterService.getInstance().success({ title: "Succès !", description: "La relance a été envoyée avec succès." })) .then(onClose); diff --git a/src/front/Components/Layouts/Folder/FolderInformation/index.tsx b/src/front/Components/Layouts/Folder/FolderInformation/index.tsx index 90749ed8..40092017 100644 --- a/src/front/Components/Layouts/Folder/FolderInformation/index.tsx +++ b/src/front/Components/Layouts/Folder/FolderInformation/index.tsx @@ -48,9 +48,11 @@ export default function FolderInformation(props: IProps) { let total = 0; let validatedDocuments = 0; folder?.customers?.forEach((customer: any) => { - const documents = customer.documents.filter((document: any) => document.depositor); - total += documents?.length ?? 0; - validatedDocuments += documents?.filter((document: any) => document.document_status === EDocumentStatus.VALIDATED).length ?? 0; + const documents = customer.documents; + // Only count documents that are not refused (still in progress) + const activeDocuments = documents?.filter((document: any) => document.document_status !== EDocumentStatus.REFUSED) ?? []; + total += activeDocuments.length; + validatedDocuments += activeDocuments.filter((document: any) => document.document_status === EDocumentStatus.VALIDATED).length; }); if (total === 0) return 0; const percentage = (validatedDocuments / total) * 100; diff --git a/src/front/Components/Layouts/Login/StepEmail/index.tsx b/src/front/Components/Layouts/Login/StepEmail/index.tsx index 17b108dd..4abbeb71 100644 --- a/src/front/Components/Layouts/Login/StepEmail/index.tsx +++ b/src/front/Components/Layouts/Login/StepEmail/index.tsx @@ -51,7 +51,7 @@ export default function StepEmail(props: IProps) { ); */ router.push( - `https://qual-connexion.idnot.fr/user/IdPOAuth2/authorize/idnot_idp_v1?client_id=B3CE56353EDB15A9&redirect_uri=http://local.lecoffreio.4nkweb:3000/authorized-client&scope=openid,profile&response_type=code`, + `https://qual-connexion.idnot.fr/user/IdPOAuth2/authorize/idnot_idp_v1?client_id=B3CE56353EDB15A9&redirect_uri=http://127.0.0.1:3000/authorized-client&scope=openid,profile&response_type=code`, ); }, [router]); @@ -89,7 +89,7 @@ export default function StepEmail(props: IProps) {
- Pour les notaires et les colaborateurs : + Pour les notaires et les collaborateurs :