@@ -22,6 +22,8 @@ import { IdentityState } from './_enums/states.enum';
2222import { Identities } from './_schemas/identities.schema' ;
2323import { IdentitiesValidationService } from './validations/identities.validation.service' ;
2424import { FactorydriveService } from '@the-software-compagny/nestjs_module_factorydrive' ;
25+ import { ApiBadRequestResponse } from "@nestjs/swagger" ;
26+ import { InitStatesEnum } from "~/management/identities/_enums/init-state.enum" ;
2527
2628@Injectable ( )
2729export class IdentitiesService extends AbstractServiceSchema {
@@ -320,17 +322,17 @@ export class IdentitiesService extends AbstractServiceSchema {
320322
321323 public transformNullsToString ( obj ) {
322324 if ( obj === null ) {
323- return "" ;
325+ return '' ;
324326 }
325327
326328 if ( Array . isArray ( obj ) ) {
327329 return obj . map ( this . transformNullsToString ) ;
328330 }
329331
330- if ( typeof obj === 'object' ) {
332+ if ( typeof obj === 'object' && ! ( obj instanceof Types . ObjectId ) ) {
331333 for ( const key in obj ) {
332334 if ( obj [ key ] === null ) {
333- obj [ key ] = "" ;
335+ obj [ key ] = '' ;
334336 } else if ( typeof obj [ key ] === 'object' ) {
335337 console . log ( 'key' , key ) ;
336338 obj [ key ] = this . transformNullsToString ( obj [ key ] ) ;
@@ -340,4 +342,165 @@ export class IdentitiesService extends AbstractServiceSchema {
340342
341343 return obj ;
342344 }
345+ public async searchDoubles ( ) {
346+ const agg1 = [
347+ {
348+ $match : {
349+ state : { $ne : IdentityState . SYNCED } ,
350+ destFusionId : { $eq : null } ,
351+ } ,
352+ } ,
353+ {
354+ $addFields : {
355+ test : {
356+ $concat : [
357+ '$additionalFields.attributes.supannPerson.supannOIDCDatedeNaissance' ,
358+ '$inetOrgPerson.givenName' ,
359+ ] ,
360+ } ,
361+ } ,
362+ } ,
363+ {
364+ $group : {
365+ _id : '$test' ,
366+ n : {
367+ $sum : 1 ,
368+ } ,
369+ list : {
370+ $addToSet : {
371+ _id : '$_id' ,
372+ uid : '$inetOrgPerson.uid' ,
373+ cn : '$inetOrgPerson.cn' ,
374+ employeeNumber : '$inetOrgPerson.employeeNumber' ,
375+ departmentNumber : '$inetOrgPerson.departmentNumber' ,
376+ } ,
377+ } ,
378+ } ,
379+ } ,
380+ {
381+ $match : {
382+ n : {
383+ $gt : 1 ,
384+ } ,
385+ } ,
386+ } ,
387+ ] ;
388+ const agg2 = [
389+ {
390+ $match : {
391+ state : { $ne : IdentityState . SYNCED } ,
392+ destFusionId : { $eq : null } ,
393+ } ,
394+ } ,
395+ {
396+ $group : {
397+ _id : '$inetOrgPerson.uid' ,
398+ n : {
399+ $sum : 1 ,
400+ } ,
401+ list : {
402+ $addToSet : {
403+ _id : '$_id' ,
404+ uid : '$inetOrgPerson.uid' ,
405+ cn : '$inetOrgPerson.cn' ,
406+ employeeNumber : '$inetOrgPerson.employeeNumber' ,
407+ departmentNumber : '$inetOrgPerson.departmentNumber' ,
408+ } ,
409+ } ,
410+ } ,
411+ } ,
412+ {
413+ $match : {
414+ n : {
415+ $gt : 1 ,
416+ } ,
417+ } ,
418+ } ,
419+ ] ;
420+ const result1 = await this . _model . aggregate ( agg1 ) ;
421+ const result2 = await this . _model . aggregate ( agg2 ) ;
422+ const result3 = result1 . map ( ( x ) => {
423+ const k = x . list [ 0 ] . _id + '/' + x . list [ 1 ] . _id ;
424+ const k1 = x . list [ 1 ] . _id + '/' + x . list [ 0 ] . _id ;
425+ return { k1 : k1 , k : k , key1 : x . list [ 0 ] . _id , key2 : x . list [ 1 ] . _id , data : x . list } ;
426+ } ) ;
427+ const result4 = result2 . map ( ( x ) => {
428+ const k = x . list [ 0 ] . _id + '/' + x . list [ 1 ] . _id ;
429+ const k1 = x . list [ 1 ] . _id + '/' + x . list [ 0 ] . _id ;
430+ return { k1 : k1 , k : k , key1 : x . list [ 0 ] . _id , key2 : x . list [ 1 ] . _id , data : x . list } ;
431+ } ) ;
432+ result4 . forEach ( ( x ) => {
433+ const r = result3 . find ( ( o ) => o . k === x . k ) ;
434+ const r1 = result3 . find ( ( o ) => o . k1 === x . k ) ;
435+ if ( r === undefined && r1 === undefined ) {
436+ result3 . push ( x ) ;
437+ }
438+ } ) ;
439+ return result3 ;
440+ }
441+ //fusionne les deux identités id2 > id1 les champs presents dans id2 et non present dans id1 seront ajoutés
442+ // retourne l'id de na nouvelle identité créée
443+ public async fusion ( id1 , id2 ) {
444+ let identity1 = null ;
445+ let identity2 = null ;
446+ try {
447+ identity1 = await this . findById ( id1 ) ;
448+ } catch ( error ) {
449+ throw new BadRequestException ( 'Id1 not found' ) ;
450+ }
451+ try {
452+ identity2 = await this . findById ( id2 ) ;
453+ } catch ( error ) {
454+ throw new BadRequestException ( 'Id2 not found' ) ;
455+ }
456+ //test si une ou les deux entités ont deja été fusionnées
457+ const x = identity1 . destFusionId
458+ if ( identity1 . destFusionId !== undefined && identity1 . destFusionId !== null ) {
459+ throw new BadRequestException ( 'Id1 already fusionned' ) ;
460+ }
461+ if ( identity2 . destFusionId !== undefined && identity2 . destFusionId !== null ) {
462+ throw new BadRequestException ( 'Id2 already fusionned' ) ;
463+ }
464+ const plainIdentity1 = toPlainAndCrush ( identity1 . toJSON ( ) , {
465+ excludePrefixes : [ '_id' , 'fingerprint' , 'metadata' ] ,
466+ } ) ;
467+ const plainIdentity2 = toPlainAndCrush ( identity2 . toJSON ( ) , {
468+ excludePrefixes : [ '_id' , 'fingerprint' , 'metadata' ] ,
469+ } ) ;
470+ const newObj = construct ( { ...plainIdentity2 , ...plainIdentity1 } ) ;
471+ //const newIdentity = await this.create(newObj);
472+ newObj . inetOrgPerson . employeeType = 'FUSION' ;
473+ newObj . inetOrgPerson . employeeNumber =
474+ identity1 . inetOrgPerson . employeeNumber + '/' + identity2 . inetOrgPerson . employeeNumber ;
475+ identity2 . inetOrgPerson . departmentNumber . forEach ( ( depN ) => {
476+ newObj . inetOrgPerson . departmentNumber . push ( depN ) ;
477+ } ) ;
478+ // si supann est present
479+ if (
480+ identity1 . additionalFields . objectClasses . includes ( 'supannPerson' ) &&
481+ identity2 . additionalFields . objectClasses . includes ( 'supannPerson' )
482+ ) {
483+ identity2 . additionalFields . attributes . supannPerson . supannTypeEntiteAffectation . forEach ( ( depN ) => {
484+ newObj . additionalFields . attributes . supannPerson . supannTypeEntiteAffectation . push ( depN ) ;
485+ } ) ;
486+ // supannRefId
487+ identity2 . additionalFields . attributes . supannPerson . supannRefId . forEach ( ( depN ) => {
488+ newObj . additionalFields . attributes . supannPerson . supannRefId . push ( depN ) ;
489+ } ) ;
490+ }
491+ newObj . state = IdentityState . TO_VALIDATE ;
492+ newObj . srcFusionId = [ identity1 . _id , identity2 . _id ] ;
493+ const newIdentity = await this . create ( newObj ) ;
494+ //MAJ identite1
495+ identity1 . destFusionId = newIdentity . _id ;
496+ identity1 . state = IdentityState . DONT_SYNC ;
497+ // modification identité1
498+ super . update ( identity1 . _id , identity1 ) ;
499+ //Maj Identity2
500+ identity2 . destFusionId = newIdentity . _id ;
501+ identity2 . state = IdentityState . DONT_SYNC ;
502+ // modification identité1
503+ super . update ( identity2 . _id , identity2 ) ;
504+ return newIdentity . _id ;
505+ }
343506}
0 commit comments