Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop

This commit is contained in:
shijing 2021-12-30 17:13:46 +08:00
commit f44b416070
11 changed files with 200 additions and 104 deletions

View File

@ -15,6 +15,9 @@ class PmService:
qs_list = list(qs) qs_list = list(qs)
for i in qs_list: for i in qs_list:
ret[i['process__number']] = { ret[i['process__number']] = {
'process':i['process'],
'process_number':i['process__number'],
'process_name':i['process__name'],
'count':i['count'], 'count':i['count'],
'count_real':i['count_real'], 'count_real':i['count_real'],
'count_ok':i['count_ok'], 'count_ok':i['count_ok'],

View File

@ -77,6 +77,7 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De
obj = self.get_object() obj = self.get_object()
if obj.is_submited: if obj.is_submited:
raise exceptions.APIException('该记录已提交不可删除') raise exceptions.APIException('该记录已提交不可删除')
WpmServies.add_wproduct_flow_log(obj.wproduct, 'test_delete')
return super().destroy(request, *args, **kwargs) return super().destroy(request, *args, **kwargs)
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=TestRecordUpdateSerializer) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=TestRecordUpdateSerializer)
@ -89,7 +90,7 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De
with transaction.atomic(): with transaction.atomic():
obj.is_submited=True obj.is_submited=True
obj.save() obj.save()
WpmServies.update_wproduct_by_test(obj, request.user) WpmServies.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算
return Response() return Response()
# def create(self, request, *args, **kwargs): # def create(self, request, *args, **kwargs):

View File

@ -130,6 +130,7 @@ class WfService(object):
import datetime, time # 用于支持条件表达式中对时间的操作 import datetime, time # 用于支持条件表达式中对时间的操作
if eval(expression, {'__builtins__':None}, {'datetime':datetime, 'time':time}): if eval(expression, {'__builtins__':None}, {'datetime':datetime, 'time':time}):
destination_state = State.objects.get(pk=i['target_state']) destination_state = State.objects.get(pk=i['target_state'])
return destination_state
return destination_state return destination_state
@classmethod @classmethod
@ -321,7 +322,8 @@ class WfService(object):
if not created: if not created:
for key, value in source_state.state_fields.items(): for key, value in source_state.state_fields.items():
if value in (State.STATE_FIELD_REQUIRED, State.STATE_FIELD_OPTIONAL): if value in (State.STATE_FIELD_REQUIRED, State.STATE_FIELD_OPTIONAL):
source_ticket_data[key] = new_ticket_data[key] if key in new_ticket_data:
source_ticket_data[key] = new_ticket_data[key]
ticket.ticket_data = source_ticket_data ticket.ticket_data = source_ticket_data
ticket.save() ticket.save()

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2021-12-30 01:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wpm', '0040_alter_wproductflow_number'),
]
operations = [
migrations.AddField(
model_name='wproductflow',
name='change_str',
field=models.CharField(default='', max_length=1000, verbose_name='变动描述'),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.9 on 2021-12-30 08:31
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0042_alter_recordformfield_field_type'),
('wpm', '0041_wproductflow_change_str'),
]
operations = [
migrations.AddField(
model_name='wprouctticket',
name='resp_process',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.process', verbose_name='责任工序'),
),
]

View File

@ -120,6 +120,7 @@ class WprouctTicket(CommonAModel):
step = models.ForeignKey(Step, verbose_name='所在步骤/发现步骤', on_delete=models.CASCADE) step = models.ForeignKey(Step, verbose_name='所在步骤/发现步骤', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE)
resp_process = models.ForeignKey(Process, verbose_name='责任工序', on_delete=models.CASCADE, null=True, blank=True)
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket') ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket')
decision = models.PositiveSmallIntegerField('最终决定', choices=WProduct.ng_choices, null=True, blank=True) decision = models.PositiveSmallIntegerField('最终决定', choices=WProduct.ng_choices, null=True, blank=True)
@ -148,7 +149,9 @@ class WproductFlow(CommonAModel):
on_delete=models.SET_NULL, null=True, blank=True) on_delete=models.SET_NULL, null=True, blank=True)
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单', ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
on_delete=models.SET_NULL, null=True, blank=True) on_delete=models.SET_NULL, null=True, blank=True)
is_lastlog = models.BooleanField('是否该子计划下的最后一条日志', default=True) is_lastlog = models.BooleanField('是否该子计划下的最后一条日志', default=True)
change_str = models.CharField('变动描述', default='', max_length=1000)
class Pick(CommonADModel): class Pick(CommonADModel):

