From 90d763babca6865d88a66e6fce2ac80541ac418f Mon Sep 17 00:00:00 2001 From: Guillaume Heurtier <guillaume.heurtier@maarch.org> Date: Tue, 1 Sep 2020 17:24:38 +0200 Subject: [PATCH] FEAT #14004 TIME 3:45 begin ar reception front --- .../controllers/RegisteredMailController.php | 14 ++- .../administration-routing.module.ts | 2 + .../administration/administration.module.ts | 2 + .../acknowledgement-reception.component.html | 68 +++++++++++++ .../acknowledgement-reception.component.ts | 95 +++++++++++++++++++ .../registered-mail-list.component.ts | 5 + src/lang/lang-en.json | 14 ++- src/lang/lang-fr.json | 14 ++- 8 files changed, 207 insertions(+), 7 deletions(-) create mode 100644 src/frontend/app/administration/registered-mail/acknowledgement-reception/acknowledgement-reception.component.html create mode 100644 src/frontend/app/administration/registered-mail/acknowledgement-reception/acknowledgement-reception.component.ts diff --git a/src/app/registeredMail/controllers/RegisteredMailController.php b/src/app/registeredMail/controllers/RegisteredMailController.php index ae7b541fd65..3446eb4a240 100644 --- a/src/app/registeredMail/controllers/RegisteredMailController.php +++ b/src/app/registeredMail/controllers/RegisteredMailController.php @@ -14,6 +14,7 @@ namespace RegisteredMail\controllers; use Com\Tecnick\Barcode\Barcode; +use Parameter\models\ParameterModel; use Contact\controllers\ContactController; use Contact\models\ContactModel; use RegisteredMail\models\RegisteredMailModel; @@ -127,8 +128,6 @@ class RegisteredMailController return $response->withStatus(400)->withJson(['errors' => 'Body number is empty or not a string']); } elseif (!preg_match("/(2C|2D|RW) ([0-9]{3} [0-9]{3} [0-9]{4}) ([0-9])/", $body['number'])) { return $response->withStatus(400)->withJson(['errors' => 'Body number is not valid']); - } elseif (!empty($body['status']) && !Validator::stringType()->length(1, 10)->validate($body['status'])) { - return $response->withStatus(400)->withJson(['errors' => 'Body status is not a string']); } $number = substr($body['number'], 3, 12); @@ -142,9 +141,12 @@ class RegisteredMailController if (empty($registeredMail)) { return $response->withStatus(400)->withJson(['errors' => 'Registered mail number not found']); } + $registeredMail = $registeredMail[0]; if ($body['type'] == 'distributed') { $set = ['received_date' => 'CURRENT_TIMESTAMP']; + $status = ParameterModel::getById(['select' => ['param_value_string'], 'id' => 'registeredMailDistributedStatus']); + $status = $status['param_value_string']; } else { if (!Validator::stringType()->notEmpty()->validate($body['returnReason'])) { return $response->withStatus(400)->withJson(['errors' => 'Body returnReason is empty or not a string']); @@ -154,11 +156,13 @@ class RegisteredMailController $receivedDate = new \DateTime($body['receivedDate']); $today = new \DateTime(); $today->setTime(00, 00, 00); - if ($receivedDate < $today) { + if ($receivedDate > $today) { return ['errors' => "Body receivedDate is not a valid date"]; } $set = ['received_date' => $body['receivedDate'], 'return_reason' => $body['returnReason'], 'return_reason_other' => $body['returnReasonOther'] ?? null]; + $status = ParameterModel::getById(['select' => ['param_value_string'], 'id' => 'registeredMailNotDistributedStatus']); + $status = $status['param_value_string']; } RegisteredMailModel::update([ @@ -166,9 +170,9 @@ class RegisteredMailController 'where' => ['id = ?'], 'data' => [$registeredMail['id']] ]); - if (!empty($body['status'])) { + if (!empty($status)) { ResModel::update([ - 'set' => ['status' => $body['status']], + 'set' => ['status' => $status], 'where' => ['res_id = ?'], 'data' => [$registeredMail['res_id']] ]); diff --git a/src/frontend/app/administration/administration-routing.module.ts b/src/frontend/app/administration/administration-routing.module.ts index 5a0d0a34a39..0fa1fbe0d73 100755 --- a/src/frontend/app/administration/administration-routing.module.ts +++ b/src/frontend/app/administration/administration-routing.module.ts @@ -53,6 +53,7 @@ import { IssuingSiteListComponent } from './registered-mail/issuing-site/issuing import { IssuingSiteComponent } from './registered-mail/issuing-site/issuing-site.component'; import { RegisteredMailListComponent } from './registered-mail/registered-mail-list.component'; import { RegisteredMailComponent } from './registered-mail/registered-mail.component'; +import {AcknowledgementReceptionComponent} from './registered-mail/acknowledgement-reception/acknowledgement-reception.component'; @NgModule({ imports: [ @@ -122,6 +123,7 @@ import { RegisteredMailComponent } from './registered-mail/registered-mail.compo { path: 'alfresco/new', canActivate: [AppGuard], component: AlfrescoAdministrationComponent }, { path: 'alfresco/:id', canActivate: [AppGuard], component: AlfrescoAdministrationComponent }, { path: 'registeredMails', canActivate: [AppGuard], component: RegisteredMailListComponent }, + { path: 'registeredMails/acknowledgement', canActivate: [AppGuard], component: AcknowledgementReceptionComponent }, { path: 'registeredMails/new', canActivate: [AppGuard], component: RegisteredMailComponent }, { path: 'registeredMails/:id', canActivate: [AppGuard], component: RegisteredMailComponent }, { path: 'issuingSites', canActivate: [AppGuard], component: IssuingSiteListComponent }, diff --git a/src/frontend/app/administration/administration.module.ts b/src/frontend/app/administration/administration.module.ts index 4afcf9bee0c..b221059a406 100755 --- a/src/frontend/app/administration/administration.module.ts +++ b/src/frontend/app/administration/administration.module.ts @@ -75,6 +75,7 @@ import { RegisteredMailComponent } from './registered-mail/registered-mail.compo import { IssuingSiteListComponent } from './registered-mail/issuing-site/issuing-site-list.component'; import { IssuingSiteComponent } from './registered-mail/issuing-site/issuing-site.component'; import { RegisteredMailListComponent } from './registered-mail/registered-mail-list.component'; +import { AcknowledgementReceptionComponent } from './registered-mail/acknowledgement-reception/acknowledgement-reception.component'; @NgModule({ @@ -158,6 +159,7 @@ import { RegisteredMailListComponent } from './registered-mail/registered-mail-l IssuingSiteListComponent, IssuingSiteComponent, RegisteredMailListComponent, + AcknowledgementReceptionComponent ], entryComponents: [ AccountLinkComponent, diff --git a/src/frontend/app/administration/registered-mail/acknowledgement-reception/acknowledgement-reception.component.html b/src/frontend/app/administration/registered-mail/acknowledgement-reception/acknowledgement-reception.component.html new file mode 100644 index 00000000000..be00b52049c --- /dev/null +++ b/src/frontend/app/administration/registered-mail/acknowledgement-reception/acknowledgement-reception.component.html @@ -0,0 +1,68 @@ +<mat-sidenav-container autosize class="maarch-container"> + <mat-sidenav-content> + <div class="bg-head"> + <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> + <div class="bg-head-title-label"> + <header-left></header-left> + </div> + <div class="bg-head-title-tool"> + <header-right></header-right> + </div> + </div> + <div class="bg-head-content" [class.fullContainer]="appService.getViewMode()"> + </div> + </div> + <div class="container" [class.fullContainer]="appService.getViewMode()"> + <div class="container-content"> + <div *ngIf="loading" style="display:flex;height:100%;"> + <mat-spinner style="margin:auto;"></mat-spinner> + </div> + <mat-card *ngIf="!loading" class="card-app-content"> + <form style="display: contents;" [formGroup]="adminFormGroup"> + <div> + <mat-form-field> + <mat-select [(ngModel)]="type" required placeholder="{{'lang.returnType' | translate}}" formControlName="type"> + <mat-option [value]="'distributed'">{{'lang.registeredMailDistributed' | translate}}</mat-option> + <mat-option [value]="'notDistributed'">{{'lang.registeredMailNotDistributed' | translate}}</mat-option> + </mat-select> + </mat-form-field> + + <mat-form-field> + <mat-label>{{'lang.registeredMailNumber' | translate}}</mat-label> + <input type="text" matInput required (change)="receiveAcknowledgement()" [(ngModel)]="number" formControlName="number"> + </mat-form-field> + + <mat-form-field *ngIf="type === 'notDistributed'" (click)="picker.open()" appearance="outline" style="cursor:pointer;margin-top: 10px;"> + <mat-label>{{'lang.registeredMailReceivedDate' | translate}}</mat-label> + <input matInput [(ngModel)]="receivedDate" [matDatepicker]="picker" + [placeholder]="this.translate.instant('lang.chooseDate')" [max]="today" readonly style="cursor:pointer;" formControlName="receivedDate" required> + <mat-datepicker-toggle matSuffix [for]="picker" *ngIf="!receivedDate"> + </mat-datepicker-toggle> + <mat-datepicker #picker></mat-datepicker> + <button mat-button color="warn" matSuffix mat-icon-button *ngIf="receivedDate" + (click)="$event.stopPropagation();receivedDate = null;" [title]="this.translate.instant('lang.eraseValue')"> + <mat-icon color="warn" class="fa fa-calendar-times"> + </mat-icon> + </button> + </mat-form-field> + + <mat-form-field *ngIf="type === 'notDistributed'" > + <mat-select [(ngModel)]="reason" formControlName="returnReason" placeholder="{{'lang.returnReason' | translate}}" required> + <mat-option value="{{'lang.returnReasonCannotAccess' | translate}}">{{'lang.returnReasonCannotAccess' | translate}}</mat-option> + <mat-option value="{{'lang.returnReasonNotClaimed' | translate}}">{{'lang.returnReasonNotClaimed' | translate}}</mat-option> + <mat-option value="{{'lang.returnReasonRejected' | translate}}">{{'lang.returnReasonRejected' | translate}}</mat-option> + <mat-option value="{{'lang.returnReasonUnknown' | translate}}">{{'lang.returnReasonUnknown' | translate}}</mat-option> + <mat-option value="{{'lang.others' | translate}}">{{'lang.others' | translate}}</mat-option> + </mat-select> + </mat-form-field> + <mat-form-field *ngIf="type === 'notDistributed' && reason === this.translate.instant('lang.others')"> + <mat-label>{{'lang.precise' | translate}}</mat-label> + <input matInput name="returnReasonOther" formControlName="returnReasonOther" [(ngModel)]="reasonOther"> + </mat-form-field> + </div> + </form> + </mat-card> + </div> + </div> + </mat-sidenav-content> +</mat-sidenav-container> diff --git a/src/frontend/app/administration/registered-mail/acknowledgement-reception/acknowledgement-reception.component.ts b/src/frontend/app/administration/registered-mail/acknowledgement-reception/acknowledgement-reception.component.ts new file mode 100644 index 00000000000..782a6171098 --- /dev/null +++ b/src/frontend/app/administration/registered-mail/acknowledgement-reception/acknowledgement-reception.component.ts @@ -0,0 +1,95 @@ +import { Component, OnInit } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import {FormBuilder, FormGroup, ValidatorFn, Validators} from '@angular/forms'; +import {catchError, tap} from 'rxjs/operators'; +import { of } from 'rxjs/internal/observable/of'; +import { NotificationService } from '../../../../service/notification/notification.service'; +import { HeaderService } from '../../../../service/header.service'; +import { FunctionsService } from '../../../../service/functions.service'; +import {AppService} from '../../../../service/app.service'; +import {TranslateService} from '@ngx-translate/core'; +import {ActivatedRoute} from '@angular/router'; + +@Component({ + selector: 'app-acknowledgement-reception', + templateUrl: 'acknowledgement-reception.component.html' +}) + +export class AcknowledgementReceptionComponent implements OnInit { + + loading: boolean = false; + + type: any; + number: any; + receivedDate: any; + reason: any; + reasonOther: any; + + today: Date = new Date(); + + adminFormGroup: FormGroup; + + constructor( + public http: HttpClient, + private notify: NotificationService, + private headerService: HeaderService, + public functions: FunctionsService, + public appService: AppService, + public translate: TranslateService, + private _formBuilder: FormBuilder, + private route: ActivatedRoute + ) { + + } + + ngOnInit() { + this.route.params.subscribe(async () => { + this.headerService.setHeader(this.translate.instant('lang.arReception')); + const validatorNumber: ValidatorFn[] = [Validators.pattern(/(2C|2D|RW) ([0-9]{3} [0-9]{3} [0-9]{4}) ([0-9])/), Validators.required]; + this.adminFormGroup = this._formBuilder.group({ + type: ['', Validators.required], + number: ['', validatorNumber], + receivedDate: ['', Validators.required], + returnReason: ['', Validators.required], + returnReasonOther: ['', Validators.required] + }); + this.loading = false; + }); + } + + receiveAcknowledgement() { + const data = { + type: this.type, + number: this.number, + receivedDate: this.receivedDate, + returnReason: this.reason, + returnReasonOther: this.reasonOther + }; + + if (this.type === 'distributed') { + if (!this.adminFormGroup.get('number').valid) { + this.notify.error(this.translate.instant('lang.fieldsNotValid')); + return; + } + } else { + if (!this.adminFormGroup.get('number').valid || !this.adminFormGroup.get('receivedDate').valid || !this.adminFormGroup.get('returnReason').valid) { + this.notify.error(this.translate.instant('lang.fieldsNotValid')); + return; + } + } + + this.http.put('../rest/registeredMails/acknowledgement', data).pipe( + tap(() => { + this.type = ''; + this.number = ''; + this.receivedDate = ''; + this.reason = ''; + this.reasonOther = ''; + }), + catchError((err) => { + this.notify.handleSoftErrors(err); + return of(false); + }) + ).subscribe(); + } +} diff --git a/src/frontend/app/administration/registered-mail/registered-mail-list.component.ts b/src/frontend/app/administration/registered-mail/registered-mail-list.component.ts index ca923b09422..34c1d68fdca 100644 --- a/src/frontend/app/administration/registered-mail/registered-mail-list.component.ts +++ b/src/frontend/app/administration/registered-mail/registered-mail-list.component.ts @@ -32,6 +32,11 @@ export class RegisteredMailListComponent implements OnInit { route: '/administration/issuingSites', label: this.translate.instant('lang.issuingSites'), current: false + }, { + icon: 'fas fa-warehouse', + route: '/administration/registeredMails/acknowledgement', + label: 'Réception AR', + current: false }, ]; diff --git a/src/lang/lang-en.json b/src/lang/lang-en.json index 4515d5da310..ac7a1390797 100644 --- a/src/lang/lang-en.json +++ b/src/lang/lang-en.json @@ -1919,5 +1919,17 @@ "rangeStartLargerThanRangeEnd": "Range start cannot be larger than range end", "trackingNumberAlreadyUsed": "Tracking number is already used", "rangeOverlaps": "Range overlaps another range", - "siteIsUsedByActiveRange": "Cannot delete issuing site : site is used by an active range" + "siteIsUsedByActiveRange": "Cannot delete issuing site : site is used by an active range", + "fieldsNotValid": "Fields are invalid", + "arReception": "AR reception", + "returnType": "Return type", + "registeredMailDistributed": "Registered mail distributed", + "registeredMailNotDistributed": "Registered mail not distributed", + "registeredMailReceivedDate": "Date of receipt", + "precise": "Precise :", + "returnReason": "Reason of return", + "returnReasonCannotAccess": "Access or address error", + "returnReasonNotClaimed": "Mail not claimed", + "returnReasonRejected": "Mail rejected by recipient", + "returnReasonUnknown": "Recipient unknown at this address" } diff --git a/src/lang/lang-fr.json b/src/lang/lang-fr.json index 8d65b1a4b5b..e9b9c41ab3b 100644 --- a/src/lang/lang-fr.json +++ b/src/lang/lang-fr.json @@ -1951,5 +1951,17 @@ "rangeStartLargerThanRangeEnd": "Le début de la plage ne peut pas être plus grand que la fin de la plage", "trackingNumberAlreadyUsed": "Le numéro de suivi est déjà utilisé", "rangeOverlaps": "La plage chevauche une autre plage", - "siteIsUsedByActiveRange": "Impossible de supprimer le site émetteur : le site est utilisé par une plage active" + "siteIsUsedByActiveRange": "Impossible de supprimer le site émetteur : le site est utilisé par une plage active", + "fieldsNotValid": "Les données saisies sont invalides", + "arReception": "Réception des AR", + "returnType": "Type de retour", + "registeredMailDistributed": "Recommandé distribué", + "registeredMailNotDistributed": "Recommandé non distribué", + "registeredMailReceivedDate": "Date de réception", + "precise": "Précisez :", + "returnReason": "Motif de retour", + "returnReasonCannotAccess": "Défaut d'accès ou d'adressage", + "returnReasonNotClaimed": "Pli avisé et non réclamé", + "returnReasonRejected": "Pli refusé par le destinataire", + "returnReasonUnknown": "Destinataire inconnu à l'adresse" } -- GitLab