Преглед на файлове

Actualizaciones gestión de personal de mantenimiento

Jose Brito преди 1 година
родител
ревизия
e67e64a170
променени са 11 файла, в които са добавени 604 реда и са изтрити 459 реда
  1. 12 0
      sistema-mantenimiento-front/src/app/components/personal-management/employee/employee-details-dialog/employee-details-dialog.component.ts
  2. 1 1
      sistema-mantenimiento-front/src/app/components/personal-management/employee/employee-form/employee-form.component.html
  3. 72 47
      sistema-mantenimiento-front/src/app/components/personal-management/employee/employee-form/employee-form.component.ts
  4. 12 2
      sistema-mantenimiento-front/src/app/components/personal-management/employee/employee.component.ts
  5. 12 1
      sistema-mantenimiento-front/src/app/components/personal-management/subcontratist/subcontratist-details-dialog/subcontratist-details-dialog.component.ts
  6. 314 311
      sistema-mantenimiento-front/src/app/components/personal-management/subcontratist/subcontratist-form/subcontratist-form.component.html
  7. 175 93
      sistema-mantenimiento-front/src/app/components/personal-management/subcontratist/subcontratist-form/subcontratist-form.component.ts
  8. 2 4
      sistema-mantenimiento-front/src/app/components/personal-management/subcontratist/subcontratist.component.ts
  9. 1 0
      sistema-mantenimiento-front/src/app/components/personal-management/work-team/work-team-form/work-team-form.component.html
  10. 2 0
      sistema-mantenimiento-front/src/app/interfaces/personal-managment/employee.interface.ts
  11. 1 0
      sistema-mantenimiento-front/src/app/interfaces/personal-managment/subcontractist.interface.ts

+ 12 - 0
sistema-mantenimiento-front/src/app/components/personal-management/employee/employee-details-dialog/employee-details-dialog.component.ts

@@ -63,6 +63,18 @@ export class EmployeeDetailsDialogComponent implements OnInit {
         if(this.employee.FECMOD != null){
           this.employee.FECMOD = this.buildDate(this.employee.FECMOD);
         }
+
+        let specialtiesArr: string[] = JSON.parse(this.employee.SPECIALITY);
+        let specialtiesStr = "";
+        for(const specialty of specialtiesArr){
+          let specialtyDec = await this._encService.decrypt(specialty);
+          specialtiesStr += `${specialtyDec}, `;
+        }
+
+        specialtiesStr = specialtiesStr.substring(0, specialtiesStr.length - 2);
+
+        this.employee.SPECIALITY = specialtiesStr;
+        this.employee.SPECIALITY_ARR = specialtiesArr;
       }
 
       this.isLoading = false;

+ 1 - 1
sistema-mantenimiento-front/src/app/components/personal-management/employee/employee-form/employee-form.component.html

@@ -39,7 +39,7 @@
                 <div class="form-cell pt-8" [ngClass]="{ fw_50: screenSize > 920, fw_100: screenSize <= 920 }">
                   <mat-form-field appearance="outline">
                     <mat-label>Equipo de Trabajo</mat-label>
