[ADD] GESTION TICKETS Y NUEVO DISEÑO

parent c46f636f
......@@ -34,10 +34,22 @@
align-items: center !important;
}
mat-card {
border: 3px solid #9cc2ff;
box-shadow: 0px 4px 6px rgba(0, 0.4, 0.4, 0.3);
}
mat-label {
opacity: 1; /* Por defecto, el label será completamente visible */
font-size: 15px;
font-family: Montserrat, sans-serif;
font-weight: bold;
line-height: 24px;
letter-spacing: .5px;
}
.custom-snackbar {
white-space: pre-line; /* Permite respetar saltos de línea */
}
......
<div class="flex justify-center w-full my-5">
<div class="border border-black w-[90vw] md:w-3/4 flex justify-center items-center shadow-lg h-12 rounded-lg bg-yellow-300">
<label class="font-bold text-lg md:text-2xl">HOJA DE RUTA</label>
<div class="border border-black w-[90vw] md:w-3/4 flex justify-center items-center shadow-lg h-12 rounded-lg bg-[#ffc161]">
<mat-label class="font-bold text-lg md:text-2xl">HOJA DE RUTA</mat-label>
</div>
</div>
<div class="body flex flex-col items-center text-[13px] md:text-[18px] relative mx-2 my-5 pb-5 md:mx-0">
<div class="flex flex-col items-center text-xs md:text-base mx-2 my-5 pb-5 md:mx-0">
<mat-card appearance="outlined" class="mt-4 flex flex-col gap-2.5 text-[#222] shadow-xl w-full md:w-[75vw]">
<mat-card appearance="outlined" class="mt-4 flex flex-col gap-2.5 text-[#222] shadow-xl w-full md:w-[75vw] border-4 border-[#d1d9e6]">
<mat-card-header class="flex flex-col items-start w-full">
<label class="text-base md:text-lg font-bold">DATOS PERSONALES</label>
<mat-label class="text-base md:text-lg font-bold">DATOS PERSONALES</mat-label>
</mat-card-header>
<mat-card-content class="w-full my-2.5" [formGroup]="datos_personal">
<!------------------------------------------------------------------------- DATOS GENERALES ------------------------------------------------------------------------------>
......@@ -45,12 +45,12 @@
<!-- agregar botones de agregar o disminuir Tecnico responsable -->
<div class="flex flex-row items-center gap-x-2">
<div class="example-button-container">
<button (click)="onEventoAgregarPersonal()" mat-fab aria-label="Example icon button with a delete icon">
<button (click)="onEventoAgregarPersonal()" mat-fab>
<mat-icon>add</mat-icon>
</button>
</div>
<div class="example-button-container">
<button (click)="onEventoQuitarPersonal()" mat-fab aria-label="Example icon button with a heart icon">
<button (click)="onEventoQuitarPersonal()" mat-fab>
<mat-icon>delete</mat-icon>
</button>
</div>
......@@ -125,9 +125,9 @@
</div>
<mat-card appearance="outlined" class="mt-4 flex flex-col gap-2.5 text-[#222] !shadow-xl w-[95vw] sm:w-[90vw] md:w-[75vw]">
<mat-card-header class="flex flex-col items-start w-full">
<label class="text-[1.1em] font-bold">
<mat-label class="text-[1.1em] font-bold">
SERVICIOS PRESTADOS
</label>
</mat-label>
</mat-card-header>
<mat-card-content class="w-full my-2.5">
<div class="div-serviocisPrestados divisionGeneral" [formGroup]="datos_servicio">
......@@ -136,9 +136,9 @@
<div class="lg:w-1/5 md:w-full">
<mat-form-field class="w-full" appearance="outline" floatLabel="always">
<mat-label>Listado de Requerimientos</mat-label>
<input soloNumeros="entero" type="text" placeholder="Buscar requerimiento" matInput #inputBusqueda formControlName="busquedaReq" [matAutocomplete]="auto" maxlength="9"
<input soloNumeros="entero" type="text" placeholder="Buscar requerimiento" matInput #inputBusquedaReq formControlName="busquedaReq" [matAutocomplete]="autorequerimiento" maxlength="9"
(input)="onBusquedaRequerimiento($event)">
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="onEventSeleccion($event)">
<mat-autocomplete #autorequerimiento="matAutocomplete" (optionSelected)="onEventSeleccion($event,1)">
<mat-option *ngFor="let option of requerimientosFiltrados" [value]="option.codigo">
{{ option.numero }}
</mat-option>
......@@ -147,19 +147,54 @@
<mat-label class="flex justify-center items-center h-full text-center font-bold text-blue-600 text-lg" [ngClass]="{'fade-out': isFading}" [innerText]="labelText"></mat-label>
</div>
<!-- <div class="grid grid-cols-2 md:grid-cols-5 gap-4 w-full md:w-4/5">-->
<div class="grid lg:grid-cols-5 md:grid-cols-3 lg:gap-4 md:gap-y-3">
<div class="lg:px-5 md:px-0.5 w-fit" *ngFor="let card of listRequerimientos" style="display: flex">
<mat-card>
<mat-card-content>
<!-- <mat-card-subtitle class="text-base font-bold">{{ card.titulo }}</mat-card-subtitle> -->
<mat-card-subtitle style="font-size: 1rem;font-weight: bold;align-content: center">{{ card.titulo }}</mat-card-subtitle>
<div class="w-fit py-2 lg:px-3 flex space-x-4">
<button mat-fab aria-label="Eliminar" matTooltip="Eliminar" matTooltipPosition="above" (click)="deleteRequerimiento(card.id)">
<button mat-fab aria-label="Eliminar" matTooltip="Eliminar" matTooltipPosition="above" (click)="onEventDeleteRequerimiento(card.id,1)">
<mat-icon class="mat-icon-small">delete</mat-icon>
</button>
<button mat-fab aria-label="Información" matTooltip="Información" matTooltipPosition="above" (click)="onEventInfoRequerimiento(card.codigo)">
<mat-icon class="mat-icon-small">info</mat-icon>
</button>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
</div>
<mat-divider style="padding: 20px 0"></mat-divider>
<div class="flex md:flex-col lg:flex-row gap-5 pb-5">
<div class="lg:w-1/5 md:w-full">
<mat-form-field class="w-full" appearance="outline" floatLabel="always">
<mat-label>Listado de Tickets</mat-label>
<input soloNumeros="entero" type="text" placeholder="Buscar Ticket" matInput #inputBusquedaTicket formControlName="busquedaTickets" [matAutocomplete]="autotickets" maxlength="9"
(input)="onBusquedaTickets($event)">
<mat-autocomplete #autotickets="matAutocomplete" (optionSelected)="onEventSeleccion($event,2)">
<mat-option *ngFor="let option of ticketsFiltrados" [value]="option.codigo">
{{ option.numero }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<mat-label class="flex justify-center items-center h-full text-center font-bold text-blue-600 text-lg" [ngClass]="{'fade-out': isFading}" [innerText]="labelText"></mat-label>
</div>
<div class="grid lg:grid-cols-5 md:grid-cols-3 lg:gap-4 md:gap-y-3">
<div class="lg:px-5 md:px-0.5 w-fit" *ngFor="let ticket of listTickets" style="display: flex">
<mat-card>
<mat-card-content>
<mat-card-subtitle style="font-size: 1rem;font-weight: bold;align-content: center">{{ ticket.titulo }}</mat-card-subtitle>
<div class="w-fit py-2 lg:px-3 flex space-x-4">
<button mat-fab aria-label="Eliminar" matTooltip="Eliminar" matTooltipPosition="above" (click)="onEventDeleteRequerimiento(ticket.id,2)">
<mat-icon class="mat-icon-small">delete</mat-icon>
</button>
<button mat-fab aria-label="Información" matTooltip="Información" matTooltipPosition="above" (click)="infoRequerimiento(card.codigo)">
<button mat-fab aria-label="Información" matTooltip="Información" matTooltipPosition="above" (click)="onEventInfoRequerimiento(ticket.codigo)">
<mat-icon class="mat-icon-small">info</mat-icon>
</button>
</div>
......@@ -190,7 +225,7 @@
<div class="grid lg:grid-cols-2 gap-5">
<div>
<div><b class="md:text-[1rem] text-[1em] text-black/60">EVIDENCIAS DEL PROBLEMA: *</b></div>
<button mat-fab class="!w-full" [color]="'blue'" (click)="file1.click()">
<button mat-fab class="!w-full" style="background-color: #ff8787" (click)="file1.click()">
<mat-label>SUBIR EVIDENCIA DEL PROBLEMA</mat-label>
<mat-icon>file_open</mat-icon>
</button>
......@@ -211,7 +246,7 @@
<div>
<div><b class="md:text-[1rem] text-[1em] text-black/60">EVIDENCIAS DE SOLUCIONES: *</b></div>
<button mat-fab class="!w-full" [color]="'blue'" (click)="file2.click()">
<button mat-fab class="!w-full" style="background-color: #7bff7b" (click)="file2.click()">
<mat-label>SUBIR EVIDENCIA DE LA SOLUCIÓN</mat-label>
<mat-icon>file_open</mat-icon>
</button>
......@@ -236,9 +271,9 @@
<mat-card appearance="outlined" class="mt-4 flex flex-col gap-2.5 text-[#222] !shadow-xl w-[90vw] sm:w-[85vw] md:w-[75vw]">
<mat-card-header class="flex flex-col items-start w-full">
<label class="text-[1.1em] font-bold">
<mat-label class="text-[1.1em] font-bold">
TRABAJOS PRESTADOS
</label>
</mat-label>
</mat-card-header>
<mat-card-content class="w-full my-2.5">
<div class="div-trabajosPrestados divisionGeneral" [formGroup]="datos_trabajo">
......@@ -305,7 +340,7 @@
<div>
<div><b class="md:text-[1rem] text-[1em] text-black/60">EVIDENCIA DE ATS: *</b></div>
<div>
<button mat-fab class="!w-full" [color]="'blue'" (click)="fotoATC.click()">
<button mat-fab class="!w-full" style="background-color: #8cfde8" (click)="fotoATC.click()">
<mat-label>SUBIR FOTO DE ATS</mat-label>
<mat-icon>file_open</mat-icon>
</button>
......@@ -325,7 +360,7 @@
<div>
<div><b class="md:text-[1rem] text-[1em] text-black/60">EVIDENCIA DE CONFORMIDAD: (OPCIONAL)</b></div>
<div>
<button mat-fab class="!w-full" [color]="'blue'" (click)="fotoConformidad.click()">
<button mat-fab class="!w-full" style="background-color: #a78cfd" (click)="fotoConformidad.click()">
<mat-label>SUBIR FOTO CONFORMIDAD</mat-label>
<mat-icon>file_open</mat-icon>
</button>
......@@ -345,7 +380,7 @@
<div>
<div><b class="md:text-[1rem] text-black/60">FIRMA DEL ENCARGADO: (OPCIONAL)</b></div>
<div>
<button mat-fab class="!w-full" [color]="'blue'" (click)="mostrarFirma({accion : 1})">
<button mat-fab class="!w-full" style="background-color: #fde88c" (click)="mostrarFirma({accion : 1})">
<mat-label>SUBIR FIRMA</mat-label>
<mat-icon>file_open</mat-icon>
</button>
......@@ -355,7 +390,7 @@
<p class="w-2/4" matTooltip="{{ (archivo.file.name + ' (' + (archivo.file.size / 1000) + ' KB)')}}" matTooltipPosition="above">{{ (archivo.file.name + ' (' + (archivo.file.size / 1000) + ' KB)') | truncate:30:true }}</p>
<div class="w-2/4 grid grid-cols-3 gap-4">
<button (click)="gestionArchivos(i,1,archivo.file)"><mat-icon>info</mat-icon></button>
<button (click)="gestionArchivos(i,3)"><mat-icon>delete</mat-icon></button>
<button (click)="gestionArchivos(i,3, [] , 4)"><mat-icon>delete</mat-icon></button>
</div>
</div>
</div>
......
import {Component, OnInit, ChangeDetectorRef, Renderer2, ElementRef, ViewChild, inject, QueryList, ViewChildren, NgModule,
AfterViewInit, contentChild} from '@angular/core';
import {Component, OnInit, ChangeDetectorRef, Renderer2, ElementRef, ViewChild, inject, QueryList, ViewChildren, NgModule,AfterViewInit, contentChild} 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';
......@@ -24,13 +23,10 @@ import {modalFirmaComponent} from "./modalFirma/modalFirma.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 { CustomDateAdapter } from '../../service/directivas_service/formatoFecha/custom-date'; // Archivo personalizado
import Notiflix from 'notiflix';
import {environment} from "../../../environment/env";
......@@ -45,7 +41,7 @@ interface lugaresTrabajo {
viewValue : string;
}
interface interRequerimientos {
interface interDocumento {
id: number;
titulo: string;
codigo: string
......@@ -122,7 +118,8 @@ export class ConformidadComponent implements AfterViewInit {
// VIEWCHILD
@ViewChild('labelAdvertencia', { static: false }) labelAdvertencia!: ElementRef;
@ViewChild('inputBusqueda', { static: false }) inputBusqueda!: ElementRef;
@ViewChild('inputBusquedaReq', { static: false }) inputBusquedaReq!: ElementRef;
@ViewChild('inputBusquedaTicket', {static:false}) inputBusquedaTicket!: ElementRef;
@ViewChildren('fileEditar1') fileInputs1!: QueryList<ElementRef> ;
@ViewChildren('fileEditar2') fileInputs2!: QueryList<ElementRef> ;
@ViewChild(ordenSalidaComponent) ordenSalidaComponent!: ordenSalidaComponent;
......@@ -138,8 +135,10 @@ export class ConformidadComponent implements AfterViewInit {
zona_list: any = [];
unidades_list : any = [];
requerimientosFiltrados: any[] = [];
ticketsFiltrados: any [] = [];
listSedesAtencion : lugaresTrabajo[] = [];
listRequerimientos: interRequerimientos[] = [];
listRequerimientos: interDocumento[] = [];
listTickets : interDocumento[] = [];
listTipoTrabajo: tiposTrabajo[] = [];
listPersonal : interPersonal[] = [{ index: 0 , id: 0 , nombre: '' }];
idBotones: number = 0;
......@@ -149,6 +148,7 @@ export class ConformidadComponent implements AfterViewInit {
personalFading : boolean = false ;
mostrarHoras : boolean = true ;
obtenerFirma :boolean = false;
encargadoTicket : any[] = [{codTipoEspecialidad : 1 , userEncargado : 'nvillarroel'} , {codTipoEspecialidad : 2 , userEncargado : 'mberrios'}];
alertaPosicionHorizontal: MatSnackBarHorizontalPosition = 'center';
alertaPosicionVertical: MatSnackBarVerticalPosition = 'bottom';
......@@ -176,6 +176,7 @@ export class ConformidadComponent implements AfterViewInit {
datos_servicio = new FormGroup({
busquedaReq : new FormControl<string | null>(null ,[Validators.maxLength(12)]),
busquedaTickets : new FormControl<string | null>(null ,[Validators.maxLength(12)]),
descripcionServicio : new FormControl<string | null>(null ,Validators.required),
causaServicio : new FormControl<string | null>(null ,Validators.required),
});
......@@ -203,6 +204,7 @@ export class ConformidadComponent implements AfterViewInit {
private snackBar: MatSnackBar
) {
this.requerimientosFiltrados = [];
this.ticketsFiltrados = [];
renderer.setStyle(document.body, 'background', 'var(--light-theme-bg)');
}
......@@ -237,6 +239,8 @@ export class ConformidadComponent implements AfterViewInit {
async ngAfterViewInit(): Promise<void> {
Notiflix.Loading.standard('Inicializando...');
const [
personal,
sede,
......@@ -251,12 +255,16 @@ export class ConformidadComponent implements AfterViewInit {
this.conformidadHelper.listadoGeneralHorizon({accion : 5})
]);
this.obtenerFormControl(this.datos_servicio,'busquedaTickets')?.disable();
//this.datos_servicio.get('busquedaTickets')?.disable();
//this.personal_list = personal;
this.sede_list = sede;
this.cargosU_list = cargosUnidos;
this.zona_list = [{ value: 1, viewValue: 'NORTE' },{ value: 2, viewValue: 'SUR' },{ value: 3, viewValue: 'ESTE' },{ value: 4, viewValue: 'CENTRO' }];
this.unidades_list = unidades;
this.listRequerimientos = [];
this.listTickets = [];
const jsonTipoTrabajo = JSON.parse(tipoTrabajo);
this.listTipoTrabajo = jsonTipoTrabajo.data;
......@@ -267,6 +275,10 @@ export class ConformidadComponent implements AfterViewInit {
this.obtenerFormControl(this.datos_personal,'tipoCargoPersonal')?.valueChanges.subscribe((value : any) => {
const cargos = value.split(',').map((item: any) => Number(item));
this.personal_list = personal.filter((item: any) => cargos.includes(item.codcargo));
if(value !== '' && value !== undefined){
this.obtenerFormControl(this.datos_servicio,'busquedaTickets')?.enable();
}
});
this.datos_personal.get('maxFechaTrabajo')?.valueChanges.subscribe((value) => {
......@@ -289,34 +301,61 @@ export class ConformidadComponent implements AfterViewInit {
}
});
Notiflix.Loading.remove();
}
//AL SELECCIONAR UN REQUERIMIENTO
onEventSeleccion(event : any){
onEventSeleccion(event : any, tipo : 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
if(tipo === 1) {
// Después de 2 segundos, comienza a desvanecer el texto
setTimeout(() => {
this.isFading = true;
}, 2000); // 2000 ms = 2 segundos
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.inputBusquedaReq.nativeElement.blur();
this.detectorChange.detectChanges();
this.requerimientosFiltrados = [];
}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 = [];
else if(tipo === 2){
if (this.listTickets.find((item) => item.codigo === valor)) {
this.labelText = 'Ya existe el Ticket ' + 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.listTickets.push({titulo: `Ticket N°${valor}`, id: this.idBotones++, codigo: valor});
this.labelText = '';
}
this.datos_servicio.get('busquedaTickets')?.setValue('');
this.inputBusquedaTicket.nativeElement.blur();
this.detectorChange.detectChanges();
this.ticketsFiltrados = [];
}
}
//AL SELECCIONAR INFORMACION DE UN REQUERIMIENTO
async infoRequerimiento(valor: any){
async onEventInfoRequerimiento(valor: any){
const requerimientoInfo = await this.conformidadHelper.listadoGeneralHorizon({accion: 3, nombreValor: valor, sede: ''});
const dialogRef = this.dialog.open(modalRequerimientoComponent,{
width: '100%',
......@@ -331,8 +370,14 @@ export class ConformidadComponent implements AfterViewInit {
}
//ELIMINAR REQUERIMIENTO SELECCIONADO
deleteRequerimiento(valor : any){
this.listRequerimientos = this.listRequerimientos.filter((item) => item.id !== valor);
onEventDeleteRequerimiento(valor : any, tipo : any){
if(tipo === 1){
this.listRequerimientos = this.listRequerimientos.filter((item) => item.id !== valor);
}else{
this.listTickets = this.listTickets.filter((item) => item.id !== valor);
}
}
//AGREGAR UN TECNICO
......@@ -419,6 +464,41 @@ export class ConformidadComponent implements AfterViewInit {
this.requerimientosFiltrados = mapeoResultado;
}
async onBusquedaTickets(event: any) {
//const codigoSede = this.obtenerFormControl(this.datos_personal,'sedePersonal')?.value;
const busquedaTicket = event.target.value;
const tipoCargoPersonal = this.datos_personal.get('tipoCargoPersonal')?.value;
const especialidad = this.cargosU_list.find((item: any) => item.cargou === tipoCargoPersonal);
const codTipoEspecialidad = especialidad.codtipocargo
const encargado = this.encargadoTicket.find(value => value.codTipoEspecialidad = codTipoEspecialidad)
const jsonParametrosReq = {
p_item: busquedaTicket,
p_sede : '',
p_responsable : encargado.userEncargado || '',
p_fecha_ini : '' ,
p_fecha_fin : '',
p_correo : '' ,
p_estado : '' ,
length : 10 ,
start : 0
};
const tickets_list = await this.conformidadHelper.listadoGeneralTickets(jsonParametrosReq) ;
const mapeoResultado = tickets_list.map((item: any) => ({
codigo: item.num_ticket,
serie : item.tenor,
numero: item.num_ticket
}));
console.log(mapeoResultado);
this.ticketsFiltrados = mapeoResultado;
}
onEventoSubirArchivo(event: any, tipo : number = 1) {
const archivosSeleccionados: FileList = event.target.files;
......@@ -497,6 +577,9 @@ export class ConformidadComponent implements AfterViewInit {
}else{
this.archivosEvidencia.splice(index, 1); // Eliminar el archivo del array de archivosEP
if(tipo === 4){
this.obtenerFirma = false;
}
}
}
......@@ -508,6 +591,7 @@ export class ConformidadComponent implements AfterViewInit {
const personal = this.listPersonal;
const datosServicio = this.datos_servicio.getRawValue();
const requerimientoRelacionados = this.listRequerimientos;
const ticketsRelacionados = this.listTickets;
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 : [];
......@@ -583,7 +667,7 @@ export class ConformidadComponent implements AfterViewInit {
if (registroCarpeta.status) {
//UNIR LOS DATOS archivosEP Y archivosES EN UN SOLO ARRAY
const registroArchivos = archivosEvidencias.map((item) => {
const paramsRegistroArchivos = archivosEvidencias.map((item) => {
return {
codconformidad: codigoConformidad,
archivo: item.file,
......@@ -600,18 +684,18 @@ export class ConformidadComponent implements AfterViewInit {
this.ConformidadService.progresoSubida.next(0); // Reiniciar progreso
const resultados: {
const RegistroArchivos: {
status: boolean,
mensaje: string
} = await this.conformidadHelper.subidaEvidencia3(registroArchivos);
} = await this.conformidadHelper.subidaEvidencia3(paramsRegistroArchivos);
if (resultados.status) { // REGISTROS DE EVIDENCIAS CONFIRMADAS Y REGISTRADAS
if (RegistroArchivos.status) { // REGISTROS DE EVIDENCIAS CONFIRMADAS Y REGISTRADAS
Notiflix.Loading.change(`Registro de Personal...`);
let statusPersonal = true;
const datosPersonalTecnico = personal.map((item) => {
const paramsRegistroPersonal = personal.map((item) => {
return {
opcion : 8,
codconformidad : codigoConformidad,
......@@ -619,10 +703,10 @@ export class ConformidadComponent implements AfterViewInit {
}
});
for (let i=0; i < datosPersonalTecnico.length; i++){
const registroRequerimiento = await this.conformidadHelper.gestionConformidad(datosPersonalTecnico[i]);
const respuestaRequerimiento = JSON.parse(registroRequerimiento);
if(!respuestaRequerimiento.status) {
for (let i=0; i < paramsRegistroPersonal.length; i++){
const RegistroPersonal = await this.conformidadHelper.gestionConformidad(paramsRegistroPersonal[i]);
const respuestaRegistroPersonal = JSON.parse(RegistroPersonal);
if(!respuestaRegistroPersonal.status) {
statusPersonal = false;
break;
}
......@@ -636,7 +720,7 @@ export class ConformidadComponent implements AfterViewInit {
Notiflix.Loading.change(`Registro de Requerimientos...`);
const datosRequerimientos = requerimientoRelacionados.map((item) => {
const paramsRequerimientos = requerimientoRelacionados.map((item) => {
return {
opcion: 3,
codconformidad: codigoConformidad,
......@@ -644,8 +728,8 @@ export class ConformidadComponent implements AfterViewInit {
};
});
for (let i = 0; i < datosRequerimientos.length; i++) {
const registroRequerimiento = await this.conformidadHelper.gestionConformidad(datosRequerimientos[i]);
for (let i = 0; i < paramsRequerimientos.length; i++) {
const registroRequerimiento = await this.conformidadHelper.gestionConformidad(paramsRequerimientos[i]);
const respuestaRequerimiento = JSON.parse(registroRequerimiento);
if (!respuestaRequerimiento.status) {
statusRequerimientos = false;
......@@ -658,82 +742,110 @@ export class ConformidadComponent implements AfterViewInit {
if (statusRequerimientos) { // REGISTRO DE REQUERIMIENTOS VALIDADOS Y REGISTRADOS
// UNA VEZ REGISTRADO TODOS LOS DATOS DE LA CONFORMIDAD, SE PROCEDE A REGISTRAR LA ORDEN DE SALIDA RELACIONADA.
let statusTickets = true;
let statusOrdenSalida = true;
if(ticketsRelacionados.length > 0){
Notiflix.Loading.change(`Registro de Tickets...`);
if (existeMaterial === 1) {
const paramsRegistroTickets = ticketsRelacionados.map((item) => {
return {
opcion: 12,
codconformidad: codigoConformidad,
codrequerimiento: parseInt(item.codigo)
};
});
for (let i = 0; i < paramsRegistroTickets.length; i++) {
const RegistroTickets = await this.conformidadHelper.gestionConformidad(paramsRegistroTickets[i]);
const respuestaRequerimiento = JSON.parse(RegistroTickets);
if (!respuestaRequerimiento.status) {
statusTickets = false;
break;
}
}
}else{
statusTickets = true;
}
Notiflix.Loading.change(`Registro de Orden de Salida...`);
if(statusTickets) {
const registroOrdenSalida = await this.conformidadHelper.gestionOrdenSalida({
accion: 1,
codlocal: datosPersonal.sedePersonal + '',
fechaRegistro: this.formatoFechaRegistro(new Date()),
descripcion: descripcionMaterial,
numordensalida : ordenSalidaMaterial
});
let statusOrdenSalida = true;
const respuestaOrdenSalida: any = JSON.parse(registroOrdenSalida);
if (existeMaterial === 1) { // REGISTRO DE TICKETS VALIDADOS Y REGISTRADOS
if (respuestaOrdenSalida.status) { // REGISTRO DE ORDEN DE SALIDA CONFIRMADO Y VALIDADO
Notiflix.Loading.change(`Registro de Orden de Salida...`);
const datosMaterialSobrante = datosMaterial.map((item) => {
return {
accion: 2,
codOrdenSalida: respuestaOrdenSalida.data.codordensalida,
codArticulo: item.codigo,
nombreArticulo: item.nombre,
unidad: item.unidad,
cantidad: item.cantidad,
estado: item.estado
};
const registroOrdenSalida = await this.conformidadHelper.gestionOrdenSalida({
accion: 1,
codlocal: datosPersonal.sedePersonal + '',
fechaRegistro: this.formatoFechaRegistro(new Date()),
descripcion: descripcionMaterial,
numordensalida : ordenSalidaMaterial
});
for (let i = 0; i < datosMaterial.length; i++) {
const registroMaterialS = await this.conformidadHelper.gestionOrdenSalida(datosMaterialSobrante[i]);
const respuestaregistroMaterialS = JSON.parse(registroMaterialS);
if (!respuestaregistroMaterialS.status) {
statusOrdenSalida = false;
break;
}
}
if (statusOrdenSalida) { // UNION DE LA ORDEN DE SALIDA CON LA CONFORMIDAD
const relacionarOrdenConformidad = await this.conformidadHelper.gestionConformidad({
opcion: 6,
codconformidad: codigoConformidad,
codordensalida: respuestaOrdenSalida.data.codordensalida
});
const respuestaOrdenSalida: any = JSON.parse(registroOrdenSalida);
const respuestarelacionarOrdenConformidad = JSON.parse(relacionarOrdenConformidad);
if (!respuestarelacionarOrdenConformidad.status) {
statusOrdenSalida = false;
if (respuestaOrdenSalida.status) { // REGISTRO DE ORDEN DE SALIDA CONFIRMADO Y VALIDADO
const datosMaterialSobrante = datosMaterial.map((item) => {
return {
accion: 2,
codOrdenSalida: respuestaOrdenSalida.data.codordensalida,
codArticulo: item.codigo,
nombreArticulo: item.nombre,
unidad: item.unidad,
cantidad: item.cantidad,
estado: item.estado
};
});
for (let i = 0; i < datosMaterial.length; i++) {
const registroMaterialS = await this.conformidadHelper.gestionOrdenSalida(datosMaterialSobrante[i]);
const respuestaregistroMaterialS = JSON.parse(registroMaterialS);
if (!respuestaregistroMaterialS.status) {
statusOrdenSalida = false;
break;
}
}
if (statusOrdenSalida) { // UNION DE LA ORDEN DE SALIDA CON LA CONFORMIDAD
const relacionarOrdenConformidad = await this.conformidadHelper.gestionConformidad({
opcion: 6,
codconformidad: codigoConformidad,
codordensalida: respuestaOrdenSalida.data.codordensalida
});
const respuestarelacionarOrdenConformidad = JSON.parse(relacionarOrdenConformidad);
if (!respuestarelacionarOrdenConformidad.status) {
statusOrdenSalida = false;
}
}
} else {
statusOrdenSalida = false; //this.mostrarAlerta('ERROR AL REGISTRAR LOS ORDEN DE SALIDA');
}
} else {
statusOrdenSalida = false; //this.mostrarAlerta('ERROR AL REGISTRAR LOS ORDEN DE SALIDA');
statusOrdenSalida = true;
}
} else {
statusOrdenSalida = true;
}
if (statusOrdenSalida) {
if (statusOrdenSalida) {
Notiflix.Loading.remove();
Notiflix.Notify.success('ÉXITO DE CONFORMIDAD ', {
position: 'center-center', // Notificación en el centro de la pantalla
timeout: 1000, // 1 segundo
width: '400px',
fontSize: '24px',
fontAwesomeIconSize: '34px',
});
Notiflix.Loading.remove();
Notiflix.Notify.success('ÉXITO DE CONFORMIDAD ', {
position: 'center-center', // Notificación en el centro de la pantalla
timeout: 1000, // 1 segundo
width: '400px',
fontSize: '24px',
fontAwesomeIconSize: '34px',
});
// Espera 1 segundo y recarga la página
setTimeout(() => {
window.location.reload();
}, 1000);
}else {
this.mostrarAlertaError('FALLO DE REGISTRO','ERROR AL REGISTRAR ORDEN DE SALIDA');
// Espera 1 segundo y recarga la página
setTimeout(() => {
window.location.reload();
}, 1000);
}else {
this.mostrarAlertaError('FALLO DE REGISTRO','ERROR AL REGISTRAR ORDEN DE SALIDA');
}
} else {
this.mostrarAlertaError('FALLO DE REGISTRO','ERROR AL REGISTRAR LOS TICKETS');
}
} else {
this.mostrarAlertaError('FALLO DE REGISTRO','ERROR AL REGISTRAR LOS REQUERIMIENTOS');
......@@ -742,9 +854,9 @@ export class ConformidadComponent implements AfterViewInit {
this.mostrarAlertaError('FALLO DE REGISTRO','ERROR AL REGISTRAR EL PERSONAL');
}
} else {
this.mostrarAlertaError('ERROR DE SUBIDA DE EVIDENCIA' , resultados.mensaje );
this.mostrarAlertaError('ERROR DE SUBIDA DE EVIDENCIA' , RegistroArchivos.mensaje );
//Agregar el eliminar registro y eliminar Documento.
await this.conformidadHelper.eliminarDocumento({
await this.conformidadHelper.eliminarArchivo({
opcion: 1,
codconformidad: codigoConformidad
});
......
......@@ -44,6 +44,15 @@ export class ConformidadHelper {
}
}
async listadoGeneralTickets(json: any){
const respuesta = await this.ConformidadService.listadoGeneralTickets(json);
if (respuesta?.status) {
return respuesta.data;
}else{
return [];
}
}
async gestionConformidad(json: any){
const respuesta = await this.ConformidadService.gestionConformidad(json);
if (respuesta?.status) {
......@@ -59,8 +68,8 @@ export class ConformidadHelper {
return respuesta
}
async eliminarDocumento(json : any){
const respuesta = await this.ConformidadService.eliminarDocumento(json);
async eliminarArchivo(json : any){
const respuesta = await this.ConformidadService.eliminarArchivo(json);
return respuesta
}
......
......@@ -22,7 +22,7 @@
<mat-label>CANTIDAD : </mat-label>
<mat-form-field class="w-full">
<mat-label>Ingrese cantidad</mat-label>
<input formControlName="cantidadArticulo" matInput soloNumeros="entero" maxlength="3" placeholder="Máx. 3 dígitos">
<input formControlName="cantidadArticulo" matInput soloNumeros="entero" maxlength="5" placeholder="Máx. 5 dígitos">
</mat-form-field>
</div>
......
......@@ -88,7 +88,7 @@
<div class="mt-6">
<div><b class="md:text-[1rem] text-[1em] text-black/60">EVIDENCIA DE MATERIAL SOBRANTE: (opcional)</b></div>
<div>
<button mat-fab class="!w-full" [color]="'blue'" (click)="fotoATC.click()">
<button mat-fab class="!w-full" style="background-color: #ffcf83" (click)="fotoATC.click()">
<mat-label>FOTO MATERIAL SOBRANTE</mat-label>
<mat-icon>file_open</mat-icon>
</button>
......
......@@ -62,6 +62,29 @@ export class ConformidadService {
}
}
async listadoGeneralTickets(json : any){
try {
const respuesta = await axios.post(this.t_asistencia_rest_link + '/api/v1/soticket/consultar_tickets',
{
p_item: json.p_item,
p_sede : json.p_sede,
p_responsable : json.p_responsable,
p_fecha_ini : json.p_fecha_ini ,
p_fecha_fin : json.p_fecha_fin,
p_correo : json.p_correo ,
p_estado : json.p_estado ,
length : json.length ,
start : json.start
}
);
return respuesta.data;
} catch (e) {
return e;
}
}
async gestionConformidad(json: any) {
const Parametros = {
......@@ -175,7 +198,7 @@ export class ConformidadService {
const responseBody = await response.json();
if (responseBody?.status) {
await this.registroDocumento({
await this.registroArchivo({
codconformidad: datos.codconformidad || 0,
tipoEvidencia: datos.tipoEvidencia || 0,
idDrive: responseBody.data.archivo_id || "",
......@@ -228,7 +251,7 @@ export class ConformidadService {
}
async registroDocumento(json: any) {
async registroArchivo(json: any) {
const parametros = {
accion: 1,
codconformidad: json.codconformidad || 0,
......@@ -249,7 +272,7 @@ export class ConformidadService {
}
}
async eliminarDocumento(json : any){
async eliminarArchivo(json : any){
const parametros = {
accion: 1,
codconformidad: json.codconformidad || 0,
......
<!doctype html>
<html lang="en">
<html lang="en" style="background-color: #caeeff;">
<head>
<meta charset="utf-8">
<title>AngularFormularioHR</title>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment