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

This commit is contained in:
shilixia 2021-12-31 13:19:27 +08:00
commit ba2b0ad4a6
6 changed files with 158 additions and 10 deletions

View File

@ -0,0 +1,57 @@
# Generated by Django 3.2.9 on 2021-12-31 03:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0042_alter_recordformfield_field_type'),
('wpm', '0042_wprouctticket_resp_process'),
]
operations = [
migrations.AddField(
model_name='operationmaterial',
name='count_cut',
field=models.PositiveIntegerField(default=0, verbose_name='切裁片数'),
),
migrations.AddField(
model_name='operationmaterial',
name='count_hua',
field=models.PositiveIntegerField(default=0, verbose_name='划伤甩片'),
),
migrations.AddField(
model_name='operationmaterial',
name='count_ok',
field=models.PositiveIntegerField(default=0, verbose_name='成品数量'),
),
migrations.AddField(
model_name='operationmaterial',
name='count_other',
field=models.PositiveIntegerField(default=0, verbose_name='其他甩片'),
),
migrations.AddField(
model_name='operationmaterial',
name='count_podian',
field=models.PositiveIntegerField(default=0, verbose_name='破点甩片'),
),
migrations.AddField(
model_name='operationmaterial',
name='count_qipao',
field=models.PositiveIntegerField(default=0, verbose_name='气泡甩片'),
),
migrations.AddField(
model_name='operationmaterial',
name='count_real',
field=models.PositiveIntegerField(default=0, verbose_name='生产片数'),
),
migrations.AlterUniqueTogether(
name='operationmaterial',
unique_together={('operation', 'material', 'batch')},
),
migrations.AlterUniqueTogether(
name='operationwproduct',
unique_together={('operation', 'wproduct')},
),
]

View File

@ -197,6 +197,10 @@ class OperationWproduct(BaseModel):
material = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='ow_subplan')
class Meta:
unique_together = (
('operation','wproduct')
)
class OperationMaterial(BaseModel):
"""
@ -214,6 +218,19 @@ class OperationMaterial(BaseModel):
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联的子计划', on_delete=models.CASCADE, null=True, blank=True)
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
#以下为冷加工下料清单所用字段
count_cut = models.PositiveIntegerField('切裁片数', default=0)
count_real = models.PositiveIntegerField('生产片数', default=0)
count_ok = models.PositiveIntegerField('成品数量', default=0)
count_qipao = models.PositiveIntegerField('气泡甩片', default=0)
count_podian = models.PositiveIntegerField('破点甩片', default=0)
count_hua = models.PositiveIntegerField('划伤甩片', default=0)
count_other = models.PositiveIntegerField('其他甩片', default=0)
class Meta:
unique_together = (
('operation','material', 'batch')
)
class OperationRecord(BaseModel):
"""
记录表格

View File

@ -12,6 +12,8 @@ from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from apps.pm.serializers import SubproductionPlanSimpleSerializer
from apps.qm.models import TestRecord, TestRecordItem
from apps.sam.serializers import OrderSimpleSerializer
from apps.system.models import User
from apps.system.serializers import UserSimpleSerializer
from apps.wpm.models import Operation, OperationEquip, OperationMaterial, OperationWproduct, Pick, WMaterial, WProduct, OperationRecord, OperationRecordItem, WprouctTicket
from django.db import transaction
@ -437,7 +439,17 @@ class WproductTicketListSerializer(serializers.ModelSerializer):
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)
order_ = OrderSimpleSerializer(source='subproduction_plan.production_plan.order', read_only=True)
product_ = MaterialSimpleSerializer(source='subproduction_plan.production_plan.product', read_only=True)
class Meta:
model = WprouctTicket
fields = '__all__'
class CuttingListSerializer(serializers.ModelSerializer):
subproduction_plan_ = SubproductionPlanSimpleSerializer(source='subproduction_plan', read_only=True)
material_ = MaterialSimpleSerializer(source='material', read_only=True)
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
class Meta:
model = OperationMaterial
fields = '__all__'

View File

@ -7,7 +7,7 @@ from apps.mtm.models import Material, Step, SubprodctionMaterial
from apps.qm.models import TestRecord
from apps.system.models import User
from apps.wf.models import State, TicketFlow, Transition
from apps.wpm.models import WProduct, WproductFlow, WprouctTicket
from apps.wpm.models import Operation, OperationMaterial, WProduct, WproductFlow, WprouctTicket
from utils.tools import ranstr
class WpmServies(object):
@ -146,3 +146,38 @@ class WpmServies(object):
setattr(ins, f.name, getattr(instance, f.name, None))
ins.change_str = change_str
ins.save()
@classmethod
def update_cutting_list_with_operation(cls, op:Operation):
"""
根据车间操作更新下料清单
"""
inputs = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_IN)
outputs = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
for i in inputs:
sp = i.subproduction_plan
i.count_cut = outputs.filter(subproduction_plan=sp).first().count
i.count_real = sp.count_real
i.count_ok = sp.count_ok
wpfs = WproductFlow.objects.filter(subproduction_plan=sp, is_lastlog=True)
i.count_qipao = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_QIPAO).count()
i.count_podian = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_PODIAN).count()
i.count_hua = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_HUA).count()
i.count_other = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_OTHER).count()
i.is_cutting = True
i.save()
@classmethod
def update_cutting_list_with_sp(cls, sp:SubProductionPlan):
"""
根据子计划更新下料清单
"""
wpfs = WproductFlow.objects.filter(subproduction_plan=sp, is_lastlog=True)
for i in OperationMaterial.objects.filter(subproduction_plan=sp, is_cutting=True):
i.count_real = sp.count_real
i.count_ok = sp.count_ok
i.count_qipao = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_QIPAO).count()
i.count_podian = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_PODIAN).count()
i.count_hua = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_HUA).count()
i.count_other = wpfs.filter(scrap_reason=WProduct.SCRAP_REASON_OTHER).count()
i.save()

