Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
ba2b0ad4a6
|
@ -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')},
|
||||||
|
),
|
||||||
|
]
|
|
@ -197,6 +197,10 @@ class OperationWproduct(BaseModel):
|
||||||
material = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE)
|
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')
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='ow_subplan')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = (
|
||||||
|
('operation','wproduct')
|
||||||
|
)
|
||||||
|
|
||||||
class OperationMaterial(BaseModel):
|
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)
|
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)
|
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):
|
class OperationRecord(BaseModel):
|
||||||
"""
|
"""
|
||||||
记录表格
|
记录表格
|
||||||
|
|
|
@ -12,6 +12,8 @@ from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
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.sam.serializers import OrderSimpleSerializer
|
||||||
|
from apps.system.models import User
|
||||||
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, WprouctTicket
|
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
|
||||||
|
@ -437,7 +439,17 @@ class WproductTicketListSerializer(serializers.ModelSerializer):
|
||||||
step_ = StepSimpleSerializer(source='step', read_only=True)
|
step_ = StepSimpleSerializer(source='step', read_only=True)
|
||||||
subproduction_plan_ = SubproductionPlanSimpleSerializer(source='subproduction_plan', read_only=True)
|
subproduction_plan_ = SubproductionPlanSimpleSerializer(source='subproduction_plan', read_only=True)
|
||||||
resp_process_ = ProcessSimpleSerializer(source='resp_process', 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:
|
class Meta:
|
||||||
model = WprouctTicket
|
model = WprouctTicket
|
||||||
fields = '__all__'
|
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__'
|
|
@ -7,7 +7,7 @@ from apps.mtm.models import Material, Step, SubprodctionMaterial
|
||||||
from apps.qm.models import TestRecord
|
from apps.qm.models import TestRecord
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
from apps.wf.models import State, TicketFlow, Transition
|
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
|
from utils.tools import ranstr
|
||||||
class WpmServies(object):
|
class WpmServies(object):
|
||||||
|
|
||||||
|
@ -146,3 +146,38 @@ class WpmServies(object):
|
||||||
setattr(ins, f.name, getattr(instance, f.name, None))
|
setattr(ins, f.name, getattr(instance, f.name, None))
|
||||||
ins.change_str = change_str
|
ins.change_str = change_str
|
||||||
ins.save()
|
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()
|
|
@ -3,7 +3,7 @@ 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, WproductTicketViewSet
|
from apps.wpm.views import CuttingListViewSet, 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')
|
||||||
|
@ -17,6 +17,7 @@ router.register('operation_input', OperationMaterialInputViewSet, basename='oper
|
||||||
router.register('operation_output', OperationMaterialOutputViewSet, basename='operation_output')
|
router.register('operation_output', OperationMaterialOutputViewSet, basename='operation_output')
|
||||||
router.register('operation_tool', OperationMaterialToolViewSet, basename='operation_tool')
|
router.register('operation_tool', OperationMaterialToolViewSet, basename='operation_tool')
|
||||||
router.register('subplan', WPlanViewSet, basename='wplan')
|
router.register('subplan', WPlanViewSet, basename='wplan')
|
||||||
|
router.register('cutting_list', CuttingListViewSet, basename='cutting_list')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('do/init/', DoFormInit.as_view()),
|
path('do/init/', DoFormInit.as_view()),
|
||||||
path('do/submit/', DoFormSubmit.as_view()),
|
path('do/submit/', DoFormSubmit.as_view()),
|
||||||
|
|
|
@ -22,7 +22,7 @@ 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, WprouctTicket
|
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 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
|
||||||
|
@ -385,6 +385,8 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
obj.update_time = timezone.now()
|
obj.update_time = timezone.now()
|
||||||
obj.save()
|
obj.save()
|
||||||
WpmServies.add_wproduct_flow_log(obj, 'scrap')
|
WpmServies.add_wproduct_flow_log(obj, 'scrap')
|
||||||
|
if obj.step.process.id == 1: #如果是冷加工
|
||||||
|
WpmServies.update_cutting_list_with_sp(obj.subproduction_plan)
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
# @action(methods=['get'], detail=False, perms_map={'get':'*'})
|
# @action(methods=['get'], detail=False, perms_map={'get':'*'})
|
||||||
|
@ -429,7 +431,8 @@ class WproductTicketViewSet(ListModelMixin, GenericViewSet):
|
||||||
玻璃审批工单
|
玻璃审批工单
|
||||||
"""
|
"""
|
||||||
perms_map={'*':'*'}
|
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
|
serializer_class = WproductTicketListSerializer
|
||||||
filterset_fields = ['step', 'material', 'subproduction_plan', 'resp_process']
|
filterset_fields = ['step', 'material', 'subproduction_plan', 'resp_process']
|
||||||
ordering_fields = ['id']
|
ordering_fields = ['id']
|
||||||
|
@ -579,9 +582,11 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
spp.save()
|
spp.save()
|
||||||
# 更新动态产品表
|
# 更新动态产品表
|
||||||
if step.type == Step.STEP_TYPE_NOM:
|
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
|
wp = i.wproduct
|
||||||
wsp = i.subproduction_plan
|
wsp = i.subproduction_plan
|
||||||
|
|
||||||
# 获取下一步子工序
|
# 获取下一步子工序
|
||||||
newstep, hasNext = WpmServies.get_next_step(wsp, step)
|
newstep, hasNext = WpmServies.get_next_step(wsp, step)
|
||||||
wp.step = newstep
|
wp.step = newstep
|
||||||
|
@ -591,17 +596,21 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
else:
|
else:
|
||||||
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
||||||
wp.material = wsp.product
|
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.operation = None
|
||||||
wp.update_by = request.user
|
wp.update_by = request.user
|
||||||
wp.save()
|
wp.save()
|
||||||
WpmServies.add_wproduct_flow_log(wp, 'operation_submit')
|
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:
|
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:
|
if i.subproduction_progress.is_main:
|
||||||
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,
|
||||||
|
@ -640,6 +649,10 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
raise exceptions.APIException('产出物料未填写或填写错误')
|
raise exceptions.APIException('产出物料未填写或填写错误')
|
||||||
op.is_submited = True
|
op.is_submited = True
|
||||||
op.save()
|
op.save()
|
||||||
|
|
||||||
|
# 如果是冷加工
|
||||||
|
if step.process.id==1:
|
||||||
|
WpmServies.update_cutting_list_with_operation(op=op)
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
|
@ -774,6 +787,19 @@ class OperationMaterialInputViewSet(ListModelMixin, CreateModelMixin, DestroyMod
|
||||||
instance.delete()
|
instance.delete()
|
||||||
return Response()
|
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):
|
class OperationMaterialOutputViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
产出物料
|
产出物料
|
||||||
|
|
Loading…
Reference in New Issue