From 84ad2c3fc0e2560c17443c915d7ce10c4d567658 Mon Sep 17 00:00:00 2001
From: Vinciane <vinciane.bizet@maarch.org>
Date: Mon, 4 Feb 2019 11:46:40 +0100
Subject: [PATCH] FEAT # 9749 Delete user - Reaffect attributaire

Reaffect when user is in listModel
---
 rest/index.php                                |   2 +
 .../controllers/ListInstanceController.php    |  89 +++++++++++
 .../models/ListInstanceModelAbstract.php      |  33 ++++
 .../resource/controllers/ResController.php    |  22 +++
 ...ministration-redirect-modal.component.html |  52 ++++--
 .../user/users-administration.component.ts    | 148 ++++++++++++++----
 6 files changed, 305 insertions(+), 41 deletions(-)

diff --git a/rest/index.php b/rest/index.php
index d705300305c..8cf78ce9995 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -200,6 +200,8 @@ $app->get('/listinstance/{id}', \Entity\controllers\ListInstanceController::clas
 $app->get('/res/{resId}/listinstance', \Entity\controllers\ListInstanceController::class . ':getListByResId');
 $app->get('/res/{resId}/visaCircuit', \Entity\controllers\ListInstanceController::class . ':getVisaCircuitByResId');
 $app->get('/res/{resId}/avisCircuit', \Entity\controllers\ListInstanceController::class . ':getAvisCircuitByResId');
+$app->get('/listinstances/dest/itemId/{itemId}', \Entity\controllers\ListInstanceController::class . ':getListWhereUserIsDest');
+$app->put('/listinstances', \Entity\controllers\ListInstanceController::class . ':updateListInstance');
 
 //ListTemplates
 $app->get('/listTemplates', \Entity\controllers\ListTemplateController::class . ':get');
diff --git a/src/app/entity/controllers/ListInstanceController.php b/src/app/entity/controllers/ListInstanceController.php
index 71701e9638d..d817fdd3230 100755
--- a/src/app/entity/controllers/ListInstanceController.php
+++ b/src/app/entity/controllers/ListInstanceController.php
@@ -20,6 +20,9 @@ use Slim\Http\Response;
 use Respect\Validation\Validator;
 use Resource\controllers\ResController;
 use Entity\models\EntityModel;
+use SrcCore\models\DatabaseModel;
+use User\models\UserModel;
+use Resource\models\ResModel;
 
 class ListInstanceController
 {
@@ -68,4 +71,90 @@ class ListInstanceController
         
         return $response->withJson($listinstances);
     }
+
+    public function getListWhereUserIsDest(Request $request, Response $response, array $aArgs) {
+        
+        $data = ListInstanceModel::getListWhereUserIsDest(['select' => ['li.*'], 'id' => $aArgs['itemId']]);
+
+        if($data) {
+            $res_id = 0;
+            $array=[];
+            foreach($data as $value) {
+                if($res_id == 0) {
+                    $res_id = $value['res_id'];
+                } else if( $res_id != $value['res_id']) {
+                    $listinstances[] = ['resId' => $res_id, "listinstances" => $array];
+                    $res_id = $value['res_id'];
+                    $array = [];
+                }
+                array_push($array, $value);
+            }
+            $listinstances[] = ['resId' => $res_id, "listinstances" => $array];
+        }
+            
+        return $response->withJson(['listinstances' => $listinstances]);   
+    }
+
+    public function updateListInstance(Request $request, Response $response)
+    {
+        $data = $request->getParams();
+
+        DatabaseModel::beginTransaction();
+
+        foreach ($data['listinstances'] as $ListInstanceByRes) {
+
+            foreach($ListInstanceByRes['listinstances'] as $instance) {
+
+                //check if basic data is empty
+                if( empty($instance['res_id']) || empty($instance['item_id']) || empty($instance['item_type']) || empty($instance['item_mode']) || empty($instance['difflist_type']) ) {
+                    DatabaseModel::rollbackTransaction();
+                    return $response->withStatus(400)->withJson(['errors' => 'Some data are empty']);
+                }
+                
+                //delete in database if exist
+                if( isset($instance['listinstance_id']) && !empty($instance['listinstance_id']) ) {
+                    $check = ListInstanceModel::getById(['select' => ['listinstance_id'], 'id' => $instance['listinstance_id']]);
+                    if( !$check) {
+                        DatabaseModel::rollbackTransaction();
+                        return $response->withStatus(400)->withJson(['errors' => 'listinstance_id is not correct']);
+                    }
+    
+                    ListInstanceModel::delete(['listinstance_id' => $instance['listinstance_id']]);
+                }
+
+                //check if redirect login already exist
+                $user = UserModel::getByLogin(['login' => $instance['item_id']]);
+                if (empty($user)) {
+                    DatabaseModel::rollbackTransaction();
+                    return $response->withStatus(400)->withJson(['errors' => 'User not found']);
+                }
+
+                //Create in database
+                if( isset($instance['listinstance_id'])) {
+                    unset($instance['listinstance_id']);
+                }
+                if( isset($instance['requested_signature'])) {
+                    unset($instance['requested_signature']);
+                }
+                if( isset($instance['signatory'])) {
+                    unset($instance['signatory']);
+                }
+                ListInstanceModel::create($instance);
+
+                //update res_letterbox
+                if($instance['item_mode'] == 'dest') {
+                    ResModel::update([
+                        'set'   => ['dest_user' => $instance['item_id']],
+                        'where' => ['res_id = ?'],
+                        'data'  => [$instance['res_id']]
+                    ]);
+                 }
+            }
+            
+        }
+
+        DatabaseModel::commitTransaction();
+
+        return $response->withJson(['success' => 'success']);
+    }
 }
