From cbc23381cbc140d5a290a417e9fcf66367836f9b Mon Sep 17 00:00:00 2001
From: Damien <damien.burel@maarch.org>
Date: Mon, 26 Mar 2018 18:07:54 +0200
Subject: [PATCH] [FEAT] #261 Priority order

---
 .../baskets-administration.component.html     |  2 -
 .../priorities-administration.component.html  | 21 ++++++---
 .../class_business_app_tools_Abstract.php     |  2 +-
 .../priorities-administration.component.ts    | 20 ++++++++-
 rest/index.php                                |  2 +
 sql/data_fr.sql                               |  8 ++--
 sql/develop.sql                               |  1 +
 sql/structure.sql                             |  1 +
 .../basket/controllers/BasketController.php   |  5 ---
 .../controllers/PriorityController.php        | 45 +++++++++++++++++++
 .../priority/models/PriorityModelAbstract.php | 23 +++++++++-
 src/core/lang/lang-en.php                     |  1 +
 src/core/lang/lang-fr.php                     |  1 +
 13 files changed, 113 insertions(+), 19 deletions(-)

diff --git a/apps/maarch_entreprise/Views/baskets-administration.component.html b/apps/maarch_entreprise/Views/baskets-administration.component.html
index daa9ab16078..5585ad10804 100644
--- a/apps/maarch_entreprise/Views/baskets-administration.component.html
+++ b/apps/maarch_entreprise/Views/baskets-administration.component.html
@@ -76,7 +76,6 @@
         </mat-sidenav-content>
         <mat-sidenav #snav2 [mode]="mobileQuery.matches ? 'over' : 'side'" [fixedInViewport]="mobileQuery.matches" fixedTopGap="56"
             position='end' [opened]="mobileQuery.matches ? false : false">
-
             <mat-list>
                 <span dnd-sortable-container [dropZones]="['boxers-zone']" [sortableData]="basketsOrder">
                     <mat-list-item disableRipple="true" *ngFor="let basket of basketsOrder;let i = index" title="deplacer" dnd-sortable
@@ -86,7 +85,6 @@
                     </mat-list-item>
                 </span>
             </mat-list>
-
         </mat-sidenav>
     </mat-sidenav-container>
 </div>
\ No newline at end of file
diff --git a/apps/maarch_entreprise/Views/priorities-administration.component.html b/apps/maarch_entreprise/Views/priorities-administration.component.html
index b1403e74bf1..e3e48d2614d 100755
--- a/apps/maarch_entreprise/Views/priorities-administration.component.html
+++ b/apps/maarch_entreprise/Views/priorities-administration.component.html
@@ -22,6 +22,12 @@
                         {{lang.add}}
                     </p>
                 </a>
+                <a mat-list-item (click)="snav2.toggle()">
+                    <mat-icon color="primary" mat-list-icon class="fa fa-list-ol"></mat-icon>
+                    <p mat-line>
+                        {{lang.basketsOrder}}
+                    </p>
+                </a>
             </mat-nav-list>
             <mat-divider></mat-divider>
             <menu-app></menu-app>
@@ -93,11 +99,16 @@
             </mat-card>
         </mat-sidenav-content>
         <mat-sidenav #snav2 [mode]="mobileQuery.matches ? 'over' : 'side'" [fixedInViewport]="mobileQuery.matches" fixedTopGap="56"
-            position='end' [opened]="mobileQuery.matches ? false : false">
-
-            <mat-nav-list>
-                <h3 mat-subheader>Actions</h3>
-            </mat-nav-list>
+                     position='end' [opened]="mobileQuery.matches ? false : false">
+            <mat-list>
+                <span dnd-sortable-container [dropZones]="['boxers-zone']" [sortableData]="prioritiesOrder">
+                    <mat-list-item disableRipple="true" *ngFor="let priority of prioritiesOrder;let i = index" title="deplacer" dnd-sortable
+                                   [sortableIndex]="i" (onDropSuccess)="updatePrioritiesOrder()">
+                        <mat-icon color="primary" mat-list-icon class="fa fa-inbox"></mat-icon>
+                        <p mat-line>{{i+1}} - {{priority.label}}</p>
+                    </mat-list-item>
+                </span>
+            </mat-list>
         </mat-sidenav>
     </mat-sidenav-container>
 </div>
