Ver código fonte

Avances equipamientos

Jose Brito 1 ano atrás
pai
commit
3ac8d76dbd

+ 2 - 0
sistema-mantenimiento-front/src/app/app.module.ts

@@ -485,6 +485,7 @@ import { SpecialtiesManagementComponent } from './components/personal-management
 import { SpecialtyFormComponent } from './components/personal-management/specialties-management/specialty-form/specialty-form.component';
 import { PriorityArticleComponent } from './components/acquisition-management/provider/artitle/priority-article/priority-article.component';
 import { GraphicEquipmentSearchComponent } from './components/equipment-management/graphic-equipment-search/graphic-equipment-search.component';
+import { GroupPendingComponent } from './components/equipment-management/group-pending/group-pending.component';
 
 
 @NgModule({
@@ -854,6 +855,7 @@ import { GraphicEquipmentSearchComponent } from './components/equipment-manageme
     SpecialtyFormComponent,
     PriorityArticleComponent,
     GraphicEquipmentSearchComponent,
+    GroupPendingComponent,
   ],
   imports: [
     MatMomentDateModule,

+ 1 - 0
sistema-mantenimiento-front/src/app/components/equipment-management/equipment-card/equipment-card.component.css

@@ -7,6 +7,7 @@
   display: flex;
   flex-direction: column;
   overflow: hidden;
+  box-sizing: border-box;
 }
 
 .pending_width{

+ 11 - 0
sistema-mantenimiento-front/src/app/components/equipment-management/equipment-management.component.css

@@ -134,4 +134,15 @@
   height: 100%;
   overflow-x: hidden;
   overflow-y: auto;
+}
+
+.pending-title-bar{
+  width: 100%;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  padding: 0 16px;
+  box-sizing: border-box;
+  justify-content: space-between;
+  align-items: center;
 }

+ 20 - 4
sistema-mantenimiento-front/src/app/components/equipment-management/equipment-management.component.html

@@ -52,7 +52,7 @@
         <mat-icon>event</mat-icon> Calendario de arborescencias
       </button>
     </mat-menu>
-    <button mat-mini-fab class="cyan_dark_background white_font ml-10" matTooltip="Actualizar datos" (click)="getPendingEquipments()">
+    <button mat-mini-fab class="cyan_dark_background white_font ml-10" matTooltip="Actualizar datos" (click)="getTotalPendingEquipments()">
       <mat-icon>refresh</mat-icon>
     </button>
   </div>
@@ -74,11 +74,27 @@
       <h3 class="ml-20"><b>Su perfil no cuenta con los permisos necesarios para visualizar la información de esta sección.</b></h3>
     </div>
 
-    <div class="pending-equipments animated fadeIn" *ngIf="!isLoading && !hasError && pendingEquipments.length > 0 && equipmentsMenuEnabled">
-      <h2>Equipos en revisión</h2>
-      <div class="pending-equipments-list">
+    <div class="pending-equipments animated fadeIn" *ngIf="!isLoading && !hasError && totalPending > 0 && equipmentsMenuEnabled">
+      <div class="pending-title-bar">
+        <h2>Equipos en revisión</h2>
+        <button mat-icon-button [matMenuTriggerFor]="pendingMenu">
+          <mat-icon>menu</mat-icon>
+        </button>
+        <mat-menu #pendingMenu>
+          <button mat-menu-item (click)="openPendingGroups('aprove')">
+            <span>Aprobar en grupo</span>
+            <mat-icon>done</mat-icon>
+          </button>
+          <button mat-menu-item (click)="openPendingGroups('decline')">
+            <span>Rechazar en grupo</span>
+            <mat-icon>close</mat-icon>
+          </button>
+        </mat-menu>
+      </div>
+      <div class="pending-equipments-list" id="pending-equipments-list">
         <app-equipment-card equipmentType="pending" *ngFor="let pendingEquipment of pendingEquipments" [pendingEquipment]="pendingEquipment" 
         (refreshPendingList)="shouldRefresh($event)"></app-equipment-card>
+        <mat-progress-bar mode="indeterminate" style="width: 456px; margin-bottom: 32px;" *ngIf="loadingPending"></mat-progress-bar>
       </div>
     </div>
 

+ 120 - 21
sistema-mantenimiento-front/src/app/components/equipment-management/equipment-management.component.ts

@@ -31,6 +31,7 @@ import { SocketService } from 'src/app/services/socket.service';
 import { UserConsultResponse } from 'src/app/interfaces/user.interface';
 import { UsersProfilesService } from 'src/app/services/users-profiles.service';
 import { ProfileInterface } from 'src/app/interfaces/profile.interface';
+import { GroupPendingComponent } from './group-pending/group-pending.component';
 
 @Component({
   selector: 'app-equipment-management',
@@ -42,6 +43,8 @@ export class EquipmentManagementComponent implements OnInit {
   hasError: boolean;
   errorStr: string;
   params: any;
+  totalPending: number;
+  loadingPending: boolean;
 
   pendingEquipments: PendingEquipmentsListItem[];
   families: FamiliesListItem[];
@@ -90,6 +93,8 @@ export class EquipmentManagementComponent implements OnInit {
     this.hasError = false;
     this.errorStr = "";
     this.params = null;
+    this.totalPending = 0;
+    this.loadingPending = false;
 
     this.pendingEquipments = [];
     this.families = [];
@@ -498,6 +503,21 @@ export class EquipmentManagementComponent implements OnInit {
     }, 150);
   }
 
+  addPendingEquipmentsScrollListener(){
+    setTimeout(() => {
+      let equipmentList = this._document.getElementById('pending-equipments-list')!;
+      equipmentList.addEventListener('scroll', (event: any) => {
+        let delta = equipmentList.scrollHeight - equipmentList.scrollTop;
+        if(delta < 400 && !this.loadingPending){
+          let offset = this.pendingEquipments.length;
+          if(offset < this.totalPending){
+            this.consultPendingEquipments(offset);
+          }
+        }
+      });
+    });
+  }
+
   async openGraphicArborescence(){
     let arborescenceStr = JSON.stringify(this.graphicArborescence);
     let arborescenceEnc = await this._encService.encrypt(arborescenceStr);
@@ -583,18 +603,56 @@ export class EquipmentManagementComponent implements OnInit {
     })
   }
 
-  async getPendingEquipments(){
+  async getTotalPendingEquipments(){
     try{
+      this.isLoading = true;
+      this.hasError = false;
+      this.errorStr = '';
+      this.totalPending = 0;
+      this.pendingEquipments = [];
+
       let idUser = localStorage.getItem('idusuario')!;
-      let pendingEquipments: PendingEquipmentsListResponse = await lastValueFrom(this._equipmentManagementService.equipmentConsultPending(idUser, 1));
+      let pendingTotal = await lastValueFrom(this._equipmentManagementService.equipmentConsultPendingTotal(idUser, 1));
       
-      this.hasError = pendingEquipments.error;
-      this.errorStr = pendingEquipments.msg;
+      this.hasError = pendingTotal.error;
+      this.errorStr = pendingTotal.msg;
 
       if(!this.hasError){
-        let equipments: PendingEquipmentsListItem[] = [];
+        this.totalPending = pendingTotal.response.TOTAL;
+        this.consultPendingEquipments(0);
+      }
+      
+      this.isLoading = false;
+      this.scrollArborescence();
+      this.addPendingEquipmentsScrollListener();
+    }catch(error: any){
+      if(error.error == undefined){
+        this.errorStr = 'Ocurrió un error inesperado (3).';
+      }else if(error.error.msg == undefined){
+        this.errorStr = 'Ocurrió un error inesperado (4).';
+      }else{
+        this.errorStr = error.error.msg;
+      }
+      this.hasError = true;
+      this.isLoading = false;
+    }
+  }
+
+  private async consultPendingEquipments(offset: number){
+    try{
+      this.loadingPending = true;
+
+      let idUser = localStorage.getItem('idusuario')!;
+      let pendingEquipments: PendingEquipmentsListResponse = await lastValueFrom(this._equipmentManagementService.equipmentConsultPending(
+        offset,
+        idUser, 
+        1
+      ));
+
+      if(pendingEquipments.error){
+        this._resourcesService.openSnackBar(pendingEquipments.msg);
+      }else{
         for(const equipment of pendingEquipments.response){
-          
           equipment.CODIGO = await this._encService.decrypt(equipment.CODIGO);
           equipment.TIPO_EQUIPAMIENTO = await this._encService.decrypt(equipment.TIPO_EQUIPAMIENTO);
           equipment.MODELO_EQUIPAMIENTO = await this._encService.decrypt(equipment.MODELO_EQUIPAMIENTO);
@@ -607,24 +665,21 @@ export class EquipmentManagementComponent implements OnInit {
           }
 
           equipment.GALERIA_IMAGENES = gallery;
-          equipments.push(equipment);
+          this.pendingEquipments.push(equipment);
         }
-
-        this.pendingEquipments = equipments;
       }
 
-      this.isLoading = false;
-      this.scrollArborescence();
+      this.loadingPending = false;
     }catch(error: any){
       if(error.error == undefined){
-        this.errorStr = 'Ocurrió un error inesperado (3).';
+        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
       }else if(error.error.msg == undefined){
-        this.errorStr = 'Ocurrió un error inesperado (4).';
+        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
       }else{
-        this.errorStr = error.error.msg;
+        this._resourcesService.openSnackBar(error.error.msg);
       }
-      this.hasError = true;
-      this.isLoading = false;
+
+      this.loadingPending = false;
     }
   }
 
@@ -658,7 +713,7 @@ export class EquipmentManagementComponent implements OnInit {
 
         this.families = familiesArr;
         if(searchPending){
-          this.getPendingEquipments();
+          this.getTotalPendingEquipments();
         }
       }
     }catch(error: any){
@@ -706,7 +761,7 @@ export class EquipmentManagementComponent implements OnInit {
 
         this.subfamilies = subfamiliesArr;
         if(searchPending){
-          this.getPendingEquipments();
+          this.getTotalPendingEquipments();
         }
       }
     }catch(error: any){
@@ -759,7 +814,7 @@ export class EquipmentManagementComponent implements OnInit {
 
         this.equipmentsBySubfamily = equipments;
         if(searchPending){
-          this.getPendingEquipments();
+          this.getTotalPendingEquipments();
         }
       }
     }catch(error: any){
@@ -958,7 +1013,7 @@ export class EquipmentManagementComponent implements OnInit {
         }
         
         this.parentEquipmentDetails = equipment.response;
-        this.getPendingEquipments();
+        this.getTotalPendingEquipments();
       }
     }catch(error: any){
       console.log(error);
@@ -976,7 +1031,7 @@ export class EquipmentManagementComponent implements OnInit {
 
   shouldRefresh(event: any){
     if(event == 'refresh'){
-      this.getPendingEquipments();
+      this.getTotalPendingEquipments();
     }
   }
 
@@ -1139,4 +1194,48 @@ export class EquipmentManagementComponent implements OnInit {
   navigateToArborescenceCalendar(){
     this._router.navigate(['sam/GEEQ/ADEQ/VAFD']);
   }
+
+  openPendingGroups(action: string){
+    let dialogRef = this._dialog.open(GroupPendingComponent, {
+      disableClose: true,
+      width: '480px',
+      data: {
+        action: action,
+      }
+    });
+
+    dialogRef.afterClosed().subscribe(res => {
+      if(res != null && res != undefined && res != ''){
+        this.changeGroupStatus(res, action);
+      }
+    })
+  }
+
+  private async changeGroupStatus(groupCode: string, action: string){
+    try{
+      let idUser = localStorage.getItem('idusuario')!;
+      let formData = new FormData();
+      let newStatus = action == 'decline' ? 'Rechazado' : 'Aprobado';
+      let codeDec = await this._encService.decrypt(groupCode);
+
+      formData.append('id_user', idUser);
+      formData.append('linea', '1');
+      formData.append('code', groupCode);
+      formData.append('status', newStatus);
+      formData.append('comments', 'test aaaaaaaaaaaaaaa');
+
+      await lastValueFrom(this._equipmentManagementService.equipmentPreCodificationGroupStatusUpdate(formData));
+
+      this._resourcesService.openSnackBar(`El grupo de equipos ${codeDec} fue ${newStatus} correctamente.`);
+      this.getTotalPendingEquipments();
+    }catch(error: any){
+      if(error.error == undefined){
+        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
+      }else if(error.error.msg == undefined){
+        this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
+      }else{
+        this._resourcesService.openSnackBar(error.error.msg);
+      }
+    }
+  }
 }

+ 44 - 0
sistema-mantenimiento-front/src/app/components/equipment-management/group-pending/group-pending.component.css

@@ -0,0 +1,44 @@
+.example-radio-group {
+  display: flex;
+  flex-direction: column;
+  margin: 15px 0;
+  align-items: flex-start;
+}
+
+.example-radio-button {
+  margin: 5px;
+}
+
+.gallery-container{
+  width: 100%;
+  height: 256px;
+  position: relative;
+  overflow: hidden;
+}
+
+.gallery-container img{
+  height: 100%;
+  width: 100%;
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+  object-fit: contain;
+}
+
+.backward-button{
+  position: absolute;
+  top: calc(50% - 24px);
+  left: 8px;
+  z-index: 9999;
+  background-color: rgba(255, 255, 255, 0.75);
+  box-shadow: 0px 10px 15px -3px rgba(0,0,0,0.25);
+}
+
+.forward-button{
+  position: absolute;
+  top: calc(50% - 24px);
+  right: 8px;
+  z-index: 9999;
+  background-color: rgba(255, 255, 255, 0.75);
+  box-shadow: 0px 10px 15px -3px rgba(0,0,0,0.25);
+}

+ 37 - 0
sistema-mantenimiento-front/src/app/components/equipment-management/group-pending/group-pending.component.html

@@ -0,0 +1,37 @@
+<h1 mat-dialog-title class="prevent-select">{{ action }} grupo de equipos en revisión</h1>
+<div mat-dialog-content class="prevent-select">
+  <div class="is-loading animated fadeIn fast" *ngIf="isLoading">
+    <mat-spinner align="center"></mat-spinner>
+    <h3>Cargando datos ...</h3>
+  </div>
+  <div class="has-error animated fadeIn pt-64" *ngIf="!isLoading && hasError">
+    <mat-icon class="red_primary_font">error</mat-icon>
+    <h2>{{ errorStr }}</h2>
+  </div>
+  <div class="dialog_details_column animated fadeIn" *ngIf="!isLoading && !hasError">
+    <h3>Seleccione el grupo que desea procesar</h3>
+    <mat-radio-group class="example-radio-group" [(ngModel)]="selectedGroup">
+      @for(equipment of pendingGroups; track equipment) {
+        <mat-radio-button class="example-radio-button" [value]="equipment.CODIGO">
+          {{ equipment.TIPO_EQUIPAMIENTO }} - {{ equipment.MODELO_EQUIPAMIENTO }}: <b>{{ equipment.TOTAL }}</b> elementos.
+        </mat-radio-button>
+        <div class="gallery-container">
+          <button mat-icon-button class="backward-button" [disabled]="images.get(equipment.CODIGO)!.length < 2" (click)="backward(equipment.CODIGO)">
+            <mat-icon>chevron_left</mat-icon>
+          </button>
+          <button mat-icon-button class="forward-button" [disabled]="images.get(equipment.CODIGO)!.length < 2" (click)="forward(equipment.CODIGO)">
+            <mat-icon>chevron_right</mat-icon>
+          </button>
+          <img *ngIf="images.get(equipment.CODIGO)!.length > 0" [src]="images.get(equipment.CODIGO)![imagesIndexes.get(equipment.CODIGO)!]" [alt]="'IMG' + imagesIndexes.get(equipment.CODIGO)!">
+          <div *ngIf="images.get(equipment.CODIGO)!.length < 1">
+            <b>Sin imágenes.</b>
+          </div>
+        </div>
+      }
+    </mat-radio-group>
+  </div>
+</div>
+<div mat-dialog-actions align="end">
+  <button mat-button mat-dialog-close>Cerrar</button>
+  <button mat-button [disabled]="selectedGroup == ''" (click)="alertProcessPendingEquipments()">Continuar</button>
+</div>

+ 23 - 0
sistema-mantenimiento-front/src/app/components/equipment-management/group-pending/group-pending.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { GroupPendingComponent } from './group-pending.component';
+
+describe('GroupPendingComponent', () => {
+  let component: GroupPendingComponent;
+  let fixture: ComponentFixture<GroupPendingComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [GroupPendingComponent]
+    })
+    .compileComponents();
+    
+    fixture = TestBed.createComponent(GroupPendingComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 140 - 0
sistema-mantenimiento-front/src/app/components/equipment-management/group-pending/group-pending.component.ts

@@ -0,0 +1,140 @@
+import { Component, Inject, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
+import { EquipmentManagementService } from 'src/app/services/equipment-management.service';
+import { lastValueFrom } from 'rxjs';
+import { PendingEquipmentsListItem, PendingEquipmentsListResponse } from 'src/app/interfaces/equipment-management.interface';
+import { EncService } from 'src/app/services/enc/enc.service';
+import { AlertComponent } from '../../resources/dialogs/alert/alert.component';
+
+@Component({
+  selector: 'app-group-pending',
+  templateUrl: './group-pending.component.html',
+  styleUrl: './group-pending.component.css'
+})
+export class GroupPendingComponent implements OnInit {
+  isLoading: boolean;
+  hasError: boolean;
+  errorStr: string;
+  action: string;
+  selectedGroup: string;
+
+  pendingGroups: PendingEquipmentsListItem[];
+  images: Map<string, string[]>;
+  imagesIndexes: Map<string, number>;
+
+  constructor(
+    @Inject(MAT_DIALOG_DATA) private _data: any,
+    private _equipmentManagementService: EquipmentManagementService,
+    private _encService: EncService,
+    private _dialog: MatDialog,
+    private _dialogRef: MatDialogRef<GroupPendingComponent>,
+  ) {
+    this.isLoading = true;
+    this.hasError = false;
+    this.errorStr = '';
+    this.action = '';
+    this.selectedGroup = '';
+
+    this.pendingGroups = [];
+    this.images = new Map();
+    this.imagesIndexes = new Map();
+  }
+
+  ngOnInit(): void {
+    this.action = this._data.action == 'aprove' ? 'Aprobar' : 'Rechazar';
+    this.getGroupedPendingEquipments();
+  }
+
+  async getGroupedPendingEquipments(){
+    try{
+      let idUser = localStorage.getItem('idusuario')!;
+      let pendingGrouped: PendingEquipmentsListResponse = await lastValueFrom(this._equipmentManagementService.equipmentConsultPendingGrouped(idUser, 1));
+
+      this.hasError = pendingGrouped.error;
+      this.errorStr = pendingGrouped.msg;
+
+      if(!this.hasError){
+        let pendingGroupedArr: PendingEquipmentsListItem[] = [];
+        for(const group of pendingGrouped.response){
+          group.CODIGO = await this._encService.decrypt(group.CODIGO);
+          group.TIPO_EQUIPAMIENTO = await this._encService.decrypt(group.TIPO_EQUIPAMIENTO);
+          group.MODELO_EQUIPAMIENTO = await this._encService.decrypt(group.MODELO_EQUIPAMIENTO);
+
+          let galleryArr = JSON.parse(group.GALERIA_IMAGENES as string);
+          let gallery: string[] = [];
+          for(const imageStr of galleryArr){
+            let imageDec = await this._encService.decrypt(imageStr);
+            gallery.push(imageDec);
+          }
+
+          group.GALERIA_IMAGENES = gallery;
+          pendingGroupedArr.push(group);
+          
+          this.images.set(group.CODIGO, group.GALERIA_IMAGENES);
+          this.imagesIndexes.set(group.CODIGO, 0);
+        }
+        
+        this.pendingGroups = pendingGroupedArr;
+      }
+
+      this.isLoading = false;
+    }catch(error: any){
+      if(error.error == undefined){
+        this.errorStr = 'Ocurrió un error inesperado.';
+      }else if(error.error.msg == undefined){
+        this.errorStr = 'Ocurrió un error inesperado.';
+      }else{
+        this.errorStr = error.error.msg;
+      }
+
+      this.hasError = true;
+      this.isLoading = false;
+    }
+  }
+
+  forward(code: string){
+    let index = this.imagesIndexes.get(code)! + 1;
+    if(index > this.images.get(code)!.length - 1){
+      this.imagesIndexes.set(code, 0);
+    }else{
+      this.imagesIndexes.set(code, index);
+    }
+  }
+
+  backward(code: string){
+    let index = this.imagesIndexes.get(code)! - 1;
+    if(index < 0){
+      this.imagesIndexes.set(code, this.images.get(code)!.length - 1);
+    }else{
+      this.imagesIndexes.set(code, index);
+    }
+  }
+
+  alertProcessPendingEquipments(){
+    let groupFilt = this.pendingGroups.filter(item => item.CODIGO == this.selectedGroup);
+    if(groupFilt.length > 0){
+      let actionLower = this.action.toLowerCase();
+      let dialogRef = this._dialog.open(AlertComponent, {
+        width: '420px',
+        disableClose: true,
+        data: {
+          title: 'Confirmación',
+          icon: 'warning',
+          description: `¿Está seguro de ${actionLower} ${groupFilt[0].TOTAL} elementos?`,
+        }
+      });
+
+      dialogRef.afterClosed().subscribe(res => {
+        if(res == true){
+          this.processPendingElements();
+        }
+      });
+    }
+  }
+
+  private async processPendingElements(){
+    let codeEnc = await this._encService.encrypt(this.selectedGroup);
+    this._dialogRef.close(codeEnc);
+  }
+}

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

@@ -1306,13 +1306,13 @@ export class NewWorkOrderComponent implements OnInit {
           let input = this._document.getElementById(`cant-req-${tool}`) as HTMLInputElement;
           if(input.value == ''){
             resourcesConf.push({
-              ID: tool.ID,
+              ID: tool,
               REQ: 0,
               TYPE: 'T'
             });
           }else{
             resourcesConf.push({
-              ID: tool.ID,
+              ID: tool,
               REQ: input.value,
               TYPE: 'T'
             });
@@ -1331,25 +1331,26 @@ export class NewWorkOrderComponent implements OnInit {
           let input = this._document.getElementById(`cant-req-${sparePart}`) as HTMLInputElement;
           if(input.value == ''){
             resourcesConf.push({
-              ID: sparePart.ID,
+              ID: sparePart,
               REQ: 0,
               TYPE: 'S'
             });
           }else{
             resourcesConf.push({
-              ID: sparePart.ID,
+              ID: sparePart,
               REQ: input.value,
               TYPE: 'S'
             });
           }
         }
       }
+      console.log(resourcesConf);
       
       formData.append('resources', JSON.stringify(resourcesConf));
-      await lastValueFrom(this._prevMaintService.savePresetWorkOrder(formData));
+      /*await lastValueFrom(this._prevMaintService.savePresetWorkOrder(formData));
 
       this._resourcesService.openSnackBar('El borrador se guardó correctamente');
-      window.history.back();
+      window.history.back();*/
     }catch(error: any){
       if(error.error == undefined){
         this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
@@ -1858,8 +1859,6 @@ export class NewWorkOrderComponent implements OnInit {
     await lastValueFrom(this._inventoryManagementService.getToolsAndSpare(USER, LINE)).then(
       (responseData: ResponseDataGetToolsAndSpare) => {
         if (!responseData.error) {
-          console.log(responseData.response.REFACCIONES);
-          
           this.tools = responseData.response.HERRAMIENTAS;
           this.spareParts = responseData.response.REFACCIONES;
 

+ 2 - 1
sistema-mantenimiento-front/src/app/interfaces/equipment-management.interface.ts

@@ -108,13 +108,14 @@ export interface PendingEquipmentsListResponse{
 }
 
 export interface PendingEquipmentsListItem{
-  IDREG: string;
+  IDREG?: string;
   CODIGO: string;
   TIPO_CODIGO: string;
   TIPO_EQUIPAMIENTO: string;
   MODELO_EQUIPAMIENTO: string;
   GALERIA_IMAGENES: string | Array<string>; 
   ESTADO_REGISTRO: string;
+  TOTAL?: number;
 }
 
 export interface PendingEquipmentResponse{

+ 14 - 2
sistema-mantenimiento-front/src/app/services/equipment-management.service.ts

@@ -46,8 +46,16 @@ export class EquipmentManagementService {
     return this.getQuery(`occupation/train/elements/${idUser}/${line}`).pipe(map((data: any) => data));
   }
 
-  equipmentConsultPending(idUser: string, line: number){
-    return this.getQuery(`equipment/consult/pending/${idUser}/${line}`).pipe(map((data: any) => data));
+  equipmentConsultPendingTotal(idUser: string, line: number){
+    return this.getQuery(`equipment/consult/pending/total/${idUser}/${line}`).pipe(map((data: any) => data));
+  }
+
+  equipmentConsultPendingGrouped(idUser: string, line: number){
+    return this.getQuery(`equipment/consult/pending/grouped/${idUser}/${line}`).pipe(map((data: any) => data));
+  }
+
+  equipmentConsultPending(offset: number, idUser: string, line: number){
+    return this.getQuery(`equipment/consult/pending/${offset}/${idUser}/${line}`).pipe(map((data: any) => data));
   }
 
   equipmentConsultPendingOnly(idReg: string, idUser: string, line: number){
@@ -160,6 +168,10 @@ export class EquipmentManagementService {
     return this.postQuery("equipment/pre-codification/status/update", body).pipe(map((data: any) => data));
   }
 
+  equipmentPreCodificationGroupStatusUpdate(body: any){
+    return this.postQuery("equipment/pre-codification/group/status/update", body).pipe(map((data: any) => data));
+  }
+
   equipmentGraphicArborescence(body: any){
     return this.postQuery("equipment/graphic-arborescence", body).pipe(map((data: any) => data));
   }