View File

@ -3,7 +3,7 @@ from rest_framework import urlpatterns
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from apps.wpm.views import DoFormInit, DoFormSubmit, OperationEquipViewSet, OperationMaterialInputViewSet, OperationMaterialOutputViewSet, OperationMaterialToolViewSet, OperationRecordViewSet, OperationViewSet, OperationWproductViewSet, WMaterialViewSet, WPlanViewSet, WProductViewSet, WproductTicketViewSet
from apps.wpm.views import CuttingListViewSet, DoFormInit, DoFormSubmit, OperationEquipViewSet, OperationMaterialInputViewSet, OperationMaterialOutputViewSet, OperationMaterialToolViewSet, OperationRecordViewSet, OperationViewSet, OperationWproductViewSet, WMaterialViewSet, WPlanViewSet, WProductViewSet, WproductTicketViewSet
router = DefaultRouter()
router.register('wmaterial', WMaterialViewSet, basename='wmaterial')
@ -17,6 +17,7 @@ router.register('operation_input', OperationMaterialInputViewSet, basename='oper
router.register('operation_output', OperationMaterialOutputViewSet, basename='operation_output')
router.register('operation_tool', OperationMaterialToolViewSet, basename='operation_tool')
router.register('subplan', WPlanViewSet, basename='wplan')
router.register('cutting_list', CuttingListViewSet, basename='cutting_list')
urlpatterns = [
path('do/init/', DoFormInit.as_view()),
path('do/submit/', DoFormSubmit.as_view()),

View File

@ -22,7 +22,7 @@ from apps.wf.serializers import WorkflowSimpleSerializer
from apps.wpm.filters import WMaterialFilterSet, WProductFilterSet
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, WproductTicketListSerializer
from apps.wpm.serializers import CuttingListSerializer, 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 django.db import transaction
from rest_framework import exceptions, serializers
@ -385,6 +385,8 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
obj.update_time = timezone.now()
obj.save()
WpmServies.add_wproduct_flow_log(obj, 'scrap')
if obj.step.process.id == 1: #如果是冷加工
WpmServies.update_cutting_list_with_sp(obj.subproduction_plan)
return Response()
# @action(methods=['get'], detail=False, perms_map={'get':'*'})
@ -429,7 +431,8 @@ class WproductTicketViewSet(ListModelMixin, GenericViewSet):
玻璃审批工单
"""
perms_map={'*':'*'}
queryset = WprouctTicket.objects.select_related('step', 'material', 'subproduction_plan', 'resp_process')
queryset = WprouctTicket.objects.select_related('step', 'material', 'subproduction_plan',
'resp_process', 'subproduction_plan__production_plan__order', 'subproduction_plan__production_plan')
serializer_class = WproductTicketListSerializer
filterset_fields = ['step', 'material', 'subproduction_plan', 'resp_process']
ordering_fields = ['id']
@ -579,9 +582,11 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
spp.save()
# 更新动态产品表
if step.type == Step.STEP_TYPE_NOM:
for i in OperationWproduct.objects.filter(operation=op):
ows = OperationWproduct.objects.filter(operation=op)
for i in ows:
wp = i.wproduct
wsp = i.subproduction_plan
# 获取下一步子工序
newstep, hasNext = WpmServies.get_next_step(wsp, step)
wp.step = newstep
@ -591,17 +596,21 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
else:
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
wp.material = wsp.product
# 更新子计划生产进度
# 如果产品有返工标记不做计算
if wp.ng_sign not in [WProduct.NG_BACK_FIX, WProduct.NG_BACK_WORK]:
WpmServies.update_subproduction_progress_main(sp=wsp)
wp.operation = None
wp.update_by = request.user
wp.save()
WpmServies.add_wproduct_flow_log(wp, 'operation_submit')
for i in ows.values('subproduction_plan').distinct():
# 更新进度
WpmServies.update_subproduction_progress_main(sp=wsp)
elif step.type == Step.STEP_TYPE_DIV:
# 更新物料产出情况
for i in OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT):
outputs = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
if not outputs.exists():
raise exceptions.APIException('请选择物料产出')
for i in outputs:
if i.subproduction_progress.is_main:
newstep, _ = WpmServies.get_next_step(i.subproduction_plan, step)
wpr = dict(material=i.material, step=newstep,
@ -640,6 +649,10 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
raise exceptions.APIException('产出物料未填写或填写错误')
op.is_submited = True
op.save()
# 如果是冷加工
if step.process.id==1:
WpmServies.update_cutting_list_with_operation(op=op)
return Response()
@ -774,6 +787,19 @@ class OperationMaterialInputViewSet(ListModelMixin, CreateModelMixin, DestroyMod
instance.delete()
return Response()
class CuttingListViewSet(ListModelMixin, GenericViewSet):
"""
下料清单
"""
perms_map={'*':'*'}
queryset = OperationMaterial.objects.select_related('operation',
'subproduction_plan', 'material', 'create_by').filter(operation__step__process__id=1)
serializer_class = CuttingListSerializer
filterset_fields = ['operation', 'subproduction_plan', 'material']
ordering_fields = ['id']
ordering = ['-id']
class OperationMaterialOutputViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
"""
产出物料