Update FolderService

This commit is contained in:
Sosthene 2025-09-11 14:10:23 +02:00
parent 9a3685ec4f
commit 4540ac726a

View File

@ -3,13 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
import User from 'src/sdk/User'; import User from 'src/sdk/User';
import AbstractService from './AbstractService'; import AbstractService from './AbstractService';
import CustomerService from './CustomerService'; import { DEFAULT_STORAGE_URLS, DEFAULT_VALIDATOR_ID } from '@Front/Config/AppConstants';
import CollaboratorService from './CollaboratorService';
import DeedTypeService from './DeedTypeService';
import DocumentTypeService from './DocumentTypeService';
import DocumentService from './DocumentService';
import FileService from './FileService';
import NoteService from './NoteService';
export default class FolderService extends AbstractService { export default class FolderService extends AbstractService {
@ -17,7 +11,7 @@ export default class FolderService extends AbstractService {
super(); super();
} }
public static createFolder(folderData: any, stakeholdersId: string[], customersId: string[]): Promise<any> { public static async createFolder(folderData: any, customersId: string[]): Promise<{ processId: string, processData: any }> {
const ownerId: string = User.getInstance().getPairingId()!; const ownerId: string = User.getInstance().getPairingId()!;
const processData: any = { const processData: any = {
@ -30,9 +24,7 @@ export default class FolderService extends AbstractService {
}; };
const privateFields: string[] = Object.keys(processData); const privateFields: string[] = Object.keys(processData);
privateFields.splice(privateFields.indexOf('uid'), 1); const allFields: string[] = [...privateFields, 'roles'];
privateFields.splice(privateFields.indexOf('utype'), 1);
privateFields.splice(privateFields.indexOf('isDeleted'), 1);
const roles: any = { const roles: any = {
demiurge: { demiurge: {
@ -40,135 +32,101 @@ export default class FolderService extends AbstractService {
validation_rules: [], validation_rules: [],
storages: [] storages: []
}, },
owner: { owners: {
members: [ownerId], members: [ownerId, DEFAULT_VALIDATOR_ID],
validation_rules: [ validation_rules: [
{ {
quorum: 0.5, quorum: 0.01,
fields: [...privateFields, 'roles', 'uid', 'utype'], fields: allFields,
min_sig_member: 1, min_sig_member: 0.01,
}, },
], ],
storages: [] storages: [...DEFAULT_STORAGE_URLS]
}, },
stakeholders: { guests: {
members: stakeholdersId, members: [],
validation_rules: [ validation_rules: [{
{ quorum: 0.01,
quorum: 0.5, fields: allFields,
fields: ['documents', 'motes'], min_sig_member: 0.01,
min_sig_member: 1, }],
}, storages: [...DEFAULT_STORAGE_URLS]
],
storages: []
}, },
customers: { customers: {
members: customersId, members: customersId,
validation_rules: [ validation_rules: [
{ {
quorum: 0.0, quorum: 0.0,
fields: privateFields, fields: allFields,
min_sig_member: 0.0, min_sig_member: 0.0,
}, },
], ],
storages: [] storages: [...DEFAULT_STORAGE_URLS]
}, },
apophis: { apophis: {
members: [ownerId], members: [ownerId, DEFAULT_VALIDATOR_ID],
validation_rules: [], validation_rules: [],
storages: [] storages: []
} }
}; };
return new Promise<any>((resolve: (processCreated: any) => void, reject: (error: string) => void) => { try {
this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => { const processCreated = await this.messageBus.createProcess(processData, privateFields, roles);
this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => { await this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id);
this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => { await this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id);
this.getFolderByUid(processCreated.processData.uid).then(resolve).catch(reject); const finalProcessData = await this.messageBus.getProcessData(processCreated.processId);
}).catch(reject);
}).catch(reject); return { processId: processCreated.processId, processData: finalProcessData };
}).catch(reject); } catch (error) {
}); throw error;
}
} }
public static getFolders(callback: (processes: any[]) => void, waitForAll: boolean = false): void { public static getFolders(callback: (processes: Record<string, any>) => void): void {
// Check if we have valid cache // Check if we have valid cache
const items: any[] = this.getItems('_folders_'); const items: Record<string, any> = this.getItems('_folders_');
if (items.length > 0 && !waitForAll) { if (Object.keys(items).length > 0) {
setTimeout(() => callback([...items]), 0); setTimeout(() => callback(items), 0);
} }
this.messageBus.getProcessesDecoded((publicValues: any) => this.messageBus.getProcessesDecoded((_processId: string, values: any) => {
publicValues['uid'] && return values['utype']
publicValues['utype'] && && values['utype'] === 'folder'
publicValues['utype'] === 'folder' && && values['isDeleted']
publicValues['isDeleted'] && && values['isDeleted'] === 'false';
publicValues['isDeleted'] === 'false' && }).then(async (processes: Record<string, any>) => {
!items.map((item: any) => item.processData.uid).includes(publicValues['uid']) if (Object.keys(processes).length === 0) {
).then(async (processes: any[]) => { callback(items);
if (processes.length === 0) {
if (waitForAll) {
callback([...items]);
}
return; return;
} }
const updatedItems: any[] = [...items]; console.log('[FolderService/getFolders] processes', processes);
for (let processIndex = 0; processIndex < processes.length; processIndex++) { const updatedItems: Record<string, any> = { ...items };
let process = processes[processIndex];
if (!waitForAll) {
process = await this.completeFolder(process, (processInProgress: any) => {
const currentItems: any[] = [...updatedItems];
const existingIndex: number = currentItems.findIndex(item => item.processData?.uid === processInProgress.processData?.uid);
if (existingIndex >= 0) {
currentItems[existingIndex] = processInProgress;
} else {
currentItems.push(processInProgress);
}
callback(currentItems);
});
} else {
process = await this.completeFolder(process);
}
for (const [processId, process] of Object.entries(processes)) {
// Update cache // Update cache
this.setItem('_folders_', process); this.setItem('_folders_', processId, process);
const existingIndex: number = updatedItems.findIndex(item => item.processData?.uid === process.processData?.uid); updatedItems[processId] = process;
if (existingIndex >= 0) {
updatedItems[existingIndex] = process;
} else {
updatedItems.push(process);
} }
if (!waitForAll) { callback(updatedItems);
callback([...updatedItems]);
}
}
if (waitForAll) {
callback([...updatedItems]);
}
}); });
} }
public static getFoldersBy(whereClause: { [path: string]: any }): Promise<any[]> { public static getFoldersBy(whereClause: { [path: string]: any }): Promise<Record<string, any>> {
return new Promise<any[]>((resolve: (folders: any[]) => void) => { return new Promise<Record<string, any>>((resolve: (folders: Record<string, any>) => void) => {
this.getFolders((processes: any[]) => { this.getFolders((processes: Record<string, any>) => {
if (processes.length === 0) { if (Object.keys(processes).length === 0) {
resolve([]); resolve({});
} else { } else {
resolve(processes.filter((process: any) => { const filteredEntries = Object.entries(processes).filter(([processId, process]) => {
const folder: any = process.processData;
for (const path in whereClause) { for (const path in whereClause) {
const paths: string[] = path.split('.'); const paths: string[] = path.split('.');
let value: any = folder; let value: any = process;
value['processId'] = processId;
for (let i = 0; i < paths.length; i++) { for (let i = 0; i < paths.length; i++) {
const currentPath = paths[i]; const currentPath = paths[i];
if (!currentPath || value === undefined || value === null) { if (!currentPath || value === undefined || value === null) {
@ -183,146 +141,40 @@ export default class FolderService extends AbstractService {
} }
return true; return true;
})); });
// Convert filtered entries back to a Record
const filteredProcesses: Record<string, any> = {};
filteredEntries.forEach(([processId, process]) => {
filteredProcesses[processId] = process;
});
resolve(filteredProcesses);
} }
}, true); });
}); });
} }
public static getFolderByUid(uid: string): Promise<any> { public static async updateFolder(processId: string, newData: any): Promise<void> {
// Check if we have valid cache try {
const item: any = this.getItem('_folders_', uid); const processUpdated = await this.messageBus.updateProcess(
if (item) { processId,
return Promise.resolve(item); { updated_at: new Date().toISOString(), ...newData },
} [],
null
);
return new Promise<any>((resolve: (process: any) => void, reject: (error: string) => void) => { const newStateId: string = processUpdated.diffs[0]?.state_id;
this.messageBus.getProcessesDecoded((publicValues: any) => await this.messageBus.notifyUpdate(processId, newStateId);
publicValues['uid'] && await this.messageBus.validateState(processId, newStateId);
publicValues['uid'] === uid &&
publicValues['utype'] && const processData = await this.messageBus.getProcessData(processId);
publicValues['utype'] === 'folder' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false'
).then(async (processes: any[]) => {
if (processes.length === 0) {
resolve(null);
} else {
let process: any = processes[0];
process = await this.completeFolder(process);
// Update cache // Update cache
this.setItem('_folders_', process); this.setItem('_folders_', processId, processData);
} catch (error) {
resolve(process); console.error('Failed to update folder:', error);
} throw error; // Re-throw to allow caller to handle
}).catch(reject);
});
}
public static updateFolder(process: any, newData: any): Promise<void> {
return new Promise<void>((resolve: () => void, reject: (error: string) => void) => {
this.messageBus.updateProcess(process.processId, { updated_at: new Date().toISOString(), ...newData }, [], null).then((processUpdated: any) => {
const newStateId: string = processUpdated.diffs[0]?.state_id;
this.messageBus.notifyUpdate(process.processId, newStateId).then(() => {
this.messageBus.validateState(process.processId, newStateId).then((_stateValidated) => {
const folderUid: string = process.processData.uid;
this.removeItem('_folders_', folderUid);
this.getFolderByUid(folderUid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
});
}
public static refreshFolderByUid(uid: string): Promise<void> {
return new Promise<void>((resolve: () => void, reject: (error: string) => void) => {
this.getFolderByUid(uid).then((process: any) => {
this.updateFolder(process, {}).then(resolve).catch(reject);
}).catch(reject);
});
}
private static async completeFolder(process: any, progressCallback?: (processInProgress: any) => void): Promise<any> {
const progressiveProcess: any = JSON.parse(JSON.stringify(process));
if (process.processData.customers && process.processData.customers.length > 0) {
process.processData.customers = await new Promise<any[]>(async (resolve: (customers: any[]) => void) => {
const customers: any[] = [];
for (const customer of process.processData.customers) {
customers.push((await CustomerService.getCustomerByUid(customer.uid)).processData);
}
resolve(customers);
});
if (process.processData.customers && process.processData.customers.length > 0) {
const documents: any[] = (await DocumentService.getDocuments()).map((process: any) => process.processData);
for (const customer of process.processData.customers) {
customer.documents = documents.filter((document: any) => (document.depositor && document.depositor.uid === customer.uid) || (document.customer && document.customer.uid === customer.uid));
for (const document of customer.documents) {
if (document.document_type) {
document.document_type = (await DocumentTypeService.getDocumentTypeByUid(document.document_type.uid)).processData;
}
if (document.files && document.files.length > 0) {
const files: any[] = [];
for (const file of document.files) {
files.push({ uid: file.uid, file_name: (await FileService.getFileByUid(file.uid)).processData.file_name });
}
document.files = files;
} }
} }
} }
}
if (progressCallback) {
progressiveProcess.processData.customers = process.processData.customers;
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
}
}
if (process.processData.stakeholders && process.processData.stakeholders.length > 0) {
process.processData.stakeholders = await new Promise<any[]>(async (resolve: (stakeholders: any[]) => void) => {
const stakeholders: any[] = [];
for (const stakeholder of process.processData.stakeholders) {
stakeholders.push((await CollaboratorService.getCollaboratorByUid(stakeholder.uid)).processData);
}
resolve(stakeholders);
});
if (progressCallback) {
progressiveProcess.processData.stakeholders = process.processData.stakeholders;
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
}
}
if (process.processData.deed && process.processData.deed.deed_type) {
const deed_type: any = (await DeedTypeService.getDeedTypeByUid(process.processData.deed.deed_type.uid)).processData;
process.processData.deed.deed_type = deed_type;
if (deed_type.document_types && deed_type.document_types.length > 0) {
// Remove duplicates
process.processData.deed.document_types = deed_type.document_types.filter((item: any, index: number) => deed_type.document_types.findIndex((t: any) => t.uid === item.uid) === index);
}
if (progressCallback) {
progressiveProcess.processData.deed = process.processData.deed;
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
}
}
const notes: any[] = (await NoteService.getNotes()).map((process: any) => process.processData);
if (notes.length > 0) {
process.processData.notes = notes.filter((note: any) => note.folder.uid === process.processData.uid);
if (progressCallback) {
progressiveProcess.processData.notes = process.processData.notes;
progressCallback(JSON.parse(JSON.stringify(progressiveProcess)));
}
}
return process;
}
}