Ver Fonte

Merge branch 'master' of http://209.50.56.224/git/ITTEC/SistemaMantenimiento

JeanBenitez há 1 ano atrás
pai
commit
e1e6591620

+ 14 - 7
sistema-mantenimiento-front/src/app/components/preventive-maintenance/work-orders/new-work-order/new-work-order.component.html

@@ -61,11 +61,10 @@
             <div class="form-cell" [ngClass]="{ C03: datesCols == 4, C06: datesCols == 2, C12: datesCols == 1 }">
               <mat-form-field class="w-100" appearance="outline">
                 <mat-label>Hora de inicio</mat-label>
-                <mat-select formControlName="startHourControl">
-                  <mat-option *ngFor="let hour of hoursArr" [value]="hour.value">
-                    {{ hour.label }}
-                  </mat-option>
-                </mat-select>
+                <input matInput formControlName="startHourControl">
+                <button mat-icon-button matSuffix [disabled]="disabledStartHour" (click)="openTimePicker('start')">
+                  <mat-icon>schedule</mat-icon>
+                </button>
                 <mat-error *ngIf="orderFormGroup.controls['startHourControl'].hasError('required')">
                   Este campo es requerido.
                 </mat-error>
@@ -87,11 +86,15 @@
             <div class="form-cell" [ngClass]="{ C03: datesCols == 4, C06: datesCols == 2, C12: datesCols == 1 }">
               <mat-form-field class="w-100" appearance="outline">
                 <mat-label>Hora de término</mat-label>
-                <mat-select formControlName="endHourControl">
+                <input matInput formControlName="endHourControl">
+                <button mat-icon-button matSuffix [disabled]="disabledEndHour" (click)="openTimePicker('end')">
+                  <mat-icon>schedule</mat-icon>
+                </button>
+                <!--<mat-select formControlName="endHourControl">
                   <mat-option *ngFor="let hour of hoursArr" [value]="hour.value">
                     {{ hour.label }}
                   </mat-option>
-                </mat-select>
+                </mat-select>-->
                 <mat-error *ngIf="orderFormGroup.controls['endHourControl'].hasError('required')">
                   Este campo es requerido.
                 </mat-error>
@@ -159,6 +162,10 @@
                         <mat-icon>visibility</mat-icon>
                         <span>Detalles del equipamiento</span>
                       </button>
+                      <button mat-menu-item (click)="openEquipmentArborescence(row.CODIGO)">
+                        <mat-icon>description</mat-icon>
+                        <span>Ficha de detalles</span>
+                      </button>
                       <button mat-menu-item (click)="openEquipmentDocuments(row.CODIGO)">
                         <mat-icon>description</mat-icon>
                         <span>Ver documentación</span>

+ 263 - 179
sistema-mantenimiento-front/src/app/components/preventive-maintenance/work-orders/new-work-order/new-work-order.component.ts

@@ -5,7 +5,7 @@ import { ActivatedRoute, Router } from '@angular/router';
 import { MatTableDataSource } from '@angular/material/table';
 import { DOCUMENT } from '@angular/common';
 import { availableFiles } from 'src/environments/environment.prod';
-import { Observable, debounceTime, distinctUntilChanged, filter, lastValueFrom, map, startWith, switchMap, tap } from 'rxjs';
+import { Observable, debounceTime, distinctUntilChanged, filter, lastValueFrom, switchMap, tap } from 'rxjs';
 import { EncService } from 'src/app/services/enc/enc.service';
 import { MatDialog } from '@angular/material/dialog';
 import { SearchFileDialogComponent } from 'src/app/components/gdel/search-file-dialog/search-file-dialog.component';
@@ -44,59 +44,9 @@ import { ResponseDataGetToolsAndSpare, ToolsAndSpare } from 'src/app/interfaces/
 import { GraphicEquipmentSearchComponent } from 'src/app/components/equipment-management/graphic-equipment-search/graphic-equipment-search.component';
 import { InterventionService } from 'src/app/services/personal-management/intervention.service';
 import { SpecialtiesListItem, SpecialtiesListResponse } from 'src/app/interfaces/specialties.interface';
+import { FunctionsService } from 'src/app/services/functions.service';
+import { TimePickerComponent } from 'src/app/components/resources/dialogs/time-picker/time-picker.component';
 