View File

@ -5,7 +5,7 @@ from apps.em.serializers import EquipmentSimpleSerializer
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse
from apps.inm.signals import update_inm from apps.inm.signals import update_inm
from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial
from apps.mtm.serializers import MaterialSimpleSerializer, RecordFormSimpleSerializer, StepSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, StepSimpleSerializer
from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.models import SubProductionPlan, SubProductionProgress
from django.utils import timezone from django.utils import timezone
@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy as _
from apps.pm.serializers import SubproductionPlanSimpleSerializer from apps.pm.serializers import SubproductionPlanSimpleSerializer
from apps.qm.models import TestRecord, TestRecordItem from apps.qm.models import TestRecord, TestRecordItem
from apps.system.serializers import UserSimpleSerializer from apps.system.serializers import UserSimpleSerializer
from apps.wpm.models import Operation, OperationEquip, OperationMaterial, OperationWproduct, Pick, WMaterial, WProduct, OperationRecord, OperationRecordItem from apps.wpm.models import Operation, OperationEquip, OperationMaterial, OperationWproduct, Pick, WMaterial, WProduct, OperationRecord, OperationRecordItem, WprouctTicket
from django.db import transaction from django.db import transaction
class PickHalfSerializer(serializers.Serializer): class PickHalfSerializer(serializers.Serializer):
@ -430,3 +430,14 @@ class OperationRecordDetailSerializer(serializers.ModelSerializer):
class ScrapSerializer(serializers.Serializer): class ScrapSerializer(serializers.Serializer):
scrap_reason = serializers.ChoiceField(choices=WProduct.scrap_reason_choices, required=False) scrap_reason = serializers.ChoiceField(choices=WProduct.scrap_reason_choices, required=False)
# wproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label='半成品ID列表') # wproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label='半成品ID列表')
class WproductTicketListSerializer(serializers.ModelSerializer):
material_ = MaterialSimpleSerializer(source='material', read_only=True)
step_ = StepSimpleSerializer(source='step', read_only=True)
subproduction_plan_ = SubproductionPlanSimpleSerializer(source='subproduction_plan', read_only=True)
resp_process_ = ProcessSimpleSerializer(source='resp_process', read_only=True)
class Meta:
model = WprouctTicket
fields = '__all__'

View File

@ -73,10 +73,6 @@ class WpmServies(object):
participant_type=State.PARTICIPANT_TYPE_PERSONAL, participant_type=State.PARTICIPANT_TYPE_PERSONAL,
intervene_type=0, intervene_type=0,
participant=user) participant=user)
# 更新子计划相关进度
cls.update_subproduction_progress_main(sp=wproduct.subproduction_plan)
else:# 如果不合格 else:# 如果不合格
wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK
# 需要走不合格品审理的工单 # 需要走不合格品审理的工单
@ -95,11 +91,15 @@ class WpmServies(object):
intervene_type=0, intervene_type=0,
participant=user) participant=user)
wproduct.update_by = user wproduct.update_by = user
wproduct.update_time = timezone.now() wproduct.update_time = timezone.now()
wproduct.test = None wproduct.test = None
wproduct.save() wproduct.save()
# 添加日志
cls.add_wproduct_flow_log(wproduct, 'test_ok' if is_testok else 'test_notok')
# 更新子计划相关进度
cls.update_subproduction_progress_main(sp=wproduct.subproduction_plan)
@classmethod @classmethod
def update_subproduction_progress_main(cls, sp:SubProductionPlan): def update_subproduction_progress_main(cls, sp:SubProductionPlan):
@ -131,3 +131,18 @@ class WpmServies(object):
if count_mtestok >= plan.count: if count_mtestok >= plan.count:
plan.state = ProductionPlan.PLAN_MTEST_DONE plan.state = ProductionPlan.PLAN_MTEST_DONE
plan.save() plan.save()
@classmethod
def add_wproduct_flow_log(cls, instance:WProduct, change_str:str=''):
"""
创建产品变动日志
"""
# update_fields = kwargs['update_fields']
WproductFlow.objects.filter(wproduct=instance, subproduction_plan=instance.subproduction_plan).update(is_lastlog=False)
ins = WproductFlow()
ins.wproduct = instance
for f in WproductFlow._meta.fields:
if f.name not in ['id', 'wproduct', 'is_lastlog']:
setattr(ins, f.name, getattr(instance, f.name, None))
ins.change_str = change_str
ins.save()

View File

