from tortoise import fields, models from tortoise.indexes import Index from tortoise.contrib.pydantic import pydantic_model_creator from tortoise.signals import post_save from typing import Type from helper.tools import genRandomStr #任务下发之前进行非标品的库存过滤, # 暂存货架有库存的替换为暂存货架库存 #Generate cmd at last, in case for order changed class Assignment(models.Model): id = fields.UUIDField(pk=True) num = fields.CharField(null=True, max_length=255, description='短编号') orderid = fields.CharField(null=True, max_length=255, description='中控系统订单编号') owner = fields.ForeignKeyField('models.User', on_delete=fields.CASCADE, null=True, description='订单所有人') # ownerj = fields.JSONField(null=True, description='owner 序列化') sequence = fields.IntField(default=0, description='管理员手动排序号') ordertime = fields.DatetimeField(null=True, description='预约领用时间') agvid = fields.CharField(null=True, max_length=255, description='AGV小车编号') subtasks = fields.ManyToManyField('models.Subtask', related_name='asignsubtasks') # subtasksj = fields.JSONField(null=True, description='subtasks 序列化') itinerary = fields.JSONField(null=True, description='订单对应的全局最短路径') cmd = fields.JSONField(null=True, description='下发给AGV的任务序列') #the last last = fields.CharField(null=True, max_length=255, description='最后上车的仓库编号') #AGV load loada = fields.IntField(default=0, description='A类型装载数量') loadb = fields.IntField(default=0, description='B类型装载数量') loadc = fields.IntField(default=0, description='C类型装载数量') loadd = fields.IntField(default=0, description='D类型装载数量') loade = fields.IntField(default=0, description='E类型装载数量') is_canceled = fields.BooleanField(default=False, description='是否取消') cancel_time = fields.DatetimeField(null=True, description='取消时间') is_processing = fields.BooleanField(default=False, description='是否进行中') is_failed = fields.BooleanField(default=False, description='是否失败') is_done = fields.BooleanField(default=False, description='是否完成') created_at = fields.DatetimeField(auto_now_add=True) updated_at = fields.DatetimeField(auto_now=True) is_valid = fields.BooleanField(default=True, description='是否有效') is_active = fields.BooleanField(default=True, description='是否删除') class PydanticMeta: # Let's exclude the created timestamp exclude = ("created_at",) allow_cycles = True max_recursion = 4 class Meta: table = 'Assignments' table_description = '任务安排表' #set the ordering where sequence > ordertime > created_at #when passing to order_by function ordering = ["-sequence", "ordertime", "created_at"] indexes = [ Index(fields={"num"}, name="num"), Index(fields={"agvid"}, name="agvid"), Index(fields={"orderid"}, name="orderididx"), Index(fields={"is_done"}, name="assignment_is_doneidx"), Index(fields={"is_canceled"}, name="assignment_is_canceledidx"), Index(fields={"is_processing"}, name="is_processingidx"), Index(fields={"is_failed"}, name="is_failedidx"), Index(fields={"is_valid"}, name="is_valididx"), Index(fields={"is_active"}, name="is_activeidx"), ] def __str__(self): return f'Assignment(id={self.id} num={self.num}, agvid={self.agvid}, created_at={self.created_at})' def as_json(self): return dict( id="{}".format(self.id), num=self.num, orderid = self.orderid, sequence = self.sequence, ordertime = "{}".format(self.ordertime), agvid=self.agvid, itinerary = self.itinerary, cmd = self.cmd, last = self.last, loada = self.loada, loadb = self.loadb, loadc = self.loadc, loadd = self.loadd, loade = self.loade, is_canceled = self.is_canceled, cancel_time = "{}".format(self.cancel_time), is_processing = self.is_processing, is_failed = self.is_failed, is_done = self.is_done, is_valid = self.is_valid, updated_at="{}".format(self.updated_at), created_at="{}".format(self.created_at) ) Assignment_Pydantic = pydantic_model_creator(Assignment, name="Assignment") # AssignmentIn_Pydantic = pydantic_model_creator(Assignment, name="AssignmentIn", exclude=("is_active", "is_valid")) @post_save(Assignment) async def assignment_post_save( sender: "Type[Assignment]", instance: Assignment, created, using_db, update_fields, ) -> None: if not instance.num or "null" == instance.num: # print("instance.num: ", instance.num) # check duplicated num async def checkNum(): num = genRandomStr(4) # print("new num: ", num) if await Assignment.filter(num = num).exists(): # print("num exist, ", num) checkNum() else: # print("num not exist, ", num) instance.num = num await instance.save() await checkNum()