._.
This commit is contained in:
parent
bd5aa7fcc6
commit
3e6e6c60f7
@ -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):
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user