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

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)))