first commit

This commit is contained in:
2026-08-27 17:29:18 -04:00
commit 2405dda41b
44 changed files with 11368 additions and 0 deletions
@@ -0,0 +1,37 @@
export type ApiResponse = [
AssignedResponse,
NoAssignedResponse
];
export interface AssignedResponse {
assigned: RouteAssignedResponse[];
}
export interface NoAssignedResponse {
noAssigned: RouteNoAssignedResponse[];
}
export interface RouteAssignedResponse {
json: RouteAssignedJson;
}
export interface RouteAssignedJson {
dia: string;
distancia: number;
horas_desplazamiento: number;
hora_laboral_semanal_usuario: number;
hora_minima_semanal_pdv: number;
horas_trabajo: string;
latitud_usuario: number;
longitud_usuario: number;
latitud_pdv: number;
longitud_pdv: number;
nombre_usuario: string;
nombre_pdv: string;
usuario_id: string;
pdv_id: number;
}
export interface RouteNoAssignedResponse {
pdv_id: number;
pdv_nombre: string,
minimo_horas_semana: number,
latitud: number,
longitud: number,
motivo: string;
}
@@ -0,0 +1,42 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import {
RouteAssignedResponse,
RouteNoAssignedResponse
} from '../models/route.model';
@Injectable({ providedIn: 'root' })
export class RouteState {
private loading = new BehaviorSubject<boolean>(false);
loading$ = this.loading.asObservable();
private assignedRoutes = new BehaviorSubject<RouteAssignedResponse[]>([]);
assignedRoutes$ = this.assignedRoutes.asObservable();
private noAssignedRoutes = new BehaviorSubject<RouteNoAssignedResponse[]>([]);
noAssignedRoutes$ = this.noAssignedRoutes.asObservable();
private selectedRoute = new BehaviorSubject<RouteAssignedResponse | null>(null);
selectedRoute$ = this.selectedRoute.asObservable();
resetLoading() {
this.loading.next(false);
}
setLoading(value: boolean) {
this.loading.next(value);
}
setAssignedRoutes(data: RouteAssignedResponse[]) {
this.assignedRoutes.next(data);
}
setNoAssignedRoutes(data: RouteNoAssignedResponse[]) {
this.noAssignedRoutes.next(data);
}
sendRoute(route: RouteAssignedResponse) {
this.selectedRoute.next(route);
}
}
@@ -0,0 +1,84 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {
from,
lastValueFrom,
mergeMap,
of,
delay,
catchError,
map,
toArray,
timeout
} from 'rxjs';
const ENDPOINT = 'http://localhost:18080/ors/v2/directions/driving-car';
const ENDPOINTJSON = 'http://localhost:18080/ors/v2/directions/driving-car/geojson';
const MAX_CONCURRENT_REQUESTS = 2;
@Injectable({
providedIn: 'root'
})
export class OrsService {
constructor(private http: HttpClient) { }
private fetchRoute(
origin: number[],
destination: number[],
isJson = false
) {
const body = {
coordinates: [origin, destination]
};
return this.http.post<any>(isJson ? ENDPOINTJSON : ENDPOINT, body).pipe(
timeout(8000),
catchError(error => {
throw error;
})
);
}
async processPairs(
pares: {
pdv_id: number;
origin: number[];
destination: number[];
}[],
concurrency = MAX_CONCURRENT_REQUESTS,
isJson = false
): Promise<any[]> {
return lastValueFrom(
from(pares).pipe(
mergeMap(
pair =>
this.fetchRoute(pair.origin, pair.destination, isJson).pipe(
delay(300),
map(data => {
if (!isJson) {
const summary = data.routes[0].summary;
return {
pdv_id: pair.pdv_id,
distance: summary.distance,
duration: summary.duration,
raw: data
};
} else {
return data;
}
}),
catchError(error =>
of({
pdv_id: pair.pdv_id,
error: error.message || 'Error ORS'
})
)
),
concurrency
),
toArray()
)
);
}
}
@@ -0,0 +1,16 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ApiResponse } from '../../core/models/route.model';
@Injectable({ providedIn: 'root' })
export class RutasService {
constructor(private http: HttpClient) { }
calcularRutas(data: FormData) {
return this.http.post<ApiResponse>(
'https://agenteit.digitalcompass.agency/webhook/calcular-camino',
data
);
}
}