diff --git a/src/app/entity/models/ListInstanceModelAbstract.php b/src/app/entity/models/ListInstanceModelAbstract.php
index 6be940b4433..6dbba183cb6 100755
--- a/src/app/entity/models/ListInstanceModelAbstract.php
+++ b/src/app/entity/models/ListInstanceModelAbstract.php
@@ -136,6 +136,20 @@ abstract class ListInstanceModelAbstract
         return true;
     }
 
+    public static function delete(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['listinstance_id']);
+        ValidatorModel::intVal($aArgs, ['listinstance_id']);
+
+        DatabaseModel::delete([
+            'table' => 'listinstance',
+            'where'  => ['listinstance_id = ?'],
+            'data'   => [$aArgs['listinstance_id']]
+        ]);
+
+        return true;
+    }
+
     public static function update(array $aArgs)
     {
         ValidatorModel::notEmpty($aArgs, ['where', 'data']);
@@ -189,4 +203,23 @@ abstract class ListInstanceModelAbstract
 
         return $aListInstances;
     }
+
+    public static function getListWhereUserIsDest(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['id']);
+        ValidatorModel::stringType($aArgs, ['id']);
+        ValidatorModel::arrayType($aArgs, ['select']);
+
+        $aListinstance = DatabaseModel::select([
+            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'table'     => ['listinstance li', 'res_letterbox res', 'mlb_coll_ext mlb'],
+            'left_join' => ['li.res_id = res.res_id', 'res.res_id = mlb.res_id'],
+            'where'     => ['res.dest_user = ?', 'li.difflist_type = ?', 'mlb.closing_date is null'],
+            'data'      => [$aArgs['id'], 'entity_id'],
+            'order_by'  => ['res_id ASC']
+        ]);
+
+        return $aListinstance;
+    }
+
 }
diff --git a/src/app/resource/controllers/ResController.php b/src/app/resource/controllers/ResController.php
index 30ac5bb4cb7..5f113d32ab1 100755
--- a/src/app/resource/controllers/ResController.php
+++ b/src/app/resource/controllers/ResController.php
@@ -720,4 +720,26 @@ class ResController
 
         return $response->withJson(['isAllowed' => true]);
     }
+
+    public function updateDestUser(Request $request, Response $response, array $aArgs)
+    {
+        $data = $request->getParams();
+
+        foreach ($data as $listInstance) {
+
+            $user = UserModel::getByLogin(['login' => $listInstance['redirectUserId']]);
+            if (empty($user)) {
+                return $response->withStatus(400)->withJson(['errors' => 'User not found']);
+            }
+
+            ListInstanceModel::update([
+                'set'   => ['item_id' => $listInstance['redirectUserId']],
+                'where' => ['item_id = ?', 'res_id = ?', 'item_mode = ?', 'process_date IS NULL'],
+                'data'  => [$aArgs['user_id'], $listInstance['res_id'], $listInstance['item_mode']]
+            ]);
+        }
+
+        return $response->withJson(['success' => 'success']);
+    }
+
 }
