Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -126,29 +126,28 @@ class Truck:
|
|
126 |
self.available_space.sort(key=lambda space: (space[2], space[1], space[0]))
|
127 |
|
128 |
|
129 |
-
# Helper functions for box packing
|
130 |
def pack_boxes_ffd(truck, consignments):
|
131 |
packed_positions = []
|
132 |
|
|
|
133 |
consignments = sorted(consignments, key=lambda c: (not c[1], -sum(box.volume() * box.quantity for box in c[0])))
|
134 |
|
135 |
for consignment in consignments:
|
136 |
-
|
137 |
-
for box in
|
138 |
for _ in range(box.quantity):
|
139 |
position = truck.add_box_ffd(box)
|
140 |
-
if position is None:
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
else:
|
147 |
-
break
|
148 |
|
149 |
return packed_positions
|
150 |
|
151 |
|
|
|
152 |
def find_max_consignments_combinations(truck, consignments, combination_limit=100):
|
153 |
combinations_that_fit = []
|
154 |
consignments_sorted = sorted(consignments, key=lambda c: (not c[1], -sum(box.volume() * box.quantity for box in c[0])))
|
@@ -228,7 +227,10 @@ def suggest_truck(consignments):
|
|
228 |
|
229 |
total_boxes = sum(box.quantity for consignment in consignments for box in consignment[0])
|
230 |
|
231 |
-
|
|
|
|
|
|
|
232 |
return {"name": truck_name, "dimensions": dimensions}
|
233 |
|
234 |
return None
|
@@ -314,30 +316,30 @@ async def submit_data(request: SubmitDataRequest):
|
|
314 |
# Assuming truck dimensions are known based on truck_name
|
315 |
trucks = {
|
316 |
"TATA ACE": {"length": 7, "width": 4.8, "height": 4.8},
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
}
|
342 |
|
343 |
if truck_name not in trucks:
|
@@ -352,9 +354,13 @@ async def submit_data(request: SubmitDataRequest):
|
|
352 |
truck = Truck(length * 12, width * 12, height * 12) # Convert feet to inches
|
353 |
packed_positions = pack_boxes_ffd(truck, consignments)
|
354 |
|
355 |
-
|
|
|
|
|
|
|
|
|
356 |
|
357 |
-
if
|
358 |
stored_combinations = find_max_consignments_combinations(truck, consignments)
|
359 |
if stored_combinations:
|
360 |
combinations_info = []
|
@@ -385,25 +391,28 @@ async def submit_data(request: SubmitDataRequest):
|
|
385 |
"width": width,
|
386 |
"height": height
|
387 |
}
|
388 |
-
}
|
|
|
389 |
}
|
390 |
|
391 |
# Redirect to the visualization page
|
392 |
-
return RedirectResponse(url=f"https://
|
393 |
-
|
394 |
|
395 |
# Prepare box data for visualization
|
396 |
-
box_data = [
|
397 |
-
|
|
|
|
|
|
|
|
|
|
|
398 |
'length': box.length,
|
399 |
'width': box.width,
|
400 |
'height': box.height,
|
401 |
'type': box.type,
|
402 |
-
'quantity': box
|
403 |
-
'position':
|
404 |
-
}
|
405 |
-
for box, pos in packed_positions
|
406 |
-
]
|
407 |
|
408 |
# Generate a unique session_id
|
409 |
session_id = str(uuid.uuid4())
|
@@ -420,7 +429,7 @@ async def submit_data(request: SubmitDataRequest):
|
|
420 |
}
|
421 |
|
422 |
# Redirect to the visualization page
|
423 |
-
return RedirectResponse(url=f"https://
|
424 |
|
425 |
|
426 |
|
@@ -456,17 +465,22 @@ async def load_combination(
|
|
456 |
packed_positions = pack_boxes_ffd(truck, consignments)
|
457 |
|
458 |
# Prepare the box data
|
459 |
-
box_data = [
|
460 |
-
|
|
|
|
|
|
|
|
|
|
|
461 |
'length': box.length,
|
462 |
'width': box.width,
|
463 |
'height': box.height,
|
464 |
'type': box.type,
|
465 |
-
'quantity':
|
466 |
-
'position':
|
467 |
-
}
|
468 |
-
|
469 |
-
|
470 |
|
471 |
# Return the box data and truck information to the frontend
|
472 |
return {
|
|
|
126 |
self.available_space.sort(key=lambda space: (space[2], space[1], space[0]))
|
127 |
|
128 |
|
|
|
129 |
def pack_boxes_ffd(truck, consignments):
|
130 |
packed_positions = []
|
131 |
|
132 |
+
# Sort consignments: priority consignments first, then by total volume (descending)
|
133 |
consignments = sorted(consignments, key=lambda c: (not c[1], -sum(box.volume() * box.quantity for box in c[0])))
|
134 |
|
135 |
for consignment in consignments:
|
136 |
+
consignment_boxes = consignment[0]
|
137 |
+
for box in consignment_boxes:
|
138 |
for _ in range(box.quantity):
|
139 |
position = truck.add_box_ffd(box)
|
140 |
+
if position is not None:
|
141 |
+
# Box is packed
|
142 |
+
packed_positions.append((box, position))
|
143 |
+
else:
|
144 |
+
# Box cannot be packed, include with position as None
|
145 |
+
packed_positions.append((box, None))
|
|
|
|
|
146 |
|
147 |
return packed_positions
|
148 |
|
149 |
|
150 |
+
|
151 |
def find_max_consignments_combinations(truck, consignments, combination_limit=100):
|
152 |
combinations_that_fit = []
|
153 |
consignments_sorted = sorted(consignments, key=lambda c: (not c[1], -sum(box.volume() * box.quantity for box in c[0])))
|
|
|
227 |
|
228 |
total_boxes = sum(box.quantity for consignment in consignments for box in consignment[0])
|
229 |
|
230 |
+
# Count successfully packed boxes
|
231 |
+
packed_boxes_count = sum(1 for _, pos in packed_positions if pos is not None)
|
232 |
+
|
233 |
+
if packed_boxes_count == total_boxes:
|
234 |
return {"name": truck_name, "dimensions": dimensions}
|
235 |
|
236 |
return None
|
|
|
316 |
# Assuming truck dimensions are known based on truck_name
|
317 |
trucks = {
|
318 |
"TATA ACE": {"length": 7, "width": 4.8, "height": 4.8},
|
319 |
+
"ASHOK LEYLAND DOST": {"length": 7, "width": 4.8, "height": 4.8},
|
320 |
+
"MAHINDRA BOLERO PICK UP": {"length": 8, "width": 5, "height": 4.8},
|
321 |
+
"ASHOK LEYLAND BADA DOST": {"length": 9.5, "width": 5.5, "height": 5},
|
322 |
+
"TATA 407": {"length": 9, "width": 5.5, "height": 5},
|
323 |
+
"EICHER 14 FEET": {"length": 14, "width": 6, "height": 6.5},
|
324 |
+
"EICHER 17 FEET": {"length": 17, "width": 6, "height": 7},
|
325 |
+
"EICHER 19 FEET": {"length": 19, "width": 7, "height": 7},
|
326 |
+
"TATA 22 FEET": {"length": 22, "width": 7.5, "height": 7},
|
327 |
+
"TATA TRUCK (6 TYRE)": {"length": 17.5, "width": 7, "height": 7},
|
328 |
+
"TAURUS 16 T (10 TYRE)": {"length": 21, "width": 7.2, "height": 7},
|
329 |
+
"TAURUS 21 T (12 TYRE)": {"length": 24, "width": 7.3, "height": 7},
|
330 |
+
"TAURUS 25 T (14 TYRE)": {"length": 28, "width": 7.8, "height": 7},
|
331 |
+
"CONTAINER 20 FT": {"length": 20, "width": 8, "height": 8},
|
332 |
+
"CONTAINER 32 FT SXL": {"length": 32, "width": 8, "height": 8},
|
333 |
+
"CONTAINER 32 FT MXL": {"length": 32, "width": 8, "height": 8},
|
334 |
+
"CONTAINER 32 FT SXL / MXL HQ": {"length": 32, "width": 8, "height": 10},
|
335 |
+
"20 FEET OPEN ALL SIDE (ODC)": {"length": 20, "width": 8, "height": 8},
|
336 |
+
"28-32 FEET OPEN-TRAILOR JCB ODC": {"length": 28, "width": 8, "height": 8},
|
337 |
+
"32 FEET OPEN-TRAILOR ODC": {"length": 32, "width": 8, "height": 8},
|
338 |
+
"40 FEET OPEN-TRAILOR ODC": {"length": 40, "width": 8, "height": 8},
|
339 |
+
"SCV": {"length": 5, "width": 12, "height": 6},
|
340 |
+
"LCV": {"length": 11, "width": 5, "height": 5},
|
341 |
+
"ICV": {"length": 16, "width": 6.5, "height": 6.5},
|
342 |
+
"MCV": {"length": 19, "width": 7, "height": 7}
|
343 |
}
|
344 |
|
345 |
if truck_name not in trucks:
|
|
|
354 |
truck = Truck(length * 12, width * 12, height * 12) # Convert feet to inches
|
355 |
packed_positions = pack_boxes_ffd(truck, consignments)
|
356 |
|
357 |
+
# Count how many boxes were successfully packed
|
358 |
+
packed_boxes_count = sum(1 for _, pos in packed_positions if pos is not None)
|
359 |
+
|
360 |
+
# Total number of boxes
|
361 |
+
total_boxes = len(packed_positions) # Since we expanded quantities during packing
|
362 |
|
363 |
+
if packed_boxes_count < total_boxes:
|
364 |
stored_combinations = find_max_consignments_combinations(truck, consignments)
|
365 |
if stored_combinations:
|
366 |
combinations_info = []
|
|
|
391 |
"width": width,
|
392 |
"height": height
|
393 |
}
|
394 |
+
},
|
395 |
+
"consignments_data": [consignment.dict() for consignment in consignments_data] # **Added**
|
396 |
}
|
397 |
|
398 |
# Redirect to the visualization page
|
399 |
+
return RedirectResponse(url=f"https://66eaf98cbe66f53e549027bb--joyful-cheesecake-ae839d.netlify.app/?session_id={session_id}", status_code=302)
|
|
|
400 |
|
401 |
# Prepare box data for visualization
|
402 |
+
box_data = []
|
403 |
+
for box, pos in packed_positions:
|
404 |
+
if pos is not None:
|
405 |
+
position = {'x': pos[0], 'y': pos[1], 'z': pos[2]}
|
406 |
+
else:
|
407 |
+
position = None # Box could not be packed
|
408 |
+
box_data.append({
|
409 |
'length': box.length,
|
410 |
'width': box.width,
|
411 |
'height': box.height,
|
412 |
'type': box.type,
|
413 |
+
'quantity': 1, # Since we're iterating over each individual box
|
414 |
+
'position': position
|
415 |
+
})
|
|
|
|
|
416 |
|
417 |
# Generate a unique session_id
|
418 |
session_id = str(uuid.uuid4())
|
|
|
429 |
}
|
430 |
|
431 |
# Redirect to the visualization page
|
432 |
+
return RedirectResponse(url=f"https://66eaf98cbe66f53e549027bb--joyful-cheesecake-ae839d.netlify.app/?session_id={session_id}", status_code=302)
|
433 |
|
434 |
|
435 |
|
|
|
465 |
packed_positions = pack_boxes_ffd(truck, consignments)
|
466 |
|
467 |
# Prepare the box data
|
468 |
+
box_data = []
|
469 |
+
for box, pos in packed_positions:
|
470 |
+
if pos is not None:
|
471 |
+
position = {'x': pos[0], 'y': pos[1], 'z': pos[2]}
|
472 |
+
else:
|
473 |
+
position = None
|
474 |
+
box_data.append({
|
475 |
'length': box.length,
|
476 |
'width': box.width,
|
477 |
'height': box.height,
|
478 |
'type': box.type,
|
479 |
+
'quantity': 1,
|
480 |
+
'position': position
|
481 |
+
})
|
482 |
+
|
483 |
+
print("Data sent to the frontend:", len(box_data))
|
484 |
|
485 |
# Return the box data and truck information to the frontend
|
486 |
return {
|