447 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			447 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Python
		
	
	
	
| from apps.wpm.models import Mlog, BatchSt
 | |
| from apps.mtm.models import Mgroup
 | |
| from apps.system.models import Dept
 | |
| from apps.inm.models import MIOItem
 | |
| from apps.qm.models import FtestWork
 | |
| from datetime import datetime
 | |
| from django.conf import settings
 | |
| import json
 | |
| from apps.utils.tools import MyJSONEncoder
 | |
| import decimal
 | |
| from apps.utils.thread import MyThread
 | |
| import logging
 | |
| import time
 | |
| from zoneinfo import ZoneInfo
 | |
| 
 | |
| myLogger = logging.getLogger('log')
 | |
| tz_shanghai = ZoneInfo("Asia/Shanghai")
 | |
| 
 | |
| # 批次统计分析
 | |
| 
 | |
| def ana_batch_thread(xbatchs: list):
 | |
|     MyThread(target=ana_batch, args=(xbatchs,)).start()
 | |
| 
 | |
| def ana_batch(xbatchs: list):
 | |
|     """
 | |
|     批次统计分析
 | |
|     """
 | |
|     time.sleep(10)
 | |
|     xbatchs = list(set(xbatchs))
 | |
|     for xbatch in xbatchs:
 | |
|         get_alldata_with_batch_and_store(xbatch)
 | |
| 
 | |
| def get_alldata_with_batch_and_store(batch: str):
 | |
|     """
 | |
|     获取某个批次的整体生产数据并保存
 | |
|     """
 | |
|     data = None
 | |
|     action = "get"
 | |
|     BASE_PROJECT_CODE = getattr(settings, "BASE_PROJECT_CODE", None)
 | |
|     if BASE_PROJECT_CODE == "gzerp":
 | |
|         action = "get_or_create"
 | |
|         data, extra = get_alldata_with_batch(batch)
 | |
|     elif BASE_PROJECT_CODE == "gxerp":
 | |
|         from apps.wpm.scripts.batch_gxerp import main
 | |
|         data, extra = main(batch)
 | |
| 
 | |
|     if  data:
 | |
|         if action == "get_or_create":
 | |
|             bobj, _ = BatchSt.objects.get_or_create(batch=batch, version=1)
 | |
|         elif action == "get":
 | |
|             bobj = BatchSt.objects.get(batch=batch, version=1)
 | |
|         bobj.data = json.loads(json.dumps(data, cls=MyJSONEncoder))
 | |
|         for k, v in extra.items():
 | |
|             if hasattr(bobj, k):
 | |
|                 setattr(bobj, k, v)
 | |
|         bobj.save()
 | |
| 
 | |
| 
 | |
| def get_alldata_with_batch(batch: str):
 | |
|     """
 | |
|     获取某个批次的整体生产数据
 | |
|     """
 | |
|     data = {"产品批次编号": batch}
 | |
|     dept7 = Dept.objects.get(name='7车间')
 | |
|     dept6 = Dept.objects.get(name='6车间')
 | |
|     dept10 = Dept.objects.get(name='10车间')
 | |
|     mgroup_blcx = Mgroup.objects.get(name="棒料成型")
 | |
|     mlogs_blcx_qs = Mlog.objects.filter(submit_time__isnull=False, mgroup=mgroup_blcx, batch=batch)
 | |
| 
 | |
|     mlog_count_fields = Mlog.count_fields()
 | |
| 
 | |
|     material_start = None
 | |
|     if mlogs_blcx_qs.exists():
 | |
|         data["产品规格"] = []
 | |
|         data["棒料成型_出料人"] = []
 | |
|         data["棒料成型_切料人"] = []
 | |
|         data["棒料成型_备注"] = ""
 | |
|         for item in mlogs_blcx_qs:
 | |
|             if material_start is None:
 | |
|                 material_start = item.material_out
 | |
|             data["产品规格"].append(item.material_out)  # 对象
 | |
|             if item.handle_user:
 | |
|                 data["棒料成型_出料人"].append(item.handle_user)  # 对象
 | |
|             if item.handle_user_2:
 | |
|                 data["棒料成型_切料人"].append(item.handle_user_2) # 对象
 | |
|             if item.note:
 | |