diff --git a/src/frontend/app/administration/user/users-administration-redirect-modal.component.html b/src/frontend/app/administration/user/users-administration-redirect-modal.component.html
index 90239b5ea7e..08995d60ee0 100755
--- a/src/frontend/app/administration/user/users-administration-redirect-modal.component.html
+++ b/src/frontend/app/administration/user/users-administration-redirect-modal.component.html
@@ -1,10 +1,11 @@
-<h2 mat-dialog-title>{{lang.redirectUserListDiff}}</h2>
-<mat-dialog-content>
-    <form #changeDiffListDestForm="ngForm">
+<form #changeDiffListDestForm="ngForm">
+    <mat-dialog-content>    
         <div class="modal-body">
+            <h2 mat-dialog-title>{{lang.redirectUserListDiff}}</h2>
             <div class="alert alert-warning" role="alert">
                 <b>{{this.data.userDestRedirect.firstname}} {{this.data.userDestRedirect.lastname}}</b>&nbsp;<span [innerHTML]="lang.chooseNewDest"></span> :
             </div>
+
             <div *ngFor="let userDestRedirectModel of data.userDestRedirectModels; index as i" id="{{userDestRedirectModel.object_id}}"
                 class="form-group">
 
@@ -29,12 +30,41 @@
                     </mat-autocomplete>
                 </mat-form-field>
             </div>
+
+            <h2 mat-dialog-title>Changement de destinataire pour les courriers en cours de traitement</h2>
+            <div class="alert alert-warning" role="alert">
+                <b>{{this.data.userDestRedirect.firstname}} {{this.data.userDestRedirect.lastname}}</b>&nbsp;<span> est destinataire de courriers en cours de traitement, veuillez choisir un utilisateur de remplacement</span> :
+            </div>
+
+            <div id="{{this.data.userDestRedirect.user_id}}" class="form-group">
+                <mat-form-field class="example-full-width">
+                    <input name="userDestRedirectModel_resDest" id="userDestRedirectModel_resDest" [(ngModel)]="this.data.userDestRedirect.redirectDestResUserId"
+                        type="text" placeholder="Nouveau destinataire pour les courriers : " matInput [matAutocomplete]="auto"
+                        [formControl]="userCtrl" required>
+                    <mat-autocomplete #auto="matAutocomplete">
+                        <ng-container *ngFor="let user of filteredUsers | async">
+                            <mat-option [value]="user.id" *ngIf="this.data.userDestRedirect.user_id != user.id">
+                                <div class="container-fluid">
+                                    <span class="col-xm-1">
+                                        <mat-icon color="primary" class="fa fa-user fa-2x" style="margin-right:0px;"></mat-icon>
+                                    </span>
+                                    <span class="col-xm-11">
+                                        {{ user.idToDisplay }}
+                                        <small>{{ user.otherInfo }}</small>
+                                    </span>
+                                </div>
+                            </mat-option>
+                        </ng-container>
+                    </mat-autocomplete>
+                </mat-form-field>
+            </div>
+
         </div>
