From 8580e997f1256afd5e3d0374cee93be5e9b93eef Mon Sep 17 00:00:00 2001 From: "florian.azizian" <florian.azizian@maarch.org> Date: Fri, 6 Dec 2019 11:37:00 +0100 Subject: [PATCH] FEAT #12510 TIME 3 admin contact parameters --- rest/index.php | 4 +- .../contact/controllers/ContactController.php | 48 ++++++-- .../ContactCustomFieldController.php | 2 + .../contact/models/ContactFillingModel.php | 3 - .../contact/models/ContactParameterModel.php | 104 ++++++++++++++++++ ...acts-filling-administration.component.html | 40 ++++--- ...ntacts-filling-administration.component.ts | 91 +++++---------- src/frontend/lang/lang-fr.ts | 26 ++--- 8 files changed, 206 insertions(+), 112 deletions(-) create mode 100755 src/app/contact/models/ContactParameterModel.php diff --git a/rest/index.php b/rest/index.php index 1d89396000d..5bef194c4d8 100755 --- a/rest/index.php +++ b/rest/index.php @@ -127,8 +127,8 @@ $app->put('/contactsGroups/{id}', \Contact\controllers\ContactGroupController::c $app->delete('/contactsGroups/{id}', \Contact\controllers\ContactGroupController::class . ':delete'); $app->post('/contactsGroups/{id}/contacts', \Contact\controllers\ContactGroupController::class . ':addContacts'); $app->delete('/contactsGroups/{id}/contacts/{contactId}', \Contact\controllers\ContactGroupController::class . ':deleteContact'); -$app->get('/contactsFilling', \Contact\controllers\ContactController::class . ':getFilling'); -$app->put('/contactsFilling', \Contact\controllers\ContactController::class . ':updateFilling'); +$app->get('/contactsParameters', \Contact\controllers\ContactController::class . ':getContactsParameters'); +$app->put('/contactsParameters', \Contact\controllers\ContactController::class . ':updateContactsParameters'); //Convert $app->post('/convertedFile', \Convert\controllers\ConvertPdfController::class . ':convertedFile'); diff --git a/src/app/contact/controllers/ContactController.php b/src/app/contact/controllers/ContactController.php index 099f6568a3d..c7be64de672 100755 --- a/src/app/contact/controllers/ContactController.php +++ b/src/app/contact/controllers/ContactController.php @@ -17,6 +17,7 @@ use Contact\models\ContactCustomFieldListModel; use Contact\models\ContactCustomFieldModel; use Contact\models\ContactFillingModel; use Contact\models\ContactModel; +use Contact\models\ContactParameterModel; use Entity\models\EntityModel; use Group\controllers\PrivilegeController; use History\controllers\HistoryController; @@ -310,37 +311,60 @@ class ContactController return $response->withStatus(204); } - public function getFilling(Request $request, Response $response) + public function getContactsParameters(Request $request, Response $response) { if (!PrivilegeController::hasPrivilege(['privilegeId' => 'admin_contacts', 'userId' => $GLOBALS['id']])) { return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']); } $contactsFilling = ContactFillingModel::get(); - $contactsFilling['rating_columns'] = json_decode($contactsFilling['rating_columns']); + $contactParameters = ContactParameterModel::get(['select' => ['*']]); + foreach ($contactParameters as $key => $parameter) { + if (strpos($parameter['identifier'], 'contactCustomField_') !== false) { + $contactCustomId = str_replace("contactCustomField_", "", $parameter['identifier']); + $customField = ContactCustomFieldListModel::getById(['select' => ['label'], 'id' => $contactCustomId]); + $contactParameters[$key]['label'] = $customField['label']; + } else { + $contactParameters[$key]['label'] = null; + } + } - return $response->withJson(['contactsFilling' => $contactsFilling]); + return $response->withJson(['contactsFilling' => $contactsFilling, 'contactsParameters' => $contactParameters]); } - public function updateFilling(Request $request, Response $response) + public function updateContactsParameters(Request $request, Response $response) { if (!PrivilegeController::hasPrivilege(['privilegeId' => 'admin_contacts', 'userId' => $GLOBALS['id']])) { return $response->withStatus(403)->withJson(['errors' => 'Service forbidden']); } $data = $request->getParams(); - $check = Validator::boolType()->validate($data['enable']); - $check = $check && Validator::arrayType()->validate($data['rating_columns']); - $check = $check && Validator::intVal()->notEmpty()->validate($data['first_threshold']) && $data['first_threshold'] > 0 && $data['first_threshold'] < 99; - $check = $check && Validator::intVal()->notEmpty()->validate($data['second_threshold']) && $data['second_threshold'] > 1 && $data['second_threshold'] < 100; - $check = $check && $data['first_threshold'] < $data['second_threshold']; + $check = Validator::arrayType()->validate($data['contactsParameters']); + $check = $check && Validator::arrayType()->validate($data['contactsFilling']); + $check = $check && Validator::boolType()->validate($data['contactsFilling']['enable']); + $check = $check && Validator::intVal()->notEmpty()->validate($data['contactsFilling']['first_threshold']) && $data['contactsFilling']['first_threshold'] > 0 && $data['contactsFilling']['first_threshold'] < 99; + $check = $check && Validator::intVal()->notEmpty()->validate($data['contactsFilling']['second_threshold']) && $data['contactsFilling']['second_threshold'] > 1 && $data['contactsFilling']['second_threshold'] < 100; + $check = $check && $data['contactsFilling']['first_threshold'] < $data['contactsFilling']['second_threshold']; if (!$check) { return $response->withStatus(400)->withJson(['errors' => 'Bad Request']); } - $data['rating_columns'] = json_encode($data['rating_columns']); - - ContactFillingModel::update($data); + foreach ($data['contactsParameters'] as $contactParameter) { + unset($contactParameter['label']); + ContactParameterModel::update([ + 'set' => [ + 'id' => $contactParameter['id'], + 'mandatory' => empty($contactParameter['mandatory']) ? 'false' : 'true', + 'filling' => empty($contactParameter['filling']) ? 'false' : 'true', + 'searchable' => empty($contactParameter['searchable']) ? 'false' : 'true', + 'displayable' => empty($contactParameter['displayable']) ? 'false' : 'true', + ], + 'where' => ['id = ?'], + 'data' => [$contactParameter['id']] + ]); + } + + ContactFillingModel::update($data['contactsFilling']); return $response->withJson(['success' => 'success']); } diff --git a/src/app/contact/controllers/ContactCustomFieldController.php b/src/app/contact/controllers/ContactCustomFieldController.php index f27ede076cb..47a014010d4 100644 --- a/src/app/contact/controllers/ContactCustomFieldController.php +++ b/src/app/contact/controllers/ContactCustomFieldController.php @@ -15,6 +15,7 @@ namespace Contact\controllers; use Contact\models\ContactCustomFieldListModel; use Contact\models\ContactCustomFieldModel; +use Contact\models\ContactParameterModel; use Group\controllers\PrivilegeController; use History\controllers\HistoryController; use Respect\Validation\Validator; @@ -139,6 +140,7 @@ class ContactCustomFieldController $field = ContactCustomFieldListModel::getById(['select' => ['label'], 'id' => $args['id']]); ContactCustomFieldModel::delete(['where' => ['custom_field_id = ?'], 'data' => [$args['id']]]); + ContactParameterModel::delete(['where' => ['identifier = ?'], 'data' => ['contactCustomField_' . $args['id']]]); ContactCustomFieldListModel::delete([ 'where' => ['id = ?'], diff --git a/src/app/contact/models/ContactFillingModel.php b/src/app/contact/models/ContactFillingModel.php index 9d505538b3b..2fcf0570b55 100755 --- a/src/app/contact/models/ContactFillingModel.php +++ b/src/app/contact/models/ContactFillingModel.php @@ -34,9 +34,7 @@ class ContactFillingModel public static function update(array $aArgs) { - ValidatorModel::notEmpty($aArgs, ['rating_columns']); ValidatorModel::boolType($aArgs, ['enable']); - ValidatorModel::stringType($aArgs, ['rating_columns']); ValidatorModel::intVal($aArgs, ['first_threshold', 'second_threshold']); $aArgs['enable'] = $aArgs['enable'] ? 'true' : 'false'; @@ -45,7 +43,6 @@ class ContactFillingModel 'table' => 'contacts_filling', 'set' => [ 'enable' => $aArgs['enable'], - 'rating_columns' => $aArgs['rating_columns'], 'first_threshold' => $aArgs['first_threshold'], 'second_threshold' => $aArgs['second_threshold'] ], diff --git a/src/app/contact/models/ContactParameterModel.php b/src/app/contact/models/ContactParameterModel.php new file mode 100755 index 00000000000..3f755c7e05d --- /dev/null +++ b/src/app/contact/models/ContactParameterModel.php @@ -0,0 +1,104 @@ +<?php + +/** +* Copyright Maarch since 2008 under licence GPLv3. +* See LICENCE.txt file at the root folder for more details. +* This file is part of Maarch software. +* +*/ + +/** +* @brief Contact Parameter Model +* @author dev@maarch.org +*/ + +namespace Contact\models; + +use SrcCore\models\DatabaseModel; +use SrcCore\models\ValidatorModel; + +class ContactParameterModel +{ + public static function get(array $args) + { + ValidatorModel::notEmpty($args, ['select']); + ValidatorModel::arrayType($args, ['select', 'where', 'data', 'orderBy']); + ValidatorModel::intType($args, ['limit']); + + $contacts = DatabaseModel::select([ + 'select' => $args['select'], + 'table' => ['contacts_parameters'], + 'where' => empty($args['where']) ? [] : $args['where'], + 'data' => empty($args['data']) ? [] : $args['data'], + 'order_by' => empty($args['orderBy']) ? [] : $args['orderBy'], + 'limit' => empty($args['limit']) ? 0 : $args['limit'] + ]); + + return $contacts; + } + + public static function getById(array $args) + { + ValidatorModel::notEmpty($args, ['id', 'select']); + ValidatorModel::intVal($args, ['id']); + ValidatorModel::arrayType($args, ['select']); + + $contact = DatabaseModel::select([ + 'select' => $args['select'], + 'table' => ['contacts_parameters'], + 'where' => ['id = ?'], + 'data' => [$args['id']], + ]); + + if (empty($contact[0])) { + return []; + } + + return $contact[0]; + } + + public static function create(array $args) + { + ValidatorModel::notEmpty($args, ['creator']); + ValidatorModel::intVal($args, ['creator']); + + $nextSequenceId = DatabaseModel::getNextSequenceValue(['sequenceId' => 'contacts_parameters_id_seq']); + $args['id'] = $nextSequenceId; + + DatabaseModel::insert([ + 'table' => 'contacts_parameters', + 'columnsValues' => $args + ]); + + return $nextSequenceId; + } + + public static function update(array $args) + { + ValidatorModel::notEmpty($args, ['set', 'where', 'data']); + ValidatorModel::arrayType($args, ['set', 'where', 'data']); + + DatabaseModel::update([ + 'table' => 'contacts_parameters', + 'set' => $args['set'], + 'where' => $args['where'], + 'data' => $args['data'] + ]); + + return true; + } + + public static function delete(array $args) + { + ValidatorModel::notEmpty($args, ['where', 'data']); + ValidatorModel::arrayType($args, ['where', 'data']); + + DatabaseModel::delete([ + 'table' => 'contacts_parameters', + 'where' => $args['where'], + 'data' => $args['data'] + ]); + + return true; + } +} diff --git a/src/frontend/app/administration/contact/contacts-filling-administration.component.html b/src/frontend/app/administration/contact/contacts-filling-administration.component.html index ef75c9f2f3d..78866c9805d 100755 --- a/src/frontend/app/administration/contact/contacts-filling-administration.component.html +++ b/src/frontend/app/administration/contact/contacts-filling-administration.component.html @@ -56,19 +56,33 @@ </mat-card> </div> </div> - <div class="row" style="margin-top:10px;"> - <div class="col-md-12 col-xs-12"> - <mat-tab-group> - <mat-tab label="{{lang.contactsFillingCriteria}}"> - <div class="row" *ngFor="let fillingColumnSelected of fillingColumnsSelected"> - <div class="col-md-3 col-sm-6 col-xs-12" *ngFor="let fillingColumn of fillingColumns;let i = index" style="padding-bottom: 5px;"> - <mat-slide-toggle color="primary" name="{{fillingColumn}}" (change)="addCriteria($event,fillingColumn)" [checked]="fillingColumnsState[i]">{{lang['contactsFilling_'+fillingColumn]}}</mat-slide-toggle> - </div> - </div> - </mat-tab> - </mat-tab-group> - </div> - </div> + <mat-table #table [dataSource]="dataSource" matSort matSortActive="identifier" matSortDirection="asc"> + <ng-container matColumnDef="identifier"> + <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.label}}</mat-header-cell> + <mat-cell *matCellDef="let element"> + <div *ngIf="!element.label">{{lang['contactsFilling_'+element.identifier]}}</div> + <div *ngIf="element.label">{{element.label}}</div> + </mat-cell> + </ng-container> + <ng-container matColumnDef="mandatory"> + <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.mandatory}}</mat-header-cell> + <mat-cell *matCellDef="let element"><mat-slide-toggle style="margin-left:11px" color="primary" (change)="addCriteria($event, element, 'mandatory')" [checked]="element.mandatory"></mat-slide-toggle></mat-cell> + </ng-container> + <ng-container matColumnDef="filling"> + <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.contactsFillingCriteria}}</mat-header-cell> + <mat-cell *matCellDef="let element"> <mat-slide-toggle style="margin-left:11px" color="primary" (change)="addCriteria($event, element, 'filling')" [checked]="element.filling"></mat-slide-toggle> </mat-cell> + </ng-container> + <ng-container matColumnDef="displayable"> + <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.autocompletionSearchable}}</mat-header-cell> + <mat-cell *matCellDef="let element"> <mat-slide-toggle style="margin-left:11px" color="primary" (change)="addCriteria($event, element, 'searchable')" [checked]="element.searchable"></mat-slide-toggle> </mat-cell> + </ng-container> + <ng-container matColumnDef="searchable"> + <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.autocompletionDisplayable}}</mat-header-cell> + <mat-cell *matCellDef="let element"> <mat-slide-toggle style="margin-left:11px" color="primary" (change)="addCriteria($event, element, 'displayable')" [checked]="element.displayable"></mat-slide-toggle> </mat-cell> + </ng-container> + <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> + <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row> + </mat-table> </mat-card> </mat-sidenav-content> </mat-sidenav-container> diff --git a/src/frontend/app/administration/contact/contacts-filling-administration.component.ts b/src/frontend/app/administration/contact/contacts-filling-administration.component.ts index 4c9d261d19c..5327fc15a64 100755 --- a/src/frontend/app/administration/contact/contacts-filling-administration.component.ts +++ b/src/frontend/app/administration/contact/contacts-filling-administration.component.ts @@ -5,6 +5,7 @@ import { NotificationService } from '../../notification.service'; import { HeaderService } from '../../../service/header.service'; import { MatSidenav } from '@angular/material/sidenav'; import { AppService } from '../../../service/app.service'; +import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material'; declare function $j(selector: any): any; @@ -20,68 +21,28 @@ export class ContactsFillingAdministrationComponent implements OnInit { lang: any = LANG; contactsFilling: any = { - 'rating_columns': [], 'enable': false, 'first_threshold': '33', 'second_threshold': '66', }; + contactsParameters: any = []; + arrRatingColumns: String[] = []; fillingColor = { 'first_threshold': '#ff9e9e', 'second_threshold': '#f6cd81', 'third_threshold': '#ccffcc', }; - fillingColumns = [ - 'address_num', - 'address_postal_code', - 'title', - 'function', - 'address_street', - 'address_town', - 'lastname', - 'departement', - 'occupancy', - 'address_country', - 'firstname', - 'phone', - 'address_complement', - 'society', - 'society_short', - 'email', - ]; - fillingColumnsState = [ - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - ]; - fillingColumnsSelected = ['society']; loading: boolean = false; + dataSource = new MatTableDataSource(this.contactsParameters); + displayedColumns = ['identifier', 'mandatory', 'filling', 'displayable', 'searchable']; + + @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator; + @ViewChild(MatSort, { static: false }) sort: MatSort; + constructor( public http: HttpClient, private notify: NotificationService, @@ -94,32 +55,30 @@ export class ContactsFillingAdministrationComponent implements OnInit { this.loading = true; - this.headerService.setHeader(this.lang.contactsFillingAdministration); + this.headerService.setHeader(this.lang.contactsParameters); window['MainHeaderComponent'].setSnav(this.sidenavLeft); window['MainHeaderComponent'].setSnavRight(null); - this.http.get('../../rest/contactsFilling') + this.http.get('../../rest/contactsParameters') .subscribe((data: any) => { this.contactsFilling = data.contactsFilling; - if (this.contactsFilling.rating_columns.length > 0) { - this.contactsFilling.rating_columns.forEach((col: any) => { - let i = this.fillingColumns.indexOf(col); - this.fillingColumnsState[i] = true; - this.arrRatingColumns.push(col); - }); - } + this.contactsParameters = data.contactsParameters; this.loading = false; + setTimeout(() => { + this.dataSource = new MatTableDataSource(this.contactsParameters); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + }, 0); }); } - addCriteria(event: any, criteria: String) { - if (event.checked) { - this.arrRatingColumns.push(criteria); - } else { - this.arrRatingColumns.splice(this.arrRatingColumns.indexOf(criteria), 1); - } - this.contactsFilling.rating_columns = this.arrRatingColumns; - this.contactsFilling.rating_columns.length == 0 ? this.contactsFilling.enable = false : this.contactsFilling.enable = true; + addCriteria(event: any, criteria: any, type: string) { + this.contactsParameters.forEach((col: any, i: number) => { + if (col.id == criteria.id) { + this.contactsParameters[i][type] = event.checked; + } + }); + this.onSubmit(); } @@ -127,7 +86,7 @@ export class ContactsFillingAdministrationComponent implements OnInit { if (this.contactsFilling.first_threshold >= this.contactsFilling.second_threshold) { this.contactsFilling.second_threshold = this.contactsFilling.first_threshold + 1; } - this.http.put('../../rest/contactsFilling', this.contactsFilling) + this.http.put('../../rest/contactsParameters', {'contactsFilling': this.contactsFilling, 'contactsParameters': this.contactsParameters}) .subscribe(() => { this.notify.success(this.lang.contactsFillingUpdated); diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts index c9dd9c62d68..063250a56d8 100755 --- a/src/frontend/lang/lang-fr.ts +++ b/src/frontend/lang/lang-fr.ts @@ -200,31 +200,22 @@ export const LANG_FR = { "contactGroupList" : "Liste des groupements", "contactInfo" : "Fiche contact", "contacts" : "Contact(s)", - "contactsFilling_address_complement" : "Tour, bâtiment, immeuble, résidence", + "contactsFilling_address_additional1" : "Tour, bâtiment, immeuble, résidence", "contactsFilling_address_country" : "Pays", - "contactsFilling_address_num" : "Numéro de rue", - "contactsFilling_address_postal_code" : "Code postal", + "contactsFilling_address_number" : "Numéro de rue", + "contactsFilling_address_postcode" : "Code postal", "contactsFilling_address_street" : "Voie", "contactsFilling_address_town" : "Ville", - "contactsFilling_contact_firstname" : "Prénom (contact physique)", - "contactsFilling_contact_function" : "Fonction (contact physique)", - "contactsFilling_contact_lastname" : "Nom (contact physique)", - "contactsFilling_contact_other_data" : "Informations complémentaires (contact physique)", - "contactsFilling_contact_title" : "Civilité (contact physique)", - "contactsFilling_departement" : "Service", + "contactsFilling_department" : "Service", "contactsFilling_email" : "Courriel", "contactsFilling_firstname" : "Prénom", "contactsFilling_function" : "Fonction", "contactsFilling_lastname" : "Nom", - "contactsFilling_occupancy" : "N° app, étage, escalier", + "contactsFilling_address_additional2" : "N° app, étage, escalier", "contactsFilling_other_data" : "Informations complémentaires", "contactsFilling_phone" : "Téléphone", - "contactsFilling_salutation_footer" : "Formule de politesse (fin de courrier)", - "contactsFilling_salutation_header" : "Formule de politesse (début de courrier)", - "contactsFilling_society_short" : "Sigle de la structure", - "contactsFilling_society" : "Structure", - "contactsFilling_title" : "Civilité", - "contactsFilling_website" : "Site internet", + "contactsFilling_company" : "Société", + "contactsFilling_civility" : "Civilité", "contactsFillingAdministration" : "Complétude des informations contacts", "contactsFillingCriteria" : "Critères de complétude", "contactsFillingStep1" : "Premier palier", @@ -1366,4 +1357,7 @@ export const LANG_FR = { "newVersion": "Nouvelle version", "information": "Information", "mustEditDocument": "Vous devez <b>éditer</b> votre document afin de pouvoir <b>valider</b> vos modifications.", + "autocompletionSearchable": "Recherchable dans l'autocomplétion", + "autocompletionDisplayable": "Affichable dans l'autocompletion", + "contactsParameters": "Paramétrage des contacts", }; -- GitLab