[ADD] AJUSTE DE DATOS Y SUBIDA DE ARCHIVOS A DRIVE Y BASE

parent 5bac3d22
......@@ -28,6 +28,7 @@
"@angular/cli": "^18.2.1",
"@angular/compiler-cli": "^18.2.0",
"@types/jasmine": "~5.1.0",
"@types/node": "^22.7.4",
"autoprefixer": "^10.4.20",
"jasmine-core": "~5.2.0",
"karma": "~6.4.0",
......@@ -4477,9 +4478,9 @@
}
},
"node_modules/@types/node": {
"version": "22.5.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz",
"integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==",
"version": "22.7.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
"integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==",
"dev": true,
"license": "MIT",
"dependencies": {
......@@ -6695,9 +6696,9 @@
}
},
"node_modules/engine.io": {
"version": "6.5.5",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz",
"integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==",
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.1.tgz",
"integrity": "sha512-NEpDCw9hrvBW+hVEOK4T7v0jFJ++KgtPl4jKFwsZVfG1XhS0dCrSb3VMb9gPAd7VAdW52VT1EnaNiU2vM8C0og==",
"dev": true,
"license": "MIT",
"dependencies": {
......@@ -12517,9 +12518,9 @@
}
},
"node_modules/socket.io": {
"version": "4.7.5",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz",
"integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==",
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz",
"integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==",
"dev": true,
"license": "MIT",
"dependencies": {
......@@ -12527,7 +12528,7 @@
"base64id": "~2.0.0",
"cors": "~2.8.5",
"debug": "~4.3.2",
"engine.io": "~6.5.2",
"engine.io": "~6.6.0",
"socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.4"
},
......
......@@ -30,6 +30,7 @@
"@angular/cli": "^18.2.1",
"@angular/compiler-cli": "^18.2.0",
"@types/jasmine": "~5.1.0",
"@types/node": "^22.7.4",
"autoprefixer": "^10.4.20",
"jasmine-core": "~5.2.0",
"karma": "~6.4.0",
......
......@@ -26,4 +26,18 @@ export class ConformidadHelper {
}
}
async gestionConformidad(json: any){
const respuesta = await this.ConformidadService.gestionConformidad(json);
if (respuesta?.status) {
return respuesta.json;
}else{
return [];
}
}
async subidaEvidencia( json : any ){
const respuesta = await this.ConformidadService.subidaEvidencia(json);
return respuesta
}
}
......@@ -29,7 +29,7 @@ import {MatTableModule} from "@angular/material/table";
template: `
<h1 mat-dialog-title>Confirmar Eliminación</h1>
<div mat-dialog-content>
<p>¿Estás seguro de que deseas eliminar este pasaje?</p>
<p>¿Estás seguro de que deseas eliminar este registro?</p>
</div>
<div mat-dialog-actions>
<button mat-button (click)="onCancelar()">Cancelar</button>
......
import { Component, Inject } from '@angular/core';
import { MatDialogActions, MatDialogClose, MatDialogContent, MatDialogTitle, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import {MatButtonModule} from '@angular/material/button';
@Component({
selector: 'app-file-preview-dialog',
imports: [MatButtonModule,
MatDialogActions,
MatDialogClose,
MatDialogContent,
MatDialogTitle],
standalone: true,
template:`
<h1 mat-dialog-title>Vista previa del archivo</h1>
<div mat-dialog-content>
<img [src]="data.imageUrl" alt="Vista previa" style="max-width: 100%; height: auto;" />
</div>
<div mat-dialog-actions>
<button mat-button mat-dialog-close>Cerrar</button>
</div>
`
})
export class modalEvidenciaComponent {
constructor(
@Inject(MAT_DIALOG_DATA)
public data: any
) {
console.log(data);
}
}
<h2 mat-dialog-title>Detalle requerimiento</h2>
<h1 mat-dialog-title>Detalle requerimiento {{detalleRequerimiento.numeroDoc || '000000000'}}</h1>
<mat-dialog-content >
<mat-card appearance="outlined" >
<mat-card-content class="flex grid grid-cols-4 gap-4" >
<div>
<mat-label>TIPO DE REQUERIMIENTO : </mat-label>
<mat-label>{{detalleRequerimiento.tipoRequerimiento || 'Sin Tipo Requerimiento'}}</mat-label>
</div>
<div>
<mat-label>FECHA REGISTRO : </mat-label>
<mat-label>{{detalleRequerimiento.fechaRegistro || 'Sin Fecha'}}</mat-label>
</div>
<div>
<mat-label>SEDE : </mat-label>
<mat-label>{{detalleRequerimiento.sede || 'Sin Sede'}}</mat-label>
</div>
<div>
<mat-label>EMPLEADO : </mat-label>
<mat-label>{{detalleRequerimiento.empleado || 'Sin Empleado'}}</mat-label>
</div>
<div>
<mat-label>OBSERVACIÓN : </mat-label>
<mat-label>{{detalleRequerimiento.observacion || 'Sin Observacion'}}</mat-label>
</div>
<div>
<mat-label>DESCRIPCIÓN : </mat-label>
<mat-label>{{detalleRequerimiento.descripcion || 'Sin descripcion'}}</mat-label>
</div>
<!-- <mat-label [innerHTML]="'REQUERIMIENTO : ' + (detalleRequerimiento[0].numeroDoc || 'Sin Requerimiento') "></mat-label>
<mat-label [innerHTML]="'SEDE : ' + (detalleRequerimiento[0].sede || 'Sin Sede') "></mat-label>
<mat-label [innerHTML]="'EMPLEADO : ' + (detalleRequerimiento[0].empleado || 'Sin Empleado') "></mat-label>
<mat-label [innerHTML]="'OBSERVACIÓN : ' + (detalleRequerimiento[0].observacion || 'Sin Observacion') "></mat-label>
<mat-label [innerHTML]="'DESCRIPCIÓN : ' + (detalleRequerimiento[0].descripcion || 'Sin descripcion') "></mat-label> -->
</mat-card-content>
</mat-card>
<mat-label [innerHTML]="'REQUERIMIENTO : ' + (detalleRequerimiento[0].numeroDoc || 'Sin Requerimiento') "></mat-label><br>
<mat-label [innerHTML]="'SEDE : ' + (detalleRequerimiento[0].sede || 'Sin Sede') "></mat-label><br>
<mat-label [innerHTML]="'EMPLEADO : ' + (detalleRequerimiento[0].empleado || 'Sin Empleado') "></mat-label><br>
<mat-label [innerHTML]="'OBSERVACIÓN : ' + (detalleRequerimiento[0].observacion || 'Sin Observacion') "></mat-label><br>
<mat-label [innerHTML]="'DESCRIPCIÓN : ' + (detalleRequerimiento[0].descripcion || 'Sin descripcion') "></mat-label><br>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource" >
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
......
import {Component, Inject, OnInit} from '@angular/core';
import {Component, ElementRef, Inject, OnInit, ViewChild} from '@angular/core';
import {provideNativeDateAdapter} from '@angular/material/core';
import {MatTableModule} from '@angular/material/table';
import { MatDialogActions, MatDialogClose, MatDialogContent, MatDialogTitle, MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog";
......@@ -9,6 +9,7 @@ import {FormControl, FormGroup, ReactiveFormsModule} from "@angular/forms";
import {MatIconModule} from '@angular/material/icon';
import {MatDividerModule} from '@angular/material/divider';
import {MatButtonModule} from '@angular/material/button';
import {MatCard, MatCardContent} from "@angular/material/card";
export interface PeriodicElement {
......@@ -25,6 +26,8 @@ export interface interDetalleRequerimiento {
cantidad: number;
}
//const ARTICULOS_DATA : detalleRequerimiento[] = [];
@Component({
......@@ -46,28 +49,55 @@ export interface interDetalleRequerimiento {
MatButtonModule,
MatDividerModule,
MatIconModule,
MatCard,
MatCardContent,
]
})
export class modalRequerimientoComponent implements OnInit{
@ViewChild('datosPrincipales') datosPrincipales!: ElementRef;
detalleRequerimiento: any;
filasRequerimientos: any;
//displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
//filasRequerimientos: any;
columnasArticulos: string[] = ['posicion', 'nombre', 'unidad', 'cantidad'];
dataSource: interDetalleRequerimiento[] = [];
constructor(@Inject(MAT_DIALOG_DATA) public data: any) {
// Puedes acceder a los datos pasados a través de 'data'
this.detalleRequerimiento = data.requerimientoInfo
this.filasRequerimientos = data.requerimientoInfo.map((item: any) => ({
posicion: item.numeral,
nombre: item.producto,
unidad: item.codUnidad,
cantidad: item.cantidad
}));
const datosPrincipales = data.requerimientoInfo?.map((item: any) => {
return {
numeroDoc : item.numeroDoc,
descripcion : item.descripcion,
observacion : item.observacion,
empleado : item.empleado,
sede : item.nombreSede,
posicion: item.numeral,
nombre: item.producto,
unidad: item.codUnidad,
cantidad: item.cantidad,
tipoRequerimiento : item.descTipoReq,
fechaRegistro : item.fechaRegistro
}
}) || [];
console.log(datosPrincipales);
if(datosPrincipales[0]){
//Obtener los valores de descripcion, observacion, sede y empleado por separado y en un solo objeto
this.detalleRequerimiento = {
numeroDoc : datosPrincipales[0].numeroDoc,
tipoRequerimiento : datosPrincipales[0].tipoRequerimiento,
descripcion : datosPrincipales[0].descripcion,
observacion : datosPrincipales[0].observacion,
empleado : datosPrincipales[0].empleado,
sede : datosPrincipales[0].sede
}
this.dataSource = datosPrincipales;
}
//this.detalleRequerimiento = data.requerimientoInfo
//this.filasRequerimientos =
console.log(this.detalleRequerimiento);
......@@ -75,7 +105,7 @@ export class modalRequerimientoComponent implements OnInit{
ngOnInit(): void {
//ARTICULOS_DATA.push(this.detalleRequerimiento);
this.dataSource = this.filasRequerimientos;
}
......
<div class="m-5">
<div class="w-full">
<mat-form-field class="w-full">
<mat-label>DESCRIPCIÓN DEL MATERIAL SOBRANTE : </mat-label>
<textarea matInput placeholder="Breve descripción de los materiales faltantes y su estado"></textarea>
</mat-form-field>
</div>
<!---------------------------------------------------------------------- SECCION MATERIALES SOBRANTES ---------------------------------------------------------------------->
<div [formGroup]="datos_materialSobrante">
<div class="grid gap-4 grid-cols-2">
<mat-label class="text-[1.1em] font-bold mb-4" style="display: flex;align-items: center;margin: unset">LISTADO DE ARTICULOS <mat-icon>attach_money</mat-icon> </mat-label>
<button [ngStyle]="{'visibility': activarNuevoArticulo ? 'visible' : 'hidden'}" [disabled]="!activarNuevoArticulo" mat-raised-button (click)="onAgregarArticulo($event)">
<mat-icon>add</mat-icon>
<b>Agregar material</b>
</button>
</div>
<div>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<ng-container matColumnDef="nombre">
<th mat-header-cell *matHeaderCellDef> NOMBRE DE ARTÍCULO </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.isNew; else displayOrigen">
<mat-form-field style="width: 25rem">
<input type="text" placeholder="Buscar articulos" matInput formControlName="articulo{{element.index}}" [matAutocomplete]="auto" maxlength="9"
(input)="onBusquedaArticulo($event,element.index)">
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="onSeleccionArticulo($event,element.index)" >
<mat-option *ngFor="let option of articulosList" [value]="option.codigo">
{{ option.nombre }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</ng-container>
<ng-template #displayOrigen>
{{element.nombre}}
</ng-template>
</td>
</ng-container>
<ng-container matColumnDef="unidad">
<th mat-header-cell *matHeaderCellDef> UNIDAD </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.isNew; else displayOrigen">
<!-- <mat-form-field style="width: 20rem" appearance="outline">
<input matInput placeholder="[Lugar de Destino]" readonly>
</mat-form-field>-->
<mat-label>{{codigoUnidad}}</mat-label>
</ng-container>
<ng-template #displayOrigen>
{{element.unidad}}
</ng-template>
</td>
</ng-container>
<ng-container matColumnDef="cantidad">
<th mat-header-cell *matHeaderCellDef> CANTIDAD </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.isNew; else displayOrigen">
<mat-form-field style="width: 10rem" appearance="outline">
<input matInput formControlName="cantidad{{element.index}}" soloNumeros value="" maxlength="2">
</mat-form-field>
</ng-container>
<ng-template #displayOrigen>
{{ element.cantidad }}
</ng-template>
</td>
</ng-container>
<ng-container matColumnDef="estado">
<th mat-header-cell *matHeaderCellDef> ESTADO ARTÍCULO </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.isNew; else displayOrigen">
<mat-form-field class="select-tipoTrabajo">
<mat-label>Seleccionar tipo de trabajo</mat-label>
<mat-select formControlName="estado{{element.index}}">
@for (tipoT of listEstadoArticulo; track tipoT) {
<mat-option [value]="tipoT.valor">{{tipoT.nombre}}</mat-option>
}
</mat-select>
</mat-form-field>
</ng-container>
<ng-template #displayOrigen>
{{ formatoEstado(element.estado) }}
</ng-template>
</td>
</ng-container>
<ng-container matColumnDef="accion">
<th mat-header-cell *matHeaderCellDef> ACCIÓN </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.acciones; else sinAcciones">
<ng-container *ngIf="element.isNew; else accionesEditar">
<button mat-icon-button (click)="onEventoConfirmarArticulo($event, element)">
<mat-icon>check_circle</mat-icon>
</button>
<button mat-icon-button (click)="onEventoCancelarArticulo($event, element)">
<mat-icon>cancel</mat-icon>
</button>
</ng-container>
<ng-template #accionesEditar>
<button mat-icon-button (click)="onEventoEditarArticulo($event, element)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button (click)="onEventoEliminarArticulo($event, element)">
<mat-icon>delete</mat-icon>
</button>
</ng-template>
</ng-container>
<ng-template #sinAcciones>
</ng-template>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnasArticulos"></tr>
<tr mat-row *matRowDef="let row; columns: columnasArticulos;"></tr>
</table>
</div>
</div>
<!---------------------------------------------------------------------- SECCION MATERIALES SOBRANTES ---------------------------------------------------------------------->
</div>
......@@ -2,7 +2,6 @@ import {Injectable} from "@angular/core";
import axios from "axios";
import {environment} from "../../../environment/env";
@Injectable({
providedIn: 'root'
})
......@@ -10,6 +9,10 @@ export class ConformidadService {
t_asistencia_rest_link = environment.t_asistencia_rest_link;
t_horizon_rest_link = environment.horizon_services_link;
t_facturacion_electronica_link = environment.facturacion_electronica_link;
value_idDrive = environment.ID_CARPETA_DRIVE_LOGISTICA;
value_correoDrive = environment.CORREO_DRIVE_LOGISTICA;
t_redireccionamiento = environment.redireccionamiento;
constructor() {
}
......@@ -30,7 +33,7 @@ export class ConformidadService {
const parametros =[
json.accion || 0,
json.nroRequerimiento || '',
json.nombreValor || '',
json.sede || '',
]
......@@ -53,19 +56,124 @@ export class ConformidadService {
}
}
async registroConformidad(json: any) {
async gestionConformidad(json: any) {
const Parametros = {
opcion : json.opcion || 0,
codconformidad : json.codconformidad || 0,
codper : json.codper || 0,
codlocal : json.codlocal || '',
fechainicio : json.fechainicio || '1999-01-01',
fechafin : json.fechafin || '1999-01-01',
descproblema : json.descproblema || '',
desccausa : json.desccausa || '',
codtipotrabajo: json.codtipotrabajo || 0 ,
desctrabajo: json.desctrabajo || '',
materialsobrate: json.materialsobrate || '',
pasaje : json.pasaje || 0,
codrequerimiento : json.codrequerimiento || 0
};
try {
const respuesta = await axios.post(this.t_asistencia_rest_link + '/api/v1/Conformidad/registroConformidad', json);
const respuesta = await axios.post(this.t_facturacion_electronica_link + '/api/v1/conformidad/registrarConformidad', Parametros);
console.log(respuesta);
return respuesta.data;
} catch (e) {
return e;
}
}
async subidaEvidencia(json:any){
const url = `${this.t_redireccionamiento}/google/drive`;
const formData = new FormData();
formData.append('archivo_nombre', json.nombreArchivo);
formData.append('archivo_binario', json.archivo);
formData.append('archivo_id_actual', '');
formData.append('carpeta_id', this.value_idDrive);
formData.append('correo', this.value_correoDrive);
formData.append('app_nombre', 'EVIDENCIAS_CONFORMIDAD');
formData.append('carpeta_nombre', 'EVIDENCIA1');
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 30000); // 30 segundos
try {
const response = await fetch(url, {
method: 'POST',
body: formData,
signal: controller.signal, // 30 segundos de timeout
});
const statusCode = response.status;
const responseBody = await response.json();
// Construir respuesta en formato JSON
/*const respuesta = {
statusCode: statusCode,
responseBody: responseBody,
};
*/
clearTimeout(timeout); // Limpiar, REVISA SI ESTO ESTA BIEN O QUITARLO
let respuesta :any ;
//console.log(statusCode,responseBody);
if(statusCode === 200){
//console.log(responseBody);
const registroEvidencia = await this.registroDocumento({
codconformidad: json.codconformidad || 0,
tipoEvidencia : json.tipoEvidencia || 0,
idDrive : responseBody.data.archivo_id || '',
enlaceDrive : responseBody.data.archivo_url_vista || '',
enlaceDescarga : responseBody.data.archivo_url || '',
nombreDocumento : json.nombreArchivo || ''
});
if(registroEvidencia?.status){
respuesta = {status: true, message: "Imagen subida"};
}else{
respuesta = { status :false , message : "Imagen no subida" };
}
//respuesta = { status :true , message : "Imagen subida" };
/*const respuestaDocumento = await axios.post(this.t_facturacion_electronica_link + '/api/v1/conformidad/registroDocumentos', registroEvidencia);+
console.log(respuestaDocumento);
respuesta = respuestaDocumento;*/
}else{
respuesta = { status :false , message : "Imagen no subida" };
}
return respuesta;
} catch (error) {
console.error('Error al registrar el archivo:', error);
throw error;
}
}
async registroDocumento(json : any){
try {
const respuesta = await axios.post(this.t_facturacion_electronica_link + '/api/v1/conformidad/registroDocumentos', json);
//console.log(respuesta);
return respuesta.data;
} catch (e) {
return e;
}
}
/*async listadoRequerimientos(json: any) {
const parametros =[
json.accion || 0,
json.nroRequerimiento || '',
json.nombreValor || '',
json.sede || '',
]
......@@ -86,4 +194,6 @@ export class ConformidadService {
return e;
}
}*/
}
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
standalone: true,
name: 'truncate'
})
export class truncarCaracteresDirective implements PipeTransform {
transform(value: string, limit: number = 20, completeWords: boolean = false, ellipsis: string = '...'): string {
if (!value) return '';
if (value.length <= limit) return value;
let truncated = value.substring(0, limit);
if (completeWords) {
const lastSpace = truncated.lastIndexOf(' ');
if (lastSpace > 0) {
truncated = truncated.substring(0, lastSpace);
}
}
return truncated + ellipsis;
}
}
/*import { SoloNumerosDirective } from './solo-numeros.directive';
describe('SoloNumerosDirective', () => {
it('should create an instance', () => {
const directive = new SoloNumerosDirective();
expect(directive).toBeTruthy();
});
});
*/
......@@ -2,10 +2,11 @@ export const environment = {
isProduction: false,
trismegisto_services_link: 'https://tp-services.sacooliveros.edu.pe',
t_asistencia_rest_link: 'http://localhost:8080/tasistencia-rest',
redireccionamiento: 'https://fichaonline.sacooliveros.edu.pe',
redireccionamiento: 'https://fichaonline.sacooliveros.edu.pe:8000/trismegisto-apis/api/v1',
facturacion_electronica_link: 'http://localhost:8080/FacturacionElectronicaSIIAA',
horizon_services_link: 'http://localhost:8080/trismegisto-api-horizons',
ID_CARPETA_DRIVE_LOGISTICA:'13mGZo3AnFqgkNRyiVAgJoW9mUoQdABdC',
CORREO_DRIVE_LOGISTICA : 'trismegisto.logistica@sacooliveros.edu.pe'
};
......
......@@ -22,7 +22,9 @@
"lib": [
"ES2022",
"dom"
]
],
"types": ["node"] // Agregado para incluir los tipos de Node.js
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
......
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