|                 data["棒料成型_备注"] = ";".join([data["棒料成型_备注"], item.note])
 | |
|             for field in mlog_count_fields:
 | |
|                 if getattr(item, field) > 0  or field in ["count_real", "count_ok"]:
 | |
|                     if f'棒料成型_{field}' not in data:
 | |
|                         data[f'棒料成型_{field}'] = getattr(item, field)
 | |
|                     else:
 | |
|                         data[f'棒料成型_{field}'] += getattr(item, field)
 | |
|         # 整理棒料成型数据
 | |
|         data["产品规格"] = list(set(data["产品规格"]))
 | |
|         data["产品规格"] = ";".join([item.specification if item.specification else "" for item in data["产品规格"]])
 | |
|         data["棒料成型_出料人"] = list(set(data["棒料成型_出料人"]))
 | |
|         data["棒料成型_出料人"] = ";".join([item.name for item in data["棒料成型_出料人"]])
 | |
|         data["棒料成型_切料人"] = list(set(data["棒料成型_切料人"]))
 | |
|         data["棒料成型_切料人"] = ";".join([item.name for item in data["棒料成型_切料人"]])
 | |
|         try:
 | |
|             data["棒料成型_合格率"] = round((data["棒料成型_count_ok"]  * 100/ data["棒料成型_count_real"]), 1)
 | |
|         except ZeroDivisionError:
 | |
|             data["棒料成型_合格率"] = 0
 | |
|         except decimal.InvalidOperation:
 | |
|             # myLogger.error(f"棒料成型_合格率计算错误decimal.InvalidOperation-{data}")
 | |
|             data["棒料成型_合格率"] = 0
 | |
|     
 | |
|     # 管料成型数据
 | |
|     mgroup_glcx = Mgroup.objects.get(name="管料成型")
 | |
|     mlogs_glcx_qs = Mlog.objects.filter(submit_time__isnull=False, mgroup=mgroup_glcx, batch=batch)
 | |
|     if mlogs_glcx_qs.exists():
 | |
|         data["产品规格"] = []
 | |
|         data["管料成型_备注"] = ""
 | |
|         for item in mlogs_glcx_qs:
 | |
|             if material_start is None:
 | |
|                 material_start = item.material_out
 | |
|             data["产品规格"].append(item.material_out)  # 对象
 | |
|             if item.note:
 | |
|                 data["管料成型_备注"] = ";".join([data["管料成型_备注"], item.note])
 | |
|             for field in mlog_count_fields:
 | |
|                 if getattr(item, field) > 0 or field in ["count_real", "count_ok"]:
 | |
|                     if f'管料成型_{field}' not in data:
 | |
|                         data[f'管料成型_{field}'] = getattr(item, field)
 | |
|                     else:
 | |
|                         data[f'管料成型_{field}'] += getattr(item, field)
 | |
|         data["产品规格"] = list(set(data["产品规格"]))
 | |
|         data["产品规格"] = ";".join([item.specification for item in data["产品规格"]])
 | |
|         data["管料成型_合格率"] = round((data["管料成型_count_ok"] * 100 / data["管料成型_count_real"]), 1)
 | |
| 
 | |
|     # 7车间生产入库数据/ 8车间中检数据
 | |
|     mioitem_count_fields = MIOItem.count_fields()
 | |
|     mioitem_qs = MIOItem.objects.filter(mio__belong_dept=dept7, mio__type="do_in", batch=batch,  mio__submit_time__isnull=False)
 | |
|     if mioitem_qs.exists():
 | |
|         data["七车间入库_日期"] = []
 | |
|         data["七车间入库_车间执行人"] = []
 | |
|         data["七车间入库_仓库执行人"] = []
 | |
|         data["七车间入库_检验备注"] = ""
 | |
|         for item in mioitem_qs:
 | |
|             if material_start is None:
 | |
|                 material_start = item.material
 | |
|             data["七车间入库_日期"].append(item.mio.inout_date)
 | |
|             if item.test_note:
 | |
|                 data["七车间入库_检验备注"] = ";".join([data["七车间入库_检验备注"], item.test_note])
 | |
|             if item.mio.mio_user:
 | |