@ -28,18 +28,14 @@ def handleTicket(sender, instance, created, **kwargs):
obj.subproduction_plan = wproduct.subproduction_plan obj.subproduction_plan = wproduct.subproduction_plan
obj.ticket = instance obj.ticket = instance
test_record = TestRecord.objects.filter(wproduct=wproduct, is_deleted=False, is_testok=False).order_by('-id').first() # test_record = TestRecord.objects.filter(wproduct=wproduct, is_deleted=False, is_testok=False).order_by('-id').first()
obj.save() obj.save()
# 工单绑定半成品 # 工单绑定半成品
wproduct.ticket = instance wproduct.ticket = instance
wproduct.save() wproduct.save()
WpmServies.add_wproduct_flow_log(wproduct, 'ticket_create')
# 检验员
if not ticket_data.get('tester', None):
ticket_data['tester'] = test_record.create_by.id
instance.ticket_data = ticket_data
instance.save()
elif instance.act_state == Ticket.TICKET_ACT_STATE_FINISH: elif instance.act_state == Ticket.TICKET_ACT_STATE_FINISH:
""" """
@ -57,6 +53,7 @@ def handleTicket(sender, instance, created, **kwargs):
wp.ng_sign = decision wp.ng_sign = decision
wt.decision = decision
if decision in [WProduct.NG_BACK_WORK, WProduct.NG_BACK_FIX]: if decision in [WProduct.NG_BACK_WORK, WProduct.NG_BACK_FIX]:
step = Step.objects.get(id=ticket_data['back_step']) step = Step.objects.get(id=ticket_data['back_step'])
wp.step = step wp.step = step
@ -69,9 +66,6 @@ def handleTicket(sender, instance, created, **kwargs):
wp.ticket = None # 解除当前工单 wp.ticket = None # 解除当前工单
wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT
wp.save() wp.save()
# 更新子计划合格进度
WpmServies.update_subproduction_progress_main(sp=sp)
else: else:
raise exceptions.APIException('返回步骤点错误') raise exceptions.APIException('返回步骤点错误')
@ -82,18 +76,8 @@ def handleTicket(sender, instance, created, **kwargs):
wp.ticket = None # 解除当前工单 wp.ticket = None # 解除当前工单
wp.save() wp.save()
# 添加日志
@receiver(post_save, sender=WProduct) WpmServies.add_wproduct_flow_log(wp, 'ticket_finish')
def update_wproduct_log(sender, instance, created, **kwargs): # 更新子计划合格进度
""" WpmServies.update_subproduction_progress_main(sp=wp.subproduction_plan)
创建产品变动日志
"""
# update_fields = kwargs['update_fields']
WproductFlow.objects.filter(wproduct=instance, subproduction_plan=instance.subproduction_plan).update(is_lastlog=False)
ins = WproductFlow()
ins.wproduct = instance
for f in WproductFlow._meta.fields:
if f.name not in ['id', 'create_time', 'update_time', 'wproduct', 'is_lastlog']:
setattr(ins, f.name, getattr(instance, f.name, None))
ins.save()

View File

@ -3,11 +3,12 @@ from rest_framework import urlpatterns
from django.urls import path, include from django.urls import path, include
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
from apps.wpm.views import DoFormInit, DoFormSubmit, OperationEquipViewSet, OperationMaterialInputViewSet, OperationMaterialOutputViewSet, OperationMaterialToolViewSet, OperationRecordViewSet, OperationViewSet, OperationWproductViewSet, WMaterialViewSet, WPlanViewSet, WProductViewSet from apps.wpm.views import DoFormInit, DoFormSubmit, OperationEquipViewSet, OperationMaterialInputViewSet, OperationMaterialOutputViewSet, OperationMaterialToolViewSet, OperationRecordViewSet, OperationViewSet, OperationWproductViewSet, WMaterialViewSet, WPlanViewSet, WProductViewSet, WproductTicketViewSet
router = DefaultRouter() router = DefaultRouter()
router.register('wmaterial', WMaterialViewSet, basename='wmaterial') router.register('wmaterial', WMaterialViewSet, basename='wmaterial')
router.register('wproduct', WProductViewSet, basename='wproduct') router.register('wproduct', WProductViewSet, basename='wproduct')
router.register('wproduct_ticket', WproductTicketViewSet, basename='wproduct_ticket')
router.register('operation', OperationViewSet, basename='operation') router.register('operation', OperationViewSet, basename='operation')
router.register('operation_wproduct', OperationWproductViewSet, basename='operation_wproduct') router.register('operation_wproduct', OperationWproductViewSet, basename='operation_wproduct')
router.register('operation_equip', OperationEquipViewSet, basename='operation_equip') router.register('operation_equip', OperationEquipViewSet, basename='operation_equip')

