You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
9.3 KiB
274 lines
9.3 KiB
from fastapi import APIRouter
|
|
from starlette.requests import Request
|
|
from tortoise.queryset import QuerySet, Prefetch
|
|
from models.assignment import Assignment, Assignment_Pydantic
|
|
from models.task import Subtask
|
|
from models.user import User, User_Pydantic
|
|
from models.order import Order
|
|
from models.agv import Agv
|
|
from models.warehouse import Vacancy
|
|
from helper import respond_to
|
|
from tortoise.contrib.pydantic import pydantic_model_creator
|
|
from agvtask.agvtasks import genCMD
|
|
from typing import Optional
|
|
|
|
assign_router = APIRouter(prefix='/assign')
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
|
|
class StateModel(BaseModel):
|
|
assignment_id: Optional[str]
|
|
|
|
# UserPydantic = pydantic_model_creator(User, name="User")
|
|
# AssignmentPydantic = pydantic_model_creator(Assignment, name="Assignment")
|
|
|
|
# Assignment_Pydantic = pydantic_model_creator(Assignment, name="AssignmentPydModel", exclude=("is_valid", "is_active"))
|
|
|
|
@assign_router.get("/")
|
|
async def read_root():
|
|
assignment = await Assignment.filter(
|
|
is_canceled = False,
|
|
is_processing = False,
|
|
is_failed = False,
|
|
is_done = False,
|
|
is_valid = True,
|
|
is_active = True
|
|
).first()
|
|
|
|
print("assignment: ", assignment)
|
|
|
|
if assignment:
|
|
owner = await assignment.owner
|
|
subtasks = await assignment.subtasks.all()
|
|
assignmentJ = assignment.as_json()
|
|
|
|
subtasksL = []
|
|
cmdStdList = []
|
|
cmdNonStdList = []
|
|
|
|
for subtask in subtasks:
|
|
if 1 == subtask.typetask \
|
|
or 1 == subtask.typetask \
|
|
or 3 == subtask.typetask \
|
|
or 5 == subtask.typetask \
|
|
or 7 == subtask.typetask:
|
|
# for standard
|
|
cmdStdList.append({
|
|
"orderid": subtask.orderid,
|
|
"name": subtask.name,
|
|
"typetask": subtask.typetask,
|
|
"action": subtask.action,
|
|
"quantity": subtask.quantity,
|
|
"coordinates": subtask.coordinates,
|
|
"traynum": subtask.traynum,
|
|
})
|
|
else:
|
|
# for non standard
|
|
cmdNonStdList.append({
|
|
"orderid": subtask.orderid,
|
|
"name": subtask.name,
|
|
"typetask": subtask.typetask,
|
|
"action": subtask.action,
|
|
"quantity": subtask.quantity,
|
|
"coordinates": subtask.coordinates,
|
|
"traynum": subtask.traynum,
|
|
})
|
|
|
|
subtasksL.append(subtask.as_json())
|
|
|
|
assignment.is_processing = True
|
|
await assignment.save()
|
|
|
|
await genCMD(assignment, cmdStdList, cmdNonStdList)
|
|
|
|
assignmentJ["owner"] = owner.as_json()
|
|
assignmentJ["subtasks"] = subtasksL
|
|
assignmentJ["cmd"] = assignment.cmd
|
|
|
|
agvs = await Agv.filter(
|
|
agvid = assignment.agvid,
|
|
is_valid = True,
|
|
is_active = True,
|
|
)
|
|
|
|
agv = None
|
|
if len(agvs) > 0:
|
|
agv = agvs[0]
|
|
agv.curorder = assignment.orderid
|
|
agv.curitinerary = assignment.itinerary
|
|
await agv.save()
|
|
else:
|
|
agv = await Agv.create(
|
|
agvid = assignment.agvid,
|
|
curorder = assignment.orderid,
|
|
curitinerary = assignment.itinerary
|
|
)
|
|
|
|
return respond_to(code=200, data=assignmentJ)
|
|
|
|
else:
|
|
return respond_to(code=405, desc="Failed", data={"state": "Cannot find valid assignments"})
|
|
|
|
|
|
'''
|
|
!!!!!!!
|
|
need to deal with Vacancy in shelf and connection!!!!
|
|
|
|
'''
|
|
|
|
# @assign_router.put('/done/{assignment_id}', summary='系统派发任务完成')
|
|
# async def update(request: Request, model: StateModel, assignment_id: str):
|
|
|
|
@assign_router.get('/done/{assignment_id}', summary='系统派发任务完成')
|
|
async def update(request: Request, assignment_id: str):
|
|
print("Done assignment_id: ", assignment_id)
|
|
|
|
assignment = await Assignment.get_or_none(id = assignment_id)
|
|
|
|
if assignment:
|
|
assignment.is_processing = False
|
|
assignment.is_done = True
|
|
assignment.is_failed = False
|
|
await assignment.save(update_fields=['is_processing', 'is_done', 'is_failed'])
|
|
|
|
await assignment.fetch_related("subtasks")
|
|
for subtask in assignment.subtasks:
|
|
#pass
|
|
subtask.is_done = True
|
|
await subtask.save(update_fields=['is_done'])
|
|
|
|
order = await Order.get_or_none(orderid = assignment.orderid)
|
|
|
|
if order:
|
|
isTaskAllDone = True
|
|
await order.fetch_related("tasks")
|
|
for task in order.tasks:
|
|
isSubtasksAllDone = True
|
|
await task.fetch_related("subtasks")
|
|
for subtask in task.subtasks:
|
|
# print("subtask: ", subtask)
|
|
if not subtask.is_done:
|
|
isSubtasksAllDone = False
|
|
break
|
|
|
|
if not isSubtasksAllDone:
|
|
isTaskAllDone = False
|
|
else:
|
|
# print("task: ", task)
|
|
task.is_done = True
|
|
await task.save(update_fields=['is_done'])
|
|
|
|
if isTaskAllDone:
|
|
order.is_done = True
|
|
order.is_failed = False
|
|
await order.save(update_fields=['is_done', 'is_failed'])
|
|
|
|
#clear Vacancy in shelf or connection
|
|
vacancies = await Vacancy.filter(
|
|
orderids__contains=[ assignment.orderid ],
|
|
is_valid = False,
|
|
is_active = True
|
|
)
|
|
|
|
for vacancy in vacancies:
|
|
orderids = vacancy.orderids
|
|
lstSet = set(orderids)
|
|
lstSet.discard( assignment.orderid )
|
|
# Converting set back to list
|
|
orderids=list(lstSet)
|
|
|
|
#reset
|
|
if len(orderids) < 1:
|
|
vacancy.is_valid = True
|
|
|
|
vacancy.orderids = orderids
|
|
await vacancy.save()
|
|
|
|
|
|
else:
|
|
return respond_to(code=404, desc="Failed", data={"state": "Cannot find order id {}".format(assignment.orderid)})
|
|
|
|
else:
|
|
return respond_to(code=404, desc="Failed", data={"state": "Cannot find assignment id {}".format(assignment.id)})
|
|
|
|
return respond_to(data={"state": "success"})
|
|
|
|
#need to finish task logic !!!!
|
|
# @assign_router.put('/failed/{assignment_id}', summary='系统派发任务失败')
|
|
# async def update(request: Request, model: StateModel, assignment_id: str):
|
|
|
|
@assign_router.get('/failed/{assignment_id}', summary='系统派发任务失败')
|
|
async def update(request: Request, assignment_id: str):
|
|
|
|
print("Failed assignment_id: ", assignment_id)
|
|
|
|
assignment = await Assignment.get_or_none(id = assignment_id)
|
|
|
|
if assignment:
|
|
assignment.is_processing = False
|
|
assignment.is_done = False
|
|
assignment.is_failed = True
|
|
await assignment.save(update_fields=['is_processing', 'is_done', 'is_failed'])
|
|
|
|
order = await Order.get_or_none(orderid = assignment.orderid)
|
|
|
|
if order:
|
|
order.is_done =False
|
|
order.is_failed = True
|
|
await order.save(update_fields=['is_done', 'is_failed'])
|
|
|
|
# await order.fetch_related("tasks")
|
|
# for task in order.tasks:
|
|
# # print("task: ", task)
|
|
# task.is_done = False
|
|
# await task.save(update_fields=['is_done'])
|
|
|
|
# await task.fetch_related("subtasks")
|
|
# for subtask in task.subtasks:
|
|
# # print("subtask: ", subtask)
|
|
# subtask.is_done = False
|
|
# await subtask.save(update_fields=['is_done'])
|
|
|
|
else:
|
|
return respond_to(code=404, desc="Failed", data={"state": "success"})
|
|
|
|
return respond_to(data={"state": "success"})
|
|
|
|
|
|
@assign_router.get('/list', summary="列出所有待下发给AGV的任务")
|
|
async def index(request: Request, page_no: int = 1, page_size: int = 20):
|
|
"""
|
|
列出所有待下发给AGV小车的任务
|
|
:param page_no: 1
|
|
:param page_size: 20
|
|
:return:
|
|
"""
|
|
offset = (page_no - 1) * page_size
|
|
|
|
query = QuerySet(Assignment).filter(is_canceled=False, is_valid=True, is_active=True) \
|
|
.select_related("owner") \
|
|
.prefetch_related(
|
|
Prefetch('subtasks', queryset=Subtask.filter(is_active = True))
|
|
)
|
|
count = await query.count()
|
|
assignments = await query.limit(page_size).offset(offset)
|
|
|
|
|
|
resData = []
|
|
for assignment in assignments:
|
|
owner = await assignment.owner
|
|
subtasks = await assignment.subtasks.all()
|
|
assignmentj = assignment.as_json()
|
|
assignmentj["owner"] = owner
|
|
assignmentj["subtasks"] = subtasks
|
|
resData.append(assignmentj)
|
|
|
|
return respond_to(code=200, data=dict(count=count, data=resData))
|
|
|
|
# return respond_to(code=200, data=dict(count=count, data=assignments))
|
|
# return await Assignment_Pydantic.from_queryset(assignments)
|
|
# return respond_to(code=200, data=dict(count=count, data=Assignment_Pydantic.from_queryset(assignments)))
|
|
|