|                 data["七车间入库_车间执行人"].append(item.mio.do_user)
 | |
|             if item.mio.do_user:
 | |
|                 data["七车间入库_仓库执行人"].append(item.mio.mio_user)
 | |
|             for field in mioitem_count_fields:
 | |
|                 f_v = getattr(item, field)
 | |
|                 if  f_v is not None and (f_v > 0 or field in ["count", "count_notok"]):
 | |
|                     if f'七车间入库_{field}' not in data:
 | |
|                         data[f'七车间入库_{field}'] = f_v
 | |
|                     else:
 | |
|                         data[f'七车间入库_{field}'] += f_v
 | |
|         data["七车间入库_合格率"] = round((data["七车间入库_count"] - data["七车间入库_count_notok"]) * 100/ data["七车间入库_count"], 1)
 | |
|         data["七车间入库_日期"] = list(set(data["七车间入库_日期"]))
 | |
|         data["七车间入库_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["七车间入库_日期"]])
 | |
|         data["七车间入库_车间执行人"] = list(set(data["七车间入库_车间执行人"]))
 | |
|         data["七车间入库_车间执行人"] = ";".join([item.name for item in data["七车间入库_车间执行人"]])
 | |
|         data["七车间入库_仓库执行人"] = list(set(data["七车间入库_仓库执行人"]))
 | |
|         if None in data["七车间入库_仓库执行人"]:
 | |
|             data["七车间入库_仓库执行人"].remove(None)
 | |
|         data["七车间入库_仓库执行人"] = ";".join([item.name for item in data["七车间入库_仓库执行人"]])
 | |
| 
 | |
|     # 十车间入库检验
 | |
|     mioitem10_qs = MIOItem.objects.filter(mio__belong_dept=dept10, mio__type="do_in", batch=batch,  mio__submit_time__isnull=False)
 | |
|     if mioitem10_qs.exists():
 | |
|         
 | |
|         data["十车间入库_抽检人"] = []
 | |
|         data["十车间入库_仓库执行人"] = []
 | |
|         data["十车间入库_日期"] = []
 | |
|         data["十车间入库_检验备注"] = ""
 | |
|         for item in mioitem10_qs:
 | |
|             if material_start is None:
 | |
|                 material_start = item.material
 | |
|             if item.test_note:
 | |
|                 data["十车间入库_检验备注"] = ";".join([data["十车间入库_检验备注"], item.test_note])
 | |
|             if item.mio.do_user:
 | |
|                 data["十车间入库_仓库执行人"].append(item.mio.do_user)
 | |
|             if item.test_user:
 | |
|                 data["十车间入库_抽检人"].append(item.test_user)
 | |
|             for field in mioitem_count_fields:
 | |
|                 if getattr(item, field) is not None and (getattr(item, field) > 0 or field in ["count", "count_notok", "count_sampling"]):
 | |
|                     if f'十车间入库_{field}' not in data:
 | |
|                         data[f'十车间入库_{field}'] = getattr(item, field)
 | |
|                     else:
 | |
|                         data[f'十车间入库_{field}'] += getattr(item, field)
 | |
|         data["十车间入库_抽检人"] = list(set(data["十车间入库_抽检人"]))
 | |
|         data["十车间入库_抽检人"] = ";".join([item.name for item in data["十车间入库_抽检人"]])
 | |
|         if data["十车间入库_count_sampling"] > 0:
 | |
|             data["十车间入库_抽检合格数"] = data["十车间入库_count_sampling"] - data["十车间入库_count_notok"]
 | |
|             data["十车间入库_抽检合格率"] = round(data["十车间入库_抽检合格数"] * 100/ data["十车间入库_count_sampling"], 1)
 | |
|         data["十车间入库_仓库执行人"] = list(set(data["十车间入库_仓库执行人"]))
 | |
|         data["十车间入库_仓库执行人"] = ";".join([item.name for item in data["十车间入库_仓库执行人"]])
 | |
|         data["十车间入库_日期"] = list(set(data["十车间入库_日期"]))
 | |
|         data["十车间入库_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["十车间入库_日期"]])
 | |
|         data["十车间入库_合格数"] = data["十车间入库_count"] - data["十车间入库_count_notok"]
 | |
|         data["十车间入库_合格率"] = round((data["十车间入库_count"] - data["十车间入库_count_notok"]) * 100/ data["十车间入库_count"], 1)
 | |
| 
 | |
|     # 管料退火生产数据
 | |
|     mgroup_gltx = Mgroup.objects.get(name="管料退火")
 | |
|     mlogs_glth_qs = Mlog.objects.filter(submit_time__isnull=False, mgroup=mgroup_gltx, batch=batch)
 | |
|     if mlogs_glth_qs.exists():
 | |
|         data["管料退火_日期"] = []
 | |
|         data["管料退火_操作人"] = []
 | |
|         data["管料退火_备注"] = ""
 | |
|         data["产品规格"] = []
 | |
|         for item in mlogs_glth_qs:
 | |
|             data["产品规格"].append(item.material_out)
 | |
|             if material_start is None:
 | |
|                 material_start = item.material_out
 | |
|             if item.note: 
 | |
|                 data["管料退火_备注"] = ";".join([data["管料退火_备注"], item.note])
 | |
|             if item.handle_date:
 | |
|                 data["管料退火_日期"].append(item.handle_date)
 | |
|             if item.handle_user:
 | |
|                 data["管料退火_操作人"].append(item.handle_user)
 | |
|             for field in mlog_count_fields: 
 | |
|                 if getattr(item, field) is not None and (getattr(item, field) > 0 or field in ["count", "count_notok"]):
 | |
|                     if f'管料退火_{field}' not in data:
 | |
|                         data[f'管料退火_{field}'] = getattr(item, field)
 | |
|                     else:
 | |
|                         data[f'管料退火_{field}'] += getattr(item, field)
 | |
|         data["管料退火_日期"] = list(set(data["管料退火_日期"]))
 | |
|         data["管料退火_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["管料退火_日期"]])
 | |
|         data["管料退火_操作人"] = list(set(data["管料退火_操作人"]))
 | |
|         data["管料退火_操作人"] = ";".join([item.name for item in data["管料退火_操作人"]])
 | |
|         data["产品规格"] = list(set(data["产品规格"]))
 | |
|         data["产品规格"] = ";".join([item.specification for item in data["产品规格"]])
 | |
| 
 | |
| 
 | |
|     # 六车间领料数据
 | |
|     mioitem6_qs = MIOItem.objects.filter(mio__belong_dept=dept6, mio__type="do_out", 
 | |
|                                          batch=batch,  
 | |
|                                          mio__submit_time__isnull=False)
 | |
|     if mioitem6_qs.exists():
 | |
|         data["六车间领料_日期"] = []
 | |
|         data["六车间领料_车间执行人"] = []
 | |
|         data["六车间领料_仓库执行人"] = []
 | |
|         data["产品规格"] = []
 | |
|         for item in mioitem6_qs:
 | |
|             data["产品规格"].append(item.material)
 | |
|             if material_start is None:
 | |
|                 material_start = item.material
 | |
|             data["六车间领料_日期"].append(item.mio.inout_date)
 | |
|             if item.mio.do_user:
 | |
|                 data["六车间领料_仓库执行人"].append(item.mio.do_user)
 | |
|             if item.mio.mio_user:
 | |
|                 data["六车间领料_车间执行人"].append(item.mio.mio_user)
 | |
|             for field in mioitem_count_fields:
 | |
|                 if getattr(item, field) is not None and getattr(item, field) > 0:
 | |
|                     if f'六车间领料_{field}' not in data:
 | |
|                         data[f'六车间领料_{field}'] = getattr(item, field)
 | |
|                     else:
 | |
|                         data[f'六车间领料_{field}'] += getattr(item, field)
 | |
|         data["六车间领料_日期"] = list(set(data["六车间领料_日期"]))
 | |
|         data["六车间领料_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["六车间领料_日期"]])
 | |
|         data["六车间领料_仓库执行人"] = list(set(data["六车间领料_仓库执行人"]))
 | |
|         data["六车间领料_仓库执行人"] = ";".join([item.name for item in data["六车间领料_仓库执行人"]])
 | |
|         data["六车间领料_车间执行人"] = list(set(data["六车间领料_车间执行人"]))
 | |
|         data["六车间领料_车间执行人"] = ";".join([item.name for item in data["六车间领料_车间执行人"]])
 | |
|         data["产品规格"] = list(set(data["产品规格"]))
 | |
|         data["产品规格"] = ";".join([item.specification for item in data["产品规格"]])
 | |
| 
 | |
|     # 六车间工段生产数据
 | |
| 
 | |
|     # 六车间工段生产数据
 | |
|     mgroup_list = ["平头", "粘铁头", "粗中细磨", "平磨", "掏管", "抛光", "开槽", "倒角"]
 | |
|     for mgroup_name in mgroup_list:
 | |
|         if mgroup_name == '粗中细磨':
 | |
|             mgroups = Mgroup.objects.filter(name__in=['粗磨', '粗中磨', '粗中细磨'])
 | |
|         else:
 | |
|             mgroups = Mgroup.objects.filter(name=mgroup_name)
 | |
|         mlogs_qs = Mlog.objects.filter(submit_time__isnull=False, mgroup__in=mgroups, batch=batch)
 | |
|         if mlogs_qs.exists():
 | |
|             data[f'六车间_{mgroup_name}_日期'] = []
 | |
|             data[f'六车间_{mgroup_name}_操作人'] = []
 | |
|             data[f'六车间_{mgroup_name}_备注'] = ""
 | |
|             for item in mlogs_qs:
 | |
|                 if material_start is None:
 | |
|                     material_start = item.material_out
 | |
|                 if item.note:
 | |
|                     data[f'六车间_{mgroup_name}_备注'] = ";".join([data[f'六车间_{mgroup_name}_备注'], item.note])
 | |
|                 if item.handle_date:
 | |
|                     data[f'六车间_{mgroup_name}_日期'].append(item.handle_date)
 | |
|                 if item.handle_user:
 | |
|                     data[f'六车间_{mgroup_name}_操作人'].append(item.handle_user)
 | |
|                 for field in mlog_count_fields:
 | |
|                     if getattr(item, field) > 0 or field in ["count_ok", "count_real"]:
 | |
|                         if f'六车间_{mgroup_name}_{field}' not in data:
 | |
|                             data[f'六车间_{mgroup_name}_{field}'] = getattr(item, field)
 | |
|                         else:
 | |
|                             data[f'六车间_{mgroup_name}_{field}'] += getattr(item, field)
 | |
|             data[f'六车间_{mgroup_name}_日期'] = list(set(data[f'六车间_{mgroup_name}_日期']))
 | |
|             data[f'六车间_{mgroup_name}_日期'] = ";".join([item.strftime("%Y-%m-%d") for item in data[f'六车间_{mgroup_name}_日期']])
 | |
|             data[f'六车间_{mgroup_name}_操作人'] = list(set(data[f'六车间_{mgroup_name}_操作人']))
 | |
|             data[f'六车间_{mgroup_name}_操作人'] = ";".join([item.name for item in data[f'六车间_{mgroup_name}_操作人']])
 | |
|             try:
 | |
|                 data[f'六车间_{mgroup_name}_合格率'] = round(data[f'六车间_{mgroup_name}_count_ok'] * 100/ data[f'六车间_{mgroup_name}_count_real'], 1)
 | |
|             except decimal.InvalidOperation:
 | |
|                 # myLogger.error(f"六车间_{mgroup_name}_合格率decimal.InvalidOperation-{data}")
 | |
|                 data[f'六车间_{mgroup_name}_合格率'] = 0
 | |
| 
 | |
|     ftestwork_count_fields = FtestWork.count_fields()
 | |
|     # 六车间中检数据
 | |
|     ftestwork_qs = FtestWork.objects.filter(batch=batch, type="process")
 | |
|     if ftestwork_qs.exists():
 | |
|         data["六车间中检_日期"] = []
 | |
|         data['六车间中检_检验人'] = []
 | |
|         for item in ftestwork_qs:
 | |
|             if material_start is None:
 | |
|                 material_start = item.material
 | |
|             if item.test_date:
 | |
|                 data["六车间中检_日期"].append(item.test_date)
 | |
|             if item.test_user:
 | |
|                 data['六车间中检_检验人'].append(item.test_user)
 | |
|             for field in ftestwork_count_fields:
 | |
|                 if field == 'count_notok_json':
 | |
|                     for k, v in getattr(item, field).items():
 | |
|                         if f'六车间中检_{k}' not in data:
 | |
|                             data[f'六车间中检_{k}'] = v
 | |
|                         else:
 | |
|                             data[f'六车间中检_{k}'] += v
 | |
|                 else:
 | |
|                     if getattr(item, field) > 0 or field in ["count", "count_ok"]:
 | |
|                         if f'六车间中检_{field}' not in data:
 | |
|                             data[f'六车间中检_{field}'] = getattr(item, field)
 | |
|                         else:
 | |
|                             data[f'六车间中检_{field}'] += getattr(item, field)
 | |
|         data["六车间中检_日期"] = list(set(data["六车间中检_日期"]))
 | |
|         data["六车间中检_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["六车间中检_日期"]])
 | |
|         data['六车间中检_检验人'] = list(set(data['六车间中检_检验人']))
 | |
|         data['六车间中检_检验人'] = ";".join([item.name for item in data['六车间中检_检验人']])
 | |
| 
 | |
|     # 六车间入库/检验数据
 | |
|     mioitem6_qs2 = MIOItem.objects.filter(mio__belong_dept=dept6, mio__type="do_in", 
 | |
|                                          batch=batch,  
 | |
|                                          mio__submit_time__isnull=False)
 | |
|     if mioitem6_qs2.exists():
 | |
|         data["六车间生产入库_日期"] = []
 | |
|         data["六车间生产入库_检验日期"] = []
 | |
|         data["六车间生产入库_检验人"] = []
 | |
|         for item in mioitem6_qs2:
 | |
|             if material_start is None:
 | |
|                 material_start = item.material
 | |
|             data["六车间生产入库_日期"].append(item.mio.inout_date)
 | |
|             if item.test_date:
 | |
|                 data["六车间生产入库_检验日期"].append(item.test_date)
 | |
|             for field in mioitem_count_fields:
 | |
|                 if getattr(item, field) is not None and (getattr(item, field) > 0 or field in ["count", "count_notok"]):
 | |
|                     if f'六车间生产入库_{field}' not in data:
 | |
|                         data[f'六车间生产入库_{field}'] = getattr(item, field)
 | |
|                     else:
 | |
|                         data[f'六车间生产入库_{field}'] += getattr(item, field)
 | |
|         data["六车间生产入库_日期"] = list(set(data["六车间生产入库_日期"]))
 | |
|         data["六车间生产入库_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["六车间生产入库_日期"]])
 | |
|         data["六车间生产入库_检验日期"] = list(set(data["六车间生产入库_检验日期"]))
 | |
|         data["六车间生产入库_检验日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["六车间生产入库_检验日期"]])
 | |
|         try:
 | |
|             data['六车间生产入库_合格率'] = round((data['六车间生产入库_count'] - data['六车间生产入库_count_notok']) * 100/ data['六车间生产入库_count'], 1)
 | |
|         except decimal.InvalidOperation:
 | |
|             # myLogger.error("六车间生产入库_合格率decimal.InvalidOperation-{data}")
 | |
|             data['六车间生产入库_合格率'] = 0
 | |
| 
 | |
|     # 成品检验数据
 | |
|     ftestwork_qs = FtestWork.objects.filter(batch=batch, type="prod")
 | |
|     if ftestwork_qs.exists():
 | |
|         data["成品检验_日期"] = []
 | |
|         data['成品检验_检验人'] = []
 | |
|         for item in ftestwork_qs:
 | |
|             if material_start is None:
 | |
|                 material_start = item.material
 | |
|             if item.test_date:
 | |
|                 data["成品检验_日期"].append(item.test_date)
 | |
|             if item.test_user:
 | |
|                 data['成品检验_检验人'].append(item.test_user)
 | |
|             for field in ftestwork_count_fields:
 | |
|                 if field == 'count_notok_json':
 | |
|                     for k, v in getattr(item, field).items():
 | |
|                         if f'成品检验_{k}' not in data:
 | |
|                             data[f'成品检验_{k}'] = v
 | |
|                         else:
 | |
|                             data[f'成品检验_{k}'] += v
 | |
|                 else:
 | |
|                     if getattr(item, field) > 0 or field in ["count", "count_ok"]:
 | |
|                         if f'成品检验_{field}' not in data:
 | |
|                             data[f'成品检验_{field}'] = getattr(item, field)
 | |
|                         else:
 | |
|                             data[f'成品检验_{field}'] += getattr(item, field)
 | |
|         data["成品检验_日期"] = list(set(data["成品检验_日期"]))
 | |
|         data["成品检验_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["成品检验_日期"]])
 | |
|         data['成品检验_检验人'] = list(set(data['成品检验_检验人']))
 | |
|         data['成品检验_检验人'] = ";".join([item.name for item in data['成品检验_检验人']])
 | |
|         data['成品检验_合格率'] = round(data['成品检验_count_ok'] * 100/ data['成品检验_count'], 1)
 | |
|         if getattr(data, "六车间领料_count", 0) > 0:
 | |
|             data["六车间_批次生产合格率"] = round(data["成品检验_count_ok"] * 100/ data["六车间领料_count"], 1)
 | |
|         if getattr(data, "棒料成型_count_real", 0) > 0:
 | |
|             data["七车间_批次应出合格率"] = round(data["成品检验_count_ok"] * 100/ data["棒料成型_count_real"], 1)
 | |
| 
 | |
|     # 销售发货数据
 | |
|     mioitem_qs = MIOItem.objects.filter(batch=batch, mio__type="sale_out", mio__submit_time__isnull=False)
 | |
|     if mioitem_qs.exists():
 | |
|         data["销售发货_日期"] = []
 | |
|         data['销售发货_仓库执行人'] = []
 | |
|         data['销售发货_count'] = 0
 | |
|         for item in mioitem_qs:
 | |
|             if material_start is None:
 | |
|                 material_start = item.material
 | |
|             if item.mio.inout_date:
 | |
|                 data["销售发货_日期"].append(item.mio.inout_date)
 | |
|             if item.mio.do_user:
 | |
|                 data['销售发货_仓库执行人'].append(item.mio.do_user)
 | |
|             data['销售发货_count']+= item.count
 | |
|         if getattr(data, "棒料成型_count_real", 0) > 0:
 | |
|             data["七车间_批次发货合格率"] = round(data["销售发货_count"] * 100/ data["棒料成型_count_real"], 1)
 | |
|         if getattr(data, "六车间领料_count", 0) > 0:
 | |
|             data["六车间_批次发货合格率"] = round(data["销售发货_count"] * 100/ data["六车间领料_count"], 1)
 | |
|         data['销售发货_仓库执行人'] = list(set(data['销售发货_仓库执行人']))
 | |
|         data['销售发货_仓库执行人'] = ";".join([item.name for item in data['销售发货_仓库执行人']])
 | |
|         data["销售发货_日期"] = list(set(data["销售发货_日期"]))
 | |
|         data["销售发货_日期"] = ";".join([item.strftime("%Y-%m-%d") for item in data["销售发货_日期"]])
 | |
| 
 | |
|     res = get_f_l_date(data)
 | |
|     return data, {"material_start": material_start, **res}
 | |
|         
 | |
| 
 | |
| def get_f_l_date(data):
 | |
|     first_date = None
 | |
|     last_date = None
 | |
|     for k, v in data.items():
 | |
|         if k.endswith("_日期"):
 | |
|             if v:
 | |
|                 v = v.split(";")
 | |
|                 if first_date is None:
 | |
|                     first_date = min(v)
 | |
|                 else:
 | |
|                     first_date = min(first_date, min(v))
 | |
|                 if last_date is None:
 | |
|                     last_date = max(v)
 | |
|                 else:
 | |
|                     last_date = max(last_date, max(v))
 | |
|     return {"first_date": first_date, 
 | |
|             "last_date": last_date, 
 | |
|             "first_time": datetime.strptime(f"{first_date} 00:00:00", "%Y-%m-%d %H:%M:%S").replace(tzinfo=tz_shanghai) if first_date else None, 
 | |
|             "last_time": datetime.strptime(f"{last_date} 23:59:59", "%Y-%m-%d %H:%M:%S").replace(tzinfo=tz_shanghai) if last_date else None}
 |