From 3e6e6c60f745f8521d1caf69edbd0bd3cd172c98 Mon Sep 17 00:00:00 2001 From: andrei Date: Sat, 5 Oct 2024 20:56:46 +0500 Subject: [PATCH] ._. --- app/core/usecases/new_total_order_service.py | 98 ++++++++++++------- .../database/repository/city_repository.py | 2 + .../fastapi/total_order_routes.py | 4 +- 3 files changed, 69 insertions(+), 35 deletions(-) diff --git a/app/core/usecases/new_total_order_service.py b/app/core/usecases/new_total_order_service.py index 16b11a3..9271f4c 100644 --- a/app/core/usecases/new_total_order_service.py +++ b/app/core/usecases/new_total_order_service.py @@ -1,10 +1,14 @@ +from datetime import datetime, timedelta from itertools import permutations from math import ceil -from pprint import pprint import requests from sqlalchemy.orm import Session +from app.infrastructure.database.dependencies import get_db +from app.infrastructure.database.models.delivery_accessories import DeliveryAccessory +from app.infrastructure.database.models.delivery_orders import DeliveryOrder +from app.infrastructure.database.models.total_orders import TotalOrder from app.infrastructure.database.repository.accessory_repository import AccessoriesRepository from app.infrastructure.database.repository.city_repository import CityRepository from app.infrastructure.database.repository.delivery_accessory_repository import DeliveryAccessoriesRepository @@ -23,36 +27,60 @@ class NewTotalOrderService: 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() + trucks = 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 = '' + with get_db() as session: + new_total_order = TotalOrder( + order_datetime=datetime.now(), + count_robots=2000, + deadline=datetime.now(), + ) + session.add(new_total_order) + session.flush() - 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) + response = '' - 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), - "Нет доступного автомобиля") - response += f"Тип автомобиля: {selected_vehicle_name}" - response += f"Количество автомобилей: {vehicle_count}" - response += f"Стоимость перевозки: {cost}\n" + for period, routes in routes_by_period.items(): + for route in routes: + vehicle_count, selected_truck = self.calculate_vehicle_requirements( + [a for a in accessories if a.period == period], trucks) + cost = self.calculate_route_cost(route, accessories, distances) + + delivery_order_deadline = new_total_order.deadline - timedelta(days=period) + + new_delivery_order = DeliveryOrder( + order_datetime=datetime.now(), + count_trucks=vehicle_count, + deadline=delivery_order_deadline, + price=cost, + truck_id=selected_truck, + total_order_id=new_delivery_order.id, + ) + + session.add(new_total_order) + + for point_index in range(len(route)): + new_delivery_accessory = DeliveryAccessory( + queue=point_index + 1, + + ) + + response += f"Период: {period}\n" + response += f"Маршрут: {' -> '.join([city.name for city in route])}\n" + selected_vehicle_name = next((truck.name for truck in trucks if truck.id == selected_truck), + "Нет доступного автомобиля") + response += f"Тип автомобиля: {selected_vehicle_name}" + response += f"Количество автомобилей: {vehicle_count}" + response += f"Стоимость перевозки: {cost}\n" + + return response def find_routes_by_period(self, grouped_by_period, distances, cities): purpose_city_id = self.city_repository.get_by_name('Челябинск').id @@ -60,8 +88,10 @@ class NewTotalOrderService: routes_by_period = {} for period, accessories in grouped_by_period.items(): - cities_in_period = [next(city for city in cities if city.id == accessory.city_id) for accessory in - accessories] + 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 == purpose_city_id)) @@ -117,37 +147,37 @@ 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 - @staticmethod - def calculate_route_cost(route, accessories, distances): + def calculate_route_cost(self, route, accessories, distances): + purpose_city_id = self.city_repository.get_by_name('Челябинск').id + total_weight = 0.0 total_cost = 0.0 for i in range(len(route) - 1): - if route[i].id != 9: - city_accessories = [accessory for accessory in accessories if accessory.cityId == route[i].id] + if route[i].id != purpose_city_id: + city_accessories = [accessory for accessory in accessories if accessory.city_id == route[i].id] total_weight += sum(accessory.weight for accessory in city_accessories) * 20.0 total_cost += distances[route[i].id - 1][route[i + 1].id - 1] * (total_weight / 1000.0) * 8 return total_cost @staticmethod - def calculate_vehicle_requirements(accessories, tracks): + def calculate_vehicle_requirements(accessories, trucks): total_weight = sum(accessory.weight for accessory in accessories) * 20 total_vehicles = float('inf') - selected_track = 0 + selected_truck = 0 - for track in tracks: - weight_vehicles = ceil(total_weight / track.weight) + for truck in trucks: + weight_vehicles = ceil(total_weight / truck.capacity) if weight_vehicles < total_vehicles: total_vehicles = weight_vehicles - selected_track = track.id + selected_truck = truck.id - return total_vehicles, selected_track + return total_vehicles, selected_truck @staticmethod def get_distance(start_coords, end_coords): diff --git a/app/infrastructure/database/repository/city_repository.py b/app/infrastructure/database/repository/city_repository.py index 6eab5d3..8d09e61 100644 --- a/app/infrastructure/database/repository/city_repository.py +++ b/app/infrastructure/database/repository/city_repository.py @@ -1,3 +1,4 @@ +from sqlalchemy import asc from sqlalchemy.orm import Session, joinedload from app.infrastructure.database.models.cities import City @@ -15,6 +16,7 @@ class CityRepository: def get_all_with_federal_district(self): return self.db.query(City) \ .options(joinedload(City.federal_district)) \ + .order_by(asc(City.id)) \ .all() def get_by_id(self, city_id: int): diff --git a/app/infrastructure/fastapi/total_order_routes.py b/app/infrastructure/fastapi/total_order_routes.py index 4c573ca..b57e466 100644 --- a/app/infrastructure/fastapi/total_order_routes.py +++ b/app/infrastructure/fastapi/total_order_routes.py @@ -60,4 +60,6 @@ def delete_total_order(total_order_id: int, db: Session = Depends(get_db), @router.post("/total-orders/calculate", response_model=TotalOrderEntity) def calculate_total_order(db: Session = Depends(get_db)): service = NewTotalOrderService(db) - return service.total_calculate() + result = service.total_calculate() + print(result) + return result