View File

@ -20,9 +20,9 @@ from rest_framework.decorators import action
from apps.wf.models import Workflow from apps.wf.models import Workflow
from apps.wf.serializers import WorkflowSimpleSerializer from apps.wf.serializers import WorkflowSimpleSerializer
from apps.wpm.filters import WMaterialFilterSet, WProductFilterSet from apps.wpm.filters import WMaterialFilterSet, WProductFilterSet
from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem, WprouctTicket
from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1ListSerailizer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2ListSerailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordDetailSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, ScrapSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestFormInitSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1ListSerailizer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2ListSerailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordDetailSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, ScrapSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestFormInitSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer, WproductTicketListSerializer
from rest_framework.response import Response from rest_framework.response import Response
from django.db import transaction from django.db import transaction
from rest_framework import exceptions, serializers from rest_framework import exceptions, serializers
@ -81,13 +81,23 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
wps.update(step=first_step, wps.update(step=first_step,
act_state=WProduct.WPR_ACT_STATE_TORETEST, is_hidden=False, warehouse=None, act_state=WProduct.WPR_ACT_STATE_TORETEST, is_hidden=False, warehouse=None,
subproduction_plan=sp, update_by=request.user, update_time=timezone.now()) subproduction_plan=sp, update_by=request.user, update_time=timezone.now())
for i in wps:
for m in i['wproducts']:
m.step = first_step
m.act_state = WProduct.WPR_ACT_STATE_TORETEST
m.is_hidden = False
m.warehouse = None
m.subproduction_plan = sp
m.update_by = request.user
m.update_time = timezone.now()
m.save()
WpmServies.add_wproduct_flow_log(instance=m, change_str='pick_half')
pw = PickWproduct() pw = PickWproduct()
pw.pick =pick pw.pick =pick
pw.wproduct = i pw.wproduct = m
pw.number = i.number pw.number = m.number
pw.material = i.material pw.material = m.material
pw.subproduction_plan = i.suproduction_plan pw.subproduction_plan = m.subproduction_plan
pw.save() pw.save()
sp.is_picked = True sp.is_picked = True
sp.save() sp.save()
@ -95,63 +105,63 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
return Response() return Response()
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WplanPutInSerializer) # @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WplanPutInSerializer)
@transaction.atomic # @transaction.atomic
def putin(self, request, pk=None): # def putin(self, request, pk=None):
""" # """
半成品入库 # 半成品入库
""" # """
serializer= WplanPutInSerializer(data=request.data) # serializer= WplanPutInSerializer(data=request.data)
serializer.is_valid(raise_exception=True) # serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data # vdata = serializer.validated_data
subplan = self.get_object() # subplan = self.get_object()
material = subplan.product # material = subplan.product
batch = subplan.number # batch = subplan.number
warehouse = vdata['warehouse'] # warehouse = vdata['warehouse']
wproducts = WProduct.objects.filter(subproduction_plan=subplan, # wproducts = WProduct.objects.filter(subproduction_plan=subplan,
act_state=WProduct.WPR_ACT_STATE_OK, material=material, is_deleted=False) # act_state=WProduct.WPR_ACT_STATE_OK, material=material, is_deleted=False)
if wproducts.exists(): # if wproducts.exists():
# 创建入库记录 # # 创建入库记录
remark = vdata.get('remark', '') # remark = vdata.get('remark', '')
fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_IN, # fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_IN,
is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark) # is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark)
# 创建入库明细 # # 创建入库明细
fifoitem = FIFOItem() # fifoitem = FIFOItem()
fifoitem.is_tested = True # fifoitem.is_tested = True
fifoitem.is_testok = True # fifoitem.is_testok = True
fifoitem.warehouse = warehouse # fifoitem.warehouse = warehouse
fifoitem.material = material # fifoitem.material = material
fifoitem.count = wproducts.count() # fifoitem.count = wproducts.count()
fifoitem.batch = batch # fifoitem.batch = batch
fifoitem.fifo = fifo # fifoitem.fifo = fifo
fifoitem.subproduction_plan = subplan # fifoitem.subproduction_plan = subplan
fifoitem.save() # fifoitem.save()
# 创建入库明细半成品 # # 创建入库明细半成品
ips = [] # ips = []
for i in wproducts: # for i in wproducts:
ip = {} # ip = {}
ip['fifoitem'] = fifoitem # ip['fifoitem'] = fifoitem
ip['wproduct'] = i # ip['wproduct'] = i
ip['number'] = i.number # ip['number'] = i.number
ip['material'] = material # ip['material'] = material
ips.append(FIFOItemProduct(**ip)) # ips.append(FIFOItemProduct(**ip))
FIFOItemProduct.objects.bulk_create(ips) # FIFOItemProduct.objects.bulk_create(ips)
# 创建IProduct # # 创建IProduct
ips2 = [] # ips2 = []
for i in wproducts: # for i in wproducts:
ip = {} # ip = {}
ip['warehouse'] = warehouse # ip['warehouse'] = warehouse
ip['batch'] = batch # ip['batch'] = batch
ip['wproduct'] = i # ip['wproduct'] = i
ip['number'] = i.number # ip['number'] = i.number
ip['material'] = material # ip['material'] = material
ips2.append(IProduct(**ip)) # ips2.append(IProduct(**ip))
IProduct.objects.bulk_create(ips2) # IProduct.objects.bulk_create(ips2)
# 更新库存并修改半成品进行状态 # # 更新库存并修改半成品进行状态
update_inm(fifo) # update_inm(fifo)
wproducts.update(act_sate=WProduct.WPR_ACT_STATE_INM, warehouse=warehouse, update_by=request.user, update_time=timezone.now()) # wproducts.update(act_sate=WProduct.WPR_ACT_STATE_INM, warehouse=warehouse, update_by=request.user, update_time=timezone.now())
return Response() # return Response()
class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet): class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
@ -232,10 +242,12 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOCOMBTEST: elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOCOMBTEST:
savedict['type'] = TestRecord.TEST_COMB savedict['type'] = TestRecord.TEST_COMB
tr = TestRecord.objects.create(**savedict) tr = TestRecord.objects.create(**savedict)
# 更新wproduct
wproduct.test = tr wproduct.test = tr
wproduct.update_by = request.user wproduct.update_by = request.user
wproduct.update_time = timezone.now() wproduct.update_time = timezone.now()
wproduct.save() wproduct.save()
WpmServies.add_wproduct_flow_log(wproduct, 'test_init')
# 创建检验条目 # 创建检验条目
for i in RecordFormField.objects.filter(form=form, is_deleted=False): for i in RecordFormField.objects.filter(form=form, is_deleted=False):
tri = TestRecordItem() tri = TestRecordItem()
@ -298,6 +310,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
i.update_by = request.user i.update_by = request.user
i.update_time = timezone.now() i.update_time = timezone.now()
i.save() i.save()
WpmServies.add_wproduct_flow_log(i, 'putins')
return Response() return Response()
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer)
@ -345,6 +358,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
wproduct.act_state=WProduct.WPR_ACT_STATE_INM wproduct.act_state=WProduct.WPR_ACT_STATE_INM
wproduct.warehouse=warehouse wproduct.warehouse=warehouse
wproduct.save() wproduct.save()
WpmServies.add_wproduct_flow_log(wproduct, 'putin')
return Response() return Response()
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=ScrapSerializer) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=ScrapSerializer)
@ -370,6 +384,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
obj.update_by = request.user obj.update_by = request.user
obj.update_time = timezone.now() obj.update_time = timezone.now()
obj.save() obj.save()
WpmServies.add_wproduct_flow_log(obj, 'scrap')
return Response() return Response()
# @action(methods=['get'], detail=False, perms_map={'get':'*'}) # @action(methods=['get'], detail=False, perms_map={'get':'*'})
@ -391,6 +406,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
raise exceptions.APIException('该产品不可发起不合格审理') raise exceptions.APIException('该产品不可发起不合格审理')
workflow = Workflow.objects.filter(name='不合格品审理单', is_deleted=False).first() workflow = Workflow.objects.filter(name='不合格品审理单', is_deleted=False).first()
if workflow: if workflow:
test_record = TestRecord.objects.filter(wproduct=obj, is_deleted=False, is_testok=False).order_by('-id').first()
exist_data = { exist_data = {
'wproduct':obj.id, 'wproduct':obj.id,
'wproduct_number':obj.number, 'wproduct_number':obj.number,
@ -398,6 +414,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
'wproduct_specification':obj.material.specification, 'wproduct_specification':obj.material.specification,
'finder':request.user.id, 'finder':request.user.id,
'find_process':obj.step.process.id, 'find_process':obj.step.process.id,
'tester':test_record.create_by.id
} }
ret = {'workflow':workflow.id} ret = {'workflow':workflow.id}
ret['exist_data'] = exist_data ret['exist_data'] = exist_data
@ -407,8 +424,16 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
class WproductTicketViewSet(ListModelMixin, GenericViewSet):
"""
玻璃审批工单
"""
perms_map={'*':'*'}
queryset = WprouctTicket.objects.select_related('step', 'material', 'subproduction_plan', 'resp_process')
serializer_class = WproductTicketListSerializer
filterset_fields = ['step', 'material', 'subproduction_plan', 'resp_process']
ordering_fields = ['id']
ordering = ['-id']
class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet): class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet):
@ -445,7 +470,11 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
if instance.is_submited: if instance.is_submited:
raise exceptions.APIException('该操作已提交') raise exceptions.APIException('该操作已提交')
# 恢复半成品可操作 # 恢复半成品可操作
instance.wp_operation.all().update(act_state=WProduct.WPR_ACT_STATE_DOWAIT) for i in instance.wp_operation.all():
i.act_state = WProduct.WPR_ACT_STATE_DOWAIT
i.update_by = request.user
i.save()
WpmServies.add_wproduct_flow_log(i, 'operation_delete')
self.perform_destroy(instance) self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
@ -465,9 +494,13 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
# 创建操作所用半成品关联记录 # 创建操作所用半成品关联记录
if 'wproducts' in vdata: if 'wproducts' in vdata:
owps = [] owps = []
WProduct.objects.filter(pk__in=[x.id for x in vdata['wproducts']]).update(operation=op, act_state=WProduct.WPR_ACT_STATE_DOING)
splans = WpmServies.get_subplans_queryset_from_wproducts(vdata['wproducts']) splans = WpmServies.get_subplans_queryset_from_wproducts(vdata['wproducts'])
for wpd in vdata['wproducts']: for wpd in vdata['wproducts']:
wpd.operation= op
wpd.act_state = WProduct.WPR_ACT_STATE_DOING
wpd.update_by = request.user
wpd.save()
WpmServies.add_wproduct_flow_log(wpd, 'operation_create')
owp = {} owp = {}
owp['operation'] = op owp['operation'] = op
owp['wproduct'] = wpd owp['wproduct'] = wpd
@ -565,6 +598,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
wp.operation = None wp.operation = None
wp.update_by = request.user wp.update_by = request.user
wp.save() wp.save()
WpmServies.add_wproduct_flow_log(wp, 'operation_submit')
elif step.type == Step.STEP_TYPE_DIV: elif step.type == Step.STEP_TYPE_DIV:
# 更新物料产出情况 # 更新物料产出情况
for i in OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT): for i in OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT):
@ -572,9 +606,12 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
newstep, _ = WpmServies.get_next_step(i.subproduction_plan, step) newstep, _ = WpmServies.get_next_step(i.subproduction_plan, step)
wpr = dict(material=i.material, step=newstep, wpr = dict(material=i.material, step=newstep,
act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='', act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='',
subproduction_plan=i.subproduction_plan) subproduction_plan=i.subproduction_plan, create_by=request.user)
for x in range(i.count): for x in range(i.count):
WProduct.objects.create(**wpr) ins = WProduct.objects.create(**wpr)
# 添加日志
WpmServies.add_wproduct_flow_log(ins, 'operation_submit')
# 更新进度
WpmServies.update_subproduction_progress_main(sp=i.subproduction_plan) WpmServies.update_subproduction_progress_main(sp=i.subproduction_plan)
elif step.type == Step.STEP_TYPE_COMB: elif step.type == Step.STEP_TYPE_COMB:
oms_w = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT, oms_w = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT,
@ -595,6 +632,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
WpmServies.update_subproduction_progress_main(sp=oms_w.subproduction_plan) WpmServies.update_subproduction_progress_main(sp=oms_w.subproduction_plan)
wproduct.create_by = request.user wproduct.create_by = request.user
wproduct.save() wproduct.save()
WpmServies.add_wproduct_flow_log(wproduct, 'operation_submit')
# 隐藏原半成品 # 隐藏原半成品
wps = WProduct.objects.filter(ow_wproduct__operation = op) wps = WProduct.objects.filter(ow_wproduct__operation = op)
wps.update(is_hidden=True, child=wproduct, update_by=request.user, update_time=timezone.now()) wps.update(is_hidden=True, child=wproduct, update_by=request.user, update_time=timezone.now())