-                    <mat-select formControlName="workteamId" (valueChange)="workteamChange(team.value)" #team>
+                    <mat-select formControlName="workteamId">
                       <mat-option value="-">Ninguno</mat-option>
                       @for (workteam of workteams; track workteam) {
                         <mat-option [value]="workteam.WORKTEAM_ID"> {{ workteam.NAME }} - {{ workteam.SPECIALITY }} </mat-option>

+ 72 - 47
sistema-mantenimiento-front/src/app/components/personal-management/employee/employee-form/employee-form.component.ts

@@ -29,6 +29,7 @@ import { GdelService } from 'src/app/services/document-management/gdel.service';
 import { HttpClient, HttpErrorResponse } from '@angular/common/http';
 import { InterventionService } from 'src/app/services/personal-management/intervention.service';
 import { SpecialtiesListItem, SpecialtiesListResponse } from 'src/app/interfaces/specialties.interface';
+import { GetWorkteams, ResponseDataGetWorkteams } from 'src/app/interfaces/personal-managment/workteam.interface';
 
 @Component({
   selector: 'app-employee-form',
@@ -43,7 +44,7 @@ export class EmployeeFormComponent implements OnInit {
   public btnSmall: boolean;
   public formGroup: FormGroup;
   public isLoadingForm: boolean;
-  public workteams: Array<any>;
+  public workteams: Array<GetWorkteams>;
   public subcontratists: Array<SubcontratistItem>;
   public countries: Array<CountriesList>;
 
@@ -522,9 +523,9 @@ export class EmployeeFormComponent implements OnInit {
       this.searchingStates = false;
     }catch(error: any){
       if(error.error == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (1).");
       }else if(error.error.msg == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (2).");
       }else{
         this._resourcesService.openSnackBar(error.error.msg);
       }
@@ -559,9 +560,9 @@ export class EmployeeFormComponent implements OnInit {
       this.searchingCities = false;
     }catch(error: any){
       if(error.error == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (3).");
       }else if(error.error.msg == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (4).");
       }else{
         this._resourcesService.openSnackBar(error.error.msg);
       }
@@ -609,9 +610,9 @@ export class EmployeeFormComponent implements OnInit {
       this.searchingTowns = false;
     }catch(error: any){
       if(error.error == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (5).");
       }else if(error.error.msg == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (6).");
       }else{
         this._resourcesService.openSnackBar(error.error.msg);
       }
@@ -650,9 +651,9 @@ export class EmployeeFormComponent implements OnInit {
       this.searchingSettings = false;
     }catch(error: any){
       if(error.error == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (7).");
       }else if(error.error.msg == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (8).");
       }else{
         this._resourcesService.openSnackBar(error.error.msg);
       }
@@ -726,9 +727,9 @@ export class EmployeeFormComponent implements OnInit {
       this.searchingAddress = false;
     }catch(error: any){
       if(error.error == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (9).");
       }else if(error.error.msg == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (10).");
       }else{
         this._resourcesService.openSnackBar(error.error.msg);
       }
@@ -753,9 +754,9 @@ export class EmployeeFormComponent implements OnInit {
       }
     }catch(error: any){
       if(error.error == undefined){
-        this.errorStr = 'Ocurrió un error inesperado.';
+        this.errorStr = 'Ocurrió un error inesperado (11).';
       }else if(error.error.msg == undefined){
-        this.errorStr = 'Ocurrió un error inesperado.';
+        this.errorStr = 'Ocurrió un error inesperado (12).';
       }else{
         this.errorStr = error.error.msg;
       }
@@ -803,9 +804,9 @@ export class EmployeeFormComponent implements OnInit {
       }
     }catch(error: any){
       if(error.error == undefined){
-        this.errorStr = "Ocurrió un error inesperado.";
+        this.errorStr = "Ocurrió un error inesperado (13).";
       }else if(error.error.msg == undefined){
-        this.errorStr = "Ocurrió un error inesperado.";
+        this.errorStr = "Ocurrió un error inesperado (14).";
       }else{
         this.errorStr = error.error.msg;
       }
@@ -843,7 +844,7 @@ export class EmployeeFormComponent implements OnInit {
       workteamId: new FormControl('', Validators.required),
       contractType: new FormControl('', Validators.required),
       subcontratistId: new FormControl({value: '', disabled: true}, Validators.required),
-      speciality: new FormControl({value: '', disabled: true}, Validators.required),
+      speciality: new FormControl([], Validators.required),
       foreigner: new FormControl('', Validators.required),
       RFC: new FormControl({value: '', disabled: true}, [Validators.required, Validators.minLength(13), Validators.maxLength(13), Validators.pattern(new RegExp(/^([A-ZÑ&]{3,4}) ?(?:- ?)?(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])) ?(?:- ?)?([A-Z\d]{2})([A\d])$/))]),
       tax: new FormControl({value: '', disabled: true}, [Validators.required, Validators.minLength(13), Validators.maxLength(13), Validators.pattern(new RegExp(/^([A-ZÑ&]{3,4}) ?(?:- ?)?(\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])) ?(?:- ?)?([A-Z\d]{2})([A\d])$/))]),
@@ -937,9 +938,11 @@ export class EmployeeFormComponent implements OnInit {
         formData.append('WORKTEAM_ID', formValue.workteamId);
         formData.append('CONTRACT_TYPE', formValue.contractType);
         formData.append('SUBCONTRATIST_ID', subcontratist);
-        formData.append('SPECIALITY', formValue.speciality);
         formData.append('FOREIGNER', formValue.foreigner);
 
+        let specialtyStr = JSON.stringify(formValue.speciality);
+        formData.append('SPECIALITY', specialtyStr);
+
         let rfc = formValue.RFC == null ? '-' : await this._encService.encrypt(formValue.RFC);
         let tax = formValue.tax == null ? '-' : await this._encService.encrypt(formValue.tax);
 
@@ -1175,9 +1178,11 @@ export class EmployeeFormComponent implements OnInit {
         formData.append('WORKTEAM_ID', formValue.workteamId);
         formData.append('CONTRACT_TYPE', formValue.contractType);
         formData.append('SUBCONTRATIST_ID', subcontratist);
-        formData.append('SPECIALITY', formValue.speciality);
         formData.append('FOREIGNER', formValue.foreigner);
 
+        let specialtyStr = JSON.stringify(formValue.speciality);
+        formData.append('SPECIALITY', specialtyStr);
+
         let rfc = formValue.RFC == null ? '-' : await this._encService.encrypt(formValue.RFC);
         let tax = formValue.tax == null ? '-' : await this._encService.encrypt(formValue.tax);
 
@@ -1395,7 +1400,7 @@ export class EmployeeFormComponent implements OnInit {
   private async getWorkteams() {
     try{
       let idUser = localStorage.getItem('idusuario')!;
-      let workTeams = await lastValueFrom(this._workteamService.getConsultOfWorkteams(idUser, 1));
+      let workTeams: ResponseDataGetWorkteams = await lastValueFrom(this._workteamService.getConsultOfWorkteams(idUser, 1));
 
       if(workTeams.error){
         this.hasError = workTeams.error;
@@ -1407,14 +1412,27 @@ export class EmployeeFormComponent implements OnInit {
           workTeamDec = await this._encService.decrypt(this.employee.WORKTEAM_ID);
         }
 
+        let workTeamsArr: GetWorkteams[] = [];
         for(const workteam of workTeams.response){
           if(workteam.STATUS == 'Activo'){
+            let specialtiesArr: string[] = JSON.parse(workteam.SPECIALITY);
+            let specialtiesStr = "";
+            for(const specialtyCode of specialtiesArr){
+              let codeDec = await this._encService.decrypt(specialtyCode);
+              specialtiesStr += `${codeDec}, `;
+            }
+
+            specialtiesStr = specialtiesStr.substring(0, specialtiesStr.length - 2);
+            workteam.SPECIALITY = specialtiesStr;
+            workteam.SPECIALTY_ARR = specialtiesArr;
+            
             let idWorkTeamDec = await this._encService.decrypt(workteam.WORKTEAM_ID);
             if(workTeamDec == idWorkTeamDec){
               this.formGroup.controls['workteamId'].setValue(workteam.WORKTEAM_ID);
             }
 
-            this.workteams.push(workteam);
+            workteam.NAME = `${workteam.NAME} (${idWorkTeamDec})`;
+            workTeamsArr.push(workteam);
           }
         }
 
@@ -1423,13 +1441,14 @@ export class EmployeeFormComponent implements OnInit {
           this.formGroup.controls['speciality'].enable();
         }
 
+        this.workteams = workTeamsArr;
         this.getSubcontratists();
       }
     }catch(error: any){
       if(error.error == undefined){
-        this.errorStr = "Ocurrió un error inesperado.";
+        this.errorStr = "Ocurrió un error inesperado (15).";
       }else if(error.error.msg == undefined){
-        this.errorStr = "Ocurrió un error inesperado.";
+        this.errorStr = "Ocurrió un error inesperado (16).";
       }else{
         this.errorStr = error.error.msg;
       }
@@ -1451,13 +1470,14 @@ export class EmployeeFormComponent implements OnInit {
       }else{
         for(const subcontratist of subcontratists.response){
           if(subcontratist.STATUS == 'Activo'){
-            let idEnc = await this._encService.encrypt(`${subcontratist.ID_SUBCONTRATIST}`);
-            if(this.employee != null && this.employee.CONTRACT_TYPE == 'Subcontratista' && this.employee.SUBCONTRATIST_ID == subcontratist.ID_SUBCONTRATIST){
-              this.formGroup.controls['subcontratistId'].setValue(idEnc);
+            let idDec = await this._encService.decrypt(subcontratist.ID_SUBCONTRATIST);
+            subcontratist.NAME = `${subcontratist.NAME} (${idDec})`;
+
+            if(this.employee != null && this.employee.CONTRACT_TYPE == 'Subcontratista' && this.employee.SUBCONTRATIST_ID == idDec){
+              this.formGroup.controls['subcontratistId'].setValue(subcontratist.ID_SUBCONTRATIST);
               this.formGroup.controls['subcontratistId'].enable();
             }
 
-            subcontratist.ID_SUBCONTRATIST = idEnc;
             this.subcontratists.push(subcontratist);
           }
         }
@@ -1466,9 +1486,9 @@ export class EmployeeFormComponent implements OnInit {
       }
     }catch(error: any){
       if(error.error == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (17).");
       }else if(error.error.msg == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (18).");
       }else{
         this._resourcesService.openSnackBar(error.error.msg);
       }
@@ -1535,9 +1555,9 @@ export class EmployeeFormComponent implements OnInit {
       }
     }catch(error: any){
       if(error.error == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (19).");
       }else if(error.error.msg == undefined){
-        this._resourcesService.openSnackBar("Ocurrió un error inesperado.");
+        this._resourcesService.openSnackBar("Ocurrió un error inesperado (20).");
       }else{
         this._resourcesService.openSnackBar(error.error.msg);
       }
@@ -1553,6 +1573,17 @@ export class EmployeeFormComponent implements OnInit {
       this.errorStr = specialties.msg;
 
       if(!this.hasError){
+        let selectedSpecialties: string[] = [];
+        if(this.employee != null){
+          let employeeSpecialtiesArr: string[] = JSON.parse(this.employee.SPECIALITY);
+          for(const specialtyCode of employeeSpecialtiesArr){
+            let specialtyDec = await this._encService.decrypt(specialtyCode);
+            let specialtyArr = specialtyDec.split(' - ');
+
+            selectedSpecialties.push(specialtyArr[0]);
+          }
+        }
+
         let specialtiesArr: SpecialtiesListItem[] = [];
         for(const specialty  of specialties.response){
           let codeDec = await this._encService.decrypt(specialty.CODIGO_ESPECIALIDAD);
@@ -1560,6 +1591,13 @@ export class EmployeeFormComponent implements OnInit {
 
           if(specialty.ESTADO == 'Activo'){
             specialtiesArr.push(specialty);
+
+            if(selectedSpecialties.includes(codeDec)){
+              let specialtyVal = this.formGroup.controls['speciality'].value;
+              specialtyVal.push(specialty.CODIGO_ESPECIALIDAD);
+
+              this.formGroup.controls['speciality'].setValue(specialtyVal);
+            }
           }
         }
 
@@ -1569,9 +1607,9 @@ export class EmployeeFormComponent implements OnInit {
       this.isLoading = false;
     }catch(error: any){
       if(error.error == undefined){
-        this.errorStr = 'Ocurrió un error inesperado.';
+        this.errorStr = 'Ocurrió un error inesperado (21).';
       }else if(error.error.msg == undefined){
-        this.errorStr = 'Ocurrió un error inesperado.';
+        this.errorStr = 'Ocurrió un error inesperado (22).';
       }else{
         this.errorStr = error.error.msg;
       }
@@ -1613,7 +1651,6 @@ export class EmployeeFormComponent implements OnInit {
         this.employee = employee.response;
 
         this.formGroup.controls['contractType'].setValue(this.employee.CONTRACT_TYPE);
-        this.formGroup.controls['speciality'].setValue(this.employee.SPECIALITY);
         this.formGroup.controls['foreigner'].setValue(this.employee.FOREIGNER);
         
         if(this.employee.FOREIGNER == 'Si'){
@@ -1673,9 +1710,9 @@ export class EmployeeFormComponent implements OnInit {
       }
     }catch(error: any){
       if(error.error == undefined){
-        this.errorStr = 'Ocurrió un error inesperado.';
+        this.errorStr = 'Ocurrió un error inesperado (23).';
       }else if(error.error.msg == undefined){
-        this.errorStr = 'Ocurrió un error inesperado.';
+        this.errorStr = 'Ocurrió un error inesperado (24).';
       }else{
         this.errorStr = error.error.msg;
       }
@@ -1900,18 +1937,6 @@ export class EmployeeFormComponent implements OnInit {
     }
   }
 
-  workteamChange(value: string){
-    if(value == '-'){
-      this.formGroup.controls['speciality'].setValue(null);
-      this.formGroup.controls['speciality'].enable();
-    }else{
-      let team = this.workteams.filter(item => item.WORKTEAM_ID == value)[0];
-      
-      this.formGroup.controls['speciality'].setValue(team.SPECIALITY);
-      this.formGroup.controls['speciality'].disable();
-    }
-  }
-
   checkAttached(type: string){
     if(type == 'AU' || type == 'OF' || type == 'CE'){
       let filesByType = this.attached.filter(item => item.type == type);

+ 12 - 2
sistema-mantenimiento-front/src/app/components/personal-management/employee/employee.component.ts

@@ -63,7 +63,7 @@ export class EmployeeComponent implements OnInit {
     this.errorStr = "";
     
     this.isLoadingForm = false;
-    this.btnSmall = false;
+    this.btnSmall = window.innerWidth <= 1405;
     this.cardSmall = false;
 
     this.txtBuscadorEmployees = '';
@@ -195,11 +195,21 @@ export class EmployeeComponent implements OnInit {
 
       if(!this.hasError){
         let employeesArr: EmployeesListItem[] = [];
+        
         for(const employee of employees.response){
           let idEmployeeDec = await this._encService.decrypt(employee.ID_EMPLOYEE);
+          let specialtiesArr: string[] = JSON.parse(employee.SPECIALITY);
+          let specialtiesStr = "";
+          for(const specialty of specialtiesArr){
+            let specialtyDec = await this._encService.decrypt(specialty);
+            specialtiesStr += `${specialtyDec}, `;
+          }
+
+          specialtiesStr = specialtiesStr.substring(0, specialtiesStr.length - 2);
 
+          employee.SPECIALITY = specialtiesStr;
+          employee.SPECIALITY_ARR = specialtiesArr;
           if(employee.TEAM_ID != null){
-            console.log(employee.TEAM_ID);
             let idTeamDec = await this._encService.decrypt(employee.TEAM_ID);
             employee.TEAM_NAME = `${employee.TEAM_NAME} (${idTeamDec})`;
           }

+ 12 - 1
sistema-mantenimiento-front/src/app/components/personal-management/subcontratist/subcontratist-details-dialog/subcontratist-details-dialog.component.ts

@@ -39,7 +39,6 @@ export class SubcontratistDetailsDialogComponent implements OnInit {
 
   async getData(idSubEnc: string){
     try{
-      
       let idSubDec = await this._encService.decrypt(idSubEnc);
       this.idSub = idSubDec;
 
@@ -52,6 +51,18 @@ export class SubcontratistDetailsDialogComponent implements OnInit {
 
       if(!this.hasError){
         this.subcontratist = subcontratist.response;
+
+        let specialtiesArr: string[] = JSON.parse(this.subcontratist.SPECIALTY);
+        let specialtiesStr = "";
+        for(const specialty of specialtiesArr){
+          let specialtyDec = await this._encService.decrypt(specialty);
+          specialtiesStr += `${specialtyDec}, `;
+        }
+
+        specialtiesStr = specialtiesStr.substring(0, specialtiesStr.length - 2);
+        
+        this.subcontratist.SPECIALTY = specialtiesStr;
+        this.subcontratist.SPECIALTY_ARR = specialtiesArr;
       }
       
       this.isLoading = false;

+ 314 - 311
sistema-mantenimiento-front/src/app/components/personal-management/subcontratist/subcontratist-form/subcontratist-form.component.html

@@ -1,329 +1,332 @@
-<div class="items-container animated fadeIn prevent-select" >
+<div class="main-container animated fadeIn prevent-select" (window:resize)="onResize()">
 
   <app-btn-navigate navigate="goback" nameButton="Gestión de subcontratistas"/>
 
-  <mat-card class="override-elevation-z8" style="width: 100%; height: 100%;">
-
-    <app-loading-card 
-      [isLoading]="isLoading" 
-      [isLoadingForm]="isLoadingForm" 
-      [txtLoading]="'Cargando formulario... '"
-    />
-
-
-    <mat-card-title style="text-align: center; margin: 15px 0;" [style.visibility]="!isLoading ? 'visible' : 'hidden'" >
-      {{ this.typeFormSubcontract.type === 'REG' ? 'Registrar Subcontratista' : 'Modificar Subcontratista' }}
-    </mat-card-title>
-    <mat-card-content [style.visibility]="isLoading ? 'visible' : 'hidden'">
-
-      @if (!isLoading && hasError) {
-        <div class="form-order-container">
-          <div class="is-loading animated fadeIn fast">
-            <mat-icon class="red_primary_font mb-40" >error</mat-icon>
-            <h3>{{ errorStr }}</h3>
+  @if (!isLoading) {
+    <mat-card class="override-card override-elevation-z8">
+      <mat-card-title style="text-align: center; margin: 15px 0;" [style.visibility]="!isLoading ? 'visible' : 'hidden'" >
+        {{ this.typeFormSubcontract.type === 'REG' ? 'Registrar Subcontratista' : 'Modificar Subcontratista' }}
+      </mat-card-title>
+      <mat-card-content>
+        @if (!isLoading && hasError) {
+          <div class="form-order-container">
+            <div class="is-loading animated fadeIn fast">
+              <mat-icon class="red_primary_font mb-40" >error</mat-icon>
+              <h3>{{ errorStr }}</h3>
+            </div>
           </div>
-        </div>
-      }
+        }
 
-      @if (!hasError) {
-        <div class="form-order-container" [style.visibility]="!isLoading ? 'visible' : 'hidden'">
-          <div class="form-column" [formGroup]="formGroup">
-            <div class="form-row">
-              <div class="form-cell pt-8" [ngClass]="{ fw_60: resourcesService.innerWidth() > 1000, fw_100: resourcesService.innerWidth() <= 1000 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>Razón Social</mat-label>
-                  <input matInput placeholder="Ingrese su Razón Social" formControlName="socialReason" (input)="formGroup.controls['socialReason'].markAsTouched()">
-                  @if (formGroup.controls['socialReason'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                  }
-                  @if (formGroup.controls['socialReason'].hasError('maxlength')) {
-                    <mat-error>La longitud máxima del campo es de 150 caracteres.</mat-error>
-                  }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_40: resourcesService.innerWidth() > 1000, fw_100: resourcesService.innerWidth() <= 1000 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>Régimen Fiscal</mat-label>
-                  <input matInput placeholder="Ingrese su Régimen Fiscal" [matAutocomplete]="autocompleteTaxRegime" formControlName="taxReference">
-                  <mat-autocomplete autoActiveFirstOption #autocompleteTaxRegime>
-                    @for (taxRegimeStr of filteredTaxRegime | async; track taxRegimeStr) {
-                      <mat-option [value]="taxRegimeStr"> {{ taxRegimeStr }} </mat-option>
+        @if (!isLoading && !hasError) {
+          <div class="form-order-container">
+            <div class="form-column" [formGroup]="formGroup">
+              <div class="form-row">
+                <div class="form-cell pt-8" [ngClass]="{ fw_60: resourcesService.innerWidth() > 1000, fw_100: resourcesService.innerWidth() <= 1000 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>Razón Social</mat-label>
+                    <input matInput placeholder="Ingrese su Razón Social" formControlName="socialReason" (input)="formGroup.controls['socialReason'].markAsTouched()">
+                    @if (formGroup.controls['socialReason'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
                     }
-                  </mat-autocomplete>
-                  @if (formGroup.controls['taxReference'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                  }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1180, fw_50: resourcesService.innerWidth() <= 1180 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>Tipo de Contribuyente</mat-label>
-                  <mat-select (ngModelChange)="onchangeType()" formControlName="contractType">
-                    <mat-option value="Persona física">Persona Física</mat-option>
-                    <mat-option value="Persona moral">Persona Moral</mat-option>
-                  </mat-select>
-                  @if (formGroup.controls['contractType'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                  }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1180, fw_50: resourcesService.innerWidth() <= 1180 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>Nacionalidad</mat-label>
-                  <mat-select (ngModelChange)="changeNationality()" formControlName="foreigner" #nat>
-                    <mat-option value="No">Nacional</mat-option>
-                    <mat-option value="Si">Extranjero</mat-option>
-                  </mat-select>
-                  @if (formGroup.controls['foreigner'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                  }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1180, fw_50: resourcesService.innerWidth() <= 1180 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline">
-                  <mat-label>R.F.C.</mat-label>
-                  <input matInput placeholder="Ingrese su R.F.C." oninput="javascript: this.value= this.value.toUpperCase();" formControlName="RFC" 
-                  (input)="formGroup.controls['RFC'].markAsTouched()">
-                  @if (formGroup.controls['RFC'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                  }
-                  @if (formGroup.controls['RFC'].hasError('minlength')) {
-                    <mat-error>Este campo debe tener al menos {{ taxLength }} caracteres.</mat-error>
-                  }
-                  @if (formGroup.controls['RFC'].hasError('maxlength')) {
-                    <mat-error>Este campo puede tener máximo {{ taxLength }} caracteres.</mat-error>
-                  }
-                  @if (formGroup.controls['RFC'].hasError('pattern')) {
-                    <mat-error>El formato del RFC ingresado es inválido.</mat-error>
-                  }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1180, fw_50: resourcesService.innerWidth() <= 1180 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>TAX ID</mat-label>
-                  <input matInput placeholder="Ingrese su TAX ID" oninput="javascript: this.value= this.value.toUpperCase();" formControlName="tax" 
-                  (input)="formGroup.controls['tax'].markAsTouched()">
-                  @if (formGroup.controls['tax'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                  }
-                  @if (formGroup.controls['tax'].hasError('minlength')) {
-                    <mat-error>Este campo debe tener al menos {{ taxLength }} caracteres.</mat-error>
-                  }
-                  @if (formGroup.controls['tax'].hasError('maxlength')) {
-                    <mat-error>Este campo puede tener máximo {{ taxLength }} caracteres.</mat-error>
-                  }
-                  @if (formGroup.controls['tax'].hasError('pattern')) {
-                    <mat-error>El formato del TAX ID ingresado es inválido.</mat-error>
-                  }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_66: resourcesService.innerWidth() > 1180, fw_100: resourcesService.innerWidth() <= 1180 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>Correo Electrónico</mat-label>
-                  <input matInput placeholder="Ingrese su Correo Electrónico" formControlName="email" (input)="formGroup.controls['email'].markAsTouched()">
-                  @if (formGroup.controls['email'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                  }
-                  @if (formGroup.controls['email'].hasError('maxlength')) {
-                    <mat-error>Este campo puede tener máximo 150 caracteres.</mat-error>
-                  }
-                  @if (formGroup.controls['email'].hasError('email')) {
-                    <mat-error>El formato del correo electrónico ingresado es inválido.</mat-error>
-                  }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>País</mat-label>
-                  <input matInput formControlName="country" [matAutocomplete]="autocompleteCountry" id="country" 
-                  (input)="checkIfAddress(country.value)" #country>
-                  <mat-autocomplete autoActiveFirstOption #autocompleteCountry (optionSelected)="checkIfAddress(country.value)">
-                    <mat-option *ngFor="let countryStr of filteredCountries | async" [value]="countryStr" 
-                    [disabled]="(countryStr == 'México (MEX)' && nat.value == 'Si') || (countryStr != 'México (MEX)' && nat.value == 'No')">
-                      {{ countryStr }}
-                    </mat-option>
-                  </mat-autocomplete>
-                  @if (formGroup.controls['country'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                  }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100" *ngIf="!searchingStates">
-                  <mat-label>Estado</mat-label>
-                  <input matInput formControlName="federalEntity" [matAutocomplete]="autocompleteState" id="state">
-                  <mat-autocomplete autoActiveFirstOption #autocompleteState>
-                    <mat-option *ngFor="let stateStr of filteredStates | async" [value]="stateStr">
-                      {{ stateStr }}
-                    </mat-option>
-                  </mat-autocomplete>
-                  @if (formGroup.controls['federalEntity'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                  }
-                </mat-form-field>
-                <mat-progress-bar mode="indeterminate" class="w-100" *ngIf="searchingStates"></mat-progress-bar>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100" *ngIf="!searchingCities">
-                  <mat-label>Municipio</mat-label>
-                  <input matInput formControlName="city" [matAutocomplete]="autocompleteCity" id="city">
-                  <mat-autocomplete autoActiveFirstOption #autocompleteCity>
-                    <mat-option *ngFor="let cityStr of filteredCities | async" [value]="cityStr">
-                      {{ cityStr }}
-                    </mat-option>
-                  </mat-autocomplete>
-                  @if (formGroup.controls['city'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                  }
-                </mat-form-field>
-                <mat-progress-bar mode="indeterminate" class="w-100" *ngIf="searchingCities"></mat-progress-bar>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100" *ngIf="!searchingTowns">
-                  <mat-label>Localidad</mat-label>
-                  <input matInput formControlName="town" [matAutocomplete]="autocompleteTown" id="town">
-                  <mat-autocomplete autoActiveFirstOption #autocompleteTown>
-                    <mat-option *ngFor="let townStr of filteredTowns | async" [value]="townStr">
-                      {{ townStr }}
-                    </mat-option>
-                  </mat-autocomplete>
-                  @if (formGroup.controls['town'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
+                    @if (formGroup.controls['socialReason'].hasError('maxlength')) {
+                      <mat-error>La longitud máxima del campo es de 150 caracteres.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_40: resourcesService.innerWidth() > 1000, fw_100: resourcesService.innerWidth() <= 1000 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>Régimen Fiscal</mat-label>
+                    <input matInput placeholder="Ingrese su Régimen Fiscal" [matAutocomplete]="autocompleteTaxRegime" formControlName="taxReference">
+                    <mat-autocomplete autoActiveFirstOption #autocompleteTaxRegime>
+                      @for (taxRegimeStr of filteredTaxRegime | async; track taxRegimeStr) {
+                        <mat-option [value]="taxRegimeStr"> {{ taxRegimeStr }} </mat-option>
+                      }
+                    </mat-autocomplete>
+                    @if (formGroup.controls['taxReference'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1180, fw_50: resourcesService.innerWidth() <= 1180 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>Tipo de Contribuyente</mat-label>
+                    <mat-select (ngModelChange)="onchangeType()" formControlName="contractType">
+                      <mat-option value="Persona física">Persona Física</mat-option>
+                      <mat-option value="Persona moral">Persona Moral</mat-option>
+                    </mat-select>
+                    @if (formGroup.controls['contractType'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1180, fw_50: resourcesService.innerWidth() <= 1180 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>Nacionalidad</mat-label>
+                    <mat-select (ngModelChange)="changeNationality()" formControlName="foreigner" #nat>
+                      <mat-option value="No">Nacional</mat-option>
+                      <mat-option value="Si">Extranjero</mat-option>
+                    </mat-select>
+                    @if (formGroup.controls['foreigner'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1180, fw_50: resourcesService.innerWidth() <= 1180 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline">
+                    <mat-label>R.F.C.</mat-label>
+                    <input matInput placeholder="Ingrese su R.F.C." oninput="javascript: this.value= this.value.toUpperCase();" formControlName="RFC" 
+                    (input)="formGroup.controls['RFC'].markAsTouched()">
+                    @if (formGroup.controls['RFC'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                    @if (formGroup.controls['RFC'].hasError('minlength')) {
+                      <mat-error>Este campo debe tener al menos {{ taxLength }} caracteres.</mat-error>
+                    }
+                    @if (formGroup.controls['RFC'].hasError('maxlength')) {
+                      <mat-error>Este campo puede tener máximo {{ taxLength }} caracteres.</mat-error>
+                    }
+                    @if (formGroup.controls['RFC'].hasError('pattern')) {
+                      <mat-error>El formato del RFC ingresado es inválido.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1180, fw_50: resourcesService.innerWidth() <= 1180 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>TAX ID</mat-label>
+                    <input matInput placeholder="Ingrese su TAX ID" oninput="javascript: this.value= this.value.toUpperCase();" formControlName="tax" 
+                    (input)="formGroup.controls['tax'].markAsTouched()">
+                    @if (formGroup.controls['tax'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                    @if (formGroup.controls['tax'].hasError('minlength')) {
+                      <mat-error>Este campo debe tener al menos {{ taxLength }} caracteres.</mat-error>
+                    }
+                    @if (formGroup.controls['tax'].hasError('maxlength')) {
+                      <mat-error>Este campo puede tener máximo {{ taxLength }} caracteres.</mat-error>
+                    }
+                    @if (formGroup.controls['tax'].hasError('pattern')) {
+                      <mat-error>El formato del TAX ID ingresado es inválido.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_66: resourcesService.innerWidth() > 1180, fw_100: resourcesService.innerWidth() <= 1180 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>Correo Electrónico</mat-label>
+                    <input matInput placeholder="Ingrese su Correo Electrónico" formControlName="email" (input)="formGroup.controls['email'].markAsTouched()">
+                    @if (formGroup.controls['email'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                    @if (formGroup.controls['email'].hasError('maxlength')) {
+                      <mat-error>Este campo puede tener máximo 150 caracteres.</mat-error>
+                    }
+                    @if (formGroup.controls['email'].hasError('email')) {
+                      <mat-error>El formato del correo electrónico ingresado es inválido.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>País</mat-label>
+                    <input matInput formControlName="country" [matAutocomplete]="autocompleteCountry" id="country" 
+                    (input)="checkIfAddress(country.value)" #country>
+                    <mat-autocomplete autoActiveFirstOption #autocompleteCountry (optionSelected)="checkIfAddress(country.value)">
+                      <mat-option *ngFor="let countryStr of filteredCountries | async" [value]="countryStr" 
+                      [disabled]="(countryStr == 'México (MEX)' && nat.value == 'Si') || (countryStr != 'México (MEX)' && nat.value == 'No')">
+                        {{ countryStr }}
+                      </mat-option>
+                    </mat-autocomplete>
+                    @if (formGroup.controls['country'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100" *ngIf="!searchingStates">
+                    <mat-label>Estado</mat-label>
+                    <input matInput formControlName="federalEntity" [matAutocomplete]="autocompleteState" id="state">
+                    <mat-autocomplete autoActiveFirstOption #autocompleteState>
+                      <mat-option *ngFor="let stateStr of filteredStates | async" [value]="stateStr">
+                        {{ stateStr }}
+                      </mat-option>
+                    </mat-autocomplete>
+                    @if (formGroup.controls['federalEntity'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                  <mat-progress-bar mode="indeterminate" class="w-100" *ngIf="searchingStates"></mat-progress-bar>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100" *ngIf="!searchingCities">
+                    <mat-label>Municipio</mat-label>
+                    <input matInput formControlName="city" [matAutocomplete]="autocompleteCity" id="city">
+                    <mat-autocomplete autoActiveFirstOption #autocompleteCity>
+                      <mat-option *ngFor="let cityStr of filteredCities | async" [value]="cityStr">
+                        {{ cityStr }}
+                      </mat-option>
+                    </mat-autocomplete>
+                    @if (formGroup.controls['city'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                  <mat-progress-bar mode="indeterminate" class="w-100" *ngIf="searchingCities"></mat-progress-bar>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100" *ngIf="!searchingTowns">
+                    <mat-label>Localidad</mat-label>
+                    <input matInput formControlName="town" [matAutocomplete]="autocompleteTown" id="town">
+                    <mat-autocomplete autoActiveFirstOption #autocompleteTown>
+                      <mat-option *ngFor="let townStr of filteredTowns | async" [value]="townStr">
+                        {{ townStr }}
+                      </mat-option>
+                    </mat-autocomplete>
+                    @if (formGroup.controls['town'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                  <mat-progress-bar mode="indeterminate" class="w-100" *ngIf="searchingTowns"></mat-progress-bar>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100" *ngIf="!searchingSettings">
+                    <mat-label>Colonia</mat-label>
+                    <input matInput formControlName="suburb" [matAutocomplete]="autocompleteSetting" id="setting">
+                    <mat-autocomplete autoActiveFirstOption #autocompleteSetting>
+                      <mat-option *ngFor="let settingStr of filteredSettings | async" [value]="settingStr">
+                        {{ settingStr }}
+                      </mat-option>
+                    </mat-autocomplete>
+                    @if (formGroup.controls['suburb'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                  <mat-progress-bar mode="indeterminate" class="w-100" *ngIf="searchingSettings"></mat-progress-bar>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100" *ngIf="!searchingAddress">
+                    <mat-label>Código Postal</mat-label>
+                    <input matInput placeholder="Ingrese su Código Postal" formControlName="postalCode" (input)="searchZipCode(zipCode.value)" #zipCode id="zipCode">
+                    @if (formGroup.controls['postalCode'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                  <mat-progress-bar mode="indeterminate" class="w-100" *ngIf="searchingAddress"></mat-progress-bar>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_50: resourcesService.innerWidth() > 1320, fw_100: resourcesService.innerWidth() <= 1320 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>Calle</mat-label>
+                    <input matInput placeholder="Ingrese su Calle" formControlName="street" (input)="formGroup.controls['street'].markAsTouched()">
+                    @if (formGroup.controls['street'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                    @if (formGroup.controls['street'].hasError('maxlength')) {
+                      <mat-error>Este campo puede tener máximo 150 caracteres.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>Número Exterior</mat-label>
+                    <input type="text" matInput placeholder="Ingrese su Número Exterior" formControlName="exteriorNumber" 
+                    (input)="formGroup.controls['exteriorNumber'].markAsTouched()">
+                    @if (formGroup.controls['exteriorNumber'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
                   }
-                </mat-form-field>
-                <mat-progress-bar mode="indeterminate" class="w-100" *ngIf="searchingTowns"></mat-progress-bar>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100" *ngIf="!searchingSettings">
-                  <mat-label>Colonia</mat-label>
-                  <input matInput formControlName="suburb" [matAutocomplete]="autocompleteSetting" id="setting">
-                  <mat-autocomplete autoActiveFirstOption #autocompleteSetting>
-                    <mat-option *ngFor="let settingStr of filteredSettings | async" [value]="settingStr">
-                      {{ settingStr }}
-                    </mat-option>
-                  </mat-autocomplete>
-                  @if (formGroup.controls['suburb'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
+                    @if (formGroup.controls['exteriorNumber'].hasError('maxlength')) {
+                    <mat-error>Este campo puede tener máximo 10 caracteres.</mat-error>
                   }
-                </mat-form-field>
-                <mat-progress-bar mode="indeterminate" class="w-100" *ngIf="searchingSettings"></mat-progress-bar>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100" *ngIf="!searchingAddress">
-                  <mat-label>Código Postal</mat-label>
-                  <input matInput placeholder="Ingrese su Código Postal" formControlName="postalCode" (input)="searchZipCode(zipCode.value)" #zipCode id="zipCode">
-                  @if (formGroup.controls['postalCode'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>Número Interior</mat-label>
+                    <input type="text" matInput placeholder="Ingrese su Número Interior" formControlName="interiorNumber" 
+                    (input)="formGroup.controls['interiorNumber'].markAsTouched()">
+                    @if (formGroup.controls['interiorNumber'].hasError('maxlength')) {
+                    <mat-error>Este campo puede tener máximo 10 caracteres.</mat-error>
                   }
-                </mat-form-field>
-                <mat-progress-bar mode="indeterminate" class="w-100" *ngIf="searchingAddress"></mat-progress-bar>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_50: resourcesService.innerWidth() > 1320, fw_100: resourcesService.innerWidth() <= 1320 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>Calle</mat-label>
-                  <input matInput placeholder="Ingrese su Calle" formControlName="street" (input)="formGroup.controls['street'].markAsTouched()">
-                  @if (formGroup.controls['street'].hasError('required')) {
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_16: resourcesService.innerWidth() > 1000, fw_33: resourcesService.innerWidth() <= 1000 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>Lada 1</mat-label>
+                    <input matInput formControlName="lada1" [matAutocomplete]="autocompleteLada1">
+                    <mat-autocomplete autoActiveFirstOption #autocompleteLada1>
+                      <mat-option *ngFor="let lada1 of filteredLadas1 | async" [value]="lada1">
+                        <img [src]="'assets/img/flags/' + flags.get(lada1) + '.png'" width="16px" height="16px" style="margin: 4px 4px 0 0;">{{ lada1 }}
+                      </mat-option>
+                    </mat-autocomplete>
+                    @if (formGroup.controls['lada1'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1000, fw_66: resourcesService.innerWidth() <= 1000 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline">
+                    <mat-label>Teléfono 1</mat-label>
+                    <input matInput placeholder="Ingrese su Teléfono 1" formControlName="telephone1" type="number"  
+                    oninput="javascript: if (this.value.length> 11) this.value = this.value.slice(0, 11);">
+                    @if (formGroup.controls['telephone1'].hasError('required')) {
                     <mat-error>Este campo es obligatorio.</mat-error>
                   }
-                  @if (formGroup.controls['street'].hasError('maxlength')) {
-                    <mat-error>Este campo puede tener máximo 150 caracteres.</mat-error>
+                    @if (formGroup.controls['telephone1'].hasError('minlength')) {
+                    <mat-error>Este debe tener al menos 7 caracteres.</mat-error>
                   }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>Número Exterior</mat-label>
-                  <input type="text" matInput placeholder="Ingrese su Número Exterior" formControlName="exteriorNumber" 
-                  (input)="formGroup.controls['exteriorNumber'].markAsTouched()">
-                  @if (formGroup.controls['exteriorNumber'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
-                }
-                  @if (formGroup.controls['exteriorNumber'].hasError('maxlength')) {
-                  <mat-error>Este campo puede tener máximo 10 caracteres.</mat-error>
-                }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_25: resourcesService.innerWidth() > 1320, fw_50: resourcesService.innerWidth() <= 1320 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>Número Interior</mat-label>
-                  <input type="text" matInput placeholder="Ingrese su Número Interior" formControlName="interiorNumber" 
-                  (input)="formGroup.controls['interiorNumber'].markAsTouched()">
-                  @if (formGroup.controls['interiorNumber'].hasError('maxlength')) {
-                  <mat-error>Este campo puede tener máximo 10 caracteres.</mat-error>
-                }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_16: resourcesService.innerWidth() > 1000, fw_33: resourcesService.innerWidth() <= 1000 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>Lada 1</mat-label>
-                  <input matInput formControlName="lada1" [matAutocomplete]="autocompleteLada1">
-                  <mat-autocomplete autoActiveFirstOption #autocompleteLada1>
-                    <mat-option *ngFor="let lada1 of filteredLadas1 | async" [value]="lada1">
-                      <img [src]="'assets/img/flags/' + flags.get(lada1) + '.png'" width="16px" height="16px" style="margin: 4px 4px 0 0;">{{ lada1 }}
-                    </mat-option>
-                  </mat-autocomplete>
-                  @if (formGroup.controls['lada1'].hasError('required')) {
-                    <mat-error>Este campo es obligatorio.</mat-error>
+                    @if (formGroup.controls['telephone1'].hasError('maxlength')) {
+                    <mat-error>Este campo puede tener máximo 11 caracteres.</mat-error>
                   }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1000, fw_66: resourcesService.innerWidth() <= 1000 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline">
-                  <mat-label>Teléfono 1</mat-label>
-                  <input matInput placeholder="Ingrese su Teléfono 1" formControlName="telephone1" type="number"  
-                  oninput="javascript: if (this.value.length> 11) this.value = this.value.slice(0, 11);">
-                  @if (formGroup.controls['telephone1'].hasError('required')) {
-                  <mat-error>Este campo es obligatorio.</mat-error>
-                }
-                  @if (formGroup.controls['telephone1'].hasError('minlength')) {
-                  <mat-error>Este debe tener al menos 7 caracteres.</mat-error>
-                }
-                  @if (formGroup.controls['telephone1'].hasError('maxlength')) {
-                  <mat-error>Este campo puede tener máximo 11 caracteres.</mat-error>
-                }
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_16: resourcesService.innerWidth() > 1000, fw_33: resourcesService.innerWidth() <= 1000 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline">
-                  <mat-label>Lada 2</mat-label>
-                  <input matInput formControlName="lada2" [matAutocomplete]="autocompleteLada2">
-                  <mat-autocomplete autoActiveFirstOption #autocompleteLada2>
-                    <mat-option *ngFor="let lada2 of filteredLadas2 | async" [value]="lada2">
-                      <img [src]="'assets/img/flags/' + flags.get(lada2) + '.png'" width="16px" height="16px" style="margin: 4px 4px 0 0;">{{ lada2 }}
-                    </mat-option>
-                  </mat-autocomplete>
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1000, fw_66: resourcesService.innerWidth() <= 1000 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
-                <mat-form-field appearance="outline">
-                  <mat-label>Teléfono 2</mat-label>
-                  <input type="number" matInput placeholder="Ingrese su Teléfono 2" minlength="7" maxlength="10" 
-                  type="number" oninput="javascript: if (this.value.length> this.maxLength) this.value = this.value.slice(0, this.maxLength);" formControlName="telephone2">
-                </mat-form-field>
-              </div>
-              <div class="form-cell pt-8" [ngClass]="{ fw_50: resourcesService.innerWidth() > 1320, fw_100: resourcesService.innerWidth() <= 1320 }">
-                <mat-form-field appearance="outline" class="w-100">
-                  <mat-label>Especialidad</mat-label>
-                  <input matInput placeholder="Ingrese su Calle" formControlName="specialty" (input)="formGroup.controls['specialty'].markAsTouched()">
-                  @if (formGroup.controls['specialty'].hasError('required')) {
-                  <mat-error>Este campo es obligatorio.</mat-error>
-                }
-                  @if (formGroup.controls['specialty'].hasError('maxlength')) {
-                  <mat-error>Este campo puede tener máximo 100 caracteres.</mat-error>
-                }
-                </mat-form-field>
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_16: resourcesService.innerWidth() > 1000, fw_33: resourcesService.innerWidth() <= 1000 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline">
+                    <mat-label>Lada 2</mat-label>
+                    <input matInput formControlName="lada2" [matAutocomplete]="autocompleteLada2">
+                    <mat-autocomplete autoActiveFirstOption #autocompleteLada2>
+                      <mat-option *ngFor="let lada2 of filteredLadas2 | async" [value]="lada2">
+                        <img [src]="'assets/img/flags/' + flags.get(lada2) + '.png'" width="16px" height="16px" style="margin: 4px 4px 0 0;">{{ lada2 }}
+                      </mat-option>
+                    </mat-autocomplete>
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_33: resourcesService.innerWidth() > 1000, fw_66: resourcesService.innerWidth() <= 1000 && resourcesService.innerWidth() > 720, fw_100: resourcesService.innerWidth() <= 720 }">
+                  <mat-form-field appearance="outline">
+                    <mat-label>Teléfono 2</mat-label>
+                    <input type="number" matInput placeholder="Ingrese su Teléfono 2" minlength="7" maxlength="10" 
+                    type="number" oninput="javascript: if (this.value.length> this.maxLength) this.value = this.value.slice(0, this.maxLength);" formControlName="telephone2">
+                  </mat-form-field>
+                </div>
+                <div class="form-cell pt-8" [ngClass]="{ fw_50: resourcesService.innerWidth() > 1320, fw_100: resourcesService.innerWidth() <= 1320 }">
+                  <mat-form-field appearance="outline" class="w-100">
+                    <mat-label>Especialidades y/u oficios</mat-label>
+                    <mat-select formControlName="specialty" multiple>
+                      <mat-option *ngFor="let specialty of specialties" [value]="specialty.CODIGO_ESPECIALIDAD">
+                        {{ specialty.NOMBRE_ESPECIALIDAD }}
+                      </mat-option>
+                    </mat-select>
+                    @if (formGroup.controls['specialty'].hasError('required')) {
+                      <mat-error>Este campo es obligatorio.</mat-error>
+                    }
+                  </mat-form-field>
+                </div>
               </div>
             </div>
           </div>
-        </div>
+        }
+      </mat-card-content>
+
+      @if (!isLoading) {
+        <mat-card-actions align="end">
+          <button mat-button (click)="this.alert()" [disabled]="formGroup.invalid || isLoadingForm">
+            <mat-icon>save</mat-icon> Guardar
+          </button>
+        </mat-card-actions>
       }
-    </mat-card-content>
-    @if (!isLoading) {
-      <mat-card-actions align="end">
-        <button mat-button (click)="this.alert()" [disabled]="formGroup.invalid || isLoadingForm">
-          <mat-icon>save</mat-icon> Guardar
-        </button>
-      </mat-card-actions>
-    }
-  </mat-card>
+    </mat-card>
+  } @else {
+    <mat-card class="override-card override-elevation-z8">
+      <app-loading-card
+        [isLoading]="isLoading"
+        [isLoadingForm]="isLoadingForm"
+        [txtLoading]="'Cargando la información del formulario'"
+      />
+    </mat-card>
+  }
 </div>

+ 175 - 93
sistema-mantenimiento-front/src/app/components/personal-management/subcontratist/subcontratist-form/subcontratist-form.component.ts

@@ -22,6 +22,8 @@ import { ProviderService } from 'src/app/services/acquisition-management/provide
 import { ResponseDataGetProvidersById, ResponseDataInformationProvider } from 'src/app/interfaces/acquisition-management/provider.interface';
 import { ResponseData } from 'src/app/interfaces/response-data';
 import { SocketService } from 'src/app/services/socket.service';
+import { SpecialtiesListItem, SpecialtiesListResponse } from 'src/app/interfaces/specialties.interface';
+import { InterventionService } from 'src/app/services/personal-management/intervention.service';
 
 @Component({
   selector: 'app-subcontratist-form',
@@ -42,6 +44,7 @@ export class SubcontratistFormComponent implements OnInit {
   public searchingSettings: boolean;
   public enableSearchByZipCode: boolean;
 
+  public specialties: SpecialtiesListItem[];
   public countries: CountriesList[];
   public countriesStr: string[];
   public countryStates: CountryState[];
@@ -73,6 +76,9 @@ export class SubcontratistFormComponent implements OnInit {
 
   public typeFormSubcontract: TypeFormSubcontract;
 
+  public btnSmall: boolean;
+  public screenSize: number;
+
   constructor(
     @Inject(DOCUMENT) private _document: Document,
     public resourcesService: ResourcesService,
@@ -83,6 +89,7 @@ export class SubcontratistFormComponent implements OnInit {
     private _sysAdminService: SystemAdminService,
     private _providerService: ProviderService,
     private _socketService: SocketService,
+    private _interventionService: InterventionService,
   ) {
     // this.action = "";
     this.isLoading = true;
@@ -100,6 +107,7 @@ export class SubcontratistFormComponent implements OnInit {
     this.formGroup = this.createFormGroup();
     this.isLoadingForm = false;
 
+    this.specialties = [];
     this.countries = [];
     this.countriesStr = [];
     this.countryStates = [];
@@ -119,9 +127,10 @@ export class SubcontratistFormComponent implements OnInit {
     this.flags = new Map();
 
     this.typeFormSubcontract = {} as TypeFormSubcontract;
+    this.btnSmall = window.innerWidth <= 1405;
+    this.screenSize = window.innerWidth;
   }
 
-
   async ngOnInit() {
     this.isLoading = true;
     const encTypeForm = this._activatedRoute.snapshot.paramMap.get('form');
@@ -133,6 +142,8 @@ export class SubcontratistFormComponent implements OnInit {
     const strTypeForm: string = await this._encService.decrypt(encTypeForm);
     this.typeFormSubcontract = JSON.parse(strTypeForm);
 
+    await this.getSpecialties();
+
     await this.getCountries();
 
     await this.getTaxRegime();
@@ -262,6 +273,46 @@ export class SubcontratistFormComponent implements OnInit {
     
   }
 
+  async getSpecialties(){
+    try{
+      let idUser = localStorage.getItem('idusuario')!;
+      let specialties: SpecialtiesListResponse = await lastValueFrom(this._interventionService.getSpecialties(idUser, 1));
+
+      this.hasError = specialties.error;
+      this.errorStr = specialties.msg;
+
+      if(!this.hasError){
+        let specialtiesArr: SpecialtiesListItem[] = [];
+        for(const specialty  of specialties.response){
+          let codeDec = await this._encService.decrypt(specialty.CODIGO_ESPECIALIDAD);
+          specialty.NOMBRE_ESPECIALIDAD = `${codeDec} - ${specialty.NOMBRE_ESPECIALIDAD}`;
+
+          if(specialty.ESTADO == 'Activo'){
+            specialtiesArr.push(specialty);
+          }
+        }
+
+        this.specialties = specialtiesArr;
+      }
+    }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;
+    }
+  }
+
+  // Método para reajustar los botones según sus dimensiones
+  public onResize(): void {
+    this.btnSmall = window.innerWidth <= 1405;
+    this.screenSize = window.innerWidth;
+  }
+
   private _filterCountries(value: string): string[]{
     const filterValue = value.toLowerCase();
     return this.countriesStr.filter(item => item.toLowerCase().includes(filterValue));
@@ -319,111 +370,140 @@ export class SubcontratistFormComponent implements OnInit {
       lada1: new FormControl('', Validators.required),
       telephone2: new FormControl(''),
       lada2: new FormControl(''),
-      specialty: new FormControl('', [Validators.required, Validators.maxLength(100)]),
+      specialty: new FormControl([], Validators.required),
     })
   }
 
   private async getDataForm() {
-    if (this.typeFormSubcontract.idSubcontract === null && this.typeFormSubcontract.type === 'UPD') {
-      this.resourcesService.openSnackBar(`Ocurrió un error al obtener los datos del subcontratista`);
-      return;
-    } else if (this.typeFormSubcontract.idSubcontract !== null && this.typeFormSubcontract.type === 'UPD') {
-      
-      const ID_SUBCONTRACT: string = this.typeFormSubcontract.idSubcontract.toString();
-      const ENC_SUBCONTRACT: string = await this._encService.encrypt(ID_SUBCONTRACT);
-      const USER: string = this.resourcesService.getUser();
-      const LINE: number = this.resourcesService.getLineNumber();
-
-      await lastValueFrom(this._subcontratistService.getSubcontratistById( ENC_SUBCONTRACT, USER, LINE )).then(
-        (responseData: ResponseDataSubcontratist) => {
-          if (!responseData.error) {            
-            
-            this.formGroup.controls['socialReason'].setValue(responseData.response.SOCIAL_REASON);
-
-            this.formGroup.controls['contractType'].setValue(responseData.response.CONTRACT_TYPE);
-            if(responseData.response.CONTRACT_TYPE == 'Persona moral'){
-              let moralTaxRegime = this.taxRegime.filter(item => item.APPLY_MORAL == 'Sí');
-              moralTaxRegime.forEach(item => {
-                this.taxRegimeStr.push(`${item.TAX_REGIME_DESC} (${item.TAX_REGIME_KEY})`);
-              });
-            }else{
-              let phisicTaxRegime = this.taxRegime.filter(item => item.APPLY_PHISIC == 'Sí');
-              phisicTaxRegime.forEach(item => {
-                this.taxRegimeStr.push(`${item.TAX_REGIME_DESC} (${item.TAX_REGIME_KEY})`);
-              });
-            }
-            this.formGroup.controls['taxReference'].enable();
+    try{
+      if (this.typeFormSubcontract.idSubcontract === null && this.typeFormSubcontract.type === 'UPD') {
+        this.resourcesService.openSnackBar(`Ocurrió un error al obtener los datos del subcontratista`);
+        return;
+      } else if (this.typeFormSubcontract.idSubcontract !== null && this.typeFormSubcontract.type === 'UPD') {
+        const ID_SUBCONTRACT: string = this.typeFormSubcontract.idSubcontract.toString();
+        const USER: string = this.resourcesService.getUser();
+        const LINE: number = this.resourcesService.getLineNumber();
+
+        let responseData: ResponseDataSubcontratist = await lastValueFrom(this._subcontratistService.getSubcontratistById(
+          ID_SUBCONTRACT, 
+          USER, 
+          LINE
+        ));
+
+        this.hasError = responseData.error;
+        this.errorStr = responseData.msg;
+
+        if(!this.hasError){
             
-            this.formGroup.controls['taxReference'].setValue(responseData.response.TAX_REFERENCE);
-            this.formGroup.controls['foreigner'].setValue(responseData.response.FOREIGNER);
+          this.formGroup.controls['socialReason'].setValue(responseData.response.SOCIAL_REASON);
 
-            if(responseData.response.FOREIGNER == 'Si'){
-              this.formGroup.controls['tax'].enable();
-              this.formGroup.controls['tax'].setValue(responseData.response.TAX);
-            }else{
-              this.formGroup.controls['RFC'].enable();
-              this.formGroup.controls['RFC'].setValue(responseData.response.RFC);
-            }
+          this.formGroup.controls['contractType'].setValue(responseData.response.CONTRACT_TYPE);
+          if(responseData.response.CONTRACT_TYPE == 'Persona moral'){
+            let moralTaxRegime = this.taxRegime.filter(item => item.APPLY_MORAL == 'Sí');
+            moralTaxRegime.forEach(item => {
+              this.taxRegimeStr.push(`${item.TAX_REGIME_DESC} (${item.TAX_REGIME_KEY})`);
+            });
+          }else{
+            let phisicTaxRegime = this.taxRegime.filter(item => item.APPLY_PHISIC == 'Sí');
+            phisicTaxRegime.forEach(item => {
+              this.taxRegimeStr.push(`${item.TAX_REGIME_DESC} (${item.TAX_REGIME_KEY})`);
+            });
+          }
+          this.formGroup.controls['taxReference'].enable();
+          
+          this.formGroup.controls['taxReference'].setValue(responseData.response.TAX_REFERENCE);
+          this.formGroup.controls['foreigner'].setValue(responseData.response.FOREIGNER);
 
-            this.formGroup.controls['email'].setValue(responseData.response.EMAIL);
-            this.formGroup.controls['country'].enable();
-            this.formGroup.controls['country'].setValue(responseData.response.COUNTRY);
-            this.formGroup.controls['federalEntity'].setValue(responseData.response.FEDERAL_ENTITY);
+          if(responseData.response.FOREIGNER == 'Si'){
+            this.formGroup.controls['tax'].enable();
+            this.formGroup.controls['tax'].setValue(responseData.response.TAX);
+          }else{
+            this.formGroup.controls['RFC'].enable();
+            this.formGroup.controls['RFC'].setValue(responseData.response.RFC);
+          }
 
-            if(responseData.response.CITY != null){
-              this.formGroup.controls['city'].setValue(responseData.response.CITY);
-            }else{
-              this.formGroup.controls['city'].setValue('Sin municipio');
-            }
+          this.formGroup.controls['email'].setValue(responseData.response.EMAIL);
+          this.formGroup.controls['country'].enable();
+          this.formGroup.controls['country'].setValue(responseData.response.COUNTRY);
+          this.formGroup.controls['federalEntity'].setValue(responseData.response.FEDERAL_ENTITY);
 
-            if(responseData.response.TOWN != null){
-              this.formGroup.controls['town'].setValue(responseData.response.TOWN);
-            }else{
-              this.formGroup.controls['town'].setValue('Sin localidad');
-            }
+          if(responseData.response.CITY != null){
+            this.formGroup.controls['city'].setValue(responseData.response.CITY);
+          }else{
+            this.formGroup.controls['city'].setValue('Sin municipio');
+          }
+
+          if(responseData.response.TOWN != null){
+            this.formGroup.controls['town'].setValue(responseData.response.TOWN);
+          }else{
+            this.formGroup.controls['town'].setValue('Sin localidad');
+          }
 
-            this.formGroup.controls['suburb'].setValue(responseData.response.SUBURB);
-            this.formGroup.controls['postalCode'].setValue(responseData.response.POSTAL_CODE);
-            this.formGroup.controls['street'].setValue(responseData.response.STREET);
-            this.formGroup.controls['exteriorNumber'].setValue(responseData.response.EXTERIOR_NUMBER);
-            this.formGroup.controls['interiorNumber'].setValue(responseData.response.INTERIOR_NUMBER);
+          this.formGroup.controls['suburb'].setValue(responseData.response.SUBURB);
+          this.formGroup.controls['postalCode'].setValue(responseData.response.POSTAL_CODE);
+          this.formGroup.controls['street'].setValue(responseData.response.STREET);
+          this.formGroup.controls['exteriorNumber'].setValue(responseData.response.EXTERIOR_NUMBER);
+          this.formGroup.controls['interiorNumber'].setValue(responseData.response.INTERIOR_NUMBER);
 
-            let countryArr = responseData.response.COUNTRY.split('(').reverse()!;
-            let countryStr = countryArr[0].replace(')', '');
-            let country = this.countries.filter(item => item.COUNTRY_ID == countryStr);
-            let countryCode = country[0].NOMECLARUTA_ISO2;
+          let countryArr = responseData.response.COUNTRY.split('(').reverse()!;
+          let countryStr = countryArr[0].replace(')', '');
+          let country = this.countries.filter(item => item.COUNTRY_ID == countryStr);
+          let countryCode = country[0].NOMECLARUTA_ISO2;
 
 
-            this.formGroup.controls['telephone1'].setValue(responseData.response.TELEPHONE1);
-            let arrLada1 = this.countries.find((element) => element.LADA === responseData.response.LADA1)
-            if (arrLada1 === undefined) {
-              this.formGroup.controls['lada1'].setValue(responseData.response.LADA1);
+          this.formGroup.controls['telephone1'].setValue(responseData.response.TELEPHONE1);
+          let arrLada1 = this.countries.find((element) => element.LADA === responseData.response.LADA1)
+          if (arrLada1 === undefined) {
+            this.formGroup.controls['lada1'].setValue(responseData.response.LADA1);
+          } else {
+            this.formGroup.controls['lada1'].setValue(`${arrLada1.LADA}-${arrLada1.NOMECLARUTA_ISO2}`);
+          }
+          
+          this.formGroup.controls['telephone2'].setValue(responseData.response.TELEPHONE2);
+          if(responseData.response.LADA2 !== null){
+            let arrLada2 = this.countries.find((element) => element.LADA === responseData.response.LADA2)
+            if (arrLada2 === undefined) {
+              this.formGroup.controls['lada2'].setValue(responseData.response.LADA1);
             } else {
-              this.formGroup.controls['lada1'].setValue(`${arrLada1.LADA}-${arrLada1.NOMECLARUTA_ISO2}`);
-            }
-            
-            this.formGroup.controls['telephone2'].setValue(responseData.response.TELEPHONE2);
-            if(responseData.response.LADA2 !== null){
-              let arrLada2 = this.countries.find((element) => element.LADA === responseData.response.LADA2)
-              if (arrLada2 === undefined) {
-                this.formGroup.controls['lada2'].setValue(responseData.response.LADA1);
-              } else {
-                this.formGroup.controls['lada2'].setValue(`${arrLada2.LADA}-${arrLada2.NOMECLARUTA_ISO2}`);
-            }
-            }else{
-              this.formGroup.controls['lada2'].setValue(null);
-              this.formGroup.controls['telephone2'].setValue(null);
+              this.formGroup.controls['lada2'].setValue(`${arrLada2.LADA}-${arrLada2.NOMECLARUTA_ISO2}`);
+          }
+          }else{
+            this.formGroup.controls['lada2'].setValue(null);
+            this.formGroup.controls['telephone2'].setValue(null);
+          }
+
+          let specialtiesArr: string[] = JSON.parse(responseData.response.SPECIALTY);
+          let selectedSpecialties: string[] = [];
+          for(const specialty of specialtiesArr){
+            let specialtyDec = await this._encService.decrypt(specialty);
+            let specialtyArr = specialtyDec.split(' - ');
+
+            selectedSpecialties.push(specialtyArr[0]);
+          }
+
+          for(const specialty of this.specialties){
+            let codeDec = await this._encService.decrypt(specialty.CODIGO_ESPECIALIDAD);
+            if(selectedSpecialties.includes(codeDec)){
+              let specialtiesVal = this.formGroup.controls['specialty'].value;
+              specialtiesVal.push(specialty.CODIGO_ESPECIALIDAD);
+          
+              this.formGroup.controls['specialty'].setValue(specialtiesVal);
             }
+          }
+        }
+      } else if (this.typeFormSubcontract.idSubcontract === null && this.typeFormSubcontract.idProvider !== null && this.typeFormSubcontract.type === 'REG') {
+        await this.setInformationProvider(this.typeFormSubcontract.idProvider);
+      }
+    }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 = 'Ocurrió un error inesperado.';
+      }
 
-            this.formGroup.controls['specialty'].setValue(responseData.response.SPECIALTY);
-         
-          } else {
-            this.resourcesService.openSnackBar(`${responseData.msg}`);
-          } 
-        }, (httpErrorResponse:HttpErrorResponse) => this.resourcesService.checkErrors(httpErrorResponse)
-      );
-    } else if (this.typeFormSubcontract.idSubcontract === null && this.typeFormSubcontract.idProvider !== null && this.typeFormSubcontract.type === 'REG') {
-      await this.setInformationProvider(this.typeFormSubcontract.idProvider);
+      this.hasError = true;
     }
   }
 
@@ -828,7 +908,8 @@ export class SubcontratistFormComponent implements OnInit {
         formData.append('TELEPHONE2', '-');
       }
       
-      formData.append('SPECIALTY', formValue.specialty);
+      let specialtiesStr = JSON.stringify(formValue.specialty);
+      formData.append('SPECIALTY', specialtiesStr);
 
       if (this.typeFormSubcontract.idProvider !== null) {
         formData.append('PROVIDER', this.typeFormSubcontract.idProvider);
@@ -871,7 +952,7 @@ export class SubcontratistFormComponent implements OnInit {
       let formValue = this.formGroup.getRawValue();
       let formData = new FormData();
       let idUser = localStorage.getItem('idusuario');
-      let idSubEnc = await this._encService.encrypt(`${this.typeFormSubcontract.idSubcontract}`);
+      let idSubEnc = `${this.typeFormSubcontract.idSubcontract}`;
   
       formData.append('linea', '1');
       formData.append('id_user', idUser!);
@@ -1087,7 +1168,8 @@ export class SubcontratistFormComponent implements OnInit {
         formData.append('TELEPHONE2', '-');
       }
       
-      formData.append('SPECIALTY', formValue.specialty);
+      let specialtiesStr = JSON.stringify(formValue.specialty);
+      formData.append('SPECIALTY', specialtiesStr);
   
       if (this.typeFormSubcontract.idProvider !== null) {
         formData.append('PROVIDER', this.typeFormSubcontract.idProvider);

+ 2 - 4
sistema-mantenimiento-front/src/app/components/personal-management/subcontratist/subcontratist.component.ts

@@ -156,11 +156,10 @@ export class SubcontratistComponent implements OnInit, AfterViewInit {
         width: '900px',
       });
     } else if (typeForm === 'DET') {
-      const id = await this._encService.encrypt(`${element.ID_SUBCONTRATIST}`);
       this._dialog.open(SubcontratistDetailsDialogComponent, {
         width: '520px',
         data: {
-          idSub: id,
+          idSub: element.ID_SUBCONTRATIST,
         }
       });
     }else if (typeForm === 'PRO' && element !== undefined) {
@@ -286,12 +285,11 @@ export class SubcontratistComponent implements OnInit, AfterViewInit {
   private async deleteSubcontratist(subcontratistId: string) {
     try{
       let idUser = localStorage.getItem('idusuario')!;
-      let idSubEnc = await this._encService.encrypt(`${subcontratistId}`);
       let formData = new FormData();
 
       formData.append('id_user', idUser);
       formData.append('linea', '1');
-      formData.append('id_subcontratist', idSubEnc);
+      formData.append('id_subcontratist', subcontratistId);
 
       await lastValueFrom(this._subcontratistService.updateToInactiveStatus(formData));
       this.resourcesService.openSnackBar('Eliminación exitosa.');

+ 1 - 0
sistema-mantenimiento-front/src/app/components/personal-management/work-team/work-team-form/work-team-form.component.html

@@ -35,6 +35,7 @@
       <div *ngIf="action == 'DET'" class="w-100">
         <h3 style="font-weight: 500;">Miembros del equipo:</h3>
         <ul>
+          <li *ngIf="members.length == 0">Sin integrantes</li>
           <li *ngFor="let member of members;">{{ member.NAME }}</li>
         </ul>
       </div>

+ 2 - 0
sistema-mantenimiento-front/src/app/interfaces/personal-managment/employee.interface.ts

@@ -71,6 +71,7 @@ export interface EmployeeInfo {
   TAX_REGIME: string | null;
   TAX_REGIME_DESCRIPTION: string | null;
   SPECIALITY: string;
+  SPECIALITY_ARR?: string[];
   FOREIGNER: string;
   RFC: string | null;
   TAX_ID: string | null;
@@ -122,6 +123,7 @@ export interface EmployeesListItem{
   NAME: string;
   CONTRACT_TYPE: string;
   SPECIALITY: string;
+  SPECIALITY_ARR?: string[];
   TEAM_ID: string | null;
   TEAM_NAME: string | null;
   REGISTER_DATE: string;

+ 1 - 0
sistema-mantenimiento-front/src/app/interfaces/personal-managment/subcontractist.interface.ts

@@ -39,6 +39,7 @@ export interface Subcontratist {
   TELEPHONE2: string | null;
   LADA2: string | null;
   SPECIALTY: string;
+  SPECIALTY_ARR?: string[];
   STATUS: string;
 }