._.
This commit is contained in:
parent
c8338ba142
commit
bd5aa7fcc6
@ -1,6 +1,8 @@
|
||||
from itertools import permutations
|
||||
from math import ceil
|
||||
from pprint import pprint
|
||||
|
||||
import requests
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.infrastructure.database.repository.accessory_repository import AccessoriesRepository
|
||||
@ -8,6 +10,7 @@ from app.infrastructure.database.repository.city_repository import CityRepositor
|
||||
from app.infrastructure.database.repository.delivery_accessory_repository import DeliveryAccessoriesRepository
|
||||
from app.infrastructure.database.repository.delivery_order_repository import DeliveryOrdersRepository
|
||||
from app.infrastructure.database.repository.total_order_repository import TotalOrdersRepository
|
||||
from app.infrastructure.database.repository.truck_repository import TrucksRepository
|
||||
|
||||
|
||||
class NewTotalOrderService:
|
||||
@ -17,38 +20,57 @@ class NewTotalOrderService:
|
||||
self.delivery_accessory_repository = DeliveryAccessoriesRepository(db)
|
||||
self.city_repository = CityRepository(db)
|
||||
self.accessory_repository = AccessoriesRepository(db)
|
||||
self.truck_repository = TrucksRepository(db)
|
||||
|
||||
def total_calculate(self):
|
||||
print(111111111111111111111111111111111111111)
|
||||
|
||||
accessories = self.accessory_repository.get_with_cities_all()
|
||||
cities = self.city_repository.get_all_with_federal_district()
|
||||
tracks = self.truck_repository.get_all()
|
||||
distances = self.create_distance_matrix(cities)
|
||||
|
||||
for i in distances:
|
||||
for j in i:
|
||||
print(j)
|
||||
print()
|
||||
|
||||
grouped_by_period = self.group_accessories_by_period(accessories)
|
||||
routes_by_period = self.find_routes_by_period(grouped_by_period, distances, cities)
|
||||
|
||||
response = ''
|
||||
|
||||
for period, routes in routes_by_period.items():
|
||||
for route in routes:
|
||||
vehicle_count, selected_track = self.calculate_vehicle_requirements(
|
||||
[a for a in accessories if a.period == period], tracks)
|
||||
cost = self.calculate_route_cost(route, accessories, distances)
|
||||
|
||||
print(f"Период: {period}")
|
||||
print(f"Маршрут: {' -> '.join([city.name for city in route])}")
|
||||
response += f"Период: {period}\n"
|
||||
response += f"Маршрут: {' -> '.join([city.name for city in route])}\n"
|
||||
selected_vehicle_name = next((track.name for track in tracks if track.id == selected_track),
|
||||
"Нет доступного автомобиля")
|
||||
print(f"Тип автомобиля: {selected_vehicle_name}")
|
||||
print(f"Количество автомобилей: {vehicle_count}")
|
||||
print(f"Стоимость перевозки: {cost}\n")
|
||||
response += f"Тип автомобиля: {selected_vehicle_name}"
|
||||
response += f"Количество автомобилей: {vehicle_count}"
|
||||
response += f"Стоимость перевозки: {cost}\n"
|
||||
|
||||
def find_routes_by_period(self, grouped_by_period, distances, cities):
|
||||
purpose_city_id = self.city_repository.get_by_name('Челябинск').id
|
||||
|
||||
routes_by_period = {}
|
||||
|
||||
for period, accessories in grouped_by_period.items():
|
||||
cities_in_period = [next(city for city in cities if city.id == accessory.cityId) for accessory in
|
||||
cities_in_period = [next(city for city in cities if city.id == accessory.city_id) for accessory in
|
||||
accessories]
|
||||
all_routes = self.generate_routes(cities_in_period, next(city for city in cities if city.id == 9))
|
||||
all_routes = self.generate_routes(cities_in_period,
|
||||
next(city for city in cities if city.id == purpose_city_id))
|
||||
|
||||
routes_with_details = []
|
||||
for route in all_routes:
|
||||
distance = self.calculate_route_distance(route, distances)
|
||||
total_weight = sum(
|
||||
sum(accessory.weight for accessory in accessories if accessory.cityId == city.id) for city in route)
|
||||
sum(accessory.weight for accessory in accessories if accessory.city_id == city.id) for city in
|
||||
route)
|
||||
cost = self.calculate_route_cost(route, accessories, distances)
|
||||
routes_with_details.append((route, (distance, total_weight, cost)))
|
||||
|
||||
@ -57,6 +79,21 @@ class NewTotalOrderService:
|
||||
|
||||
return routes_by_period
|
||||
|
||||
def create_distance_matrix(self, cities):
|
||||
num_cities = len(cities)
|
||||
distances = [[0] * num_cities for _ in range(num_cities)]
|
||||
|
||||
for i in range(num_cities):
|
||||
for j in range(num_cities):
|
||||
if i != j:
|
||||
start_coords = (cities[i].x_coordinate, cities[i].y_coordinate)
|
||||
end_coords = (cities[j].x_coordinate, cities[j].y_coordinate)
|
||||
distances[i][j] = self.get_distance(start_coords, end_coords)
|
||||
else:
|
||||
distances[i][j] = 0
|
||||
|
||||
return distances
|
||||
|
||||
@staticmethod
|
||||
def group_accessories_by_period(accessories):
|
||||
grouped = {}
|
||||
@ -80,6 +117,7 @@ class NewTotalOrderService:
|
||||
@staticmethod
|
||||
def calculate_route_distance(route, distances):
|
||||
total_distance = 0
|
||||
pprint(distances)
|
||||
for i in range(len(route) - 1):
|
||||
total_distance += distances[route[i].id - 1][route[i + 1].id - 1]
|
||||
return total_distance
|
||||
@ -110,3 +148,17 @@ class NewTotalOrderService:
|
||||
selected_track = track.id
|
||||
|
||||
return total_vehicles, selected_track
|
||||
|
||||
@staticmethod
|
||||
def get_distance(start_coords, end_coords):
|
||||
base_url = "http://router.project-osrm.org/route/v1/driving"
|
||||
url = f"{base_url}/{start_coords[1]},{start_coords[0]};{end_coords[1]},{end_coords[0]}?overview=full"
|
||||
|
||||
response = requests.get(url)
|
||||
data = response.json()
|
||||
|
||||
if data['routes']:
|
||||
distance = data['routes'][0]['distance'] / 1000
|
||||
return distance
|
||||
else:
|
||||
return float('inf')
|
||||
|
||||
@ -9,6 +9,9 @@ class CityRepository:
|
||||
def get_all(self):
|
||||
return self.db.query(City).all()
|
||||
|
||||
def get_by_name(self, city_name):
|
||||
return self.db.query(City).filter(City.name == city_name).first()
|
||||
|
||||
def get_all_with_federal_district(self):
|
||||
return self.db.query(City) \
|
||||
.options(joinedload(City.federal_district)) \
|
||||
|
||||
@ -4,6 +4,7 @@ from fastapi import APIRouter, HTTPException, Depends
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.usecases.auth_service import verify_token
|
||||
from app.core.usecases.new_total_order_service import NewTotalOrderService
|
||||
from app.infrastructure.database.dependencies import get_db
|
||||
from app.core.entities.total_order import TotalOrderEntity
|
||||
from app.core.usecases.total_order_service import TotalOrdersService
|
||||
@ -54,3 +55,9 @@ def delete_total_order(total_order_id: int, db: Session = Depends(get_db),
|
||||
if not success:
|
||||
raise HTTPException(status_code=404, detail="Total order not found")
|
||||
return success
|
||||
|
||||
|
||||
@router.post("/total-orders/calculate", response_model=TotalOrderEntity)
|
||||
def calculate_total_order(db: Session = Depends(get_db)):
|
||||
service = NewTotalOrderService(db)
|
||||
return service.total_calculate()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user