-/* interface ToolsAndSpare{
-  ID: string;
-  NOMB: string;
-  MODE: string;
-  CANTDISP: number;
-  TYPE: string;
-  UNIT: string;
-} */
-/* const TOOLS_TMP: ToolsAndSpare[] = [
-  {ID: 'H1', NOMB: 'Pinzas eléctricas', MODE: 'PE-862', CANTDISP: 35, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H2', NOMB: 'Pinzas mecánicas', MODE: 'M985', CANTDISP: 27, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H3', NOMB: 'Pinzas de presión', MODE: 'RG-12', CANTDISP: 30, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H4', NOMB: 'Juego de llaves Allen', MODE: 'ALL88', CANTDISP: 75, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H5', NOMB: 'Extractor de rodamientos', MODE: 'EX-ROD-1500', CANTDISP: 3, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H6', NOMB: 'Kit llaves inglesas', MODE: '5530S', CANTDISP: 7, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H7', NOMB: 'Kit llaves españolas', MODE: '964F', CANTDISP: 8, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H8', NOMB: 'Juego de llaves Torx', MODE: 'TORX3423W', CANTDISP: 42, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H9', NOMB: 'Cautín de lápiz 33W', MODE: '33WCL', CANTDISP: 15, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H10', NOMB: 'Juego de dados milimétricos', MODE: 'DMM450', CANTDISP: 6, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H11', NOMB: 'Juego de dados pulgadas', MODE: 'DIN865', CANTDISP: 9, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H12', NOMB: 'Probador de corriente', MODE: '569', CANTDISP: 33, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H13', NOMB: 'Multímetro', MODE: 'TGH885', CANTDISP: 17, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H14', NOMB: 'Planta generadora para soldadura', MODE: 'PLAGEN-589', CANTDISP: 1, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H15', NOMB: 'Amperímetro de gancho', MODE: 'A0032', CANTDISP: 4, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H16', NOMB: 'Rotomartillo', MODE: '551', CANTDISP: 2, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H17', NOMB: 'Kit taladro inalámbrico', MODE: 'FP581', CANTDISP: 12, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H18', NOMB: 'Kit taládro alámbrico', MODE: 'HG862', CANTDISP: 10, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H19', NOMB: 'Juego de desarmadores', MODE: '8913-KSOA', CANTDISP: 5, TYPE: 'Herramienta', UNIT: 'Pieza'},
-  {ID: 'H20', NOMB: 'Martillo', MODE: 'TS438', CANTDISP: 23, TYPE: 'Herramienta', UNIT: 'Pieza'},
-];
-const SPARE_PARTS_TMP: ToolsAndSpare[] = [
-  {ID: 'S1', NOMB: 'Neumático para NM-16', MODE: 'NM16NEU235', CANTDISP: 45, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S2', NOMB: 'Neumático para NM-22', MODE: 'NM22NEU652', CANTDISP: 51, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S3', NOMB: 'Rodamiento cónico', MODE: 'RC-4265', CANTDISP: 84, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S4', NOMB: 'Rodamiento axial', MODE: 'RA-5130', CANTDISP: 96, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S5', NOMB: 'Rodamiento angular', MODE: 'RN-3541', CANTDISP: 79, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S6', NOMB: 'Grasa 1-310', MODE: 'G1.310', CANTDISP: 9, TYPE: 'Refaccción', UNIT: 'Kilogramo'},
-  {ID: 'S7', NOMB: 'Aceite 10W-40', MODE: 'A10W40', CANTDISP: 16, TYPE: 'Refaccción', UNIT: 'Litro'},
-  {ID: 'S8', NOMB: 'Soldadura de estaño', MODE: 'LDA-913', CANTDISP: 39, TYPE: 'Refaccción', UNIT: 'Metro'},
-  {ID: 'S9', NOMB: 'Soldadura de plata', MODE: 'BDA-516', CANTDISP: 21, TYPE: 'Refaccción', UNIT: 'Metro'},
-  {ID: 'S10', NOMB: 'Pastilla de frenado', MODE: '754SSV', CANTDISP: 25, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S11', NOMB: 'Cable de cobre calibre 0', MODE: 'CC0-884', CANTDISP: 120, TYPE: 'Refaccción', UNIT: 'Metro'},
-  {ID: 'S12', NOMB: 'Rosetas de cable Ethernet', MODE: '165-BFS', CANTDISP: 12, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S13', NOMB: 'Pintura', MODE: '53469', CANTDISP: 250, TYPE: 'Refaccción', UNIT: 'Litro'},
-  {ID: 'S14', NOMB: 'Solvente de pintura', MODE: '2516', CANTDISP: 310, TYPE: 'Refaccción', UNIT: 'Litro'},
-  {ID: 'S15', NOMB: 'Lámina galvanizada', MODE: 'SFAS-320', CANTDISP: 38, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S16', NOMB: 'Botón de freno de emergencia', MODE: 'B-51321', CANTDISP: 14, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S17', NOMB: 'Disco duro de estado sólido 512GB', MODE: 'SSD-512', CANTDISP: 22, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S18', NOMB: 'Mouse óptico', MODE: 'MO1165', CANTDISP: 26, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S19', NOMB: 'Teclado para PC', MODE: '5413', CANTDISP: 24, TYPE: 'Refaccción', UNIT: 'Pieza'},
-  {ID: 'S20', NOMB: 'Cable HDMI 2m', MODE: 'ASD-181', CANTDISP: 6, TYPE: 'Refaccción', UNIT: 'Pieza'},
-]; */
 export interface Instruction{
   ID: string,
   INSTRUCCION: string,
@@ -120,6 +70,8 @@ export class NewWorkOrderComponent implements OnInit {
   isNew: boolean;
   loadingActivators: boolean;
   searchingEquipments: boolean;
+  disabledStartHour: boolean;
+  disabledEndHour: boolean;
   errorStr: string;
   action: string;
   idOrder: string | null;
@@ -197,6 +149,7 @@ export class NewWorkOrderComponent implements OnInit {
     private _equipmentsService: EquipmentManagementService,
     private _inventoryManagementService: InventoryManagementService,
     private _interventionService: InterventionService,
+    private _functionsService: FunctionsService,
   ) { 
     this.isUploading = false;
     this.isLoading = true;
@@ -204,6 +157,8 @@ export class NewWorkOrderComponent implements OnInit {
     this.isNew = false;
     this.loadingActivators = false;
     this.searchingEquipments = false;
+    this.disabledStartHour = true;
+    this.disabledEndHour = true;
     this.errorStr = "";
     this.action = "";
     this.idOrder = null;
@@ -270,7 +225,7 @@ export class NewWorkOrderComponent implements OnInit {
     this.activatorConfigStr = '';
   }
 
-  async ngOnInit() {
+  ngOnInit() {
     this._activatedRoute.queryParams.subscribe(res => {
       let params = res['idOrder'];
       if(params == undefined){
@@ -338,10 +293,15 @@ export class NewWorkOrderComponent implements OnInit {
       switchMap(value => this._filterEquipments(value))
     ).subscribe(autoCompleteList => {
       this.autoCompleteEquipments = autoCompleteList;
-    })
+    });
+
+    this.orderFormGroup.controls['startDateControl'].valueChanges.subscribe((_) => {
+      this.verifyDateTime('start');
+    });
 
-    this.fillHours();
-    await this._getToolsAndSpare()
+    this.orderFormGroup.controls['endDateControl'].valueChanges.subscribe((_) => {
+      this.verifyDateTime('end');
+    });
   }
 
   private async _filterEquipments(value: string): Promise<string[]>{
@@ -364,20 +324,6 @@ export class NewWorkOrderComponent implements OnInit {
     return equipmentsStr;
   }
 
-  fillHours(){
-    for(let i = 0; i  < 24; i++){
-      let period = i < 12 ? 'AM' : 'PM';
-      let hourInt = i > 12 ? i - 12 : i;
-      let hourStr = hourInt < 10 ? `0${hourInt}` : `${hourInt}`;
-      let hour = i < 10 ? `0${i}` : `${i}`;
-
-      this.hoursArr.push({ value: `${hour}:00:00`, label: `${hourStr}:00 ${period}` });
-      this.hoursArr.push({ value: `${hour}:15:00`, label: `${hourStr}:15 ${period}` });
-      this.hoursArr.push({ value: `${hour}:30:00`, label: `${hourStr}:30 ${period}` });
-      this.hoursArr.push({ value: `${hour}:45:00`, label: `${hourStr}:45 ${period}` });
-    }
-  }
-
   async getProfileAccess(idOrder: string){
     try{
       let permissionsEnc = localStorage.getItem('permisos');
@@ -421,6 +367,7 @@ export class NewWorkOrderComponent implements OnInit {
     try{
       let idUser = localStorage.getItem('idusuario')!;
       let order: PreventiveWorkOrderResponse = await lastValueFrom(this._prevMaintService.getWorkOrder(idOrder, idUser, 1));
+      console.log(order);
 
       this.hasError = order.error;
       this.errorStr = order.msg;
@@ -1069,7 +1016,7 @@ export class NewWorkOrderComponent implements OnInit {
   
       this.orderFormGroup.controls['startHourControl'].removeValidators(Validators.required);
       this.orderFormGroup.controls['startHourControl'].setValue('');
-      this.orderFormGroup.controls['startHourControl'].disable();
+      this.disabledStartHour = true;
   
       this.orderFormGroup.controls['endDateControl'].removeValidators(Validators.required);
       this.orderFormGroup.controls['endDateControl'].setValue(null);
@@ -1077,7 +1024,7 @@ export class NewWorkOrderComponent implements OnInit {
   
       this.orderFormGroup.controls['endHourControl'].removeValidators(Validators.required);
       this.orderFormGroup.controls['endHourControl'].setValue('');
-      this.orderFormGroup.controls['endHourControl'].disable();
+      this.disabledEndHour = true;
 
       this.orderFormGroup.controls['activatorControl'].setValue('');
       this.loadingActivators = true;
@@ -1159,7 +1106,7 @@ export class NewWorkOrderComponent implements OnInit {
 
     this.orderFormGroup.controls['startHourControl'].removeValidators(Validators.required);
     this.orderFormGroup.controls['startHourControl'].setValue('');
-    this.orderFormGroup.controls['startHourControl'].disable();
+    this.disabledStartHour = true;
 
     this.orderFormGroup.controls['endDateControl'].removeValidators(Validators.required);
     this.orderFormGroup.controls['endDateControl'].setValue(null);
@@ -1167,7 +1114,7 @@ export class NewWorkOrderComponent implements OnInit {
 
     this.orderFormGroup.controls['endHourControl'].removeValidators(Validators.required);
     this.orderFormGroup.controls['endHourControl'].setValue('');
-    this.orderFormGroup.controls['endHourControl'].disable();
+    this.disabledEndHour = true;
 
     if(value == 'CAN'){
       let dialogRef = this._dialog.open(ActivatorDialogComponent, {
@@ -1194,18 +1141,18 @@ export class NewWorkOrderComponent implements OnInit {
           this.orderFormGroup.controls['startDateControl'].addValidators(Validators.required);
           this.orderFormGroup.controls['startDateControl'].enable();
           this.orderFormGroup.controls['startHourControl'].addValidators(Validators.required);
-          this.orderFormGroup.controls['startHourControl'].enable();
           this.orderFormGroup.controls['endDateControl'].enable();
-          this.orderFormGroup.controls['endHourControl'].enable();
+          this.disabledStartHour = false;
+          this.disabledEndHour = false;
         }
       }
     }else if(type == 'ME' || type == 'VA'){
       this.orderFormGroup.controls['startDateControl'].addValidators(Validators.required);
       this.orderFormGroup.controls['startDateControl'].enable();
       this.orderFormGroup.controls['startHourControl'].addValidators(Validators.required);
-      this.orderFormGroup.controls['startHourControl'].enable();
       this.orderFormGroup.controls['endDateControl'].enable();
-      this.orderFormGroup.controls['endHourControl'].enable();
+      this.disabledStartHour = false;
+      this.disabledEndHour = false;
     }
 
     this.getActivatorConfigStr(value, type);
@@ -1224,10 +1171,12 @@ export class NewWorkOrderComponent implements OnInit {
 
       if(type == 'CA' || type == 'SI'){
         let startDate = new Date(conditionsObj.startDate);
+        let startHour = this._functionsService.convertFullHourToHumanHour(conditionsObj.startHour);
+
         switch(conditionsObj.repeat){
           case "NR": 
             this.orderFormGroup.controls['startDateControl'].setValue(startDate);
-            this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
+            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
             
             configStr += "Esta orden no se repite"; 
           break;
@@ -1235,25 +1184,25 @@ export class NewWorkOrderComponent implements OnInit {
             configStr += `Esta orden se repite anualmente el día ${startDate.getDate()} de ${this.MONTHS[startDate.getMonth()]}`;
   
             this.orderFormGroup.controls['startDateControl'].setValue(startDate);
-            this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
+            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
           break;
           case "ME":
             configStr += `Esta orden se repite mensualmente los días ${startDate.getDate()}`;
   
             this.orderFormGroup.controls['startDateControl'].setValue(startDate);
-            this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
+            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
           break;
           case "SE":
             configStr += `Esta orden se repite semanalmente los días ${this.dayNames[startDate.getDay()]}`;
   
             this.orderFormGroup.controls['startDateControl'].setValue(startDate);
-            this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
+            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
           break;
           case "TD":
             configStr += `Esta ordense repite todos los días desde el ${startDate.getDate()} de ${this.MONTHS[startDate.getMonth()]} del ${startDate.getFullYear()}`;
   
             this.orderFormGroup.controls['startDateControl'].setValue(startDate);
-            this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
+            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
           break;
           case "PE":
             let customRepeat = JSON.parse(conditionsObj.customRepeat);
@@ -1327,13 +1276,13 @@ export class NewWorkOrderComponent implements OnInit {
             
               this.orderFormGroup.controls['endDateControl'].setValue(dateObj);
               this.orderFormGroup.controls['endHourControl'].addValidators(Validators.required);
-              this.orderFormGroup.controls['endHourControl'].enable();
+              this.disabledEndHour = false;
             }else if(endsAt[0] == 'A'){
               configStr += `finaliza después de ${endsAt[2]} repetici${parseInt(endsAt[2]) > 1 ? 'ones' : 'ón'}.`;
             }
           
             this.orderFormGroup.controls['startDateControl'].setValue(startDate);
-            this.orderFormGroup.controls['startHourControl'].setValue(conditionsObj.startHour);
+            this.orderFormGroup.controls['startHourControl'].setValue(startHour);
           break;
         }
       }else{
@@ -1362,96 +1311,66 @@ export class NewWorkOrderComponent implements OnInit {
       let idUser = localStorage.getItem('idusuario');
       let formData = new FormData();
       let formValue = this.orderFormGroup.getRawValue();
-      
-      if(formValue.descriptionControl == ''){
-        formData.append('description', '-');
-      }else{
-        formData.append('description', formValue.descriptionControl);
-      }
-      
-      if(formValue.staffControl == ''){
-        formData.append('staff', '-');
-      }else{
-        let staffArr: any[] = [];
-        formValue.staffControl.forEach((item: string) => {
-          let itemArr = item.split('-');
-          staffArr.push({
-            ID: itemArr[0],
-            TYPE: itemArr[1]
-          });
-        });
-        
-        let staffStr = JSON.stringify(staffArr);
-        formData.append('staff', staffStr);
-      }
 
-      if(formValue.startDateControl == null){
-        formData.append('start_date', '-');
-      }else{
-        let startDate = formValue.startDateControl as Date;
-        let startDateYear = startDate.getFullYear();
-        let startDateMonth = startDate.getMonth() + 1;
-        let startDateDay = startDate.getDate();
+      let description = formValue.descriptionControl == '' ? '-' : formValue.descriptionControl;
+      formData.append('description', description);
 
-        formData.append('start_date', `${startDateYear}-${startDateMonth < 10 ? `0${startDateMonth}`: `${startDateMonth}`}-${startDateDay < 10 ? `0${startDateDay}`: `${startDateDay}`}`);
-      }
+      let staffStr = '[]';
+      if(formValue.staffControl.length > 0){
+        let specialtiesArr: any[] = [];
+        for(const specialty of formValue.staffControl){
+          let input = this._document.getElementById(`cant-req-${specialty}`) as HTMLInputElement;
+          let valStr = input.value;
+          let valNum = parseInt(valStr) <= 0 ? 1 : parseInt(valStr);
 
-      if(formValue.startHourControl == ''){
-        formData.append('start_hour', '-');
-      }else{
-        formData.append('start_hour', formValue.startHourControl);
+          specialtiesArr.push({
+            SPECIALTY: specialty,
+            CANT: valNum,
+          });
+        }
+
+        staffStr = JSON.stringify(specialtiesArr);
       }
+      
+      formData.append('staff', staffStr);
 
-      if(formValue.endDateControl == null){
-        formData.append('end_date', '-');
-      }else{
-        let endDate = formValue.endDateControl as Date;
-        let endDateYear = endDate.getFullYear();
-        let endDateMonth = endDate.getMonth() + 1;
-        let endDateDay = endDate.getDate();
+      let startDate = formValue.startDateControl == null ? '-' : this._functionsService.getFormattedDate(formValue.startDateControl as Date);
+      formData.append('start_date', startDate);
 
-        formData.append('end_date', `${endDateYear}-${endDateMonth < 10 ? `0${endDateMonth}`: `${endDateMonth}`}-${endDateDay < 10 ? `0${endDateDay}`: `${endDateDay}`}`);
-      }
+      let startHour = formValue.startHourControl == '' ? '-' : this._functionsService.convertHumanHourToFullHour(formValue.startHourControl);
+      formData.append('start_hour', startHour);
 
-      if(formValue.endHourControl == ''){
-        formData.append('end_hour', '-');
-      }else{
-        formData.append('end_hour', formValue.endHourControl);
-      }
+      let endDate = formValue.endDateControl == null ? '-' : this._functionsService.getFormattedDate(formValue.endDateControl as Date);
+      formData.append('end_date', endDate);
 
-      if(formValue.equipmentControl == ''){
-        formData.append('equipment', '-');
-      }else{
-        formData.append('equipment', formValue.equipmentControl);
-      }
+      let endHour = formValue.endHourControl == '' ? '-' : this._functionsService.convertHumanHourToFullHour(formValue.endHourControl);
+      formData.append('end_hour', endHour);
 
-      if(formValue.inmTimeControl == ''){
-        formData.append('inm_time', '-');
-      }else{
-        formData.append('inm_time', formValue.inmTimeControl);
+      let equipment = '-';
+      if(formValue.equipmentControl != ''){
+        let equipmentArr = formValue.equipmentControl.split(' - ');
+        if(equipmentArr.length != 3){
+          this._resourcesService.openSnackBar('El formato del equipamiento seleccionado es inválido.');
+          return;
+        }else{
+          equipment = await this._encService.encrypt(equipmentArr[0]);
+        }
       }
 
-      if(formValue.totalTimeControl == ''){
-        formData.append('total_time', '-');
-      }else{
-        formData.append('total_time', formValue.totalTimeControl);
-      }
+      formData.append('equipment', equipment);
+
+      let inmTime = formValue.inmTimeControl == '' ? '-' : formValue.inmTimeControl;
+      formData.append('inm_time', inmTime);
 
+      let totalTime = formValue.totalTimeControl == '' ? '-' : formValue.totalTimeControl;
+      formData.append('total_time', totalTime);
       formData.append('attached', JSON.stringify(this.attached));
 
-      if(formValue.activatorTypeControl == ''){
-        formData.append('activator_type', '-');
-      }else{
-        formData.append('activator_type', formValue.activatorTypeControl);
-      }
+      let activatorType = formValue.activatorTypeControl == '' ? '-' : formValue.activatorTypeControl;
+      formData.append('activator_type', activatorType);
 
-      if(formValue.activatorControl == 0){
-        formData.append('activator', '-');
-      }else{
-        let activatorEnc = await this._encService.encrypt(`${formValue.activatorControl}`);
-        formData.append('activator', activatorEnc);
-      }
-      
+      let activator = formValue.activatorControl == 0 ? '-' : await this._encService.encrypt(`${formValue.activatorControl}`);
+      formData.append('activator', activator);
       formData.append('id_user', idUser!);
       formData.append('linea', '1');
       formData.append('exists', this.isNew ? 'N' : 'S');
@@ -1460,28 +1379,26 @@ export class NewWorkOrderComponent implements OnInit {
         formData.append('id_order', this.idOrder!);
       }
 
-      if(this.instructions.length == 0){
-        formData.append('instructions', '{}');
-      }else{
+      let instructions = '[]';
+      if(this.instructions.length > 0){
         let instructionsEnc: Instruction[] = [];
         for(const instruction of this.instructions){
           instruction.ID = await this._encService.encrypt(instruction.ID);
           instructionsEnc.push(instruction);
         }
 
-        formData.append('instructions', JSON.stringify(instructionsEnc));
+        instructions = JSON.stringify(instructionsEnc);
       }
       
-      if(formValue.clasificationControl == ''){
-        formData.append('clasification', '-');
-      }else{
-        formData.append('clasification', formValue.clasificationControl);
-      }
-      
-      let toolsConf: any[] = [];
+      formData.append('instructions', instructions);
+
+      let classification = formValue.clasificationControl == '' ? '-' : formValue.clasificationControl;
+      formData.append('clasification', classification);
+
+      let resourcesConf: any[] = [];
       for(const tool of formValue.toolsControl){
         if(tool == 'SH'){
-          toolsConf.push({
+          resourcesConf.push({
             ID: 'SH',
             REQ: '-',
             TYPE: 'T'
@@ -1489,13 +1406,13 @@ export class NewWorkOrderComponent implements OnInit {
         }else{
           let input = this._document.getElementById(`cant-req-${tool}`) as HTMLInputElement;
           if(input.value == ''){
-            toolsConf.push({
+            resourcesConf.push({
               ID: tool.ID,
               REQ: 0,
               TYPE: 'T'
             });
           }else{
-            toolsConf.push({
+            resourcesConf.push({
               ID: tool.ID,
               REQ: input.value,
               TYPE: 'T'
@@ -1506,7 +1423,7 @@ export class NewWorkOrderComponent implements OnInit {
 
       for(const sparePart of formValue.sparePartsControl){
         if(sparePart == 'SH'){
-          toolsConf.push({
+          resourcesConf.push({
             ID: 'SH',
             REQ: '-',
             TYPE: 'S'
@@ -1514,13 +1431,13 @@ export class NewWorkOrderComponent implements OnInit {
         }else{
           let input = this._document.getElementById(`cant-req-${sparePart}`) as HTMLInputElement;
           if(input.value == ''){
-            toolsConf.push({
+            resourcesConf.push({
               ID: sparePart.ID,
               REQ: 0,
               TYPE: 'S'
             });
           }else{
-            toolsConf.push({
+            resourcesConf.push({
               ID: sparePart.ID,
               REQ: input.value,
               TYPE: 'S'
@@ -1529,7 +1446,7 @@ export class NewWorkOrderComponent implements OnInit {
         }
       }
       
-      formData.append('resources', JSON.stringify(toolsConf));
+      formData.append('resources', JSON.stringify(resourcesConf));
       await lastValueFrom(this._prevMaintService.savePresetWorkOrder(formData));
 
       this._resourcesService.openSnackBar('El borrador se guardó correctamente');
@@ -2046,6 +1963,7 @@ export class NewWorkOrderComponent implements OnInit {
       }, (httpErrorResponse: HttpErrorResponse) => this._resourcesService.checkErrors(httpErrorResponse)
     )
   }
+
   openArborescenceSearch(){
     let dialogRef = this._dialog.open(GraphicEquipmentSearchComponent, {
       disableClose: true,
@@ -2059,6 +1977,172 @@ export class NewWorkOrderComponent implements OnInit {
       }
     });
   }
+
+  async openEquipmentArborescence(selectedEquipment: string){
+    let codeDec = await this._encService.decrypt(selectedEquipment);
+    let codeArr = codeDec.split('_');
+
+    if(codeArr.length == 2){
+      let pbsArr = codeArr[1].split('.');
+      if(pbsArr.length > 3){
+        let familyEnc = await this._encService.encrypt(pbsArr[0]);
+        let subFamilyEnc = await this._encService.encrypt(pbsArr[1]);
+        let arborescence: string[] = [];
+
+        for(let i = 3; i < pbsArr.length; i++){
+          let equipmentCode = pbsArr[i];
+          let parentIndex = i - 4;
+
+          if(parentIndex >= 0){
+            let parent = arborescence[parentIndex];
+            let fullCode = `${parent}.${equipmentCode}`;
+            arborescence.push(fullCode);
+          }else{
+            let fullCode = `${codeArr[0]}_${pbsArr[0]}.${pbsArr[1]}.${pbsArr[2]}.${equipmentCode}`;
+            arborescence.push(fullCode);
+          }
+        }
+
+        let arborescenceArr: string[] = [];
+        for(const item of arborescence){
+          let itemEnc = await this._encService.encrypt(item);
+          arborescenceArr.push(itemEnc);
+        }
+
+        let arborescenceStr = JSON.stringify(arborescenceArr);
+        let arborescenceEnc = window.btoa(arborescenceStr);
+
+        let url = this._router.createUrlTree(['sam/GEEQ'], {
+          queryParams: {
+            family: familyEnc,
+            subfamily: subFamilyEnc,
+            arborescence: arborescenceEnc
+          }
+        });
+
+        if(window.location.href.includes('#')){
+          let locationArr = window.location.href.split('#');
+          window.open(`${locationArr[0]}#${url.toString()}`);
+        }
+      }
+    }
+  }
+
+  openTimePicker(type: string){
+    let time = type == 'start' ? this.orderFormGroup.controls['startHourControl'].value : this.orderFormGroup.controls['endHourControl'].value;
+    let dialogRef = this._dialog.open(TimePickerComponent, {
+      data: {
+        time: time,
+      }
+    });
+
+    dialogRef.afterClosed().subscribe(res => {
+      if(res != null && res != undefined && res != ''){
+        if(type == 'start'){
+          this.orderFormGroup.controls['startHourControl'].setValue(res);
+        }else{
+          this.orderFormGroup.controls['endHourControl'].setValue(res);
+        }
+        
+        this.verifyDateTime(type);
+      }
+    });
+  }
+  
+  verifyDateTime(type: string){
+    let startDate = this.orderFormGroup.controls['startDateControl'].value;
+    let startHour = this.orderFormGroup.controls['startHourControl'].value;
+    let endDate = this.orderFormGroup.controls['endDateControl'].value;
+    let endHour = this.orderFormGroup.controls['endHourControl'].value;
+
+    if(type == 'start' && startHour != null && startDate != null){
+      let startDateStr = `${startDate.getFullYear()}-${startDate.getMonth() + 1}-${startDate.getDate()}`;
+      let startHourArr = `${startHour}`.split(' ');
+      if(startHourArr.length == 2){
+        let startHour = startHourArr[0].split(':');
+        let startHourNum = parseInt(startHour[0]);
+        
+        if(startHourArr[1] == 'PM'){
+          startHourNum = startHourNum < 12 ? startHourNum + 12 : startHourNum;
+        }
+
+        let startHourStr = startHourNum < 10 ? `0${startHourNum}` : `${startHourNum}`;
+        let startTimeStr = `${startHourStr}:${startHour[1]}:00`;
+
+        let startDateTimeStr = `${startDateStr} ${startTimeStr}`;
+        let startDateTime = new Date(startDateTimeStr);
+        let startTimestamp = startDateTime.getTime();
+
+        if(endHour != null && endDate != null){
+          let endDateStr = `${endDate.getFullYear()}-${endDate.getMonth() + 1}-${endDate.getDate()}`;
+          let endHourArr = `${endHour}`.split(' ');
+          if(endHourArr.length == 2){
+            let endHour = endHourArr[0].split(':');
+            let endHourNum = parseInt(endHour[0]);
+            
+            if(endHourArr[1] == 'PM'){
+              endHourNum = endHourNum < 12 ? endHourNum + 12 : endHourNum;
+            }
+    
+            let endHourStr = endHourNum < 10 ? `0${endHourNum}` : `${endHourNum}`;
+            let endTimeStr = `${endHourStr}:${endHour[1]}:00`;
+    
+            let endDateTimeStr = `${endDateStr} ${endTimeStr}`;
+            let endDateTime = new Date(endDateTimeStr);
+            let endTimestamp = endDateTime.getTime();
+        
+            if(startTimestamp > endTimestamp){
+              this._resourcesService.openSnackBar('La hora de inicio no puede ser mayor a la hora de término.');
+              setTimeout(() => this.orderFormGroup.controls['startHourControl'].setValue(null), 250);
+            }
+          }
+        }
+      }
+    }else if(type == 'end' && endHour != null && endDate != null){
+      let endDateStr = `${endDate.getFullYear()}-${endDate.getMonth() + 1}-${endDate.getDate()}`;
+      let endHourArr = `${endHour}`.split(' ');
+      if(endHourArr.length == 2){
+        let endHour = endHourArr[0].split(':');
+        let endHourNum = parseInt(endHour[0]);
+        
+        if(endHourArr[1] == 'PM'){
+          endHourNum = endHourNum < 12 ? endHourNum + 12 : endHourNum;
+        }
+
+        let endHourStr = endHourNum < 10 ? `0${endHourNum}` : `${endHourNum}`;
+        let endTimeStr = `${endHourStr}:${endHour[1]}:00`;
+
+        let endDateTimeStr = `${endDateStr} ${endTimeStr}`;
+        let endDateTime = new Date(endDateTimeStr);
+        let endTimestamp = endDateTime.getTime();
+
+        if(startHour != null && startDate != null){
+          let startDateStr = `${startDate.getFullYear()}-${startDate.getMonth() + 1}-${startDate.getDate()}`;
+          let startHourArr = `${startHour}`.split(' ');
+          if(startHourArr.length == 2){
+            let startHour = startHourArr[0].split(':');
+            let startHourNum = parseInt(startHour[0]);
+            
+            if(startHourArr[1] == 'PM'){
+              startHourNum = startHourNum < 12 ? startHourNum + 12 : startHourNum;
+            }
+    
+            let startHourStr = startHourNum < 10 ? `0${startHourNum}` : `${startHourNum}`;
+            let startTimeStr = `${startHourStr}:${startHour[1]}:00`;
+    
+            let startDateTimeStr = `${startDateStr} ${startTimeStr}`;
+            let startDateTime = new Date(startDateTimeStr);
+            let startTimestamp = startDateTime.getTime();
+
+            if(endTimestamp < startTimestamp){
+              this._resourcesService.openSnackBar('La hora de término no puede ser menor a la hora de inicio.');
+              setTimeout(() => this.orderFormGroup.controls['endHourControl'].setValue(null), 250);
+            }
+          }
+        }
+      }
+    }
+  }
 }
 
 export class WorkOrderStateMatcher implements ErrorStateMatcher{

+ 1 - 1
sistema-mantenimiento-front/src/app/components/preventive-maintenance/work-orders/order-details/order-details.component.ts

@@ -186,7 +186,7 @@ export class OrderDetailsComponent implements OnInit {
         let equipmentCodeDec = await this._encService.decrypt(order.response.EQUIPAMIENTO);
         order.response.TIPO_EQUIPAMIENTO = `${equipmentCodeDec} - ${order.response.TIPO_EQUIPAMIENTO}`;
 
-        let idEquipmentDec = await this._encService.decrypt(order.response.ID_EQUIPAMIENTO);
+        let idEquipmentDec = await this._encService.decrypt(order.response.ID_EQUIPAMIENTO!);
         order.response.MODELO_EQUIPAMIENTO = `${order.response.MODELO_EQUIPAMIENTO} (${idEquipmentDec})`;
         order.response.INSTRUCCIONES_ARR = instructionsArr;
 

+ 3 - 3
sistema-mantenimiento-front/src/app/interfaces/preventive-work-order.interface.ts

@@ -14,9 +14,9 @@ export interface PreventiveWorkOrder{
     INSTRUCCIONES: string;
     INSTRUCCIONES_ARR?: Instruction[];
     EQUIPAMIENTO: string;
-    TIPO_EQUIPAMIENTO: string;
-    MODELO_EQUIPAMIENTO: string;
-    ID_EQUIPAMIENTO: string;
+    TIPO_EQUIPAMIENTO: string | null;
+    MODELO_EQUIPAMIENTO: string | null;
+    ID_EQUIPAMIENTO: string | null;
     FECHAINICIO: string | null;
     FECHAFINAL: string | null;
     ANALISIS: string | null;

+ 45 - 0
sistema-mantenimiento-front/src/app/services/functions.service.ts

@@ -266,4 +266,49 @@ export class FunctionsService {
     
     return `${year}${month}${day} ${hour}:${minutes}:${seconds}`;
   }
+
+  getFormattedDate(date: Date): string{
+    let year = date.getFullYear();
+    let month = date.getMonth() + 1;
+    let day = date.getDate();
+    
+    return `${year}-${month < 10 ? `0${month}` : `${month}`}-${day < 10 ? `0${day}` : `${day}`}`;
+  }
+
+  convertFullHourToHumanHour(hour: string): string{
+    let hourArr = hour.split(':');
+    if(hourArr.length == 3){
+      let hourNum = parseInt(hourArr[0]);
+      let period = hourNum < 12 ? 'AM' : 'PM';
+  
+      if(period == 'PM'){
+        hourNum = hourNum > 12 ? hourNum - 12 : hourNum;
+      }
+  
+      let hourStr = hourNum < 10 ? `0${hourNum}` : `${hourNum}`;
+      return `${hourStr}:${hourArr[1]} ${period}`;
+    }
+    
+    return "";
+  }
+
+  convertHumanHourToFullHour(hour: string): string{
+    let timeArr = hour.split(' ');
+    if(timeArr.length == 2){
+      let hourArr = timeArr[0].split(':');
+      if(hourArr.length == 2){
+        let hourNum = parseInt(hourArr[0]);
+        if(timeArr[1] == 'PM'){
+          hourNum = hourNum < 12 ? hourNum + 12 : hourNum;
+        }
+
+        let hourStr = hourNum < 10 ? `0${hourNum}` : `${hourNum}`;
+        return `${hourStr}:${hourArr[1]}:00`;
+      }
+
+      return "";
+    }
+    
+    return "";
+  }
 }