|
|
@@ -18,6 +18,8 @@ import { PreventiveOrderDetailsComponent } from '../preventive-order-details/pre
|
|
|
import { ResourcesService } from '../../../services/resources.service';
|
|
|
import { AlertComponent } from '../../resources/dialogs/alert/alert.component';
|
|
|
import { CommnetsDialogComponent } from '../../corrective-maintenance/operations-management/commnets-dialog/commnets-dialog.component';
|
|
|
+import { StatusTimelineComponent } from '../../corrective-maintenance/operations-management/status-timeline/status-timeline.component';
|
|
|
+import { StaffSelectionComponent } from '../../corrective-maintenance/operations-management/staff-selection/staff-selection.component';
|
|
|
|
|
|
@Component({
|
|
|
selector: 'app-unprogrammed-visits',
|
|
|
@@ -31,7 +33,7 @@ export class UnprogrammedVisitsComponent implements OnInit {
|
|
|
|
|
|
dataSource?: MatTableDataSource<UnprogrammedVisit>;
|
|
|
displayedColumns = [
|
|
|
- 'numeracion',
|
|
|
+ 'Número de visita',
|
|
|
'equipamiento',
|
|
|
'descripcion',
|
|
|
'estado',
|
|
|
@@ -64,6 +66,7 @@ export class UnprogrammedVisitsComponent implements OnInit {
|
|
|
R: 'Rechazado',
|
|
|
A: 'Aprobado',
|
|
|
F: 'Finalizado',
|
|
|
+ EL: 'Eliminado',
|
|
|
};
|
|
|
|
|
|
constructor(
|
|
|
@@ -528,4 +531,262 @@ export class UnprogrammedVisitsComponent implements OnInit {
|
|
|
const pageSize = this.paginator?.pageSize ?? 10;
|
|
|
return pageIndex * pageSize + index + 1;
|
|
|
}
|
|
|
+
|
|
|
+ async openStaffSelectionDialog(idVisit: string) {
|
|
|
+ const idVisitStr = idVisit.replace('Visita #', '').trim();
|
|
|
+ const idVisitEnc = await this._encService.encrypt(idVisitStr);
|
|
|
+ const dialogRef = this._dialog.open(StaffSelectionComponent, {
|
|
|
+ disableClose: true,
|
|
|
+ width: '540px',
|
|
|
+ maxWidth: '540px',
|
|
|
+ data: {
|
|
|
+ idOrder: idVisitEnc,
|
|
|
+ orderType: 'Preventivo',
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ dialogRef.afterClosed().subscribe((res) => {
|
|
|
+ if (res != null && res != undefined && res != '') {
|
|
|
+ this.approveVisit(idVisitEnc, res);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // Métodos de acción implementados
|
|
|
+ private async approveVisit(idVisit: string, config: string) {
|
|
|
+ try {
|
|
|
+ const idUser = localStorage.getItem('idusuario')!;
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append('id_user', idUser);
|
|
|
+ formData.append('linea', '1');
|
|
|
+ formData.append('id_order', idVisit);
|
|
|
+ formData.append('config', config);
|
|
|
+
|
|
|
+ const response = await lastValueFrom(
|
|
|
+ this._prevMaintService.assignOperariosToPreventiveVisit(formData)
|
|
|
+ );
|
|
|
+ if (response?.error) {
|
|
|
+ this._resourcesService.openSnackBar(
|
|
|
+ response.msg || 'Ocurrió un error al aprobar la visita.'
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ this._resourcesService.openSnackBar(
|
|
|
+ response?.msg || 'La visita se aprobó correctamente.'
|
|
|
+ );
|
|
|
+ }
|
|
|
+ this.getUnprogrammedVisits();
|
|
|
+ } catch (error: any) {
|
|
|
+ if (error.error == undefined) {
|
|
|
+ this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
|
|
|
+ } else if (error.error.msg == undefined) {
|
|
|
+ this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
|
|
|
+ } else {
|
|
|
+ this._resourcesService.openSnackBar(error.error.msg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ rejectVisit(visit: UnprogrammedVisit) {
|
|
|
+ const visitId = `${visit.IDVISITA ?? ''}`.trim();
|
|
|
+ if (!visitId) {
|
|
|
+ this._resourcesService.openSnackBar('No se pudo identificar la visita.');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const confirmDialogRef = this._dialog.open(AlertComponent, {
|
|
|
+ width: '420px',
|
|
|
+ maxWidth: '420px',
|
|
|
+ disableClose: true,
|
|
|
+ data: {
|
|
|
+ title: 'Confirmación',
|
|
|
+ icon: 'warning',
|
|
|
+ description: `¿Está seguro de rechazar la visita #${visitId}?`,
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ confirmDialogRef.afterClosed().subscribe((confirmed) => {
|
|
|
+ if (confirmed === true) {
|
|
|
+ const commentsDialogRef = this._dialog.open(CommnetsDialogComponent, {
|
|
|
+ width: '480px',
|
|
|
+ maxWidth: '480px',
|
|
|
+ disableClose: true,
|
|
|
+ data: {
|
|
|
+ idOrder: visitId,
|
|
|
+ status: 'Rechazar',
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ commentsDialogRef.afterClosed().subscribe((comments) => {
|
|
|
+ if (comments != undefined && comments != null && comments != '') {
|
|
|
+ if (comments.length < 15) {
|
|
|
+ this._resourcesService.openSnackBar(
|
|
|
+ 'Los comentarios deben tener al menos 15 caracteres.'
|
|
|
+ );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.updateVisitStatus(visitId, 'R', comments);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ cancelVisit(visit: UnprogrammedVisit) {
|
|
|
+ const visitId = `${visit.IDVISITA ?? ''}`.trim();
|
|
|
+ if (!visitId) {
|
|
|
+ this._resourcesService.openSnackBar('No se pudo identificar la visita.');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const confirmDialogRef = this._dialog.open(AlertComponent, {
|
|
|
+ width: '420px',
|
|
|
+ maxWidth: '420px',
|
|
|
+ disableClose: true,
|
|
|
+ data: {
|
|
|
+ title: 'Confirmación',
|
|
|
+ icon: 'warning',
|
|
|
+ description: `¿Está seguro de cancelar la visita #${visitId}?`,
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ confirmDialogRef.afterClosed().subscribe((confirmed) => {
|
|
|
+ if (confirmed === true) {
|
|
|
+ const commentsDialogRef = this._dialog.open(CommnetsDialogComponent, {
|
|
|
+ width: '480px',
|
|
|
+ maxWidth: '480px',
|
|
|
+ disableClose: true,
|
|
|
+ data: {
|
|
|
+ idOrder: visitId,
|
|
|
+ status: 'Cancelar',
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ commentsDialogRef.afterClosed().subscribe((comments) => {
|
|
|
+ if (comments != undefined && comments != null && comments != '') {
|
|
|
+ if (comments.length < 15) {
|
|
|
+ this._resourcesService.openSnackBar(
|
|
|
+ 'Los comentarios deben tener al menos 15 caracteres.'
|
|
|
+ );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.updateVisitStatus(visitId, 'C', comments);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ transferVisit(visit: UnprogrammedVisit) {
|
|
|
+ console.log('transferVisit', visit);
|
|
|
+ // TODO: Implementar diálogo de selección de usuario para traspasar
|
|
|
+ this._resourcesService.openSnackBar(
|
|
|
+ 'Funcionalidad de traspaso en desarrollo.'
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ deleteVisit(visit: UnprogrammedVisit) {
|
|
|
+ const visitId = `${visit.IDVISITA ?? ''}`.trim();
|
|
|
+ if (!visitId) {
|
|
|
+ this._resourcesService.openSnackBar('No se pudo identificar la visita.');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const confirmDialogRef = this._dialog.open(AlertComponent, {
|
|
|
+ width: '420px',
|
|
|
+ maxWidth: '420px',
|
|
|
+ disableClose: true,
|
|
|
+ data: {
|
|
|
+ title: 'Confirmación',
|
|
|
+ icon: 'warning',
|
|
|
+ description: `¿Está seguro de eliminar la visita #${visitId}? Esta acción no se puede deshacer.`,
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ confirmDialogRef.afterClosed().subscribe((confirmed) => {
|
|
|
+ if (confirmed === true) {
|
|
|
+ // Eliminar no requiere comentarios según el endpoint, solo status EL
|
|
|
+ this.updateVisitStatus(visitId, 'EL', 'Eliminada por el usuario');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ openCostAnalysis(visit: UnprogrammedVisit) {
|
|
|
+ const visitId = `${visit.IDVISITA ?? ''}`.trim();
|
|
|
+ if (!visitId) {
|
|
|
+ this._resourcesService.openSnackBar('No se pudo identificar la visita.');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Navegar a la ruta de análisis de costos
|
|
|
+ this._encService.encrypt(visitId).then((idEnc) => {
|
|
|
+ this._router.navigate(['sam/GMPR/ORTR/COTP/analisis'], {
|
|
|
+ queryParams: {
|
|
|
+ data: idEnc,
|
|
|
+ },
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // Método común para actualizar estado de visita
|
|
|
+ private async updateVisitStatus(
|
|
|
+ idVisit: string,
|
|
|
+ newStatus: string,
|
|
|
+ comments: string
|
|
|
+ ) {
|
|
|
+ try {
|
|
|
+ const idUser = localStorage.getItem('idusuario')!;
|
|
|
+ const idVisitEnc = await this._encService.encrypt(idVisit);
|
|
|
+
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append('id_user', idUser);
|
|
|
+ formData.append('linea', '1');
|
|
|
+ formData.append('id_visit', idVisitEnc);
|
|
|
+ formData.append('comments', comments);
|
|
|
+ formData.append('status', newStatus);
|
|
|
+
|
|
|
+ const response = await lastValueFrom(
|
|
|
+ this._prevMaintService.updateVisitStatus(formData)
|
|
|
+ );
|
|
|
+
|
|
|
+ if (response?.error) {
|
|
|
+ this._resourcesService.openSnackBar(
|
|
|
+ response.msg ||
|
|
|
+ 'Ocurrió un error al actualizar el estado de la visita.'
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ const statusMessages: Record<string, string> = {
|
|
|
+ VA: 'La visita se aprobó correctamente.',
|
|
|
+ R: 'La visita se rechazó correctamente.',
|
|
|
+ C: 'La visita se canceló correctamente.',
|
|
|
+ EL: 'La visita se eliminó correctamente.',
|
|
|
+ };
|
|
|
+ this._resourcesService.openSnackBar(
|
|
|
+ response?.msg ||
|
|
|
+ statusMessages[newStatus] ||
|
|
|
+ 'El estado se actualizó correctamente.'
|
|
|
+ );
|
|
|
+ }
|
|
|
+ this.getUnprogrammedVisits();
|
|
|
+ } catch (error: any) {
|
|
|
+ if (error.error == undefined) {
|
|
|
+ this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
|
|
|
+ } else if (error.error.msg == undefined) {
|
|
|
+ this._resourcesService.openSnackBar('Ocurrió un error inesperado.');
|
|
|
+ } else {
|
|
|
+ this._resourcesService.openSnackBar(error.error.msg);
|
|
|
+ }
|
|
|
+ this.getUnprogrammedVisits();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Seguimiento del estado - Implementado
|
|
|
+ openStatusTimeline(idVisit: string) {
|
|
|
+ this._dialog.open(StatusTimelineComponent, {
|
|
|
+ width: '480px',
|
|
|
+ maxWidth: '480px',
|
|
|
+ data: {
|
|
|
+ idOrder: idVisit,
|
|
|
+ orderType: 'Preventivo',
|
|
|
+ },
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|