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