factory/apps/wpm/views.py

400 lines
15 KiB
Python

from django.db import transaction
from django.db.models import Prefetch
from django.shortcuts import render
from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, UpdateModelMixin
from rest_framework.response import Response
from rest_framework.serializers import Serializer
from django.db.models import Sum
from django.utils import timezone
from apps.mtm.models import Material
from apps.pm.models import Mtask
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from apps.utils.mixins import BulkCreateModelMixin
from .filters import StLogFilter, SfLogFilter, WMaterialFilter, MlogFilter, HandoverFilter
from .models import SfLog, SfLogExp, StLog, WMaterial, Mlog, Handover, Mlogb, AttLog, OtherLog
from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer, MlogRevertSerializer,
MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer, HandoverSerializer,
GenHandoverSerializer, GenHandoverWmSerializer, MlogAnaSerializer, AttLogSerializer, OtherLogSerializer)
from .services import mlog_submit, update_mtask, handover_submit, mlog_revert
from apps.monitor.services import create_auditlog, delete_auditlog
# Create your views here.
class StLogViewSet(CustomModelViewSet):
"""
list:异常记录
异常记录
"""
queryset = StLog.objects.all()
serializer_class = StLogSerializer
select_related_fields = ['mgroup']
filterset_class = StLogFilter
ordering = ['-start_time']
def destroy(self, request, *args, **kwargs):
obj: StLog = self.get_object()
if obj.is_shutdown:
raise ParseError('停机记录不可删除')
return super().destroy(request, *args, **kwargs)
class SfLogViewSet(UpdateModelMixin, ListModelMixin, DestroyModelMixin, CustomGenericViewSet):
"""
list:值班记录
值班记录
"""
perms_map = {'get': '*', 'put': 'sflog.update', 'delete': 'sflog.delete'}
queryset = SfLog.objects.all()
serializer_class = SfLogSerializer
select_related_fields = ['mgroup', 'shift', 'team', 'leader']
filterset_class = SfLogFilter
search_fields = ['note']
ordering = ['-start_time']
@action(methods=['get'], detail=True, perms_map={'get': '*'})
def init_test(self, request, pk=None):
"""
初始化检测录入
初始化检测录入
"""
from apps.qm.models import QuaStat, TestItem
from apps.qm.serializers import QuaStatSerializer
obj = self.get_object()
test_materials = Material.objects.filter(
id__in=obj.mgroup.test_materials).order_by('sort', '-create_time')
for material in test_materials:
testitems = TestItem.objects.filter(
id__in=material.testitems).order_by('sort', '-create_time')
for testitem in testitems:
params = {'material': material,
'testitem': testitem, 'sflog': obj}
QuaStat.objects.get_or_create(
**params, defaults={**params, **{'create_by': request.user, 'belong_dept': obj.mgroup.belong_dept}})
qs = QuaStat.objects.filter(sflog=obj).order_by(
'material__sort', 'material__create_time', 'testitem__sort', 'testitem__create_time')
sr = QuaStatSerializer(instance=qs, many=True)
return Response(sr.data)
class SfLogExpViewSet(ListModelMixin, UpdateModelMixin, CustomGenericViewSet):
"""
list:异常值班处理
异常值班处理
"""
perms_map = {'get': '*', 'put': 'sflogexp.update'}
queryset = SfLogExp.objects.all()
serializer_class = SflogExpSerializer
select_related_fields = ['sflog', 'sflog__mgroup', 'stlog', 'sflog__team', 'sflog__shift', 'sflog__leader']
filterset_fields = ['sflog', 'stlog']
class WMaterialViewSet(ListModelMixin, CustomGenericViewSet):
"""
list: 车间库存
车间库存
"""
perms_map = {'get': '*'}
queryset = WMaterial.objects.all()
serializer_class = WMaterialSerializer
select_related_fields = ['material', 'belong_dept', 'material__process']
search_fields = ['material__name',
'material__number', 'material__specification']
filterset_class = WMaterialFilter
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=DeptBatchSerializer)
@transaction.atomic
def batchs(self, request):
"""获取车间的批次号(废弃)
获取车间的批次号
"""
sr = DeptBatchSerializer(data=request.data)
sr.is_valid(raise_exception=True)
vdata = sr.validated_data
batchs = WMaterial.objects.filter(
belong_dept__name=vdata['belong_dept_name'], count__gt=0).values_list('batch', flat=True).distinct()
return Response(list(batchs))
class MlogViewSet(CustomModelViewSet):
"""
list: 生产日志
生产日志
"""
queryset = Mlog.objects.all()
serializer_class = MlogSerializer
select_related_fields = ['create_by', 'update_by', 'mtask',
'handle_user', 'handle_user_2', 'equipment', 'equipment_2']
prefetch_related_fields = ['handle_users',
'material_outs', 'b_mlog', 'equipments']
filterset_class = MlogFilter
@transaction.atomic
def perform_create(self, serializer):
ins = serializer.save()
data = MlogSerializer(ins).data
create_auditlog('create', ins, data)
@transaction.atomic
def perform_destroy(self, instance):
if instance.submit_time is not None:
raise ParseError('日志已提交不可变动')
delete_auditlog(instance, instance.id)
instance.delete()
@transaction.atomic
def perform_update(self, serializer):
ins = serializer.instance
if ins.submit_time is not None:
raise ParseError('该日志已提交!')
val_old = MlogSerializer(instance=ins).data
serializer.save()
val_new = MlogSerializer(instance=ins).data
create_auditlog('update', ins, val_new, val_old)
@action(methods=['post'], detail=True, perms_map={'post': 'mlog.submit'}, serializer_class=Serializer)
@transaction.atomic
def submit(self, request, *args, **kwargs):
"""日志提交(变动车间库存)
日志提交
"""
ins: Mlog = self.get_object()
vdata_old = MlogSerializer(ins).data
now = timezone.now()
if ins.submit_time:
raise ParseError('该日志已提交!')
if ins.mtask and ins.mtask.state == Mtask.MTASK_STOP:
raise ParseError('该任务已停止!')
mlog_submit(ins, self.request.user, now)
if ins.mtask:
update_mtask(ins.mtask)
vdata_new = MlogSerializer(ins).data
create_auditlog('submit', ins, vdata_new,
vdata_old, now, self.request.user)
return Response(MlogSerializer(instance=ins).data)
@action(methods=['post'], detail=True, perms_map={'post': 'mlog.submit'}, serializer_class=MlogRevertSerializer)
@transaction.atomic
def revert(self, request, *args, **kwargs):
"""撤回日志提交
撤回日志提交
"""
ins: Mlog = self.get_object()
user = request.user
if ins.submit_time is None:
raise ParseError('日志未提交不可撤销')
if user != ins.submit_user:
raise ParseError('非提交人不可撤销!')
now = timezone.now()
mlog_revert(ins, user, now)
if ins.mtask:
mtask = ins.mtask
mtask.state = Mtask.MTASK_ASSGINED
mtask.save()
update_mtask(ins.mtask)
create_auditlog('revert', ins, {}, {}, now, user,
request.data.get('change_reason', ''))
return Response(MlogSerializer(instance=ins).data)
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MlogRelatedSerializer)
@transaction.atomic
def related_first(self, request, *args, **kwargs):
"""获取相关任务的第一道工序日志
获取相关任务的第一道工序日志
"""
sr = MlogRelatedSerializer(data=request.data)
sr.is_valid(raise_exception=True)
vdata = sr.validated_data
mtask = vdata['mtask']
if mtask.utask:
mtasks = mtask.related
mlogs = Mlog.objects.filter(mtask__in=mtasks).order_by(
'mtask__mgroup__process__sort', 'batch', 'create_time')
data = MlogSerializer(instance=mlogs, many=True).data
res_data = []
for ind, val in enumerate(data):
if ind == 0:
res_data.append(val)
else:
before = data[ind-1]
if val['batch'] != before['batch']:
res_data.append(val)
return Response(res_data)
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MlogAnaSerializer)
def ana(self, request):
"""核心统计数据
核心统计数据
"""
sr = MlogAnaSerializer(data=request.data)
sr.is_valid(raise_exception=True)
vdata = sr.validated_data
mlogs = Mlog.objects.exclude(submit_time=None)
if vdata.get('belong_dept_name', ''):
mlogs = mlogs.filter(
mgroup__belong_dept__name=vdata['belong_dept_name'])
if vdata.get('material_cate', ''):
mlogs = mlogs.filter(
material_out__cate=vdata['material_cate'])
if vdata.get('start_date', ''):
mlogs = mlogs.filter(handle_date__gte=vdata['start_date'])
if vdata.get('end_date', ''):
mlogs = mlogs.filter(handle_date__lte=vdata['end_date'])
res = mlogs.aggregate(
count_real=Sum('count_real'),
count_ok=Sum('count_ok'),
count_notok=Sum('count_notok'),
count_n_zw=Sum('count_n_zw'),
count_n_tw=Sum('count_n_tw'),
count_n_qp=Sum('count_n_qp'),
count_n_wq=Sum('count_n_wq'),
count_n_dl=Sum('count_n_dl'),
count_n_pb=Sum('count_n_pb'),
count_n_dxt=Sum('count_n_dxt'),
count_n_jsqx=Sum('count_n_jsqx'),
count_n_qt=Sum('count_n_qt'))
for i in res:
if res[i] is None:
res[i] = 0
return Response(res)
class HandoverViewSet(CustomModelViewSet):
"""
list: 交接记录
交接记录
"""
queryset = Handover.objects.all()
serializer_class = HandoverSerializer
select_related_fields = ['send_user',
'send_dept', 'recive_user', 'recive_dept']
filterset_class = HandoverFilter
def perform_destroy(self, instance):
user = self.request.user
if instance.submit_time is not None:
raise ParseError('日志已提交不可变动')
if instance.send_user != user and instance.recive_user != user and instance.create_by != user:
raise ParseError('非交送人和接收人不可删除该记录')
return super().perform_destroy(instance)
@action(methods=['post'], detail=True, perms_map={'post': 'handover.submit'}, serializer_class=Serializer)
@transaction.atomic
def submit(self, request, *args, **kwargs):
"""交接记录提交(变动车间库存)
交接记录提交
"""
ins: Handover = self.get_object()
user = self.request.user
if user != ins.recive_user:
raise ParseError('非接收人不可提交')
if ins.submit_time is None:
handover_submit(ins, user, None)
return Response()
@action(methods=['post'], detail=False, perms_map={'post': 'handover.create'}, serializer_class=GenHandoverWmSerializer)
@transaction.atomic
def gen_by_wm(self, request):
"""从车间库存生成交接记录(废弃)
从车间库存生成交接记录
"""
sr = GenHandoverWmSerializer(data=request.data)
sr.is_valid(raise_exception=True)
vdata = sr.validated_data
user = request.user
send_date, send_mgroup, send_user, recive_dept, recive_user, wm, count = vdata['send_date'], vdata['send_mgroup'], vdata[
'send_user'], vdata['recive_dept'], vdata['recive_user'], vdata['wm'], vdata['count']
if send_mgroup.belong_dept != wm.belong_dept:
raise ParseError('送料工段错误!')
handover = Handover.objects.create(
send_date=send_date,
send_user=send_user,
recive_dept=recive_dept,
recive_user=recive_user,
send_mgroup=send_mgroup,
send_dept=wm.belong_dept,
batch=wm.batch,
material=wm.material,
count=count,
wm=wm,
create_by=user
)
return Response({'handover': handover.id})
@action(methods=['post'], detail=False, perms_map={'post': 'handover.create'}, serializer_class=GenHandoverSerializer)
@transaction.atomic
def gen_by_mlog(self, request):
"""从生产日志生成交接记录(废弃)
从生产日志生成交接记录
"""
sr = GenHandoverSerializer(data=request.data)
sr.is_valid(raise_exception=True)
vdata = sr.validated_data
user = request.user
send_date, send_user, recive_dept, recive_user = vdata['send_date'], vdata[
'send_user'], vdata['recive_dept'], vdata['recive_user']
for mlog in vdata['mlogs']:
Handover.objects.create(
send_date=send_date,
send_user=send_user,
recive_dept=recive_dept,
recive_user=recive_user,
send_dept=mlog.mgroup.belong_dept,
batch=mlog.batch,
material=mlog.material_out,
count=mlog.count_real,
count_eweight=mlog.count_real_eweight,
mlog=mlog,
send_mgroup=mlog.mgroup,
create_by=user
)
return Response()
class AttlogViewSet(CustomModelViewSet):
"""
list: 车间到岗
车间到岗
"""
queryset = AttLog.objects.all()
serializer_class = AttLogSerializer
select_related_fields = ['user', 'post', 'sflog']
filterset_fields = ['sflog__mgroup',
'sflog__mgroup__belong_dept__name', 'sflog__work_date', 'sflog__mgroup__cate', 'sflog__mgroup__need_enm']
ordering = ['-sflog__work_date', 'create_time']
class OtherLogViewSet(CustomModelViewSet):
"""
list: 其他生产记录
其他生产记录
"""
queryset = OtherLog.objects.all()
serializer_class = OtherLogSerializer
filterset_fields = {
"product": ["exact"],
"handle_date": ["exact", "gte", "lte"]
}
search_fields = ['product']
ordering = ['-handle_date', '-create_time']