[FIXED] FORMATOS Y LLAMADO DE ARTICULOS

parent ed6695f8
......@@ -5,7 +5,11 @@
"projects": {
"angular-formularioHR": {
"projectType": "application",
"schematics": {},
"schematics": {
"@schematics/angular:application": {
"strict": false
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
......
......@@ -256,7 +256,7 @@
<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 type="text" placeholder="Buscar requerimiento" matInput #inputBusqueda formControlName="busquedaReq" [matAutocomplete]="auto" maxlength="9"
<input soloNumeros="entero" type="text" placeholder="Buscar requerimiento" matInput #inputBusqueda formControlName="busquedaReq" [matAutocomplete]="auto" maxlength="9"
(input)="onBusquedaRequerimiento($event)">
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="onEventSeleccion($event)">
<mat-option *ngFor="let option of requerimientosFiltrados" [value]="option.codigo">
......@@ -362,8 +362,8 @@
</mat-card-header>
<mat-card-content class="w-full my-2.5">
<div class="div-trabajosPrestados divisionGeneral" [formGroup]="datos_trabajo">
<div>
<mat-form-field class="md:w-full lg:w-1/3" appearance="outline" floatLabel="always">
<div class="flex flex-row gap-x-2">
<mat-form-field class="md:w-1/2 lg:w-1/3" appearance="outline" floatLabel="always">
<mat-label>Tipo de trabajo</mat-label>
<mat-select formControlName="tipoTrabajo" placeholder="[Seleccionar tipo de trabajo]">
@for (tipoT of listTipoTrabajo; track tipoT) {
......@@ -371,7 +371,16 @@
}
</mat-select>
</mat-form-field>
<mat-form-field class="md:w-1/2 lg:w-1/3" appearance="outline" floatLabel="always">
<mat-label>Ingresar porcentaje de avance</mat-label>
<input soloNumeros="entero" type="text" placeholder="Avance realizado" matInput formControlName="avanceTrabajo" maxlength="3">
</mat-form-field>
</div>
<div class="w-full mt-5">
<mat-form-field class="w-full" >
<mat-label>DESCRIPCIÓN DEL TRABAJO</mat-label>
......@@ -434,7 +443,7 @@
</div>
<div>
<div><b class="md:text-[1rem] text-black/60">FIRMA DEL ENCARGADO: *</b></div>
<div><b class="md:text-[1rem] text-black/60">FIRMA DEL ENCARGADO:</b></div>
<div>
<button mat-fab class="!w-full" [color]="'blue'" (click)="mostrarFirma({accion : 1})">
<mat-label>SUBIR FIRMA</mat-label>
......
......@@ -15,7 +15,13 @@ import {FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, V
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 {
provideNativeDateAdapter,
MatNativeDateModule,
MAT_DATE_FORMATS,
MAT_DATE_LOCALE,
DateAdapter
} from '@angular/material/core';
import {DateRange, MatDatepickerModule, MatDateRangeInput } from '@angular/material/datepicker';
import { NgxMatTimepickerModule } from '@alexfriesen/ngx-mat-timepicker';
import {MatFormFieldModule} from '@angular/material/form-field';
......@@ -41,6 +47,8 @@ import { modalEvidenciaComponent } from "./modalEvidencia/modalEvidencia.compone
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 { AngularSignaturePadModule, SignaturePadComponent } from '@almothafar/angular-signature-pad';
......@@ -129,7 +137,14 @@ interface interFile{
ordenSalidaComponent,
//AngularSignaturePadModule,
],
providers: [provideNativeDateAdapter(),DatePipe, DecimalPipe, { provide: MAT_DATE_FORMATS, useValue: MY_DATE_FORMATS } ],
providers: [
provideNativeDateAdapter(),
DatePipe,
DecimalPipe,
//{ provide: MAT_DATE_FORMATS, useValue: MY_DATE_FORMATS },
{ provide: MAT_DATE_LOCALE, useValue: 'es-ES' }, // Configurar el idioma español
{ provide: DateAdapter, useClass: CustomDateAdapter } // Adaptador personalizado
],
selector: 'app-conformidad',
standalone: true,
templateUrl: './conformidad.componente.html',
......@@ -139,7 +154,6 @@ interface interFile{
export class ConformidadComponent implements AfterViewInit {
private barraAlerta = inject(MatSnackBar);
//@ViewChild('signature') public signaturePad!: SignaturePadComponent;
// VIEWCHILD
@ViewChild('labelAdvertencia', { static: false }) labelAdvertencia!: ElementRef;
......@@ -147,14 +161,12 @@ export class ConformidadComponent implements AfterViewInit {
@ViewChildren('fileEditar1') fileInputs1!: QueryList<ElementRef> ;
@ViewChildren('fileEditar2') fileInputs2!: QueryList<ElementRef> ;
@ViewChild(ordenSalidaComponent) ordenSalidaComponent!: ordenSalidaComponent;
//@ViewChild(ordenSalidaComponent) datos_materialSobrante!: FormGroup;
// VIEWCHILD
//INICIALIZACION DE VARIABLES UTILIZABLES
opcionEnvironmnet : number = environment.opcion;
resultadoArchivos : any = [];
opcionEnvironmnet : boolean = environment.isProduction;
personal_list: any = [];
sede_list: any = [];
cargosU_list : any = [];
......@@ -216,6 +228,7 @@ export class ConformidadComponent implements AfterViewInit {
datos_trabajo = new FormGroup({
tipoTrabajo : new FormControl<string>('1' ,Validators.required),
descripcionTrabajo : new FormControl<string>('' ,Validators.required),
avanceTrabajo : new FormControl('' ,[Validators.required, Validators.min(1),Validators.max(100)]),
});
existeMaterialS : FormGroup = new FormGroup({
......@@ -304,8 +317,6 @@ export class ConformidadComponent implements AfterViewInit {
// 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);
......@@ -502,8 +513,6 @@ export class ConformidadComponent implements AfterViewInit {
this.personalFading = true;
}, 2000); // 2000 ms = 2 segundos
}else{
this.personalText = '';
......@@ -732,17 +741,12 @@ export class ConformidadComponent implements AfterViewInit {
const nuevosArchivos = Array.from(archivosSeleccionados).filter(file => file.type === 'image/png' || file.type === 'image/jpeg');
nuevosArchivos.forEach( async (file) => {
if(tipo === 3 || tipo === 4){
if(tipo === 4){
const Encontrado = this.archivosEvidencia.find((item) => item.tipoEvidencia === tipo);
if (Encontrado) {
this.archivosEvidencia = this.archivosEvidencia.filter((item) => item.tipoEvidencia !== tipo);
this.archivosEvidencia.push({tipoEvidencia: tipo, file: file});
}else{
this.archivosEvidencia.push({tipoEvidencia: tipo, file: file});
}
......@@ -830,26 +834,6 @@ export class ConformidadComponent implements AfterViewInit {
let contadorExtras = 1;
const datosMaterialSobrante = this.ordenSalidaComponent?.datos_materialSobrante?.get('descMaterial')?.value ? this.ordenSalidaComponent?.datos_materialSobrante?.get('descMaterial')?.value : '';
/*const codigoConformidad= 14;
const registroArchivos = archivosEvidencias.map((item) => {
return {
codconformidad: codigoConformidad,
archivo: item.file,
tipoArchivo : typeof item.file,
tipoEvidencia: item.tipoEvidencia,
nombreArchivo: (item.tipoEvidencia === 1) ? 'EVIDENCIA_PROBLEMA_' + codigoConformidad + "_" + (contadorEP++) :
(item.tipoEvidencia === 2) ? 'EVIDENCIA_SOLUCION_' + codigoConformidad + "_" + (contadorES++) :
(item.tipoEvidencia === 3) ? 'EVINDENCIA_ATC' + codigoConformidad + "_" + (constadorATC++) :
(item.tipoEvidencia === 4) ? 'FIRMA' + codigoConformidad + "_" + (contadorFirma++) : 'DATO_EXTRA' + codigoConformidad + "_" + (contadorExtras++)
};
});*/
/*this.resultadoArchivos = '';
for(let i = 0 ; i < registroArchivos.length ; i++){
this.resultadoArchivos = registroArchivos[i].nombreArchivo + ' - ' + registroArchivos[i].tipoEvidencia + ' - ' + registroArchivos[i].tipoArchivo + ' || ' + this.resultadoArchivos;
}*/
Notiflix.Loading.pulse(); // Muestra un loading
if (!this.validarDatosPersonales(datosPersonal)) {
......@@ -872,7 +856,7 @@ export class ConformidadComponent implements AfterViewInit {
return;
}
if (!this.datos_trabajo.valid) {
if(!this.validarDatosTrabajo(datosTrabajo)){
this.mostrarAlerta('VALIDAR DATOS DE TRABAJO');
return;
}
......@@ -887,7 +871,8 @@ export class ConformidadComponent implements AfterViewInit {
codtipotrabajo: parseInt(datosTrabajo.tipoTrabajo || '1'),
desctrabajo: datosTrabajo.descripcionTrabajo,
minhoratrabajo : datosPersonal.minHoraTrabajo,
maxhoratrabajo : datosPersonal.maxHoraTrabajo
maxhoratrabajo : datosPersonal.maxHoraTrabajo,
avance : datosTrabajo.avanceTrabajo,
});
const respuestaConformidad : any = JSON.parse(registroConformidad);
......@@ -1081,6 +1066,15 @@ export class ConformidadComponent implements AfterViewInit {
datosPersonal?.minFechaTrabajo && validarHoras ;
}
private validarDatosTrabajo(datosTrabajo: any) : boolean{
const TipoTrabajo = datosTrabajo.tipoTrabajo;
const Avance = datosTrabajo.avanceTrabajo;
return TipoTrabajo !== null && Avance !== null && Avance <= 100 && Avance >= 1;
}
validarPersonal(personal: any[]): boolean {
return personal.length > 0 && personal.every((item) => item.id != '0' && item.nombre != '');
}
......@@ -1101,9 +1095,9 @@ export class ConformidadComponent implements AfterViewInit {
else if(archivosEvidencia.find((item) => item.tipoEvidencia === 3) === undefined){
advertencia += `REQUIERE SUBIR EVIDENCIA DE ATS`;
}
else if(archivosEvidencia.find((item) => item.tipoEvidencia === 4) === undefined){
/*else if(archivosEvidencia.find((item) => item.tipoEvidencia === 4) === undefined){
advertencia += `REQUIERE SUBIR EVIDENCIA DE FIRMA`;
}
}*/
if(advertencia !== ''){
this.mostrarAlerta(advertencia);
......@@ -1135,10 +1129,15 @@ export class ConformidadComponent implements AfterViewInit {
});
dialogRef.afterClosed().subscribe(result => {
if(result !== 0 || result !== undefined){
this.obtenerFirma = true;
if(result !== 0 && result !== undefined){
if(this.obtenerFirma){
}else{
const Archivo = this.blobToFile(result.blob, result.nombre);
this.archivosEvidencia.push({tipoEvidencia: 4, file: Archivo});
}
this.obtenerFirma = true;
}else{
this.obtenerFirma = false;
this.mostrarAlerta('FIRMA NO REGISTRADA');
......@@ -1150,5 +1149,15 @@ export class ConformidadComponent implements AfterViewInit {
blobToFile(blob: Blob, fileName: string, mimeType?: string): File {
return new File([blob], fileName, { type: mimeType || blob.type });
}
fileToBase64(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);
});
}
}
......@@ -86,13 +86,14 @@ export class modalArticuloOC {
}
onCancelar(): void {
this.Articulo = {};
this.Articulo = {Editar: this.Editar, Cancelado : true};
this.dialogRef.close(this.Articulo);
}
onConfirmar(): void {
this.Articulo = {
Cancelado : false,
codigoArticulo : '',
nombreArticulo : this.datos_Articulo.get('nombreArticulo')?.value,
unidadArticulo : this.datos_Articulo.get('unidadArticulo')?.value,
......
......@@ -172,9 +172,9 @@ export class ordenSalidaComponent implements OnInit {
});
dialogRef.afterClosed().subscribe(result => {
console.log(result);
//console.log(result);
if(result){
if(!result.Cancelado){
const NuevaFila : listaArticulos = {
index : this.indexArticulo++,
codigo: result.codigoArticulo,
......@@ -203,7 +203,7 @@ export class ordenSalidaComponent implements OnInit {
dialogRef.afterClosed().subscribe(result => {
console.log(result);
if(result){
if(!result.Cancelado){
const NuevaFila : listaArticulos = {
index : elemento.index,
codigo: result.codigoArticulo,
......
......@@ -74,6 +74,7 @@ export class ConformidadService {
codordensalida : json.codordensalida || 0,
minhoratrabajo : json.minhoratrabajo || '',
maxhoratrabajo : json.maxhoratrabajo || '',
avance : json.avance || 0,
};
try {
......@@ -140,19 +141,19 @@ export class ConformidadService {
formData.append('app_nombre', 'ORDEN_COMPRA'); // USANDO ESTE NOMBRE DE APP(ORDEN_COMPRA) YA QUE NO CUENTA CON LA CONFIGURACION DE SUBCARPETAS
formData.append('carpeta_nombre', datos.tipoEvidencia === 1 ? 'EVIDENCIAS_PROBLEMAS' :
datos.tipoEvidencia === 2 ? 'EVIDENCIAS_SOLUCIONES' : 'EVIDENCIAS_EXTRAS' );
//const controller = new AbortController();
//const timeout = setTimeout(() => controller.abort(), 60000); // 30 segundos
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 60000); // 30 segundos
try {
const response = await fetch(url, {
method: 'POST',
body: formData,
//signal: controller.signal, // 30 segundos de timeout
signal: controller.signal, // 30 segundos de timeout
});
const statusCode = response.status;
const responseBody = await response.json();
console.log(response)
//clearTimeout(timeout); // Limpiar, REVISA SI ESTO ESTA BIEN O QUITARLO
//console.log(response)
clearTimeout(timeout); // Limpiar, REVISA SI ESTO ESTA BIEN O QUITARLO
if (statusCode === 200) {
......@@ -165,6 +166,8 @@ export class ConformidadService {
nombreDocumento: datos.nombreArchivo || ''
});
//console.log(registroEvidencia);
if (responseBody?.status) {
respuesta = {status: true, message: "Imagenes subidas"};
} else {
......@@ -234,4 +237,14 @@ export class ConformidadService {
}
}
base64ToFile(base64: string, fileName: string, mimeType: string): File {
const byteCharacters = atob(base64.split(',')[1]); // Decodificar Base64
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
return new File([byteArray], fileName, { type: mimeType });
}
}
import { Injectable } from '@angular/core';
import { NativeDateAdapter } from '@angular/material/core';
@Injectable()
export class CustomDateAdapter extends NativeDateAdapter {
override parse(value: any): Date | null {
if (!value) return null;
const parts = value.split('/');
if (parts.length === 3) {
const day = +parts[0];
const month = +parts[1] - 1;
const year = +parts[2];
return new Date(year, month, day);
}
return null;
}
override format(date: Date, displayFormat: string): string {
const day = date.getDate().toString().padStart(2, '0');
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const year = date.getFullYear();
return `${day}/${month}/${year}`;
}
}
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