import { Component, OnInit, ChangeDetectorRef, Renderer2, ElementRef, ViewChild, inject, QueryList, ViewChildren } from '@angular/core'; import {FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms'; import {MatIconModule} from '@angular/material/icon'; import {MatDividerModule} from '@angular/material/divider'; import {MatButtonModule} from '@angular/material/button'; import {provideNativeDateAdapter , MatNativeDateModule , MAT_DATE_FORMATS } from '@angular/material/core'; import {DateRange, MatDatepickerModule, MatDateRangeInput } from '@angular/material/datepicker'; import {MatFormFieldModule} from '@angular/material/form-field'; import {MatInputModule} from '@angular/material/input'; import {MatSelectModule} from '@angular/material/select'; import {MatButtonToggleModule} from '@angular/material/button-toggle'; import {MatCheckboxModule} from '@angular/material/checkbox'; import {ConformidadHelper} from "./helper/conformidad.helper"; import {NgClass, NgForOf, NgIf, DatePipe, AsyncPipe, NgStyle} from "@angular/common"; import {MatCard, MatCardContent, MatCardFooter, MatCardHeader, MatCardTitle , MatCardModule} from '@angular/material/card'; import {Observable, from, min, of} from 'rxjs'; import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {MatTooltipModule} from '@angular/material/tooltip'; import {MatDialog, MatDialogModule} from '@angular/material/dialog'; import {modalRequerimientoComponent} from "./modalRequerimiento/modalRequerimiento.componente"; import {MatTableModule} from '@angular/material/table'; import { MatCell, MatCellDef, MatColumnDef, MatHeaderCell, MatHeaderRow, MatHeaderRowDef, MatRow, MatRowDef, MatTable } from "@angular/material/table"; import { SoloNumerosDirective } from '../../service/directivas_service/soloNumeros/solo-numeros.directive'; // Importa la directiva import { MY_DATE_FORMATS } from "../../service/directivas_service/formatoFecha/date-format"; // Asegúrate de ajustar la ruta import { MatSnackBar, MatSnackBarHorizontalPosition, MatSnackBarVerticalPosition,} from '@angular/material/snack-bar'; import { ConfirmarEliminacionComponent } from './modalEliminarPasaje/eliminarPasaje.componente'; import { modalEvidenciaComponent } from "./modalEvidencia/modalEvidencia.componente"; import { truncarCaracteresDirective } from "../../service/directivas_service/restriccionCaracteres/truncarCaracteres.directive"; import { ordenSalidaComponent } from "../ordensalida/ordensalida.componente"; import {elementSelectors} from "@angular/cdk/schematics"; import Notiflix from 'notiflix'; interface tiposTrabajo { value: string; viewValue: string; } interface interRequerimientos { id: number; titulo: string; codigo: string } interface interDetallePasaje { index: number; lugarOrigen: string; lugarDestino : string; monto: number; fecha: Date; isNew: boolean; isEdit : boolean; acciones: boolean; } interface interFile{ tipoEvidencia: number; file: File; } @Component({ imports: [ SoloNumerosDirective, MatDatepickerModule, MatNativeDateModule, MatFormFieldModule, FormsModule, ReactiveFormsModule, MatSelectModule, MatInputModule, MatButtonToggleModule, MatCheckboxModule, NgForOf, MatCard, MatCardContent, MatCardFooter, MatCardHeader, MatCardTitle, MatCardModule, MatButtonModule, MatDividerModule, MatIconModule, MatAutocompleteModule, AsyncPipe, MatTooltipModule, NgClass, MatCell, MatCellDef, MatColumnDef, MatHeaderCell, MatHeaderRow, MatHeaderRowDef, MatRow, MatRowDef, MatTable, MatTableModule, NgIf, NgStyle, truncarCaracteresDirective, ordenSalidaComponent, ], providers: [provideNativeDateAdapter(),DatePipe, { provide: MAT_DATE_FORMATS, useValue: MY_DATE_FORMATS } ], selector: 'app-conformidad', standalone: true, templateUrl: './conformidad.componente.html', styleUrls: ['./conformidad.componente.css'], //changeDetection: ChangeDetectionStrategy.OnPush, }) export class ConformidadComponent implements OnInit { private barraAlerta = inject(MatSnackBar); // VIEWCHILD @ViewChild('labelAdvertencia', { static: false }) labelAdvertencia!: ElementRef; @ViewChild('inputBusqueda', { static: false }) inputBusqueda!: ElementRef; @ViewChildren('fileEditar1') fileInputs1!: QueryList<ElementRef> ; @ViewChildren('fileEditar2') fileInputs2!: QueryList<ElementRef> ; @ViewChild(ordenSalidaComponent) ordenSalidaComponent!: ordenSalidaComponent; //@ViewChild(ordenSalidaComponent) datos_materialSobrante!: FormGroup; // VIEWCHILD //INICIALIZACION DE LISTADO DE TIPOS DE TRABAJO listTipoTrabajo: tiposTrabajo[] = [ {value: '1', viewValue: 'Instalación-Revisión'}, {value: '2', viewValue: 'Instalación-Ampliación'}, {value: '3', viewValue: 'Mantenimiento-Reparación'}, {value: '4', viewValue: 'Mantenimiento-Remodelación'}, {value: '5', viewValue: 'Reposición'}, {value: '6', viewValue: 'Reinstalación'}, ]; //INICIALIZACION DE LISTADO DE TIPOS DE TRABAJO //INICIALIZACION DE VARIABLES UTILIZABLES personal_list: any = []; sede_list: any = []; requerimientosFiltrados: any[] = []; listRequerimientos: interRequerimientos[] = []; idBotones: number = 0; indexPasaje : number = 0 ; labelText: string = ''; // Texto que se muestra inicialmente isFading: boolean = false; // Controla si la animación de desvanecimiento debe activarse activarPasajes : boolean = false; lugarDestinoPasaje : string = ''; columnasPasaje: string[] = ['lugarOrigen', 'lugarDestino', 'monto', 'fecha','accion']; dataSource: interDetallePasaje[] = []; alertaPosicionHorizontal: MatSnackBarHorizontalPosition = 'center'; alertaPosicionVertical: MatSnackBarVerticalPosition = 'bottom'; alertaDuracion : number = 3; minFechaLimite: Date | null = new Date(); maxFechaLimite: Date | null = new Date(); archivosEvidencia : interFile[] = []; //INICIALIZACION DE VARIABLES UTILIZABLES // GROUPO DE FORMULARIO datos_personal = new FormGroup({ tecnicoPersonal : new FormControl(null ,Validators.required), sedePersonal : new FormControl(null,Validators.required), areaPersonal : new FormControl<string>('' ,Validators.required), codAreaPersona : new FormControl(), minFechaTrabajo : new FormControl<Date>(new Date(), Validators.required), maxFechaTrabajo : new FormControl<Date>(new Date(), Validators.required), pasajeTotal: new FormControl<number>(0), }); datos_servicio = new FormGroup({ busquedaReq : new FormControl<string | null>(null ,[Validators.maxLength(12)]), descripcionServicio : new FormControl<string | null>(null ,Validators.required), causaServicio : new FormControl<string | null>(null ,Validators.required), }); datos_trabajo = new FormGroup({ tipoTrabajo : new FormControl<string>('1' ,Validators.required), descripcionTrabajo : new FormControl<string>('' ,Validators.required), }); datos_pasajeAcumulado = new FormGroup<any>({ }); datos_lugarOrigen : FormGroup = new FormGroup<any>({}) ; datos_fechaPasaje : FormGroup = new FormGroup<any>({}) ; existeMaterialS : FormGroup = new FormGroup({ existeMaterial : new FormControl(null ,Validators.required), }); //formulario: FormGroup | undefined; // GROUPO DE FORMULARIO constructor( private conformidadHelper: ConformidadHelper, private renderer: Renderer2, private detectorChange : ChangeDetectorRef, public dialog: MatDialog, private datePipe: DatePipe, private fb: FormBuilder ) { this.requerimientosFiltrados = []; renderer.setStyle(document.body, 'background', 'var(--light-theme-bg)'); } //ACCESOS RAPIDOS A GRUPOS DE FORMULARIOS agregarFormControl(formGroup: FormGroup, formControlName: string, formControl: FormControl = new FormControl()): any { return formGroup.addControl(formControlName, formControl); } obtenerFormControl(formGroup: FormGroup, formControlName: string): any { return formGroup.get(formControlName); } removerFormControl(formGroup: FormGroup, formControlName: string): any { return formGroup.removeControl(formControlName); } //ACCESOS RAPIDOS A GRUPOS DE FORMULARIOS formatoFecha(fecha: Date): string { return this.datePipe.transform(fecha, 'dd/MM/yyyy') || ''; } formatoFechaDate(fecha: Date): string { return this.datePipe.transform(fecha, 'yyyy/MM/dd') || ''; } formatoFechaRegistro(fecha: Date){ return this.datePipe.transform(fecha, 'yyyy-mm-dd') || ''; } async ngOnInit(): Promise<void> { const [ personal, sede ] = await Promise.all([ this.conformidadHelper.cargarPersonal(), this.conformidadHelper.listadoGeneralHorizon({accion: 1}), ]); this.personal_list = personal; this.sede_list = sede; this.dataSource = []; this.activarPasajes = false; this.habilitarSeccionPersonal(true); // Detecta cambios en el formulario de Datos Personal exceptuando 'lugarDestinoPasaje' para desbloquear el boton de 'Agregar Pasaje' this.datos_personal.valueChanges.subscribe(value => { const controlesInvalidos = Object.keys(this.datos_personal.controls) .filter(controlName => this.obtenerFormControl(this.datos_personal,controlName)?.invalid); //console.log('Controles inválidos con errores:', controlesInvalidos); this.activarPasajes = controlesInvalidos.length === 0 ? true : false; // En caso ya existan registros en la tabla de pasajes , se limpiará el listado y las filas existentes. if(this.dataSource.length > 0 && !this.activarPasajes){ this.dataSource = []; this.indexPasaje = 0; this.datos_pasajeAcumulado.reset(); this.datos_fechaPasaje.reset(); this.datos_lugarOrigen.reset(); } }); // Sincronizar el valor de 'sedePersonal' con los selects la tabla de pasaje //this.datos_personal.get('sedePersonal')?.valueChanges.subscribe((value) => { this.obtenerFormControl(this.datos_personal,'sedePersonal')?.valueChanges.subscribe((value : any) => { this.lugarDestinoPasaje = this.sede_list.find((item: any) => item.codlocal === value)?.deslocal || ''; }); //Sincroniza todos los inputs de monto de pasaje con el total de pasajes this.datos_pasajeAcumulado.valueChanges.subscribe(values => { const inputControls = Object.keys(values).filter(key => key.includes('montoPasaje')); const sum : number = (inputControls.reduce((acc, key) => acc + (Number(values[key]) || 0), 0) ) || 0; this.datos_personal.get('pasajeTotal')?.setValue(sum, { emitEvent: false }); }); //Condicionar a todos los controladores de Lugar de Origen para que si se escoge el mismo lugar que el lugar de origen salga una advertencia this.datos_lugarOrigen.valueChanges.subscribe(value => { const lugarDestino = this.datos_personal.get('sedePersonal')?.value; if(lugarDestino) { const inputControls = Object.keys(value); inputControls.forEach((idlugar) => { const lugarOrigen = value[idlugar]; if (lugarOrigen) { if (lugarOrigen === lugarDestino) { this.datos_lugarOrigen.get(idlugar)?.setErrors({'incorrect': true}); } }else{ this.datos_lugarOrigen.get(idlugar)?.setErrors({'incorrect': false}); } }); }else{ this.datos_personal.get('sedePersonal')?.setErrors({'incorrect': true}); } }); this.datos_personal.get('maxFechaTrabajo')?.valueChanges.subscribe((value) => { let minFecha : any = this.datos_personal.get('minFechaTrabajo')?.value; let maxFecha : any = value; if( minFecha && maxFecha ){ this.minFechaLimite = new Date(minFecha); this.maxFechaLimite = new Date(maxFecha); //Obtener todos los formControNames dentro del formGroup datos_fechaPasaje const inputControls = Object.keys(this.datos_fechaPasaje.controls); //Iterar sobre cada formControlName inputControls.forEach((key) => { let fechaPasaje = this.datos_fechaPasaje.get(key)?.value; if(fechaPasaje){ let fechaPasajeDate = new Date(fechaPasaje); if(fechaPasajeDate >= (this.minFechaLimite || new Date()) && fechaPasajeDate <= (this.maxFechaLimite|| new Date()) ){ this.datos_fechaPasaje.get(key)?.setErrors({'incorrect': false}); }else{ this.datos_fechaPasaje.get(key)?.setErrors({'incorrect': true}); this.datos_fechaPasaje.get(key)?.setValue(''); } } }); } }); this.existeMaterialS.get('existeMaterial')?.valueChanges.subscribe((value) => { console.log(value); }); } //AL SELECCIONAR UN REQUERIMIENTO onEventSeleccion(event : any){ const valor = event.option.value; if(this.listRequerimientos.find((item) => item.codigo === valor)){ this.labelText = 'Ya existe el requerimiento ' + valor + ' en el listado'; // Cambia el texto this.isFading = false; // Resetea el estado de opacidad para mostrar el texto // Después de 2 segundos, comienza a desvanecer el texto setTimeout(() => { this.isFading = true; }, 2000); // 2000 ms = 2 segundos }else{ this.listRequerimientos.push({ titulo: `RQ N°${valor}`, id: this.idBotones++ , codigo: valor }); this.labelText = ''; } this.datos_servicio.get('busquedaReq')?.setValue(''); this.inputBusqueda.nativeElement.blur(); this.detectorChange.detectChanges(); this.requerimientosFiltrados = []; } //AL SELECCIONAR INFORMACION DE UN REQUERIMIENTO async infoRequerimiento(valor: any){ const requerimientoInfo = await this.conformidadHelper.listadoGeneralHorizon({accion: 3, nombreValor: valor, sede: ''}); const dialogRef = this.dialog.open(modalRequerimientoComponent,{ width: '100%', maxWidth: '90%', minWidth: '50%', height: '50%', data: { requerimientoInfo } }); dialogRef.afterClosed().subscribe(result => { console.log(`Dialog result: ${result}`); }); } //ELIMINAR REQUERIMIENTO SELECCIONADO deleteRequerimiento(valor : any){ this.listRequerimientos = this.listRequerimientos.filter((item) => item.id !== valor); } //AL SELECCIONAR UN TECNICO, MOSTRAR AUTOMATICAMENTE SU AREA onEventoSeleccionTecnico(event: any) { // IMPRIMER EL ÁREA DEL TÉCNICO AL SELECCIONARLO const areaControl = this.datos_personal.get('areaPersonal'); const codAreaControl = this.datos_personal.get('codAreaPersona'); const codigoPer = event.value; const personal_list = this.personal_list; const personal_datos = personal_list.find((item: any) => item.codper === codigoPer); if(Object.keys(personal_datos).length > 0){ areaControl?.setValue(personal_datos.descargo); codAreaControl?.setValue(personal_datos.codarea); }else{ areaControl?.setValue('Sin Cargo'); codAreaControl?.setValue('0'); } areaControl?.updateValueAndValidity(); codAreaControl?.updateValueAndValidity(); } //REALIZAR UNA BUSQUEDA DE REQUERIMIENTO async onBusquedaRequerimiento(event: any) { const codigoSede = this.obtenerFormControl(this.datos_personal,'sedePersonal')?.value; const busquedaReq = event.target.value; const jsonParametrosReq = { accion : 2, nombreValor : busquedaReq, sede : codigoSede }; const requerimiento_list = await this.conformidadHelper.listadoGeneralHorizon(jsonParametrosReq) ; const mapeoResultado = requerimiento_list.map((item: any) => ({ codigo: item.CODIGONUM, serie : item.CSERIE_DOC, numero: item.CODIGONUM })); this.requerimientosFiltrados = mapeoResultado; } //AL SELECCIONAR LA OPCIÓN DE NUEVO PASAJE onEventoNuevoPasaje(event : any){ const NuevaFila : interDetallePasaje = { index: this.indexPasaje++, lugarOrigen: '', lugarDestino: '', monto: 0, fecha: new Date(), isNew: true, isEdit : false, acciones: true }; this.agregarFormControl(this.datos_pasajeAcumulado,'montoPasaje'+NuevaFila.index,new FormControl<number | null>(null,[Validators.maxLength(12)])); this.agregarFormControl(this.datos_fechaPasaje,'fechaPasaje'+NuevaFila.index,new FormControl<Date | null>(null,[Validators.maxLength(12)])); this.agregarFormControl(this.datos_lugarOrigen,'lugarOrigen'+NuevaFila.index,new FormControl<String | null>(null ,[Validators.maxLength(12)])); this.dataSource.forEach((item) => { if (item.index !== NuevaFila.index) { item.isEdit = false; item.isNew = false; item.acciones = false; } }); this.dataSource = [...this.dataSource,NuevaFila]; this.activarPasajes = false; this.habilitarSeccionPersonal(false); } onEventoConfirmarPasaje(event: any, elemento: any){ const lugarOrigen = this.obtenerFormControl(this.datos_lugarOrigen,`lugarOrigen${elemento.index}`)?.value; const lugarDestino = this.obtenerFormControl(this.datos_personal,'sedePersonal')?.value || ''; const pasaje = this.obtenerFormControl(this.datos_pasajeAcumulado,`montoPasaje${elemento.index}`)?.value; const fechaPasaje = this.obtenerFormControl(this.datos_fechaPasaje,`fechaPasaje${elemento.index}`)?.value; //VALIDAR LOS VALORES OBTENIDOS ANTES DE REALIZAR UN REGISTRO if(this.validarRegistroPasaje(elemento.index)){ // Agregar los datos recogidos de la fila para agregarlos en dataSource y actualizar la tabla const index = this.dataSource.findIndex((item) => item.index === elemento.index); this.dataSource[index] = { index: elemento.index, lugarOrigen: this.sede_list.find((item: any) => item.codlocal === lugarOrigen)?.deslocal || '' , lugarDestino: this.sede_list.find((item: any) => item.codlocal === lugarDestino)?.deslocal || '' , monto: pasaje, fecha: fechaPasaje, isNew: false, isEdit : false, acciones: true }; this.dataSource.forEach((item) => {item.acciones = true; }); // VUELVE A ACTIVAR TODAS LAS ACCION this.dataSource = [...this.dataSource]; this.activarPasajes = true; this.habilitarSeccionPersonal(true); this.barraAlerta.open( 'REGISTRO INGRESADO' , '' , { horizontalPosition: this.alertaPosicionHorizontal, verticalPosition: this.alertaPosicionVertical, duration: this.alertaDuracion * 1000 }); }else{ this.barraAlerta.open( 'VALIDAR DATOS INGRESADOS' , '' , { horizontalPosition: this.alertaPosicionHorizontal, verticalPosition: this.alertaPosicionVertical, duration: this.alertaDuracion * 1000 }); } } validarRegistroPasaje(index : number){ const lugarOrigen = this.datos_lugarOrigen.get('lugarOrigen'+index)?.value; const lugarDestino = this.datos_personal.get('sedePersonal')?.value; const fechaPasaje = this.datos_fechaPasaje.get('fechaPasaje'+index)?.value; const montoPasaje = this.datos_pasajeAcumulado.get('montoPasaje'+index)?.value; this.obtenerFormControl(this.datos_lugarOrigen,'lugarOrigen'+index)?.setErrors({'incorrect': !(lugarOrigen && lugarOrigen !== lugarDestino) , emitEvent: true}); this.obtenerFormControl(this.datos_fechaPasaje,'fechaPasaje'+index)?.setErrors({'incorrect': !fechaPasaje , emitEvent: true }); this.obtenerFormControl(this.datos_pasajeAcumulado,'montoPasaje'+index)?.setErrors({'incorrect': !(montoPasaje && montoPasaje > 0) , emitEvent: true }); return lugarOrigen && lugarDestino && fechaPasaje && montoPasaje && montoPasaje > 0 && lugarOrigen !== lugarDestino; } onEventoCancelarPasaje(event: any, elemento: any){ const index = this.dataSource.findIndex((item) => item.index === elemento.index);//Descubriendo el index this.dataSource.forEach((item) => { item.acciones = true; }); // Que todas las filas vuelvan a tener las acciones if(this.dataSource[index].isEdit){ this.dataSource[index].isEdit = false; this.dataSource[index].isNew = false; this.dataSource = [...this.dataSource]; }else{ this.dataSource = this.dataSource.filter((item) => item.index !== elemento.index); this.removerFormControl(this.datos_pasajeAcumulado,'montoPasaje'+elemento.index); this.removerFormControl(this.datos_fechaPasaje,'fechaPasaje'+elemento.index); this.removerFormControl(this.datos_lugarOrigen,'lugarOrigen'+elemento.index); } this.habilitarSeccionPersonal(true); this.activarPasajes = true } //Editar una fila de pasaje onEventoEditarPasaje(event: any, elemento: any) { //const index = this.dataSource.findIndex((item) => item.index === elemento.index);//Descubriendo el index this.dataSource.forEach((item) => { if (item.index === elemento.index) { item.isEdit = true; item.isNew = true; item.acciones = true; } else { item.isEdit = false; item.isNew = false; item.acciones = false; } }); this.dataSource = [...this.dataSource]; // Volviendo a ingresar los datos para que la tabla se actualice y la fila cambie con las condiciones del HTML this.activarPasajes = false; } onEventoEliminarPasaje(event: any, elemento: any){ //Al presionar el boton aparecerá un Dialog confirmando si desea eliminar el registro, al aceptar la fila del registro se eliminará. const dialogRef = this.dialog.open(ConfirmarEliminacionComponent); dialogRef.afterClosed().subscribe(result => { if (result) { const index = elemento.index; if (index >= 0) { this.dataSource = this.dataSource.filter((item) => item.index !== elemento.index); this.removerFormControl(this.datos_pasajeAcumulado,'montoPasaje'+elemento.index); this.removerFormControl(this.datos_fechaPasaje,'fechaPasaje'+elemento.index); this.removerFormControl(this.datos_lugarOrigen,'lugarOrigen'+elemento.index); } } }); } habilitarSeccionPersonal(datos: boolean){ if(datos){ this.datos_personal.get('tecnicoPersonal')?.enable({ emitEvent: false }); this.datos_personal.get('sedePersonal')?.enable({ emitEvent: false }); this.datos_personal.get('areaPersonal')?.enable({ emitEvent: false }); this.datos_personal.get('maxFechaTrabajo')?.enable({ emitEvent: false }); this.datos_personal.get('minFechaTrabajo')?.enable({ emitEvent: false }); }else{ this.datos_personal.get('tecnicoPersonal')?.disable({ emitEvent: false }); this.datos_personal.get('sedePersonal')?.disable({ emitEvent: false }); this.datos_personal.get('areaPersonal')?.disable({ emitEvent: false }); this.datos_personal.get('maxFechaTrabajo')?.disable({ emitEvent: false }); this.datos_personal.get('minFechaTrabajo')?.disable({ emitEvent: false }); } } onEventoSubirArchivo(event: any, tipo : number = 1) { const archivosSeleccionados: FileList = event.target.files; const nuevosArchivos = Array.from(archivosSeleccionados).filter(file => file.type === 'image/png'); nuevosArchivos.forEach( async (file) => { if(!this.archivosEvidencia.find((item) => item.file.name === file.name)){ this.archivosEvidencia.push({tipoEvidencia : tipo , file : file }); } }); } seleccionarInput(index : number, tipo : number){ if(tipo === 1){ const input = this.fileInputs1.toArray()[index]; input.nativeElement.click(); // Simula el clic en el input file correspondiente }else{ const input = this.fileInputs2.toArray()[index]; input.nativeElement.click(); // Simula el clic en el input file correspondiente } } async gestionArchivos(index: number, accion : number, file : any = [], tipo : number = 1){ if(accion === 1){ const fileReader = new FileReader(); fileReader.onload = () => { this.dialog.open(modalEvidenciaComponent, { data: { imageUrl: fileReader.result // Pasar la imagen al modal } }); }; fileReader.readAsDataURL(file); // Convertir el archivo a URL para mostrarlo }else if(accion === 2){ const archivoSeleccionado = file.target.files[0]; // Obteniendo el File //OBTENER EL ARCHIVO FILE Y UBICARLO EN EL ARRAY DE archivosEP EN EL MISMO INDEX if(archivoSeleccionado) { //COMPRAR EL NOMBRE DEL ARCHIVOS CON TODA LA LISTA EXISTENTE PARA EVITAR REPETICIONES if(!this.archivosEvidencia.find((item) => item.file.name === archivoSeleccionado.name)){ this.archivosEvidencia[index].file = archivoSeleccionado; }else{ this.barraAlerta.open( 'ARCHIVO YA SE ENCUENTRA EN LA LISTA' , '' , { horizontalPosition: this.alertaPosicionHorizontal, verticalPosition: this.alertaPosicionVertical, duration: this.alertaDuracion * 1000 }); } } }else{ this.archivosEvidencia.splice(index, 1); // Eliminar el archivo del array de archivosEP } } async gestionConformidad() { //Obtener todos los datos del form Group datos_personal const datosPersonal = this.datos_personal.getRawValue(); const datosPasajes = this.dataSource; const datosServicio = this.datos_servicio.getRawValue(); const requerimientoRelacionados = this.listRequerimientos; const datosTrabajo = this.datos_trabajo.getRawValue(); const existeMaterial = parseInt(this.existeMaterialS.get('existeMaterial')?.value) || 0; const datosMaterial = this.ordenSalidaComponent?.dataSource.length > 0 ? this.ordenSalidaComponent?.dataSource : []; const archivosEvidencias = this.archivosEvidencia; let contadorEP = 1; let contadorES = 1; const datosMaterialSobrante = this.ordenSalidaComponent?.datos_materialSobrante?.get('descMaterial')?.value ? this.ordenSalidaComponent?.datos_materialSobrante?.get('descMaterial')?.value : ''; //console.log(existeMaterial); //console.log(datosMaterial); //console.log(datosMaterialSobrante); //console.log(this.ordenSalidaComponent?); //CREACION DE CARPETA DE EVIDENCIAS Notiflix.Loading.pulse(); const registroEvidencia = await this.conformidadHelper.creacionCarpeta({codconformidad: 40}); console.log(registroEvidencia); Notiflix.Loading.remove(); //Subida simultanea de evidencias de PROBLEMAS y SOLUCIONES /*const registroArchivos = archivosEvidencias.map((item) => { return { codconformidad : 40, archivo: item.file, tipoEvidencia : item.tipoEvidencia, nombreArchivo : (item.tipoEvidencia === 1) ? 'EVIDENCIA_PROBLEMA_'+40+"_"+(contadorEP++) : 'EVIDENCIA_SOLUCION_'+40+"_"+(contadorES++) }; }); const filtroEvidenciasProblemas = registroArchivos.filter((item) => item.tipoEvidencia === 1); const filtroEvidenciasSoluciones = registroArchivos.filter((item) => item.tipoEvidencia === 2); console.log(filtroEvidenciasProblemas); console.log(filtroEvidenciasSoluciones); const registroEvidencia = await Promise.all([this.conformidadHelper.subidaEvidencia(filtroEvidenciasProblemas),this.conformidadHelper.subidaEvidencia(filtroEvidenciasSoluciones)]); console.log(registroEvidencia)*/ /*Notiflix.Loading.pulse(); // Muestra un loading if (!this.validarDatosPersonales(datosPersonal)) { this.mostrarAlerta('VALIDAR DATOS PERSONALES'); return; } if (!this.validarPasajes(datosPasajes)) { this.mostrarAlerta('VALIDAR PASAJES'); return; } if (!this.validarArchivos(archivosEvidencias)) { const tipoEvidencia = archivosEvidencias.find((item) => item.tipoEvidencia === 1) ? 2 : (archivosEvidencias.find((item) => item.tipoEvidencia === 2) ? 1 : 0 ); const advertencia = tipoEvidencia === 0 ? 'REQUIERE SUBIR EVIDENCIAS' : (tipoEvidencia === 1 ? 'REQUIERE SUBIR EVIDENCIA DE PROBLEMA' : 'REQUIERE SUBIR EVIDENCIA DE SERVICIOS'); this.mostrarAlerta(advertencia); return; } if (!this.validarMaterialSobrante(existeMaterial, this.ordenSalidaComponent?.dataSource)) { this.mostrarAlerta('VALIDAR MATERIAL SOBRANTE'); return; } if (!this.datos_trabajo.valid) { this.mostrarAlerta('VALIDAR DATOS DE TRABAJO'); return; } const registroConformidad = await this.conformidadHelper.gestionConformidad({ opcion: 1, codper: datosPersonal.tecnicoPersonal, codlocal: datosPersonal.sedePersonal, fechainicio: this.formatoFechaRegistro(datosPersonal.minFechaTrabajo || new Date() ) , fechafin: this.formatoFechaRegistro(datosPersonal.maxFechaTrabajo || new Date() ) , descproblema: datosServicio.descripcionServicio, desccausa: datosServicio.causaServicio, codtipotrabajo: parseInt(datosTrabajo.tipoTrabajo || '1'), desctrabajo: datosTrabajo.descripcionTrabajo }); const respuestaConformidad : any = JSON.parse(registroConformidad); if(respuestaConformidad.status){ // DATOS DE CONFORMIDAD VALIDADOS Y REGISTRADOS let statusPasaje = true ; if(datosPasajes.length > 0){ console.log(datosPasajes) const datosPasaje = datosPasajes.map((item) => { return { opcion: 2, codconformidad : respuestaConformidad.data.codconformidad, codlocal: this.datos_lugarOrigen.get('lugarOrigen'+item.index)?.value, pasaje: item.monto, fechainicio: this.formatoFechaRegistro(item.fecha) }; }); for (let i=0; i < datosPasaje.length; i++){ const registroPasaje = await this.conformidadHelper.gestionConformidad(datosPasaje[i]); const respuestaPasaje = JSON.parse(registroPasaje); if(!respuestaPasaje.status) { statusPasaje = false; break; } } } if(statusPasaje){ // DATOS DE PASAJES VALIDADOS Y REGISTRADOS let statusRequerimientos = true ; if(requerimientoRelacionados.length > 0){ console.log(requerimientoRelacionados); const datosRequerimientos = requerimientoRelacionados.map((item) => { return { opcion: 3, codconformidad : respuestaConformidad.data.codconformidad, codrequerimiento : parseInt(item.codigo) }; }); for (let i=0; i < datosRequerimientos.length; i++){ const registroRequerimiento = await this.conformidadHelper.gestionConformidad(datosRequerimientos[i]); const respuestaRequerimiento = JSON.parse(registroRequerimiento); if(!respuestaRequerimiento.status) { statusRequerimientos = false; break; } } } if(statusRequerimientos){ // REGISTRO DE REQUERIMIENTOS VALIDADOS Y REGISTRADOS //UNIR LOS DATOS archivosEP Y archivosES EN UN SOLO ARRAY let statusEvidencias = true; const registroArchivos = archivosEvidencias.map((item) => { return { codconformidad : respuestaConformidad.data.codconformidad, archivo: item.file, tipoEvidencia : item.tipoEvidencia, nombreArchivo : (item.tipoEvidencia === 1) ? 'EVIDENCIA_PROBLEMA_'+respuestaConformidad.data.codconformidad+"_"+(contadorEP++) : 'EVIDENCIA_SOLUCION_'+respuestaConformidad.data.codconformidad+"_"+(contadorES++) }; }); for (let i=0; i < registroArchivos.length; i++){ const registroEvidencia = await this.conformidadHelper.subidaEvidencia(registroArchivos[i]); console.log(registroEvidencia); if(!registroEvidencia?.status) { statusEvidencias = false; break; } } console.log(statusEvidencias); if(statusEvidencias) { // REGISTRO DE EVIDENCIAS SUBIDAS AL DRIVE Y REGISTRADAS EN BASE let statusOrdenSalida = true; if(existeMaterial === 1){ const registroOrdenSalida = await this.conformidadHelper.gestionOrdenSalida({ accion : 1, codper: datosPersonal.tecnicoPersonal, codlocal: datosPersonal.sedePersonal, fechaRegistro: this.formatoFechaRegistro(new Date()), descripcion : datosMaterialSobrante }); console.log(registroOrdenSalida); const respuestaOrdenSalida : any = JSON.parse(registroOrdenSalida); if(respuestaOrdenSalida.status) { const datosMaterialSobrante = datosMaterial.map((item) => { return { accion: 2, codOrdenSalida : respuestaOrdenSalida.data.codordensalida, codArticulo : item.codigoArticulo, cantidad: item.cantidad, estado : item.estado }; }); for (let i=0; i < datosMaterial.length; i++){ const registroMaterialS = await this.conformidadHelper.gestionOrdenSalida(datosMaterialSobrante[i]); console.log(registroMaterialS); const respuestaregistroMaterialS = JSON.parse(registroMaterialS); if(!respuestaregistroMaterialS.status) { statusOrdenSalida = false; break; } } }else{ this.mostrarAlerta('ERROR AL REGISTRAR LOS ORDEN DE SALIDA'); } }else{ statusOrdenSalida = true; } console.log(statusOrdenSalida); if(statusOrdenSalida){ console.log("SE REGISTRO TODO CORRECTAMENTE") }else{ this.mostrarAlerta('ERROR AL REGISTRAR ORDEN DE SALIDA'); } }else{ this.mostrarAlerta('ERROR AL REGISTRAR LOS ARCHIVOS DE EVIDENCIA'); } } }else{ this.mostrarAlerta('ERROR AL REGISTRAR LOS REQUERIMIENTOS'); } }else{ this.mostrarAlerta('ERROR AL REGISTRAR LA CONFORMIDAD'); }*/ } validarDatosPersonales(datosPersonal: any): boolean { return datosPersonal?.codAreaPersona && datosPersonal?.sedePersonal && datosPersonal?.tecnicoPersonal && datosPersonal?.maxFechaTrabajo && datosPersonal?.minFechaTrabajo; } validarPasajes(datosPasajes: any[]): boolean { return (datosPasajes.length > 0 && datosPasajes.every((item) => item.lugarOrigen && item.lugarDestino && item.monto && item.fecha)) || datosPasajes.length === 0; } validarArchivos(archivosEvidencia : any[]): boolean { return archivosEvidencia.find((item) => item.tipoEvidencia === 1) && archivosEvidencia.find((item) => item.tipoEvidencia === 2);//Debe existir por lo menos un archivo de evidencia de problema y uno de solucion } validarMaterialSobrante(existeMaterial: number, dataSource: any[]): boolean { return (existeMaterial === 1 && dataSource.length > 0) || existeMaterial === 0; } mostrarAlerta(mensaje: string): void { Notiflix.Loading.remove(); this.barraAlerta.open(mensaje, '', { horizontalPosition: this.alertaPosicionHorizontal, verticalPosition: this.alertaPosicionVertical, duration: this.alertaDuracion * 1000 }); } }