Spaces:
Sleeping
Sleeping
File size: 6,265 Bytes
e40294e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
from typing import Dict
from solverforge_legacy.solver import SolverStatus
from solverforge_legacy.solver.score import HardSoftDecimalScore
from . import domain
from .warehouse import WarehouseLocation, Side
# =============================================================================
# Domain to API Model Conversion
# =============================================================================
def location_to_model(location: WarehouseLocation) -> domain.WarehouseLocationModel:
return domain.WarehouseLocationModel(
shelving_id=location.shelving_id,
side=location.side.name,
row=location.row
)
def product_to_model(product: domain.Product) -> domain.ProductModel:
return domain.ProductModel(
id=product.id,
name=product.name,
volume=product.volume,
location=location_to_model(product.location)
)
def order_item_to_model(item: domain.OrderItem) -> domain.OrderItemModel:
return domain.OrderItemModel(
id=item.id,
order_id=item.order_id,
product=product_to_model(item.product)
)
def order_to_model(order: domain.Order) -> domain.OrderModel:
return domain.OrderModel(
id=order.id,
items=[order_item_to_model(item) for item in order.items]
)
def trolley_step_to_model(step: domain.TrolleyStep) -> domain.TrolleyStepModel:
return domain.TrolleyStepModel(
id=step.id,
order_item=order_item_to_model(step.order_item),
trolley=step.trolley.id if step.trolley else None,
trolley_id=step.trolley_id
)
def trolley_to_model(trolley: domain.Trolley) -> domain.TrolleyModel:
return domain.TrolleyModel(
id=trolley.id,
bucket_count=trolley.bucket_count,
bucket_capacity=trolley.bucket_capacity,
location=location_to_model(trolley.location),
steps=[step.id for step in trolley.steps]
)
def solution_to_model(solution: domain.OrderPickingSolution) -> domain.OrderPickingSolutionModel:
return domain.OrderPickingSolutionModel(
trolleys=[trolley_to_model(t) for t in solution.trolleys],
trolley_steps=[trolley_step_to_model(s) for s in solution.trolley_steps],
score=str(solution.score) if solution.score else None,
solver_status=solution.solver_status.name if solution.solver_status else None
)
# =============================================================================
# API Model to Domain Conversion
# =============================================================================
def model_to_location(model: domain.WarehouseLocationModel) -> WarehouseLocation:
return WarehouseLocation(
shelving_id=model.shelving_id,
side=Side[model.side],
row=model.row
)
def model_to_product(model: domain.ProductModel) -> domain.Product:
return domain.Product(
id=model.id,
name=model.name,
volume=model.volume,
location=model_to_location(model.location)
)
def model_to_solution(model: domain.OrderPickingSolutionModel) -> domain.OrderPickingSolution:
"""Convert API model to domain object."""
# First pass: create all products and orders without cross-references
products: Dict[str, domain.Product] = {}
orders: Dict[str, domain.Order] = {}
# Extract unique products and orders from trolley steps
for step_model in model.trolley_steps:
item_model = step_model.order_item
product_model = item_model.product
# Create product if not seen
if product_model.id not in products:
products[product_model.id] = model_to_product(product_model)
# Create order if not seen
order_id = item_model.order_id
if order_id and order_id not in orders:
orders[order_id] = domain.Order(id=order_id, items=[])
# Second pass: create order items and trolley steps
trolley_steps = []
step_lookup: Dict[str, domain.TrolleyStep] = {}
for step_model in model.trolley_steps:
item_model = step_model.order_item
product = products[item_model.product.id]
order = orders.get(item_model.order_id) if item_model.order_id else None
order_item = domain.OrderItem(
id=item_model.id,
order=order,
product=product
)
# Add item to order's item list
if order:
order.items.append(order_item)
step = domain.TrolleyStep(
id=step_model.id,
order_item=order_item
)
trolley_steps.append(step)
step_lookup[step.id] = step
# Third pass: create trolleys and set up relationships
trolleys = []
trolley_lookup: Dict[str, domain.Trolley] = {}
for trolley_model in model.trolleys:
trolley = domain.Trolley(
id=trolley_model.id,
bucket_count=trolley_model.bucket_count,
bucket_capacity=trolley_model.bucket_capacity,
location=model_to_location(trolley_model.location),
steps=[]
)
trolleys.append(trolley)
trolley_lookup[trolley.id] = trolley
# Populate steps list
for step_ref in trolley_model.steps:
step_id = step_ref if isinstance(step_ref, str) else step_ref.id
if step_id in step_lookup:
step = step_lookup[step_id]
trolley.steps.append(step)
# Set shadow variable (for consistency, though solver will reset)
step.trolley = trolley
# Set up previous/next step references based on list order
for trolley in trolleys:
for i, step in enumerate(trolley.steps):
step.previous_step = trolley.steps[i - 1] if i > 0 else None
step.next_step = trolley.steps[i + 1] if i < len(trolley.steps) - 1 else None
# Handle score
score = None
if model.score:
score = HardSoftDecimalScore.parse(model.score)
# Handle solver status
solver_status = SolverStatus.NOT_SOLVING
if model.solver_status:
solver_status = SolverStatus[model.solver_status]
return domain.OrderPickingSolution(
trolleys=trolleys,
trolley_steps=trolley_steps,
score=score,
solver_status=solver_status
)
|