[ADD] NUEVOS CAMBOS Y FILTROS

parent 273b20c0
......@@ -19,6 +19,7 @@
"@angular/platform-browser-dynamic": "^18.2.0",
"@angular/router": "^18.2.0",
"axios": "^1.7.7",
"ngx-mat-timepicker": "^19.0.0",
"notiflix": "^3.2.8",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
......@@ -10178,6 +10179,26 @@
"dev": true,
"license": "MIT"
},
"node_modules/ngx-mat-timepicker": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/ngx-mat-timepicker/-/ngx-mat-timepicker-19.0.0.tgz",
"integrity": "sha512-r40jia6koyxwPRU8vG7XyeqfZrKI7tMnwcF6a4EqYiX5cM8CODpLeAq686fQteFD00dBc+t57+pCC1MMDp36Kw==",
"license": "MIT",
"dependencies": {
"ts-luxon": "^5.0.6",
"tslib": "^2.5.3"
},
"peerDependencies": {
"@angular/animations": "^19.0.0",
"@angular/cdk": "^19.0.0",
"@angular/common": "^19.0.0",
"@angular/compiler": "^19.0.0",
"@angular/core": "^19.0.0",
"@angular/forms": "^19.0.0",
"@angular/material": "^19.0.0",
"@angular/platform-browser": "^19.0.0"
}
},
"node_modules/nice-napi": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
......@@ -13406,6 +13427,15 @@
"dev": true,
"license": "Apache-2.0"
},
"node_modules/ts-luxon": {
"version": "5.0.6",
"resolved": "https://registry.npmjs.org/ts-luxon/-/ts-luxon-5.0.6.tgz",
"integrity": "sha512-FFSi0UKcQ8lgCBBTl6OMGcp26cANEV67cwJyXi4pTHuxa28wJUDtjBwcgDGn04a+wqtnHqdNaMnor2UDicmPDQ==",
"license": "MIT",
"engines": {
"node": ">=13"
}
},
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
......
......@@ -21,6 +21,7 @@
"@angular/platform-browser-dynamic": "^18.2.0",
"@angular/router": "^18.2.0",
"axios": "^1.7.7",
"ngx-mat-timepicker": "^19.0.0",
"notiflix": "^3.2.8",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
......
......@@ -42,3 +42,7 @@ mat-label {
opacity: 1; /* Por defecto, el label será completamente visible */
}
.custom-snackbar {
white-space: pre-line; /* Permite respetar saltos de línea */
}
......@@ -13,6 +13,16 @@
</mat-card-header>
<mat-card-content class="w-full my-2.5" [formGroup]="datos_personal">
<!------------------------------------------------------------------------- DATOS GENERALES ------------------------------------------------------------------------------>
<div class="flex gap-4 mb-4">
<mat-form-field class="basis-1/4" appearance="outline" floatLabel="always">
<mat-label>TIPO TRABAJADOR</mat-label>
<mat-select formControlName="tipoCargoPersonal" placeholder="[Seleccionar zona]" required>
<mat-option *ngFor="let option of this.cargosU_list" [value]="option.cargou">
{{option.tipocargo}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="flex flex-row gap-4 mb-4">
<div class="basis-2/4">
<div class="flex flex-row gap-x-2" *ngFor="let personal of listPersonal">
......@@ -29,9 +39,11 @@
<input formControlName="areaPersonal{{personal.index}}" matInput placeholder="[Área designada]" value="" readonly>
</mat-form-field>
</div>
</div>
<!-- agregar botones de agregar o disminuir Tecnico responsable -->
<div class="flex flex-row gap-x-2">
<div class="basis-2/4">
<!-- 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">
<mat-icon>add</mat-icon>
......@@ -42,11 +54,13 @@
<mat-icon>delete</mat-icon>
</button>
</div>
<mat-label class="font-bold text-blue-600 text-lg" [ngClass]="{'fade-out': personalFading}" [innerText]="personalText"></mat-label>
<mat-label class=" font-bold text-blue-600 text-lg" [ngClass]="{'fade-out': personalFading}" [innerText]="personalText"></mat-label>
</div>
</div>
</div>
<div class="basis-2/4">
<div class="w-full gap-4 mb-4">
<!-- <div class="basis-3/4"> -->
<div class="flex flex-row gap-x-2">
<mat-form-field class="w-full" appearance="outline" floatLabel="always">
<mat-label>Zona</mat-label>
......@@ -75,9 +89,37 @@
<mat-datepicker-toggle matIconSuffix [for]="picker" [disabled]="datos_personal.controls['minFechaTrabajo'].disabled"></mat-datepicker-toggle>
<mat-date-range-picker #picker></mat-date-range-picker>
</mat-form-field>
<div class="gap-x-2" [ngStyle]="{ display: mostrarHoras ? 'flex' : 'none' }">
<mat-form-field class="w-full" appearance="outline" floatLabel="always">
<mat-label>Selecciona hora inicio</mat-label>
<input
matInput
[ngxMatTimepicker]="timepicker"
formControlName="minHoraTrabajo"
placeholder="00:00"
/>
<ngx-mat-timepicker-toggle matIconSuffix [for]="timepicker"></ngx-mat-timepicker-toggle>
<ngx-mat-timepicker #timepicker></ngx-mat-timepicker>
</mat-form-field>
<mat-form-field class="w-full" appearance="outline" floatLabel="always">
<mat-label>Selecciona hora fin</mat-label>
<input
matInput
[ngxMatTimepicker]="timepicker2"
formControlName="maxHoraTrabajo"
placeholder="00:00"
/>
<ngx-mat-timepicker-toggle matIconSuffix [for]="timepicker2"></ngx-mat-timepicker-toggle>
<ngx-mat-timepicker #timepicker2></ngx-mat-timepicker>
</mat-form-field>
</div>
</div>
</div>
<!--</div>-->
</div>
<!------------------------------------------------------------------------- DATOS GENERALES ------------------------------------------------------------------------------>
......@@ -223,7 +265,7 @@
</mat-option>
</mat-autocomplete>
</mat-form-field>
<mat-label class="font-bold text-blue-600 text-lg" [ngClass]="{'fade-out': isFading}" [innerText]="labelText"></mat-label>
<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">-->
......@@ -420,345 +462,6 @@
REGISTRO CONFORMIDAD
</button>
</div>
<!--
<mat-card appearance="outlined" class="mt-4 flex flex-col gap-2.5 text-[#222] !shadow-xl w-[90vw] md:w-[75vw]">
<mat-card-header class="flex flex-col items-start w-full">
<label class="text-[1.1em] font-bold">
DATOS PERSONALES
</label>
</mat-card-header>
<mat-card-content class="w-full my-2.5">
<div class="flex flex-row gap-x-4" [formGroup]="datos_personal">
<mat-form-field class="basis-1/4" appearance="outline" floatLabel="always">
<mat-label>Técnico responsable</mat-label>
<mat-select formControlName="tecnicoPersonal" placeholder="[Seleccionar técnico]" (selectionChange)="onEventoSeleccionTecnico($event)" required>
<mat-option *ngFor="let option of this.personal_list" [value]="option?.codper">
{{option?.personal}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="basis-1/4" appearance="outline" floatLabel="always">
<mat-label>Área designada</mat-label>
<input formControlName="areaPersonal" matInput placeholder="[Área designada]" value="" readonly>
</mat-form-field>
<mat-form-field class="basis-1/4" appearance="outline" floatLabel="always">
<mat-label>Sede designada : </mat-label>
<mat-select formControlName="sedePersonal" placeholder="[Seleccionar sede]" required>
<mat-option *ngFor="let option of this.sede_list" [value]="option?.codlocal">
{{option?.deslocal}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="basis-1/4" appearance="outline" floatLabel="always">
<mat-label>Rango de fechas : </mat-label>
<mat-date-range-input [rangePicker]="picker">
<input matStartDate formControlName="minFechaTrabajo" placeholder="Fecha inicial" readonly >
<input matEndDate formControlName="maxFechaTrabajo" placeholder="Fecha Fin" readonly>
</mat-date-range-input>
<mat-datepicker-toggle matIconSuffix [for]="picker" [disabled]="datos_personal.controls['minFechaTrabajo'].disabled"></mat-datepicker-toggle>
<mat-date-range-picker #picker></mat-date-range-picker>
</mat-form-field>
</div>
<div class="flex flex-row gap-x-4">
<div class="basis-3/12">
<mat-form-field [formGroup]="datos_personal" style="width: 20rem" appearance="outline" floatLabel="always">
<mat-label>Pasaje designado : </mat-label>
<input matInput formControlName="pasajeTotal" placeholder="Calculo final del pasaje" value="" readonly>
</mat-form-field>
</div>
<div class="basis-9/12 ">
<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 PASAJES <mat-icon>attach_money</mat-icon> </mat-label>
<button mat-raised-button [ngStyle]="{'visibility': activarPasajes ? 'visible' : 'hidden'}" [disabled]="!activarPasajes" (click)="onEventoNuevoPasaje($event)">
<mat-icon>add</mat-icon>
<b>Agregar pasaje</b>
</button>
</div>
<div>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<ng-container matColumnDef="lugarOrigen">
<th mat-header-cell *matHeaderCellDef style="width: 20%"> LUGAR DE ORIGEN </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.isNew; else displayOrigen">
<mat-form-field [formGroup]="datos_lugarOrigen" appearance="outline" floatLabel="always">
<mat-select formControlName="lugarOrigen{{element.index}}" placeholder="[Seleccionar de origen]" required>
<mat-option *ngFor="let option of this.sede_list" [value]="option?.codlocal">
{{option?.deslocal}}
</mat-option>
</mat-select>
</mat-form-field>
</ng-container>
<ng-template #displayOrigen>
{{element.lugarOrigen}}
</ng-template>
</td>
</ng-container>
<ng-container matColumnDef="lugarDestino">
<th mat-header-cell *matHeaderCellDef style="width: 20%"> LUGAR DESTINO </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.isNew; else displayOrigen">
<mat-form-field appearance="outline">
<input matInput placeholder="[Lugar de Destino]" [value]="lugarDestinoPasaje" readonly>
</mat-form-field>
</ng-container>
<ng-template #displayOrigen>
{{element.lugarDestino}}
</ng-template>
</td>
</ng-container>
<ng-container matColumnDef="monto">
<th mat-header-cell *matHeaderCellDef style="width: 10%"> MONTO </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.isNew; else displayOrigen">
<mat-form-field [formGroup]="datos_pasajeAcumulado" appearance="outline">
<input matInput formControlName="montoPasaje{{element.index}}" soloNumeros placeholder="[Monto]" value="" maxlength="2">
</mat-form-field>
</ng-container>
<ng-template #displayOrigen>
{{element.monto}}
</ng-template>
</td>
</ng-container>
<ng-container matColumnDef="fecha">
<th mat-header-cell *matHeaderCellDef style="width: 20%;"> FECHA </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.isNew; else displayOrigen">
<mat-form-field [formGroup]="datos_fechaPasaje" appearance="outline">
<input matInput [matDatepicker]="fechaPasaje" formControlName="fechaPasaje{{element.index}}" [min]="minFechaLimite" [max]="maxFechaLimite">
<mat-hint>DD/MM/YYYY</mat-hint>
<mat-datepicker-toggle matIconSuffix [for]="fechaPasaje"></mat-datepicker-toggle>
<mat-datepicker #fechaPasaje></mat-datepicker>
</mat-form-field>
</ng-container>
<ng-template #displayOrigen>
{{formatoFecha(element.fecha)}}
</ng-template>
</td>
</ng-container>
<ng-container matColumnDef="accion">
<th mat-header-cell *matHeaderCellDef style="width: 30%;"> 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)="onEventoConfirmarPasaje($event, element)">
<mat-icon>check_circle</mat-icon>
</button>
<button mat-icon-button (click)="onEventoCancelarPasaje($event, element)">
<mat-icon>cancel</mat-icon>
</button>
</ng-container>
<ng-template #accionesEditar>
<button mat-icon-button (click)="onEventoEditarPasaje($event, element)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button (click)="onEventoEliminarPasaje($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="columnasPasaje"></tr>
<tr mat-row *matRowDef="let row; columns: columnasPasaje;"></tr>
</table>
</div>
</div>
</div>
</mat-card-content>
</mat-card>
-->
<!---------------------------------------------------------------------- SERVICIOS PRESTADOS ---------------------------------------------------------------------->
<!--<mat-card appearance="outlined" class="mt-4 flex flex-col gap-2.5 text-[#222] !shadow-xl w-[90vw] md:w-[75vw]">
<mat-card-header class="flex flex-col items-start w-full">
<label class="text-[1.1em] font-bold">
SERVICIOS PRESTADOS
</label>
</mat-card-header>
<mat-card-content class="w-full my-2.5">
<div class="div-serviocisPrestados divisionGeneral" [formGroup]="datos_servicio">
<div class="servicio-descripcion">
<div class="flex flex-row gap-5 pb-5">
<div class="basis-1/5">
<mat-form-field style="width: 15rem" 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)="onBusquedaRequerimiento($event)">
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="onEventSeleccion($event)" >
<mat-option *ngFor="let option of requerimientosFiltrados" [value]="option.codigo">
{{ option.numero }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<mat-label [ngClass]="{'fade-out': isFading}" [innerText]="labelText"></mat-label>
</div>
<div class="grid grid-cols-5 gap-4 basis-4/5">
<div class="contenedorRequerimiento" *ngFor="let card of listRequerimientos" style="display: flex">
<mat-card>
<mat-card-content>
<mat-card-subtitle style="font-size: 1rem;font-weight: bold;align-content: center">{{ card.titulo }}</mat-card-subtitle>
<div class="w-fit py-2 px-3 flex space-x-4">
<button mat-fab aria-label="Eliminar" matTooltip="Eliminar" matTooltipPosition="above" (click)="deleteRequerimiento(card.id)">
<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)">
<mat-icon class="mat-icon-small">info</mat-icon>
</button>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
</div>
<div class="grid grid-flow-col md:grid-cols-2 gap-5" >
<div>
<mat-form-field class="example-full-width">
<mat-label>DESCRIPCIÓN DEL PROBLEMA </mat-label>
<textarea matInput placeholder="Breve descripción sobrel los problemas encontrados en la sede" formControlName="descripcionServicio"
cdkTextareaAutosize
cdkAutosizeMinRows="3"
cdkAutosizeMaxRows="10"
[required]="false"></textarea>
</mat-form-field>
</div>
<div>
<mat-form-field class="example-full-width">
<mat-label>DESCRIPCIÓN DE LA CAUSA </mat-label>
<textarea matInput placeholder="Breve descripción sobre las causas del problema" formControlName="causaServicio"
cdkTextareaAutosize
cdkAutosizeMinRows="3"
cdkAutosizeMaxRows="10"
[required]="false"></textarea>
</mat-form-field>
</div>
</div>
</div>
<div class="grid grid-flow-col md:grid-cols-2 gap-5">
<div class="">
<div> <b class="md:text-[1rem] text-[1em] text-black/60">EVIDENCIAS DEL PROBLEMAS : *</b> </div>
<div>
<button mat-fab class="!w-full"
[color]="'blue'"
(click)="file1.click()">
<mat-label> SUBIR EVIDENCIA DEL PROBLEMA </mat-label>
<mat-icon class="font-size: 48px; height: 48px; width: 48px">file_open</mat-icon>
</button>
<input type="file" #file1 (change)="onEventoSubirArchivo($event)" class="hidden" multiple accept="image/png" />
</div>
<br>
<div *ngFor="let archivo of archivosEvidencia; let i = index" class="flex">
<div *ngIf="archivo.tipoEvidencia === 1" class="flex w-full">
<div class="w-2/4"><p>{{ (archivo.file.name + ' (' + (archivo.file.size / 1000) + ' KB)') | truncate:30:true }}</p></div>
<div class="w-2/4 grid grid-cols-3 gap-4 justify-center" >
<button type="button" (click)="gestionArchivos(i,1,archivo.file)"><mat-icon class="mat-icon-small">info</mat-icon></button>
<button type="button" (click)="seleccionarInput(i,1)"><mat-icon class="mat-icon-small">edit</mat-icon></button>
<input type="file" #fileEditar1 (change)="gestionArchivos(i,2,$event)" class="hidden" multiple accept="image/png" />
<button type="button" (click)="gestionArchivos(i,3)"><mat-icon class="mat-icon-small">delete</mat-icon></button>
</div>
</div>
</div>
</div>
<div class="">
<div> <b class="md:text-[1rem] text-[1em] text-black/60">EVIDENCIAS DE SOLUCIONES : *</b> </div>
<div>
<button mat-fab class="!w-full"
[color]="'blue'"
(click)="file2.click()">
<mat-label>SUBIR EVIDENCIA DE LA SOLUCIÓN</mat-label>
<mat-icon>file_open</mat-icon>
</button>
<input type="file" #file2 (change)="onEventoSubirArchivo($event,2)" class="hidden" multiple accept="image/png">
</div>
<br>
<div *ngFor="let archivo of archivosEvidencia; let i = index" class="flex">
<div *ngIf="archivo.tipoEvidencia === 2" class="flex w-full">
<div class="w-2/4"><p>{{ (archivo.file.name + ' (' + (archivo.file.size / 1000) + ' KB)') | truncate:30:true }}</p></div>
<div class="w-2/4 grid grid-cols-3 gap-4 justify-center" >
<button type="button" (click)="gestionArchivos(i,1,archivo.file,2)"><mat-icon class="mat-icon-small">info</mat-icon></button>
<button type="button" (click)="seleccionarInput(i,2)"><mat-icon class="mat-icon-small">edit</mat-icon></button>
<input type="file" #fileEditar2 (change)="gestionArchivos(i,2,$event,2)" class="hidden" multiple accept="image/png" />
<button type="button" (click)="gestionArchivos(i,3,2)"><mat-icon class="mat-icon-small">delete</mat-icon></button>
</div>
</div>
</div>
</div>
</div>
</div>
</mat-card-content>
</mat-card>-->
<!---------------------------------------------------------------------- SERVICIOS PRESTADOS ---------------------------------------------------------------------->
<!---------------------------------------------------------------------- TRABAJOS PRESTADOS ---------------------------------------------------------------------->
<!--<mat-card appearance="outlined" class="mt-4 flex flex-col gap-2.5 text-[#222] !shadow-xl w-[90vw] md:w-[75vw]">
<mat-card-header class="flex flex-col items-start w-full">
<label class="text-[1.1em] font-bold">
TRABAJOS PRESTADOS
</label>
</mat-card-header>
<mat-card-content class="w-full my-2.5">
<div class="div-trabajosPrestados divisionGeneral" [formGroup]="datos_trabajo">
<label style="font-weight: bold; font-size: 1.2rem; font-family: 'inherit'">TIPO DE TRABAJO : </label>
<mat-form-field class="select-tipoTrabajo">
<mat-label>Seleccionar tipo de trabajo</mat-label>
<mat-select formControlName="tipoTrabajo">
@for (tipoT of listTipoTrabajo; track tipoT) {
<mat-option [value]="tipoT.value">{{tipoT.viewValue}}</mat-option>
}
</mat-select>
</mat-form-field>
<br>
<mat-form-field class="example-full-width">
<mat-label>DESCRIPCIÓN DEL TRABAJO</mat-label>
<textarea matInput placeholder="Breve descripciòn del trabajo realizado" formControlName="descripcionTrabajo" [required]="false"></textarea>
</mat-form-field>
</div>
</mat-card-content>
</mat-card> -->
<!---------------------------------------------------------------------- TRABAJOS PRESTADOS ---------------------------------------------------------------------->
<!--<mat-card appearance="outlined" class="mt-4 flex flex-col gap-2.5 text-[#222] !shadow-xl w-[90vw] md:w-[75vw]" [formGroup]="existeMaterialS">
<mat-card-header class="justify-center content-center gap-x-4 w-full mb-4">
<mat-label class="flex items-center text-[1.1em] font-bold">
MATERIAL SOBRANTE
</mat-label>
<mat-button-toggle-group formControlName="existeMaterial" aria-label="Existe material sobrante" value="0">
<mat-button-toggle value="1">SI</mat-button-toggle>
<mat-button-toggle value="0">NO</mat-button-toggle>
</mat-button-toggle-group>
</mat-card-header>
<ng-container *ngIf="existeMaterialS.get('existeMaterial')?.value === '1'">
<mat-card-content>
<ordensalida-component></ordensalida-component>
</mat-card-content>
</ng-container>
</mat-card>
<div class="mt-4 flex flex-col">
<button mat-fab extended (click)="gestionConformidad()">
<mat-icon>app_registration</mat-icon>
REGISTRO CONFORMIDAD
</button>
</div>-->
</div>
......
......@@ -15,7 +15,8 @@ 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 {DateRange, MatDatepickerModule, MatDateRangeInput } from '@angular/material/datepicker';
import { NgxMatTimepickerModule } from 'ngx-mat-timepicker';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatInputModule} from '@angular/material/input';
import {MatSelectModule} from '@angular/material/select';
......@@ -36,8 +37,10 @@ import { MatSnackBar, MatSnackBarHorizontalPosition, MatSnackBarVerticalPosition
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 { ordenSalidaComponent } from "../ordensalida/ordensalida.componente";
import {elementSelectors} from "@angular/cdk/schematics";
import Notiflix from 'notiflix';
import { DecimalPipe } from '@angular/common';
import {environment} from "../../../environment/env";
......@@ -84,6 +87,7 @@ interface interFile{
imports: [
SoloNumerosDirective,
MatDatepickerModule,
NgxMatTimepickerModule,
MatNativeDateModule,
MatFormFieldModule,
FormsModule,
......@@ -142,16 +146,12 @@ export class ConformidadComponent implements AfterViewInit {
// VIEWCHILD
// INICIALIZACION DE SEDES
//INICIALIZACION DE VARIABLES UTILIZABLES
opcionEnvironmnet : number = environment.opcion;
personal_list: any = [];
sede_list: any = [];
cargosU_list : any = [];
zona_list: any = [];
requerimientosFiltrados: any[] = [];
listSedesAtencion : lugaresTrabajo[] = [];
......@@ -165,6 +165,7 @@ export class ConformidadComponent implements AfterViewInit {
isFading: boolean = false; // Controla si la animación de desvanecimiento debe activarse
personalText : string = '';
personalFading : boolean = false ;
mostrarHoras : boolean = true ;
activarPasajes : boolean = false;
//lugarDestinoPasaje : string = '';
......@@ -181,8 +182,6 @@ export class ConformidadComponent implements AfterViewInit {
archivosEvidencia : interFile[] = [];
archivosProblema : interFile[] = [];
archivosSolucion : interFile[] = [];
archivosATC : interFile[] = [];
archivosFirma : interFile[] = [];
//INICIALIZACION DE VARIABLES UTILIZABLES
// GRUPO DE FORMULARIO
......@@ -191,9 +190,12 @@ export class ConformidadComponent implements AfterViewInit {
tecnicoPersonal0 : new FormControl(null ,Validators.required),
areaPersonal0 : new FormControl<string>('' ,Validators.required),
zonaPersonal : new FormControl(null,Validators.required),
tipoCargoPersonal : new FormControl<string>('' ,Validators.required),
sedePersonal : new FormControl(null,Validators.required),
minFechaTrabajo : new FormControl<Date>(new Date(), Validators.required),
maxFechaTrabajo : new FormControl<Date>(new Date(), Validators.required),
minHoraTrabajo : new FormControl<string | null>(''),
maxHoraTrabajo : new FormControl<string | null>(''),
//pasajeTotal: new FormControl<number>(0),
});
......@@ -267,15 +269,18 @@ export class ConformidadComponent implements AfterViewInit {
const [
personal,
sede,
tipoTrabajo
tipoTrabajo,
cargosUnidos
] = await Promise.all([
this.conformidadHelper.cargarPersonal(),
this.conformidadHelper.cargarSedes(),
this.conformidadHelper.gestionConformidad({opcion: 9})
this.conformidadHelper.gestionConformidad({opcion: 9}),
this.conformidadHelper.cargarCargosU()
]);
this.personal_list = personal;
//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.dataSource = []; // Inicializa la tabla de pasajes
this.activarPasajes = false;
......@@ -286,29 +291,34 @@ export class ConformidadComponent implements AfterViewInit {
//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 => {
/*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);
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){
if(this.dataSource.length > 0 && !this.activarPasajes){
this.dataSource = [];
this.indexPasaje = 0;
this.datos_pasajeAcumulado.reset();
this.datos_fechaPasaje.reset();
this.datos_lugarOrigen.reset();
}*/
});
}
});*/
this.obtenerFormControl(this.datos_personal,'zonaPersonal')?.valueChanges.subscribe((value : any) => {
console.log('VALOR SELECCIONAD0 : ' + value);
this.listSedesAtencion = this.sede_list.filter((item: any) => item.zona === value).map((item: any) => ({ value: item.id_local, viewValue: item.deslocal }));
});
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));
});
// Sincronizar el valor de 'sedePersonal' con los selects la tabla de pasaje
/*this.obtenerFormControl(this.datos_personal,'sedePersonal')?.valueChanges.subscribe((value : any) => {
this.lugarDestinoPasaje = this.listadoSedesTrabajo.find((item: any) => item.value === value)?.viewValue || '';
......@@ -344,12 +354,25 @@ export class ConformidadComponent implements AfterViewInit {
});*/
/*this.datos_personal.get('maxFechaTrabajo')?.valueChanges.subscribe((value) => {
this.datos_personal.get('maxFechaTrabajo')?.valueChanges.subscribe((value) => {
let minFecha : any = this.datos_personal.get('minFechaTrabajo')?.value;
let maxFecha : any = value;
if( minFecha && maxFecha ){
const min = this.formatoFechaDate(new Date(minFecha));
const max = this.formatoFechaDate(new Date(maxFecha));
if(min == max){
this.mostrarHoras = true;
}else{
this.mostrarHoras = false;
}
this.datos_personal.get('minHoraTrabajo')?.setValue('00:00');
this.datos_personal.get('maxHoraTrabajo')?.setValue('00:00');
/*
this.minFechaLimite = new Date(minFecha);
this.maxFechaLimite = new Date(maxFecha);
......@@ -368,14 +391,9 @@ export class ConformidadComponent implements AfterViewInit {
this.datos_fechaPasaje.get(key)?.setValue('');
}
}
});
});*/
}
});*/
/*this.existeMaterialS.get('existeMaterial')?.valueChanges.subscribe((value) => {
console.log(value);
});*/
});
}
//AL SELECCIONAR UN REQUERIMIENTO
......@@ -517,6 +535,7 @@ export class ConformidadComponent implements AfterViewInit {
const control = this.obtenerFormControl(formGroup,formControlName);
if (control && control.value != null) {
const formattedValue = this.decimalPipe.transform(control.value, '1.2-2');
control.setValue(formattedValue, { emitEvent: false });
}
}*/
......@@ -811,12 +830,10 @@ export class ConformidadComponent implements AfterViewInit {
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);
if(!this.validarArchivos(archivosEvidencias)){
return;
}
};
if (!this.validarMaterialSobrante(existeMaterial, this.ordenSalidaComponent?.dataSource)) {
this.mostrarAlerta('VALIDAR MATERIAL SOBRANTE');
......@@ -836,7 +853,9 @@ export class ConformidadComponent implements AfterViewInit {
descproblema: datosServicio.descripcionServicio,
desccausa: datosServicio.causaServicio,
codtipotrabajo: parseInt(datosTrabajo.tipoTrabajo || '1'),
desctrabajo: datosTrabajo.descripcionTrabajo
desctrabajo: datosTrabajo.descripcionTrabajo,
minhoratrabajo : datosPersonal.minHoraTrabajo,
maxhoratrabajo : datosPersonal.maxHoraTrabajo
});
const respuestaConformidad : any = JSON.parse(registroConformidad);
......@@ -889,7 +908,6 @@ export class ConformidadComponent implements AfterViewInit {
break;
}
}
}
if (statusRequerimientos) { // REGISTRO DE REQUERIMIENTOS VALIDADOS Y REGISTRADOS
......@@ -914,7 +932,6 @@ export class ConformidadComponent implements AfterViewInit {
};
});
const filtroEvidenciasProblemas = registroArchivos.filter((item) => item.tipoEvidencia === 1);
const filtroEvidenciasSoluciones = registroArchivos.filter((item) => item.tipoEvidencia === 2);
const filtroEvidenciasExtras = registroArchivos.filter((item) => item.tipoEvidencia === 3 || item.tipoEvidencia === 4);
......@@ -969,7 +986,6 @@ export class ConformidadComponent implements AfterViewInit {
break;
}
}
if (statusOrdenSalida) { // UNION DE LA ORDEN DE SALIDA CON LA CONFORMIDAD
const relacionarOrdenConformidad = await this.conformidadHelper.gestionConformidad({
......@@ -985,12 +1001,9 @@ export class ConformidadComponent implements AfterViewInit {
statusOrdenSalida = false;
}
}
} else {
this.mostrarAlerta('ERROR AL REGISTRAR LOS ORDEN DE SALIDA');
}
} else {
statusOrdenSalida = true;
}
......@@ -1029,21 +1042,48 @@ export class ConformidadComponent implements AfterViewInit {
}
validarDatosPersonales(datosPersonal: any): boolean {
const min = this.formatoFechaDate(new Date(datosPersonal?.minFechaTrabajo));
const max = this.formatoFechaDate(new Date(datosPersonal?.maxFechaTrabajo));
let validarHoras;
if(min == max){
validarHoras = datosPersonal?.minHoraTrabajo && datosPersonal?.maxHoraTrabajo;
}else{
validarHoras = true;
}
return datosPersonal?.sedePersonal &&
datosPersonal?.maxFechaTrabajo &&
datosPersonal?.minFechaTrabajo;
datosPersonal?.minFechaTrabajo && validarHoras ;
}
validarPersonal(personal: any[]): boolean {
return personal.length > 0 && personal.every((item) => item.id != '0' && item.nombre != '');
}
validarPasajes(datosPasajes: any[]): boolean {
/*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
let advertencia = '';
if(archivosEvidencia.find((item) => item.tipoEvidencia === 1) === undefined){
advertencia += `REQUIERE SUBIR EVIDENCIA DE PROBLEMA`;
}
else if(archivosEvidencia.find((item) => item.tipoEvidencia === 2) === undefined){
advertencia += `REQUIERE SUBIR EVIDENCIA DE SOLUCION`;
}
else if(archivosEvidencia.find((item) => item.tipoEvidencia === 3) === undefined){
advertencia += `REQUIERE SUBIR EVIDENCIA DE ATC`;
}
else if(archivosEvidencia.find((item) => item.tipoEvidencia === 4) === undefined){
advertencia += `REQUIERE SUBIR EVIDENCIA DE FIRMA`;
}
this.mostrarAlerta(advertencia);
return (advertencia === '');//Debe existir por lo menos un archivo de evidencia de problema y uno de solucion
}
validarMaterialSobrante(existeMaterial: number, dataSource: any[]): boolean {
......@@ -1053,15 +1093,14 @@ export class ConformidadComponent implements AfterViewInit {
mostrarAlerta(mensaje: string): void {
Notiflix.Loading.remove();
this.barraAlerta.open(mensaje, '', {
horizontalPosition: this.alertaPosicionHorizontal,
verticalPosition: this.alertaPosicionVertical,
duration: this.alertaDuracion * 1000
duration: this.alertaDuracion * 1000,
panelClass: ['custom-snackbar'],
});
}
}
......@@ -26,6 +26,15 @@ export class ConformidadHelper {
}
}
async cargarCargosU(){
const respuesta = await this.ConformidadService.listadoGeneral(4);
if(respuesta?.status){
return respuesta.data;
}else{
return [];
}
}
async listadoGeneralHorizon(json: any){
const respuesta = await this.ConformidadService.listadoGeneralHorizon(json);
if (respuesta?.status) {
......
......@@ -71,7 +71,9 @@ export class ConformidadService {
desctrabajo: json.desctrabajo || '',
pasaje : json.pasaje || 0,
codrequerimiento : json.codrequerimiento || 0,
codordensalida : json.codordensalida || 0
codordensalida : json.codordensalida || 0,
minhoratrabajo : json.minhoratrabajo || '',
maxhoratrabajo : json.maxhoratrabajo || '',
};
try {
......
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