-        <mat-dialog-actions>
-            <button mat-raised-button color="warn" *ngIf="data.userDestRedirect.mode == 'del'" type="submit" class="btn btn-danger" (click)="dialogRef.close(this.data.userDestRedirectModels)"
-                [disabled]="!sendFunction()">{{lang.delete}} {{lang.user}}</button>
-            <button mat-raised-button color="primary" *ngIf="data.userDestRedirect.mode == 'up'" type="submit" (click)="dialogRef.close(this.data.userDestRedirectModels)"
-                [disabled]="!sendFunction()">{{lang.suspend}} {{lang.user}}</button>
-        </mat-dialog-actions>
-    </form>
-</mat-dialog-content>
\ No newline at end of file
+    </mat-dialog-content>
+    <mat-dialog-actions>
+        <button mat-raised-button color="warn" *ngIf="data.userDestRedirect.mode == 'del'" type="submit" class="btn btn-danger" (click)="dialogRef.close(this.data)"
+            [disabled]="!sendFunction()">{{lang.delete}} {{lang.user}}</button>
+        <button mat-raised-button color="primary" *ngIf="data.userDestRedirect.mode == 'up'" type="submit" (click)="dialogRef.close(this.data.userDestRedirectModels)"
+            [disabled]="!sendFunction()">{{lang.suspend}} {{lang.user}}</button>
+    </mat-dialog-actions>
+</form>
\ No newline at end of file
diff --git a/src/frontend/app/administration/user/users-administration.component.ts b/src/frontend/app/administration/user/users-administration.component.ts
index a5db724851a..79c223f4047 100755
--- a/src/frontend/app/administration/user/users-administration.component.ts
+++ b/src/frontend/app/administration/user/users-administration.component.ts
@@ -35,6 +35,7 @@ export class UsersAdministrationComponent extends AutoCompletePlugin implements
     config                                  : any                   = {};
     userDestRedirect                        : any                   = {};
     userDestRedirectModels                  : any[]                 = [];
+    listinstances                           : any[]                 = [];
     quota                                   : any                   = {};
     user                                    : any                   = {};
 