\ No newline at end of file
diff --git a/apps/maarch_entreprise/class/class_business_app_tools_Abstract.php b/apps/maarch_entreprise/class/class_business_app_tools_Abstract.php
index d7c0ee256e3..b901bf3fe8e 100755
--- a/apps/maarch_entreprise/class/class_business_app_tools_Abstract.php
+++ b/apps/maarch_entreprise/class/class_business_app_tools_Abstract.php
@@ -560,7 +560,7 @@ abstract class business_app_tools_Abstract extends Database
         $_SESSION['mail_priorities_color']      = [];
         $_SESSION['default_mail_priority']      = 0;
 
-        $priorities = \Priority\models\PriorityModel::get();
+        $priorities = \Priority\models\PriorityModel::get(['orderBy' => ['"order" NULLS LAST']]);
         $i = 0;
         foreach ($priorities as $priority) {
             $_SESSION['mail_priorities'][$i] = $priority['label'];
diff --git a/apps/maarch_entreprise/js/angular/app/administration/priorities-administration.component.ts b/apps/maarch_entreprise/js/angular/app/administration/priorities-administration.component.ts
index 0ee7d78c609..d618710e6d2 100644
--- a/apps/maarch_entreprise/js/angular/app/administration/priorities-administration.component.ts
+++ b/apps/maarch_entreprise/js/angular/app/administration/priorities-administration.component.ts
@@ -3,7 +3,7 @@ import { MediaMatcher } from '@angular/cdk/layout';
 import { HttpClient } from '@angular/common/http';
 import { LANG } from '../translate.component';
 import { NotificationService } from '../notification.service';
-import { MatPaginator, MatTableDataSource, MatSort } from '@angular/material';
+import {MatPaginator, MatTableDataSource, MatSort } from '@angular/material';
 
 declare function $j(selector: any): any;
 
@@ -23,9 +23,11 @@ export class PrioritiesAdministrationComponent implements OnInit {
     loading         : boolean   = false;
 
     priorities      : any[]     = [];
+    prioritiesOrder : any[]     = [];
     dataSource      : any;
     displayedColumns            = ['label', 'delays', 'working_days', 'default_priority', 'actions'];
 
+
     @ViewChild(MatPaginator) paginator: MatPaginator;
     @ViewChild(MatSort) sort: MatSort;
     applyFilter(filterValue: string) {
@@ -53,6 +55,12 @@ export class PrioritiesAdministrationComponent implements OnInit {
             .subscribe((data: any) => {
                 this.priorities = data["priorities"];
                 this.loading = false;
+                this.http.get(this.coreUrl + "rest/sortedPriorities")
+                    .subscribe((data: any) => {
+                        this.prioritiesOrder = data['priotities'];
+                    }, () => {
+                        location.href = "index.php";
+                    });
                 setTimeout(() => {
                     this.dataSource = new MatTableDataSource(this.priorities);
                     this.dataSource.paginator = this.paginator;
@@ -79,4 +87,14 @@ export class PrioritiesAdministrationComponent implements OnInit {
                 })
         }
     }
+
+    updatePrioritiesOrder() {
+        this.http.put(this.coreUrl + "rest/sortedPriorities", this.prioritiesOrder)
+            .subscribe((data: any) => {
+                this.prioritiesOrder = data['priorities'];
+                this.notify.success(this.lang.modificationSaved);
+            }, (err) => {
+                this.notify.error(err.error.errors);
+            });
+    }
 }
diff --git a/rest/index.php b/rest/index.php
index 2ab3fdbff25..8fd578d8236 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -228,6 +228,8 @@ $app->post('/priorities', \Priority\controllers\PriorityController::class . ':cr
 $app->get('/priorities/{id}', \Priority\controllers\PriorityController::class . ':getById');
 $app->put('/priorities/{id}', \Priority\controllers\PriorityController::class . ':update');
 $app->delete('/priorities/{id}', \Priority\controllers\PriorityController::class . ':delete');
+$app->get('/sortedPriorities', \Priority\controllers\PriorityController::class . ':getSorted');
+$app->put('/sortedPriorities', \Priority\controllers\PriorityController::class . ':updateSort');
 
 //Reports
 $app->get('/reports/groups', \Report\controllers\ReportController::class . ':getGroups');
diff --git a/sql/data_fr.sql b/sql/data_fr.sql
index c475e2cb151..edcccbe7bd3 100755
--- a/sql/data_fr.sql
+++ b/sql/data_fr.sql
@@ -1697,10 +1697,10 @@ Select setval('templates_seq', (select max(template_id)+1 from templates), false
 
 /* PRIORITIES */
 TRUNCATE TABLE priorities;
-INSERT INTO priorities (id, label, color, working_days, delays, default_priority) VALUES ('poiuytre1357nbvc', 'Normal', '#009dc5', TRUE, null, TRUE);
-INSERT INTO priorities (id, label, color, working_days, delays, default_priority) VALUES ('poiuytre1379nbvc', 'Urgent', '#ffa500', TRUE, 8, FALSE);
-INSERT INTO priorities (id, label, color, working_days, delays, default_priority) VALUES ('poiuytre1391nbvc', 'Très urgent', '#ff0000', TRUE, 4, FALSE);
-INSERT INTO priorities (id, label, color, working_days, delays, default_priority) VALUES ('poiuytre1313nbvc', 'SVA/SVR', '#ffa500', TRUE, null, FALSE);
+INSERT INTO priorities (id, label, color, working_days, delays, default_priority, "order") VALUES ('poiuytre1357nbvc', 'Normal', '#009dc5', TRUE, null, TRUE, 1);
+INSERT INTO priorities (id, label, color, working_days, delays, default_priority, "order") VALUES ('poiuytre1379nbvc', 'Urgent', '#ffa500', TRUE, 8, FALSE, 2);
+INSERT INTO priorities (id, label, color, working_days, delays, default_priority, "order") VALUES ('poiuytre1391nbvc', 'Très urgent', '#ff0000', TRUE, 4, FALSE, 3);
+INSERT INTO priorities (id, label, color, working_days, delays, default_priority, "order") VALUES ('poiuytre1313nbvc', 'SVA/SVR', '#ffa500', TRUE, null, FALSE, 4);
 
 ------------
 --NOTIFICATIONS
diff --git a/sql/develop.sql b/sql/develop.sql
index ff7d476073a..4e1f7fe999d 100755
--- a/sql/develop.sql
+++ b/sql/develop.sql
@@ -23,6 +23,7 @@ CREATE TABLE priorities
   working_days boolean NOT NULL,
   delays integer,
   default_priority boolean NOT NULL DEFAULT FALSE,
+  order integer,
   CONSTRAINT priorities_pkey PRIMARY KEY (id)
 )
 WITH (OIDS=FALSE);
diff --git a/sql/structure.sql b/sql/structure.sql
index 0b538f4c8d0..5257d305d98 100755
--- a/sql/structure.sql
+++ b/sql/structure.sql
@@ -1981,6 +1981,7 @@ CREATE TABLE priorities
   working_days boolean NOT NULL,
   delays integer,
   default_priority boolean NOT NULL DEFAULT FALSE,
+  order integer,
   CONSTRAINT priorities_pkey PRIMARY KEY (id)
 )
 WITH (OIDS=FALSE);
diff --git a/src/app/basket/controllers/BasketController.php b/src/app/basket/controllers/BasketController.php
index 916fd41ecb5..8ffe4a05f15 100644
--- a/src/app/basket/controllers/BasketController.php
+++ b/src/app/basket/controllers/BasketController.php
@@ -180,11 +180,6 @@ class BasketController
             return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
         }
 
-        $theBasket = BasketModel::getById(['id' => $aArgs['id'], 'select' => ['basket_order']]);
-        if (empty($theBasket)) {
-            return $response->withStatus(400)->withJson(['errors' => 'Basket not found']);
-        }
-
         $data = $request->getParams();
 
         foreach ($data as $key => $basketToUpdate) {
diff --git a/src/app/priority/controllers/PriorityController.php b/src/app/priority/controllers/PriorityController.php
index 880ab5e60f0..d355e7e7ff6 100644
--- a/src/app/priority/controllers/PriorityController.php
+++ b/src/app/priority/controllers/PriorityController.php
@@ -116,4 +116,49 @@ class PriorityController
 
         return $response->withJson(['priorities' => PriorityModel::get()]);
     }
+
+    public function getSorted(Request $request, Response $response)
+    {
+        if (!ServiceModel::hasService(['id' => 'admin_priorities', 'userId' => $GLOBALS['userId'], 'location' => 'apps', 'type' => 'admin'])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
+        }
+
+        $priorities = PriorityModel::get([
+            'select'    => ['id', 'label', '"order"'],
+            'orderBy'   => ['"order" NULLS LAST']
+        ]);
+
+        return $response->withJson(['priotities' => $priorities]);
+    }
+
+    public function updateSort(Request $request, Response $response)
+    {
+        if (!ServiceModel::hasService(['id' => 'admin_priorities', 'userId' => $GLOBALS['userId'], 'location' => 'apps', 'type' => 'admin'])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']);
+        }
+
+        $data = $request->getParams();
+
+        foreach ($data as $key => $priorityToUpdate) {
+            if ($key != $priorityToUpdate['order']) {
+                PriorityModel::updateOrder(['id' => $priorityToUpdate['id'], 'order' => $key]);
+            }
+        }
+
+        HistoryController::add([
+            'tableName' => 'priorities',
+            'recordId'  => $GLOBALS['userId'],
+            'eventType' => 'UP',
+            'info'      => _PRIORITY_SORT_MODIFICATION,
+            'moduleId'  => 'priority',
+            'eventId'   => 'priorityModification',
+        ]);
+
+        $priorities = PriorityModel::get([
+            'select'    => ['id', 'label', '"order"'],
+            'orderBy'   => ['"order" NULLS LAST']
+        ]);
+
+        return $response->withJson(['priorities' => $priorities]);
+    }
 }
diff --git a/src/app/priority/models/PriorityModelAbstract.php b/src/app/priority/models/PriorityModelAbstract.php
index ff7873800ea..fccccffac03 100644
--- a/src/app/priority/models/PriorityModelAbstract.php
+++ b/src/app/priority/models/PriorityModelAbstract.php
@@ -20,11 +20,14 @@ abstract class PriorityModelAbstract
 {
     public static function get(array $aArgs = [])
     {
-        ValidatorModel::arrayType($aArgs, ['select']);
+        ValidatorModel::arrayType($aArgs, ['select', 'where', 'data', 'orderBy']);
 
         $aReturn = DatabaseModel::select([
             'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
             'table'     => ['priorities'],
+            'where'     => $aArgs['where'],
+            'data'      => $aArgs['data'],
+            'order_by'  => $aArgs['orderBy']
         ]);
 
         return $aReturn;
@@ -96,6 +99,24 @@ abstract class PriorityModelAbstract
         return true;
     }
 
+    public static function updateOrder(array $aArgs)
+    {
+        ValidatorModel::notEmpty($aArgs, ['id']);
+        ValidatorModel::stringType($aArgs, ['id']);
+        ValidatorModel::intVal($aArgs, ['order']);
+
+        DatabaseModel::update([
+            'table'     => 'priorities',
+            'set'       => [
+                '"order"'  => $aArgs['order']
+            ],
+            'where'     => ['id = ?'],
+            'data'      => [$aArgs['id']]
+        ]);
+
+        return true;
+    }
+
     public static function resetDefaultPriority()
     {
         DatabaseModel::update([
diff --git a/src/core/lang/lang-en.php b/src/core/lang/lang-en.php
index 4a8154a4842..3d608d29a4a 100644
--- a/src/core/lang/lang-en.php
+++ b/src/core/lang/lang-en.php
@@ -57,6 +57,7 @@ define('_PARAMETER_SUPPRESSION', 'Parameter suppression');
 define('_PRIORITY_CREATION', 'Priority creation');
 define('_PRIORITY_MODIFICATION', 'Priority modification');
 define('_PRIORITY_SUPPRESSION', 'Priority suppression');
+define('_PRIORITY_SORT_MODIFICATION', 'Priorities order modification');
 define('_REPORT_MODIFICATION', 'Report modification');
 define('_STATUS_ADDED', 'Statut added');
 define('_STATUS_DELETED', 'Statut deleted');
diff --git a/src/core/lang/lang-fr.php b/src/core/lang/lang-fr.php
index af87aabdd16..fe99a6545a9 100644
--- a/src/core/lang/lang-fr.php
+++ b/src/core/lang/lang-fr.php
@@ -57,6 +57,7 @@ define('_PARAMETER_SUPPRESSION', 'Suppression paramètre');
 define('_PRIORITY_CREATION', 'Création priorité');
 define('_PRIORITY_MODIFICATION', 'Modification priorité');
 define('_PRIORITY_SUPPRESSION', 'Suppression priorité');
+define('_PRIORITY_SORT_MODIFICATION', 'Modification ordre priorités');
 define('_REPORT_MODIFICATION', 'Modification états et édition');
 define('_STATUS_ADDED', 'Statut ajouté');
 define('_STATUS_DELETED', 'Statut supprimé');
-- 
GitLab