1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030 |
- from django.db import models
- from container.models import ContainerListModel,ContainerWCSModel,TaskModel
- # 库位主表(记录实时状态)
- class LocationModel(models.Model):
- LOCATION_TYPES = (
- ('T5', '5货位'), # 5托盘/批次
- ('T4', '4货位'), # 4托盘/批次
- ('S4', '4单货位'), # 4单托盘
- ('T2', '2货位'), # 2托盘/批次
- ('T1', '散货位'), # 1托盘
- ('M1', '通道区'), # 通道区
- ('E1', '提升机'), # 提升机
- ('C1', '输送机'), # 输送机
- ('B1', '充电桩'), # 货架区
- )
- LOCATION_STATUS = (
- ('available', '可用'),
- ('occupied', '占用'),
- ('disabled', '禁用'),
- ('reserved', '预留'),
- ('maintenance', '维护中'),
- )
- warehouse_code = models.CharField(max_length=255, verbose_name="Warehouse code")
- warehouse_name = models.CharField(max_length=255, verbose_name="Warehouse Name")
- shelf_type = models.CharField(max_length=255,default = 'storage', verbose_name="Shelf Type")
- row = models.IntegerField(verbose_name="Row") # 位置的行号
- col = models.IntegerField(verbose_name="Column") # 位置的列号
- layer = models.IntegerField(verbose_name="Layer") # 位置的层号
- update_time = models.DateTimeField(auto_now=True, blank=True, null=True, verbose_name="Update Time")
- empty_label = models.BooleanField(default=True, verbose_name="Empty Flag")
- location_code = models.CharField(max_length=20, unique=True, verbose_name='库位编码')
- location_group = models.CharField(max_length=20, verbose_name='库位组')
- # 示例:T1-L1C001-1
- # T1-L1C001-1 代表货位类型为T1,层号为1,列号为001,货位号为1
- location_type = models.CharField(max_length=3, choices=LOCATION_TYPES, verbose_name='货位类型')
- status = models.CharField(max_length=20, choices=LOCATION_STATUS, default='available', verbose_name='库位状态')
- max_capacity = models.PositiveIntegerField(verbose_name='最大容量') # 根据类型自动设置
- current_quantity = models.PositiveIntegerField(default=0, verbose_name='当前数')
- c_number = models.IntegerField(default=1, verbose_name='库位远近排序')
- current_containers = models.ManyToManyField(ContainerListModel,
- through='LocationContainerLink',
- verbose_name='当前存放托盘')
- coordinate = models.CharField(max_length=50, verbose_name='三维坐标') # 格式:行-列-层
- access_priority = models.IntegerField(
- default=0,
- verbose_name='访问优先级',
- help_text='值越大表示越远离主通道,应优先使用'
- )
- is_active = models.BooleanField(default=True, verbose_name='是否有效')
- class Meta:
- db_table = 'location'
- verbose_name = 'Location'
- verbose_name_plural = "Location"
- ordering = ['-id']
- unique_together = ( 'warehouse_code','row', 'col', 'layer') # 防止重复坐标
-
- @classmethod
- def get_existing_positions(cls, warehouse_code, rows, cols, layers):
- """获取已存在的坐标集合"""
- return set(
- cls.objects.filter(
- warehouse_code=warehouse_code,
- row__lte=rows,
- col__lte=cols,
- layer__lte=layers
- ).values_list('row', 'col', 'layer')
- )
- def get_active_containers(self):
- """获取当前有效的容器列表"""
- from .models import LocationContainerLink
- active_links = LocationContainerLink.objects.filter(
- location=self,
- is_active=True
- ).select_related('container') # 优化查询
- return [link.container for link in active_links] # 返回容器列表
- @classmethod
- def generate_locations(cls, warehouse_code):
- # 清空现有数据(新增部分)
- cls.objects.filter(warehouse_code=warehouse_code).delete()
- """根据规划图生成库位"""
- # 定义核心参数(根据规划图调整)
- MAIN_AISLES = [18, 1] # 子通道列号
- SUB_AISLES = [2,8, 13] # 主通道行号
- for row in range(1, 14): # 1-13行
- for col in range(1, 3): # 1-19列
- for layer in range(1, 4): # 1-3层
- # 判断通道区
- if col in MAIN_AISLES or row in SUB_AISLES:
- loc_type = 'M1'
- c_number = row
- # 通道
-
- if col ==1 and row == 1:
- loc_type = 'T1'
- c_number = 1
-
- # 判断货位类型(根据实际规划)
-
- else:
- if row <2:
- loc_type = 'T1'
- c_number = 1
- elif row < 8:
- loc_type = 'T5'
- c_number = row-2
- elif row < 13:
- loc_type = 'T4'
- c_number = row-8
- else:
- loc_type = 'T2'
- c_number = 16-row
- # 生成唯一编码
- location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}"
- location_group = f"{loc_type}-L{layer}C{col:03d}"
- # print(f"生成库位:{location_code}-{row}-{col}-{layer}")
-
- # 创建库位
- cls.objects.update_or_create(
- warehouse_code=warehouse_code,
- warehouse_name="立体仓库",
- row=row,
- col=col,
- layer=layer,
- c_number=c_number,
- shelf_type=loc_type,
- defaults={
- 'location_code': location_code,
- 'location_group': location_group,
- 'location_type': loc_type,
- 'max_capacity': {
- 'T5': 5,
- 'T4': 4,
- 'T2': 2,
- 'T1': 1,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0
- }[loc_type],
- 'coordinate': f"{row}-{col}-{layer}",
- 'is_active': True
- },
- access_priority=c_number
- )
- for row in range(1, 16): # 1-15行
- for col in range(3, 17): # 1-16列
- for layer in range(1, 4): # 1-3层
- # 判断通道区
- if col in MAIN_AISLES or row in SUB_AISLES:
- loc_type = 'M1'
- c_number = row
- # 通道
-
- if col ==18 and row == 1:
- loc_type = 'T1'
- c_number = 1
-
- # 判断货位类型(根据实际规划)
-
- else:
- if row <2:
- loc_type = 'T1'
- c_number = 1
- elif row < 8:
- loc_type = 'T5'
- c_number = row-2
- elif row < 13:
- loc_type = 'T4'
- c_number = row-8
- else:
- loc_type = 'T2'
- c_number = 16-row
- # 生成唯一编码
- location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}"
- location_group = f"{loc_type}-L{layer}C{col:03d}"
- # print(f"生成库位:{location_code}-{row}-{col}-{layer}")
-
- # 创建库位
- cls.objects.update_or_create(
- warehouse_code=warehouse_code,
- row=row,
- col=col,
- layer=layer,
- c_number=c_number,
- shelf_type=loc_type,
- defaults={
- 'location_code': location_code,
- 'location_group': location_group,
- 'location_type': loc_type,
- 'max_capacity': {
- 'T5': 5,
- 'T4': 4,
- 'T2': 2,
- 'T1': 1,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0
- }[loc_type],
- 'coordinate': f"{row}-{col}-{layer}",
- 'is_active': True
- },
- access_priority=c_number
- )
- # print("✅ 库位生成成功!")
- for row in range(1, 14): # 1-15行
- for col in range(17, 20): # 1-16列
- for layer in range(1, 4): # 1-3层
- # 判断通道区
- if col in MAIN_AISLES or row in SUB_AISLES:
- loc_type = 'M1'
- c_number = row
- # 通道
-
- if col ==18 and row == 1:
- loc_type = 'T1'
- c_number = 1
-
- # 判断货位类型(根据实际规划)
-
- else:
- if row <2:
- loc_type = 'T1'
- c_number = 1
- elif row < 8:
- loc_type = 'T5'
- c_number = row-2
- elif row < 13:
- loc_type = 'T4'
- c_number = row-8
- else:
- loc_type = 'T2'
- c_number = 16-row
- # 生成唯一编码
- location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}"
- location_group = f"{loc_type}-L{layer}C{col:03d}"
- # print(f"生成库位:{location_code}-{row}-{col}-{layer}")
-
- # 创建库位
- cls.objects.update_or_create(
- warehouse_code=warehouse_code,
- row=row,
- col=col,
- layer=layer,
- c_number=c_number,
- shelf_type=loc_type,
- defaults={
- 'location_code': location_code,
- 'location_group': location_group,
- 'location_type': loc_type,
- 'max_capacity': {
- 'T5': 5,
- 'T4': 4,
- 'T2': 2,
- 'T1': 1,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0
- }[loc_type],
- 'coordinate': f"{row}-{col}-{layer}",
- 'is_active': True
- },
- access_priority=c_number
- )
- # print("✅ 库位生成成功!")
- for row in range(1, 18): # 1-17行
- for col in range(20, 30): # 19-29列
- for layer in range(1, 4): # 1-3层
- # 判断通道区
- if col in MAIN_AISLES or row in SUB_AISLES:
- loc_type = 'M1'
- c_number = row
- # 通道
-
- if col ==18 and row == 1:
- loc_type = 'T1'
- c_number = 1
- if col ==29 and row == 1:
- loc_type = 'T1'
- c_number = 1
- if col ==29 and row == 14:
- loc_type = 'S4'
- c_number = 4
- if col ==29 and row == 15:
- loc_type = 'S4'
- c_number = 3
- if col ==29 and row == 16:
- loc_type = 'S4'
- c_number = 2
- if col ==29 and row == 17:
- loc_type = 'S4'
- c_number = 1
-
-
- # 判断货位类型(根据实际规划)
-
- else:
- # 判断货位类型(根据实际规划)
- if row < 2:
- loc_type = 'T1'
- c_number = row
-
- elif row < 8:
- loc_type = 'T5'
- c_number = row-2
- elif row < 13:
- loc_type = 'T4'
- c_number = row-8
- else:
- loc_type = 'S4'
- c_number = 18-row
-
-
- # 生成唯一编码
- location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}"
- location_group = f"{loc_type}-L{layer}C{col:03d}"
- # print(f"生成库位:{location_code}-{row}-{col}-{layer}")
-
- # 创建库位
- cls.objects.update_or_create(
- warehouse_code=warehouse_code,
- row=row,
- col=col,
- layer=layer,
- c_number=c_number,
- shelf_type=loc_type,
- defaults={
- 'location_code': location_code,
- 'location_group': location_group,
- 'location_type': loc_type,
- 'max_capacity': {
- 'T5': 5,
- 'T4': 4,
- 'S4': 4,
- 'T2': 2,
- 'T1': 1,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0,
- 'B1': 0
- }[loc_type],
- 'coordinate': f"{row}-{col}-{layer}",
- 'is_active': True
- },
- access_priority=c_number
- )
- # 输送机
- for row in [14]: # 1-17行
- for col in [1,18]: # 1-19列
- for layer in range(1, 4): # 1-3层
- # 判断货位类型(根据实际规划)
- loc_type = 'C1'
- c_number = 1
- location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}"
- location_group = f"{loc_type}-L{layer}C{col:03d}"
- # print(f"生成库位:{location_code}-{row}-{col}-{layer}")
-
- # 创建库位
- # 创建库位
- cls.objects.update_or_create(
- warehouse_code=warehouse_code,
- row=row,
- col=col,
- layer=layer,
- c_number=c_number,
- shelf_type=loc_type,
- defaults={
- 'location_code': location_code,
- 'location_group': location_group,
- 'location_type': loc_type,
- 'max_capacity': {
- 'T5': 5,
- 'T4': 4,
- 'S4': 4,
- 'T2': 2,
- 'T1': 1,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0,
- 'B1': 0
- }[loc_type],
- 'coordinate': f"{row}-{col}-{layer}",
- 'is_active': True
- },
- access_priority=c_number
- )
- for row in [16]: # 1-17行
- for col in [1,18]: # 1-19列
- for layer in [1]: # 1-3层
- # 判断货位类型(根据实际规划)
- loc_type = 'C1'
- c_number = row
- location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}"
- location_group = f"{loc_type}-L{layer}C{col:03d}"
- # 创建库位
- cls.objects.update_or_create(
- warehouse_code=warehouse_code,
- row=row,
- col=col,
- layer=layer,
- c_number=c_number,
- shelf_type=loc_type,
- defaults={
- 'location_code': location_code,
- 'location_group': location_group,
- 'location_type': loc_type,
- 'max_capacity': {
- 'T5': 5,
- 'T4': 4,
- 'S4': 4,
- 'T2': 2,
- 'T1': 1,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0,
- 'B1': 0
- }[loc_type],
- 'coordinate': f"{row}-{col}-{layer}",
- 'is_active': True
- },
- access_priority=c_number
- )
- # 提升机
- for row in [15]: # 1-17行
- for col in [1,18]: # 1-19列
- for layer in range(1, 4): # 1-3层
- # 判断货位类型(根据实际规划)
- loc_type = 'E1'
- c_number = row
- location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}"
- location_group = f"{loc_type}-L{layer}C{col:03d}"
- # 创建库位
- cls.objects.update_or_create(
- warehouse_code=warehouse_code,
- row=row,
- col=col,
- layer=layer,
- c_number=c_number,
- shelf_type=loc_type,
- defaults={
- 'location_code': location_code,
- 'location_group': location_group,
- 'location_type': loc_type,
- 'max_capacity': {
- 'T5': 5,
- 'T4': 4,
- 'S4': 4,
- 'T2': 2,
- 'T1': 1,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0,
- 'B1': 0
- }[loc_type],
- 'coordinate': f"{row}-{col}-{layer}",
- 'is_active': True
- },
- access_priority=c_number
- )
- # 充电桩
- for row in [14]: # 1-17行
- for col in [2]: # 1-19列
- for layer in range(1, 3): # 1-3层
- # 判断货位类型(根据实际规划)
- loc_type = 'B1'
- c_number = 1
- location_code = f"{loc_type}-L{layer}C{col:03d}-{c_number:02d}"
- location_group = f"{loc_type}-L{layer}C{col:03d}"
- # 创建库位
- cls.objects.update_or_create(
- warehouse_code=warehouse_code,
- row=row,
- col=col,
- layer=layer,
- c_number=c_number,
- shelf_type=loc_type,
- defaults={
- 'location_code': location_code,
- 'location_group': location_group,
- 'location_type': loc_type,
- 'max_capacity': {
- 'T5': 5,
- 'T4': 4,
- 'S4': 4,
- 'T2': 2,
- 'T1': 1,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0,
- 'B1': 0
- }[loc_type],
- 'coordinate': f"{row}-{col}-{layer}",
- 'is_active': True
- },
- access_priority=c_number
- )
-
- class LocationGroupModel(models.Model):
- LOCATION_TYPES = (
- ('T5', '5货位'), # 5托盘/批次
- ('T4', '4货位'), # 4托盘/批次
- ('S4', '4单货位'), # 4单托盘
- ('T2', '2货位'), # 2托盘/批次
- ('T1', '散货位'), # 1托盘
- )
- LOCATION_STATUS = (
- ('available', '可用'),
- ('occupied', '占用'),
- ('full', '满'),
- ('disabled', '禁用'),
- ('reserved', '预留'),
- ('maintenance', '维护中'),
- )
- warehouse_code = models.CharField(max_length=50, verbose_name='仓库编码')
- group_name = models.CharField(max_length=50, verbose_name='库位组名称')
- group_type = models.CharField(max_length=50, choices=LOCATION_TYPES, verbose_name='库位组类型')
- group_code = models.CharField(max_length=50, verbose_name='库位组编码')
- layer = models.PositiveIntegerField(verbose_name='层数')
- location_items = models.ManyToManyField(LocationModel, verbose_name='库位')
- status = models.CharField(max_length=20, choices=LOCATION_STATUS, default='available', verbose_name='库位状态')
- max_capacity = models.PositiveIntegerField(verbose_name='最大容量') # 根据类型自动设置
- current_quantity = models.PositiveIntegerField(default=0, verbose_name='当前托盘数')
- current_goods_quantity = models.PositiveIntegerField(default=0, verbose_name='当前货物数')
- current_batch = models.CharField(max_length=50, default='', verbose_name='当前批次')
- current_goods_code = models.CharField(max_length=50, default='', verbose_name='当前货物编码')
- access_priority = models.IntegerField(
- default=0,
- verbose_name='访问优先级',
- help_text='值越大表示越远离主通道,应优先使用'
- )
- left_priority = models.IntegerField(
- default=0,
- verbose_name='左侧优先级',
- help_text='值越大表示越靠左,应优先使用'
- )
- right_priority = models.IntegerField(
- default=0,
- verbose_name='右侧优先级',
- help_text='值越大表示越靠右,应优先使用'
- )
- is_active = models.BooleanField(default=True, verbose_name='是否有效')
- # create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
- class Meta:
- db_table = 'location_group'
- verbose_name = 'Location Group'
- verbose_name_plural = "Location Group"
- ordering = ['-id']
- unique_together = ( 'warehouse_code', 'group_code') # 防止重复组编码
- @classmethod
- def generate_group(cls,warehouse_code):
- cls.objects.filter(warehouse_code=warehouse_code).delete()
- MAIN_AISLES = [18, 1] # 子通道列号
- SUB_AISLES = [2,8, 13] # 主通道行号
- for row in range(1, 14): # 1-13行
- for col in range(1, 3): # 1-19列
- for layer in range(1, 4): # 1-3层
- # 判断通道区
- if col in MAIN_AISLES or row in SUB_AISLES:
- loc_type = 'M1'
- c_number = row
- # 通道
-
- if col ==1 and row == 1:
- loc_type = 'T1'
- c_number = 1
-
- # 判断货位类型(根据实际规划)
-
- else:
- if row <2:
- loc_type = 'T1'
- c_number = 1
- elif row < 8:
- loc_type = 'T5'
- c_number = row-2
- elif row < 13:
- loc_type = 'T4'
- c_number = row-8
- else:
- loc_type = 'T2'
- c_number = 16-row
- # 生成唯一编码
- print(f"生成库组:{row}-{col}-{layer}")
- if loc_type == 'M1':
- continue
- # 创建库位
- group_code = f"{loc_type}-L{layer}C{col:03d}"
- group_name = f"{loc_type}-L{layer}C{col:03d}"
- # 使用(row+col)*layer作为库位排序
- left_priority = (abs(row-13)+abs(col-1))*layer
- right_priority = (abs(row-13)+abs(col-18))*layer
-
- if cls.objects.filter(warehouse_code=warehouse_code, group_code=group_code).exists():
- group_item = cls.objects.get(warehouse_code=warehouse_code, group_code=group_code)
- group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer))
- group_item.save()
- else:
- group_item = cls.objects.create(
- warehouse_code=warehouse_code,
- layer=layer,
- group_name=group_name,
- group_type=loc_type,
- group_code=group_code,
- max_capacity={
- 'T5': 5,
- 'T4': 4,
- 'T2': 2,
- 'T1': 1,
- 'S4': 4,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0
- }[loc_type],
- current_quantity=0,
- status='available',
- access_priority=c_number,
- left_priority=left_priority,
- right_priority=right_priority,
- is_active=True
- )
- group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer))
- group_item.save()
-
- for row in range(1, 16): # 1-15行
- for col in range(3, 17): # 1-16列
- for layer in range(1, 4): # 1-3层
- # 判断通道区
- if col in MAIN_AISLES or row in SUB_AISLES:
- loc_type = 'M1'
- c_number = row
- # 通道
-
- if col ==18 and row == 1:
- loc_type = 'T1'
- c_number = 1
-
- # 判断货位类型(根据实际规划)
-
- else:
- if row <2:
- loc_type = 'T1'
- c_number = 1
- elif row < 8:
- loc_type = 'T5'
- c_number = row-2
- elif row < 13:
- loc_type = 'T4'
- c_number = row-8
- else:
- loc_type = 'T2'
- c_number = 16-row
- # print(f"生成库位:{location_code}-{row}-{col}-{layer}")
- if loc_type == 'M1':
- continue
- # 创建库位
- group_code = f"{loc_type}-L{layer}C{col:03d}"
- group_name = f"{loc_type}-L{layer}C{col:03d}"
- left_priority = (abs(row-13)+abs(col-1))*layer
- right_priority = (abs(row-13)+abs(col-18))*layer
-
- if cls.objects.filter(warehouse_code=warehouse_code, group_code=group_code).exists():
- group_item = cls.objects.get(warehouse_code=warehouse_code, group_code=group_code)
- group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer))
- group_item.save()
- else:
- group_item = cls.objects.create(
- warehouse_code=warehouse_code,
- layer=layer,
- group_name=group_name,
- group_type=loc_type,
- group_code=group_code,
- max_capacity={
- 'T5': 5,
- 'T4': 4,
- 'T2': 2,
- 'T1': 1,
- 'S4': 4,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0
- }[loc_type],
- current_quantity=0,
- status='available',
- access_priority=c_number,
- left_priority=left_priority,
- right_priority=right_priority,
- is_active=True
- )
- group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer))
- group_item.save()
-
-
- for row in range(1, 14): # 1-15行
- for col in range(17, 20): # 1-16列
- for layer in range(1, 4): # 1-3层
- # 判断通道区
- if col in MAIN_AISLES or row in SUB_AISLES:
- loc_type = 'M1'
- c_number = row
- # 通道
-
- if col ==18 and row == 1:
- loc_type = 'T1'
- c_number = 1
-
- # 判断货位类型(根据实际规划)
-
- else:
- if row <2:
- loc_type = 'T1'
- c_number = 1
- elif row < 8:
- loc_type = 'T5'
- c_number = row-2
- elif row < 13:
- loc_type = 'T4'
- c_number = row-8
- else:
- loc_type = 'T2'
- c_number = 16-row
- # print(f"生成库位:{location_code}-{row}-{col}-{layer}")
- if loc_type == 'M1':
- continue
- # 创建库位
- group_code = f"{loc_type}-L{layer}C{col:03d}"
- group_name = f"{loc_type}-L{layer}C{col:03d}"
- left_priority = (abs(row-13)+abs(col-1))*layer
- right_priority = (abs(row-13)+abs(col-18))*layer
-
- if cls.objects.filter(warehouse_code=warehouse_code, group_code=group_code).exists():
- group_item = cls.objects.get(warehouse_code=warehouse_code, group_code=group_code)
- group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer))
- group_item.save()
- else:
- group_item = cls.objects.create(
- warehouse_code=warehouse_code,
- layer=layer,
- group_name=group_name,
- group_type=loc_type,
- group_code=group_code,
- max_capacity={
- 'T5': 5,
- 'T4': 4,
- 'T2': 2,
- 'T1': 1,
- 'S4': 4,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0
- }[loc_type],
- current_quantity=0,
- status='available',
- access_priority=c_number,
- left_priority=left_priority,
- right_priority=right_priority,
- is_active=True
- )
- group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer))
- group_item.save()
-
- for row in range(1, 18): # 1-17行
- for col in range(20, 30): # 19-29列
- for layer in range(1, 4): # 1-3层
- # 判断通道区
- if col in MAIN_AISLES or row in SUB_AISLES:
- loc_type = 'M1'
- c_number = row
- # 通道
-
- if col ==18 and row == 1:
- loc_type = 'T1'
- c_number = 1
- if col ==29 and row == 1:
- loc_type = 'T1'
- c_number = 1
- if col ==29 and row == 14:
- loc_type = 'S4'
- c_number = 4
- if col ==29 and row == 15:
- loc_type = 'S4'
- c_number = 3
- if col ==29 and row == 16:
- loc_type = 'S4'
- c_number = 2
- if col ==29 and row == 17:
- loc_type = 'S4'
- c_number = 1
-
-
- # 判断货位类型(根据实际规划)
-
- else:
- # 判断货位类型(根据实际规划)
- if row < 2:
- loc_type = 'T1'
- c_number = row
-
- elif row < 8:
- loc_type = 'T5'
- c_number = row-2
- elif row < 13:
- loc_type = 'T4'
- c_number = row-8
- else:
- loc_type = 'S4'
- c_number = 18-row
- # print(f"生成库位:{location_code}-{row}-{col}-{layer}")
- if loc_type == 'M1':
- continue
- # 创建库位
- group_code = f"{loc_type}-L{layer}C{col:03d}"
- group_name = f"{loc_type}-L{layer}C{col:03d}"
- left_priority = (abs(row-13)+abs(col-1))*layer
- right_priority = (abs(row-13)+abs(col-18))*layer
-
- if cls.objects.filter(warehouse_code=warehouse_code, group_code=group_code).exists():
- group_item = cls.objects.get(warehouse_code=warehouse_code, group_code=group_code)
- group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer))
- group_item.save()
- else:
- group_item = cls.objects.create(
- warehouse_code=warehouse_code,
- layer=layer,
- group_name=group_name,
- group_type=loc_type,
- group_code=group_code,
- max_capacity={
- 'T5': 5,
- 'T4': 4,
- 'T2': 2,
- 'T1': 1,
- 'S4': 4,
- 'M1': 0,
- 'E1': 0,
- 'C1': 0
- }[loc_type],
- current_quantity=0,
- status='available',
- access_priority=c_number,
- left_priority=left_priority,
- right_priority=right_priority,
- is_active=True
- )
- group_item.location_items.add(LocationModel.objects.get(warehouse_code=warehouse_code, row=row, col=col, layer=layer))
- group_item.save()
-
- # 库位-托盘关联表(记录实时存放关系)
- class LocationContainerLink(models.Model):
- location = models.ForeignKey(
- LocationModel,
- on_delete=models.CASCADE,
- related_name='container_links',
- verbose_name='库位'
- )
-
- container = models.ForeignKey(
- ContainerListModel,
- on_delete=models.CASCADE,
- related_name='location_links',
- verbose_name='关联容器'
- )
- task_wcs = models.ForeignKey(ContainerWCSModel, on_delete=models.CASCADE, null=True, blank=True)
- task_detail = models.ForeignKey(TaskModel, on_delete=models.CASCADE, null=True, blank=True)
- put_time = models.DateTimeField(auto_now_add=True, verbose_name='上架时间')
- operator = models.CharField(max_length=50, verbose_name='操作人')
- is_active = models.BooleanField(default=True, verbose_name='是否有效')
- class Meta:
- db_table = 'location_container_link'
- verbose_name = 'Location-Container Link'
- verbose_name_plural = "Location-Container Link"
- ordering = ['-id']
- unique_together = ( 'location', 'container') # 防止重复关联
-
- class DeviceModel(models.Model):
- warehouse_code = models.CharField(max_length=255, verbose_name="Warehouse Code")
- location = models.ForeignKey(LocationModel, on_delete=models.CASCADE)
- device_id = models.CharField(max_length=255, verbose_name="Device ID")
- device_name = models.CharField(max_length=255, verbose_name="Device Name")
- device_type = models.CharField(max_length=255, verbose_name="Device Type")
- ip_address = models.CharField(max_length=255, verbose_name="IP Address")
- port = models.IntegerField(verbose_name="Port")
- mode = models.CharField(default='inbound', max_length=255, verbose_name="Mode")
- status = models.CharField(max_length=255, verbose_name="Status")
- create_time = models.DateTimeField(auto_now_add=True, verbose_name="Create Time")
- update_time = models.DateTimeField(auto_now=True, blank=True, null=True, verbose_name="Update Time")
- class Meta:
- db_table = 'device'
- verbose_name = 'Device'
- verbose_name_plural = "Device"
- ordering = ['-id']
- unique_together = ( 'location', 'device_id') # 防止重复设备
- @classmethod
- def generate_device(cls,warehouse_code):
- cls.objects.filter(warehouse_code=warehouse_code).delete()
- # 输送机
- location = LocationModel.objects.get(warehouse_code=warehouse_code, row=16, col=1, layer=1)
- # 创建库位
- cls.objects.update_or_create(
- warehouse_code=warehouse_code,
- location=location,
- device_id=f"203",
- device_name=f"203",
- device_type='输送机',
- ip_address='192.168.18.1',
- mode = 'inbound',
- port=203,
- status='available',
- )
- location = LocationModel.objects.get(warehouse_code=warehouse_code, row=16, col=18, layer=1)
- # 创建库位
- cls.objects.update_or_create(
- warehouse_code=warehouse_code,
- location=location,
- device_id=f"103",
- device_name=f"103",
- device_type='输送机',
- ip_address='192.168.18.1',
- mode = 'outbound',
- port=103,
- status='available',
- )
-
-
- # 库位变更记录(历史追溯)
- class LocationChangeLog(models.Model):
- OPERATION_TYPES = (
- ('put', '上架'),
- ('pick', '下架'),
- ('move_in', '移入'),
- ('move_out', '移出')
- )
-
- location = models.ForeignKey(LocationModel, on_delete=models.CASCADE, verbose_name='库位')
- container = models.ForeignKey(ContainerListModel, on_delete=models.CASCADE, verbose_name='托盘')
- task_wcs = models.ForeignKey(ContainerWCSModel, on_delete=models.CASCADE, null=True, blank=True, verbose_name='WCS任务')
- task_detail = models.ForeignKey(TaskModel, on_delete=models.CASCADE, null=True, blank=True, verbose_name='批次详情')
- operation_type = models.CharField(max_length=10, choices=OPERATION_TYPES, verbose_name='操作类型')
- related_location = models.ForeignKey(LocationModel,
- on_delete=models.SET_NULL,
- null=True,
- related_name='related_logs',
- verbose_name='关联库位') # 用于移库操作
- timestamp = models.DateTimeField(auto_now_add=True, verbose_name='操作时间')
- class Meta:
- db_table = 'location_change_log'
- verbose_name = 'Location Change Log'
- verbose_name_plural = "Location Change Log"
- ordering = ['-id']
- class base_location(models.Model):
- layer1_pressure = models.IntegerField(default=0, verbose_name='第一层工作压力')
- layer2_pressure = models.IntegerField(default=0, verbose_name='第二层工作压力')
- layer3_pressure = models.IntegerField(default=0, verbose_name='第三层工作压力')
- class Meta:
- db_table = 'base_location'
- verbose_name = 'Base_location'
- verbose_name_plural = "Base_location"
- ordering = ['-id']
- class alloction_pre(models.Model):
- batch_number = models.CharField(max_length=255, verbose_name='批次号')
- layer_pre_type = models.JSONField(default=list, verbose_name='预留方案')
- layer_solution_type = models.JSONField(default=list, verbose_name='规划方案')
- layer1_task_finish_number = models.IntegerField(default=0, verbose_name='第一层任务完成数')
- layer2_task_finish_number = models.IntegerField(default=0, verbose_name='第二层任务完成数')
- layer3_task_finish_number = models.IntegerField(default=0, verbose_name='第三层任务完成数')
- create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
- class Meta:
- db_table = 'allocation_pre'
- verbose_name = 'Allocation_pre'
- verbose_name_plural = "Allocation_pre"
- ordering = ['-id']
- class allocation_history(models.Model):
- location = models.ForeignKey(LocationModel, on_delete=models.CASCADE, verbose_name='库位')
- container = models.ForeignKey(ContainerListModel, on_delete=models.CASCADE, verbose_name='托盘')
- task_wcs = models.ForeignKey(ContainerWCSModel, on_delete=models.CASCADE, null=True, blank=True, verbose_name='WCS任务')
- task_detail = models.ForeignKey(TaskModel, on_delete=models.CASCADE, null=True, blank=True, verbose_name='批次详情')
- operation_type = models.CharField(max_length=10, verbose_name='操作类型')
- related_location = models.ForeignKey(LocationModel,
- on_delete=models.SET_NULL,
- null=True,
- related_name='related_logs_history',
- verbose_name='关联库位') # 用于移库操作
- timestamp = models.DateTimeField(auto_now_add=True, verbose_name='操作时间')
- class Meta:
- db_table = 'allocation_history'
- verbose_name = 'Allocation_history'
- verbose_name_plural = "Allocation_history"
- ordering = ['-id']
|