@@ -182,53 +183,136 @@ export class UsersAdministrationComponent extends AutoCompletePlugin implements
         if (user.inDiffListDest == 'Y') {
             user.mode = 'del';
             this.userDestRedirect = user;
+
+            //get listModel
             this.http.get(this.coreUrl + 'rest/listTemplates/entityDest/itemId/' + user.user_id)
                 .subscribe((data: any) => {
+
                     this.userDestRedirectModels = data.listTemplates;
-                    this.config = { data: { userDestRedirect: this.userDestRedirect, userDestRedirectModels: this.userDestRedirectModels } };
+                    this.config = { 
+                        data: { 
+                            userDestRedirect: this.userDestRedirect, 
+                            userDestRedirectModels: this.userDestRedirectModels
+                        } 
+                    };
+
+                    //open modal
                     this.dialogRef = this.dialog.open(UsersAdministrationRedirectModalComponent, this.config);
-                    this.dialogRef.afterClosed().subscribe((result: string) => {
+                    this.dialogRef.afterClosed().subscribe((result: any) => {
+
                         if (result) {
-                            user.redirectListModels = result;
+                            user.redirectListModels     = result.userDestRedirectModels;
+                            user.redirectDestResUserId  = result.userDestRedirect.redirectDestResUserId;
+
                             //first, update listModels
                             this.http.put(this.coreUrl + 'rest/listTemplates/entityDest/itemId/' + user.user_id, user)
                                 .subscribe((data: any) => {
                                     if (data.errors) {
                                         this.notify.error(data.errors);
                                     } else {
-                                        //then delete user
-                                        this.http.delete(this.coreUrl + 'rest/users/' + user.id)
-                                            .subscribe(() => {
-                                                for (let i in this.data) {
-                                                    if (this.data[i].id == user.id) {
-                                                        this.data.splice(Number(i), 1);
-                                                    }
-                                                }
-                                                this.dataSource = new MatTableDataSource(this.data);
-                                                this.dataSource.paginator = this.paginator;
-                                                this.dataSource.sort = this.sort;
 
-                                                if (this.quota.userQuota && user.enabled == 'Y') {
-                                                    this.quota.actives--;
-                                                } else if (this.quota.userQuota && user.enabled == 'N') {
-                                                    this.quota.inactives--;
-                                                }
+                                        //secund get listInstances where user is dest
+                                        this.http.get(this.coreUrl + 'rest/listinstances/dest/itemId/' + user.user_id)
+                                            .subscribe((data: any) => {
+                                                
+                                                if (data.listinstances){
+                                                    this.listinstances = data.listinstances;
+                                                    this.listinstances.forEach((list: any) => {
+                                                        list.listinstances.forEach((element:any) => {
+                                                            if(element.item_mode == 'dest') {
+                                                                element.item_id = user.redirectDestResUserId;
+                                                            }
+                                                        });
+                                                    });
 
-                                                this.notify.success(this.lang.userDeleted + ' « ' + user.user_id + ' »');
+                                                    user.listinstances = this.listinstances;
+
+                                                    //third update listinstances and res_letterbox
+                                                    this.http.put(this.coreUrl + 'rest/listinstances', user)
+                                                        .subscribe((data: any) => {
+                                                            if (data.errors) {
+                                                                this.notify.error(data.errors);
+                                                            } else {
+                                                                //then delete user
+                                                                this.http.delete(this.coreUrl + 'rest/users/' + user.id)
+                                                                .subscribe(() => {
+                                                                    for (let i in this.data) {
+                                                                        if (this.data[i].id == user.id) {
+                                                                            this.data.splice(Number(i), 1);
+                                                                        }
+                                                                    }
+                                                                    this.dataSource = new MatTableDataSource(this.data);
+                                                                    this.dataSource.paginator = this.paginator;
+                                                                    this.dataSource.sort = this.sort;
+
+                                                                    if (this.quota.userQuota && user.enabled == 'Y') {
+                                                                        this.quota.actives--;
+                                                                    } else if (this.quota.userQuota && user.enabled == 'N') {
+                                                                        this.quota.inactives--;
+                                                                    }
+
+                                                                    this.notify.success(this.lang.userDeleted + ' « ' + user.user_id + ' »');
+                                                                    
+                                                                //end delete user
+                                                                }, (err) => {
+                                                                    this.notify.error(err.error.errors);
+                                                                });
+                                                            }   
+
+                                                        //end update listinstances and res_letterbox 
+                                                        }, (err) => {
+                                                            this.notify.error(err.error.errors);
+                                                        });
+                                                
+                                                } else {
+                                                   //delete user
+                                                   this.http.delete(this.coreUrl + 'rest/users/' + user.id)
+                                                   .subscribe(() => {
+                                                       for (let i in this.data) {
+                                                           if (this.data[i].id == user.id) {
+                                                               this.data.splice(Number(i), 1);
+                                                           }
+                                                       }
+                                                       this.dataSource = new MatTableDataSource(this.data);
+                                                       this.dataSource.paginator = this.paginator;
+                                                       this.dataSource.sort = this.sort;
+
+                                                       if (this.quota.userQuota && user.enabled == 'Y') {
+                                                           this.quota.actives--;
+                                                       } else if (this.quota.userQuota && user.enabled == 'N') {
+                                                           this.quota.inactives--;
+                                                       }
+
+                                                       this.notify.success(this.lang.userDeleted + ' « ' + user.user_id + ' »');
+
+                                                    //end delete user
+                                                    }, (err) => {
+                                                        this.notify.error(err.error.errors);
+                                                    });
+                                                }
+                                                                                            
+                                        //end get listinstances
+                                        }, (err) => {
+                                            this.notify.error(err.error.errors);
+                                        });
 
-                                            }, (err) => {
-                                                this.notify.error(err.error.errors);
-                                            });
                                     }
-                                }, (err) => {
-                                    this.notify.error(err.error.errors);
-                                });
+
+                            //end update listModels
+                            }, (err) => {
+                                this.notify.error(err.error.errors);
+                            });
+
                         }
+
+                    //end modal
                     });
 
-                }, (err) => {
-                    this.notify.error(err.error.errors);
-                });
+            //end listModel
+            }, (err) => {
+                this.notify.error(err.error.errors);
+            });
+
         } else {
             let r = confirm(this.lang.confirmAction + ' ' + this.lang.delete + ' « ' + user.user_id + ' »');
 
@@ -258,7 +342,7 @@ export class UsersAdministrationComponent extends AutoCompletePlugin implements
 }
 @Component({
     templateUrl: "users-administration-redirect-modal.component.html",
-    styles: [".mat-dialog-content{height:260px;max-height: 65vh;}"]
+    styles: [".mat-dialog-content{max-height: 80vh;}"]
 })
 export class UsersAdministrationRedirectModalComponent extends AutoCompletePlugin {
     lang: any = LANG;
@@ -274,6 +358,10 @@ export class UsersAdministrationRedirectModalComponent extends AutoCompletePlugi
             }
         });
 
+        if(!this.data.userDestRedirect.redirectDestResUserId) {
+            valid = false;
+        }
+
         return valid;
     }
 }
-- 
GitLab