diff --git a/hb_client/src/api/pum.js b/hb_client/src/api/pum.js
new file mode 100644
index 0000000..2a807b4
--- /dev/null
+++ b/hb_client/src/api/pum.js
@@ -0,0 +1,61 @@
+import request from '@/utils/request'
+
+export function getPuorderList(query) {
+ return request({
+ url: '/pum/pu_order/',
+ method: 'get',
+ params: query
+ })
+}
+export function createPuorder(data) {
+ return request({
+ url: '/pum/pu_order/',
+ method: 'post',
+ data
+ })
+}
+export function updatePuorder(id, data) {
+ return request({
+ url: `/pum/pu_order/${id}/`,
+ method: 'put',
+ data
+ })
+}
+export function deletePuorder(id, data) {
+ return request({
+ url: `/pum/pu_order/${id}/`,
+ method: 'delete',
+ data
+ })
+}
+//采购订单审核
+export function createPuorderAudit(id,data) {
+ return request({
+ url: `/pum/pu_order/${id}/audit/`,
+ method: 'post',
+ data
+ })
+}
+//采购订单条目
+export function getPuorderItemList(query) {
+ return request({
+ url: '/pum/pu_order_item/',
+ method: 'get',
+ params: query
+ })
+}
+export function createPuorderItem(data) {
+ return request({
+ url: '/pum/pu_order_item/',
+ method: 'post',
+ data
+ })
+}
+//采购订单条目删除
+export function deletePuorderItem(id, data) {
+ return request({
+ url: `/pum/pu_order_item/${id}/`,
+ method: 'delete',
+ data
+ })
+}
\ No newline at end of file
diff --git a/hb_client/src/router/index.js b/hb_client/src/router/index.js
index 0efd28e..fe7eead 100644
--- a/hb_client/src/router/index.js
+++ b/hb_client/src/router/index.js
@@ -501,10 +501,17 @@ export const asyncRoutes = [
meta: { title: '供应商', icon: 'example', perms: ['vendor_manage'] }
},
{
- path: 'vendor',
- name: 'vendor',
- component: () => import('@/views/procurement/vendor'),
+ path: 'puorder',
+ name: 'puorder',
+ component: () => import('@/views/procurement/puorder'),
meta: { title: '采购订单', icon: 'example', perms: ['vendor_manage'] }
+ },
+ {
+ path: 'puorderitem/:id',
+ name: 'puorderitem',
+ component: () => import('@/views/procurement/puorderitem'),
+ meta: { title: '采购订单项', perms: ['vendor_manage'] },
+ hidden: true
}
]
},
diff --git a/hb_client/src/views/procurement/puorder.vue b/hb_client/src/views/procurement/puorder.vue
new file mode 100644
index 0000000..6a28a35
--- /dev/null
+++ b/hb_client/src/views/procurement/puorder.vue
@@ -0,0 +1,292 @@
+
+
+
+
+ 新增采购订单
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+ {{ scope.row.number }}
+
+
+ {{
+ scope.row.vendor_.name
+ }}
+
+
+
+ 未审核
+ 已审核
+
+
+
+
+
+ 订单项
+ 审核
+ 编辑
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确认
+
+
+
+
+
diff --git a/hb_client/src/views/procurement/puorderitem.vue b/hb_client/src/views/procurement/puorderitem.vue
new file mode 100644
index 0000000..3a8b9d3
--- /dev/null
+++ b/hb_client/src/views/procurement/puorderitem.vue
@@ -0,0 +1,197 @@
+
+
+
+
+ 新增采购订单项
+
+
+
+
+
+
+ {{ scope.row.material_.name }}
+
+
+ {{ scope.row.material_.specification }}
+
+
+
+ {{ scope.row.count }}
+
+
+ {{ scope.row.delivered_count }}
+
+
+ {{ scope.row.delivery_date }}
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 确认
+
+
+
+
+
diff --git a/hb_client/src/views/procurement/vendor.vue b/hb_client/src/views/procurement/vendor.vue
index bf1a781..a40edb0 100644
--- a/hb_client/src/views/procurement/vendor.vue
+++ b/hb_client/src/views/procurement/vendor.vue
@@ -75,6 +75,7 @@
编辑
diff --git a/hb_server/apps/develop/views.py b/hb_server/apps/develop/views.py
index 1e84384..2412742 100644
--- a/hb_server/apps/develop/views.py
+++ b/hb_server/apps/develop/views.py
@@ -10,7 +10,7 @@ from apps.pm.models import ProductionPlan, SubProductionPlan
from apps.sam.models import Order
from apps.wf.models import Ticket
from apps.wpm.models import Operation, OperationMaterial, WProduct, WproductFlow
-from apps.wpm.services import WpmServies
+from apps.wpm.services import WpmService
from apps.em.tasks import update_equip_state_by_next_check_date
# Create your views here.
@@ -46,7 +46,7 @@ class UpdateCuttingView(APIView):
i.coperation = op
i.save()
WproductFlow.objects.filter(wproduct=i).update(coperation=op)
- WpmServies.update_cutting_list_with_operation(op)
+ WpmService.update_cutting_list_with_operation(op)
return Response()
from apps.qm.models import TestRecord
@@ -90,7 +90,7 @@ class UpdateSpg(APIView):
冷加工重新计算合格率
"""
for i in SubProductionPlan.objects.filter(subproduction__process__id=1):
- WpmServies.update_subproduction_progress_main(sp=i)
+ WpmService.update_subproduction_progress_main(sp=i)
return Response()
diff --git a/hb_server/apps/inm/models.py b/hb_server/apps/inm/models.py
index 90d80c7..64b4108 100644
--- a/hb_server/apps/inm/models.py
+++ b/hb_server/apps/inm/models.py
@@ -67,11 +67,13 @@ class FIFO(CommonADModel):
FIFO_TYPE_SALE_OUT = 2
FIFO_TYPE_PUR_IN = 3
FIFO_TYPE_DO_IN = 4
+ FIFO_TYPE_OTHER_IN = 5
type_choices = (
(FIFO_TYPE_DO_OUT, '生产领料'),
(FIFO_TYPE_SALE_OUT, '销售提货'),
(FIFO_TYPE_PUR_IN, '采购入库'),
- (FIFO_TYPE_DO_IN, '生产入库')
+ (FIFO_TYPE_DO_IN, '生产入库'),
+ (FIFO_TYPE_OTHER_IN, '其他入库')
)
number = models.CharField('记录编号', max_length=100)
type = models.IntegerField('出入库类型', default=1)
diff --git a/hb_server/apps/inm/serializers.py b/hb_server/apps/inm/serializers.py
index b1e842a..44aeb52 100644
--- a/hb_server/apps/inm/serializers.py
+++ b/hb_server/apps/inm/serializers.py
@@ -80,7 +80,7 @@ class FIFOItemCreateSerializer(serializers.ModelSerializer):
class Meta:
model = FIFOItem
fields = ['warehouse',
- 'material', 'batch', 'fifo', 'files', 'pu_order_item']
+ 'material', 'batch', 'fifo', 'files', 'pu_order_item', 'count']
def create(self, validated_data):
fifo = validated_data['fifo']
@@ -97,7 +97,7 @@ class FIFOItemCreateSerializer(serializers.ModelSerializer):
class FIFOItemUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = FIFOItem
- fields = ['warehouse', 'batch', 'files']
+ fields = ['warehouse', 'batch', 'files', 'count']
class FIFOItemSerializer(serializers.ModelSerializer):
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
diff --git a/hb_server/apps/inm/views.py b/hb_server/apps/inm/views.py
index 7a4e069..a7ba143 100644
--- a/hb_server/apps/inm/views.py
+++ b/hb_server/apps/inm/views.py
@@ -25,7 +25,8 @@ class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
"""
仓库-增删改查
"""
- perms_map = {'*': '*'}
+ perms_map = {'get': '*', 'post':'warehouse_create',
+ 'put':'warehouse_update', 'delete':'warehouse_delete'}
queryset = WareHouse.objects.select_related('create_by').all()
serializer_class = WareHouseSerializer
search_fields = ['name', 'number', 'place']
@@ -43,7 +44,7 @@ class InventoryViewSet(ListModelMixin, GenericViewSet):
"""
仓库物料表
"""
- perms_map = {'*': '*'}
+ perms_map = {'get': '*'}
queryset = Inventory.objects.select_related(
'material', 'warehouse').filter(count__gt=0).all()
serializer_class = InventorySerializer
@@ -54,7 +55,7 @@ class InventoryViewSet(ListModelMixin, GenericViewSet):
class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
- perms_map = {'*': '*'}
+ perms_map = {'get': '*'}
queryset = MaterialBatch.objects.select_related(
'material', 'warehouse').filter(count__gt=0).all()
serializer_class = MaterialBatchSerializer
@@ -81,7 +82,8 @@ class FIFOItemViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, Updat
"""
出入库记录详情表
"""
- perms_map = {'*': '*'}
+ perms_map = {'get': '*', 'post':'fifoitem_create',
+ 'put':'fifoitem_update', 'delete':'fifoitem_delete'}
queryset = FIFOItem.objects.select_related('material', 'fifo').prefetch_related('files').all()
serializer_class = FIFOItemSerializer
filterset_fields = ['material', 'fifo',
@@ -115,7 +117,7 @@ class FIFOItemViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, Updat
raise ValidationError('该出入库记录已审核')
return super().destroy(request, *args, **kwargs)
- @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=InmTestRecordCreateSerializer)
+ @action(methods=['post'], detail=False, perms_map={'post': 'fifoitem_test'}, serializer_class=InmTestRecordCreateSerializer)
def test(self, request, pk=None):
"""
检验
@@ -147,7 +149,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
"""
出入库记录
"""
- perms_map = {'*': '*'}
+ perms_map = {'get': '*', 'delete':'fifo_delete'}
queryset = FIFO.objects.select_related('auditor', 'create_by')
serializer_class = FIFOListSerializer
filterset_fields = '__all__'
@@ -166,7 +168,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
raise exceptions.APIException('该记录已审核,不可删除')
return super().destroy(request, *args, **kwargs)
- @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=FIFOInPurSerializer)
+ @action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_pur'}, serializer_class=FIFOInPurSerializer)
def in_pur(self, request, pk=None):
"""
采购入库
@@ -176,7 +178,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
serializer.save(create_by=request.user)
return Response()
- @action(methods=['post'], detail=False, perms_map={'post': '*'},
+ @action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_other'},
serializer_class=FIFOInOtherSerializer)
def in_other(self, request, pk=None):
"""
@@ -187,7 +189,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
serializer.save(create_by=request.user)
return Response()
- @action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=serializers.Serializer)
+ @action(methods=['post'], detail=True, perms_map={'post': 'fifo_audit'}, serializer_class=serializers.Serializer)
def audit(self, request, pk=None):
"""
审核通过
@@ -213,7 +215,7 @@ class IProductViewSet(ListModelMixin, GenericViewSet):
"""
半成品库存表
"""
- perms_map = {'*': '*'}
+ perms_map = {'get': '*'}
queryset = IProduct.objects.select_related(
'material', 'warehouse',
'wproduct__subproduction_plan__production_plan__order',
diff --git a/hb_server/apps/monitor/views.py b/hb_server/apps/monitor/views.py
index ffd85fe..b383f4d 100644
--- a/hb_server/apps/monitor/views.py
+++ b/hb_server/apps/monitor/views.py
@@ -45,7 +45,7 @@ def get_file_list(file_path):
return dir_list
class LogView(APIView):
-
+ permission_classes = [IsAuthenticated]
@swagger_auto_schema(manual_parameters=[
openapi.Parameter('name', openapi.IN_QUERY, description='日志文件名', type=openapi.TYPE_STRING)
])
@@ -82,7 +82,7 @@ class LogView(APIView):
class LogDetailView(APIView):
-
+ permission_classes = [IsAuthenticated]
def get(self, request, name):
"""
查看日志详情
diff --git a/hb_server/apps/mtm/migrations/0045_usedstep_need_test.py b/hb_server/apps/mtm/migrations/0045_usedstep_need_test.py
new file mode 100644
index 0000000..11b7fff
--- /dev/null
+++ b/hb_server/apps/mtm/migrations/0045_usedstep_need_test.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.9 on 2022-01-29 07:12
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('mtm', '0044_subproduction_need_combtest'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='usedstep',
+ name='need_test',
+ field=models.BooleanField(default=False, verbose_name='工序内检验'),
+ ),
+ ]
diff --git a/hb_server/apps/mtm/models.py b/hb_server/apps/mtm/models.py
index 4afb8b5..f8ccc83 100644
--- a/hb_server/apps/mtm/models.py
+++ b/hb_server/apps/mtm/models.py
@@ -242,6 +242,7 @@ class UsedStep(CommonADModel):
涉及的生产子工序
"""
step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedstep')
+ need_test = models.BooleanField('工序内检验', default=False)
remark = models.TextField('生产备注', null=True, blank=True)
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='usedstep_subproduction')
diff --git a/hb_server/apps/pm/filters.py b/hb_server/apps/pm/filters.py
index aa9c6da..a53c29d 100644
--- a/hb_server/apps/pm/filters.py
+++ b/hb_server/apps/pm/filters.py
@@ -3,7 +3,7 @@ from apps.mtm.models import Material, Step
from apps.pm.models import ProductionPlan, SubProductionProgress
from apps.wpm.models import Operation, WProduct
from datetime import *
-from apps.wpm.services import WpmServies
+from apps.wpm.services import WpmService
from django.db.models import F
from utils.mixins import DynamicFieldsFilterMixin
@@ -52,9 +52,9 @@ class SubproductionProgressFilterSet(filters.FilterSet):
wproducts = WProduct.objects.filter(ow_wproduct__operation=value)
step = operation.step
if wproducts.exists():
- subplans = WpmServies.get_subplans_queryset_from_wproducts(wproducts)
+ subplans = WpmService.get_subplans_queryset_from_wproducts(wproducts)
else:
- subplans = WpmServies.get_subplans_queyset_from_step(step)
+ subplans = WpmService.get_subplans_queyset_from_step(step)
queryset = queryset.filter(subproduction_plan__in=subplans)
if step.type == Step.STEP_TYPE_NOM:
queryset = queryset.exclude(material__type__in =[Material.MA_TYPE_HALFGOOD, Material.MA_TYPE_GOOD])
diff --git a/hb_server/apps/pm/views.py b/hb_server/apps/pm/views.py
index 0fea0a7..449cb2d 100644
--- a/hb_server/apps/pm/views.py
+++ b/hb_server/apps/pm/views.py
@@ -89,7 +89,8 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
subps = SubProduction.objects.filter(product=production_plan.product).order_by('process__number')
for index, i in enumerate(subps):
steps = Step.objects.filter(usedstep__subproduction=i, usedstep__subproduction__is_deleted=False,
- usedstep__is_deleted=False, is_deleted=False).values('id', 'number', 'name', 'usedstep__remark')
+ usedstep__is_deleted=False, is_deleted=False
+ ).values('id', 'number', 'name', 'usedstep__remark', need_test=F('usedstep__need_test'))
instance = SubProductionPlan.objects.create(production_plan=production_plan, subproduction=i,
start_date=production_plan.start_date, end_date=production_plan.end_date,
workshop=i.process.workshop, process=i.process, create_by=request.user,
diff --git a/hb_server/apps/qm/migrations/0023_auto_20220129_1512.py b/hb_server/apps/qm/migrations/0023_auto_20220129_1512.py
new file mode 100644
index 0000000..912b50e
--- /dev/null
+++ b/hb_server/apps/qm/migrations/0023_auto_20220129_1512.py
@@ -0,0 +1,36 @@
+# Generated by Django 3.2.9 on 2022-01-29 07:12
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('qm', '0022_auto_20211216_1401'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='testrecord',
+ name='is_midtesing',
+ field=models.BooleanField(default=False, verbose_name='是否子工序检验中'),
+ ),
+ migrations.AddField(
+ model_name='testrecorditem',
+ name='create_by',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='testrecorditem_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人'),
+ ),
+ migrations.AddField(
+ model_name='testrecorditem',
+ name='update_by',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='testrecorditem_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
+ ),
+ migrations.AlterField(
+ model_name='testrecord',
+ name='type',
+ field=models.PositiveSmallIntegerField(choices=[(20, '工序检验'), (30, '工序复检'), (36, '夹层检验'), (40, '成品检验')], default=20),
+ ),
+ ]
diff --git a/hb_server/apps/qm/migrations/0024_rename_is_midtesing_testrecord_is_midtesting.py b/hb_server/apps/qm/migrations/0024_rename_is_midtesing_testrecord_is_midtesting.py
new file mode 100644
index 0000000..720045d
--- /dev/null
+++ b/hb_server/apps/qm/migrations/0024_rename_is_midtesing_testrecord_is_midtesting.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.9 on 2022-01-29 07:24
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('qm', '0023_auto_20220129_1512'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='testrecord',
+ old_name='is_midtesing',
+ new_name='is_midtesting',
+ ),
+ ]
diff --git a/hb_server/apps/qm/models.py b/hb_server/apps/qm/models.py
index c3db665..db776de 100644
--- a/hb_server/apps/qm/models.py
+++ b/hb_server/apps/qm/models.py
@@ -47,13 +47,11 @@ class TestRecord(CommonADModel):
"""
检验记录
"""
- TEST_STEP = 10
TEST_PROCESS = 20
TEST_PROCESS_RE = 30
TEST_COMB = 36
TEST_FINAL = 40
type_choice = (
- (TEST_STEP, '子工序检验'),
(TEST_PROCESS, '工序检验'),
(TEST_PROCESS_RE, '工序复检'),
(TEST_COMB, '夹层检验'),
@@ -70,6 +68,7 @@ class TestRecord(CommonADModel):
fifo_item = models.ForeignKey('inm.fifoitem', verbose_name='关联的出入库批次', on_delete=models.CASCADE, null=True, blank=True)
origin_test = models.ForeignKey('self', verbose_name='原检验记录', on_delete=models.CASCADE, null=True, blank=True)
is_submited = models.BooleanField('是否提交', default=False)
+ is_midtesting = models.BooleanField('是否子工序检验中', default=False)
remark = models.TextField('备注', default='')
diff --git a/hb_server/apps/qm/serializers.py b/hb_server/apps/qm/serializers.py
index ecfc2d3..fd64cd6 100644
--- a/hb_server/apps/qm/serializers.py
+++ b/hb_server/apps/qm/serializers.py
@@ -135,7 +135,7 @@ class TestRecordUpdateSerializer(serializers.ModelSerializer):
if i['field_value'] != tri.field_value:
tri.field_value = i['field_value']
tri.update_by = update_by
- tri.is_testok = i['is_testok']
- tri.is_hidden = i['is_hidden']
- tri.save()
+ tri.is_testok = i['is_testok']
+ tri.is_hidden = i['is_hidden']
+ tri.save()
return instance
diff --git a/hb_server/apps/qm/views.py b/hb_server/apps/qm/views.py
index 247e6d6..7cb1f40 100644
--- a/hb_server/apps/qm/views.py
+++ b/hb_server/apps/qm/views.py
@@ -12,7 +12,7 @@ from django.db import transaction
from rest_framework.decorators import action
from apps.wpm.models import WProduct
-from apps.wpm.services import WpmServies
+from apps.wpm.services import WpmService
# Create your views here.
class StandardViewSet(CreateUpdateModelAMixin, ModelViewSet):
"""
@@ -69,7 +69,7 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De
def update(self, request, *args, **kwargs):
obj = self.get_object()
- if obj.is_submited:
+ if obj.is_submited and obj.is_midtesting is False:
raise exceptions.APIException('该记录已提交不可编辑')
return super().update(request, *args, **kwargs)
@@ -77,20 +77,22 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De
obj = self.get_object()
if obj.is_submited:
raise exceptions.APIException('该记录已提交不可删除')
- WpmServies.add_wproduct_flow_log(obj.wproduct, 'test_delete')
+ WpmService.add_wproduct_flow_log(obj.wproduct, 'test_delete')
return super().destroy(request, *args, **kwargs)
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=TestRecordUpdateSerializer)
def submit(self, request, pk=None):
obj = self.get_object()
+ if obj.is_submited and obj.is_midtesting is False:
+ raise exceptions.APIException('该记录已提交')
# 校验是否有未填项目
- if obj.type != TestRecord.TEST_PROCESS_RE:
+ if obj.type != TestRecord.TEST_PROCESS_RE and obj.is_midtesting is False:
if TestRecordItem.objects.filter(field_value__isnull=True, is_hidden=False, test_record=obj).exists():
raise exceptions.APIException('存在未填写项目')
with transaction.atomic():
obj.is_submited=True
obj.save()
- WpmServies.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算
+ WpmService.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算
return Response()
# def create(self, request, *args, **kwargs):
diff --git a/hb_server/apps/wpm/filters.py b/hb_server/apps/wpm/filters.py
index 5cfb6ea..2798e98 100644
--- a/hb_server/apps/wpm/filters.py
+++ b/hb_server/apps/wpm/filters.py
@@ -1,7 +1,7 @@
from django_filters import rest_framework as filters
from apps.mtm.models import Material, Step
-from apps.wpm.services import WpmServies
+from apps.wpm.services import WpmService
from utils.mixins import DynamicFieldsFilterMixin
from .models import Operation, OperationMaterial, OperationRecord, WMaterial, WProduct
@@ -20,10 +20,10 @@ class WMaterialFilterSet(filters.FilterSet):
wproducts = WProduct.objects.filter(ow_wproduct__operation=value)
step = operation.step
if wproducts.exists():
- subplans = WpmServies.get_subplans_queryset_from_wproducts(
+ subplans = WpmService.get_subplans_queryset_from_wproducts(
wproducts)
else:
- subplans = WpmServies.get_subplans_queyset_from_step(step)
+ subplans = WpmService.get_subplans_queyset_from_step(step)
queryset = queryset.filter(subproduction_plan__in=subplans).exclude(
material__type=Material.MA_TYPE_HALFGOOD)
return queryset
diff --git a/hb_server/apps/wpm/migrations/0053_auto_20220129_1512.py b/hb_server/apps/wpm/migrations/0053_auto_20220129_1512.py
new file mode 100644
index 0000000..21d27fe
--- /dev/null
+++ b/hb_server/apps/wpm/migrations/0053_auto_20220129_1512.py
@@ -0,0 +1,65 @@
+# Generated by Django 3.2.9 on 2022-01-29 07:12
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('mtm', '0045_usedstep_need_test'),
+ ('wpm', '0052_auto_20220125_1116'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='wproduct',
+ name='material_check',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wp_material_check', to='mtm.material', verbose_name='按物料状态检查'),
+ ),
+ migrations.AddField(
+ model_name='wproductflow',
+ name='material_check',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wpf_material_check', to='mtm.material', verbose_name='按物料状态检查'),
+ ),
+ migrations.AlterField(
+ model_name='wproduct',
+ name='child',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wp_child', to='wpm.wproduct'),
+ ),
+ migrations.AlterField(
+ model_name='wproduct',
+ name='material',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='wp_material', to='mtm.material', verbose_name='所属物料状态'),
+ ),
+ migrations.AlterField(
+ model_name='wproduct',
+ name='pre_step',
+ field=models.ForeignKey(blank=True, help_text='已执行完的步骤', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wp_pre_step', to='mtm.step', verbose_name='已执行到'),
+ ),
+ migrations.AlterField(
+ model_name='wproduct',
+ name='step',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wp_step', to='mtm.step', verbose_name='所在步骤'),
+ ),
+ migrations.AlterField(
+ model_name='wproductflow',
+ name='child',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wpf_child', to='wpm.wproductflow'),
+ ),
+ migrations.AlterField(
+ model_name='wproductflow',
+ name='material',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='wpf_material', to='mtm.material', verbose_name='所属物料状态'),
+ ),
+ migrations.AlterField(
+ model_name='wproductflow',
+ name='pre_step',
+ field=models.ForeignKey(blank=True, help_text='已执行完的步骤', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wpf_pre_step', to='mtm.step', verbose_name='已执行到'),
+ ),
+ migrations.AlterField(
+ model_name='wproductflow',
+ name='step',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='wpf_step', to='mtm.step', verbose_name='所在步骤'),
+ ),
+ ]
diff --git a/hb_server/apps/wpm/models.py b/hb_server/apps/wpm/models.py
index 571960e..997e65c 100644
--- a/hb_server/apps/wpm/models.py
+++ b/hb_server/apps/wpm/models.py
@@ -1,4 +1,5 @@
import re
+
from rest_framework import exceptions
from django.db import models
from django.db.models.base import Model
@@ -88,16 +89,20 @@ class WProduct(CommonAModel):
number = models.CharField(
'物品编号', unique=True, null=True, blank=True, max_length=50)
material = models.ForeignKey(
- Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
+ Material, verbose_name='所属物料状态', on_delete=models.CASCADE,
+ related_name='wp_material')
+ material_check = models.ForeignKey(
+ Material, verbose_name='按物料状态检查', on_delete=models.CASCADE,
+ null=True, blank=True, related_name='wp_material_check')
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True,
- on_delete=models.CASCADE, related_name='w_pre_step')
+ on_delete=models.CASCADE, related_name='wp_pre_step')
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True,
- related_name='w_step')
+ related_name='wp_step')
act_state = models.IntegerField(
'进行状态', default=0, choices=act_state_choices)
is_hidden = models.BooleanField('是否隐藏', default=False)
child = models.ForeignKey('self', blank=True, null=True,
- on_delete=models.CASCADE, related_name='wproduct_child')
+ on_delete=models.CASCADE, related_name='wp_child')
remark = models.CharField('备注', max_length=200, null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE,
related_name='wproduct_subplan')
@@ -164,16 +169,19 @@ class WproductFlow(CommonAModel):
WProduct, on_delete=models.CASCADE, verbose_name='关联产品', null=True, blank=True)
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
material = models.ForeignKey(
- Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
+ Material, verbose_name='所属物料状态', on_delete=models.CASCADE, related_name='wpf_material')
+ material_check = models.ForeignKey(
+ Material, verbose_name='按物料状态检查', on_delete=models.CASCADE,
+ null=True, blank=True, related_name='wpf_material_check')
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True,
- on_delete=models.CASCADE, related_name='wl_pre_step')
+ on_delete=models.CASCADE, related_name='wpf_pre_step')
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True,
- related_name='wl_step')
+ related_name='wpf_step')
act_state = models.IntegerField(
'进行状态', default=0, choices=WProduct.act_state_choices)
is_hidden = models.BooleanField('是否隐藏', default=False)
child = models.ForeignKey('self', blank=True, null=True,
- on_delete=models.CASCADE, related_name='wproduct_child')
+ on_delete=models.CASCADE, related_name='wpf_child')
remark = models.CharField('备注', max_length=200, null=True, blank=True)
subproduction_plan = models.ForeignKey(
SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE)
diff --git a/hb_server/apps/wpm/services.py b/hb_server/apps/wpm/services.py
index d880f7f..c3ca066 100644
--- a/hb_server/apps/wpm/services.py
+++ b/hb_server/apps/wpm/services.py
@@ -9,19 +9,21 @@ from apps.system.models import User
from apps.wf.models import State, TicketFlow, Transition
from apps.wpm.models import Operation, OperationMaterial, WProduct, WproductFlow, WprouctTicket
from utils.tools import ranstr
-class WpmServies(object):
+class WpmService(object):
@classmethod
def get_next_step(cls, subproduction_plan:SubProductionPlan, nowstep:Step):
"""
获取下一步骤
"""
- stepIds = [i['id'] for i in subproduction_plan.steps]
+ steps_list = subproduction_plan.steps
+ stepIds = [i['id'] for i in steps_list]
pindex = stepIds.index(nowstep.id)
+ need_test = steps_list[pindex].get('need_test', False)
if pindex + 1 < len(stepIds):
- return Step.objects.get(pk=stepIds[pindex+1]), True
+ return Step.objects.get(pk=stepIds[pindex+1]), need_test
else:
- return nowstep, False
+ return nowstep, need_test
@classmethod
def get_subplans_queryset_from_wproducts(cls, wproducts:List):
@@ -47,9 +49,15 @@ class WpmServies(object):
"""
is_testok = test.is_testok
wproduct = test.wproduct
+ test_i = None
if is_testok:
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST: # 复检
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
+
+ elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and \
+ test.is_midtesing is True:
+ wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
+ test_i = test
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.material.type == Material.MA_TYPE_GOOD: # 成品检验
wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST
@@ -97,7 +105,7 @@ class WpmServies(object):
wproduct.update_by = user
wproduct.update_time = timezone.now()
- wproduct.test = None
+ wproduct.test = test_i
wproduct.last_test_result = is_testok
wproduct.save()
# 添加日志
diff --git a/hb_server/apps/wpm/signals.py b/hb_server/apps/wpm/signals.py
index 9b37b54..04455d7 100644
--- a/hb_server/apps/wpm/signals.py
+++ b/hb_server/apps/wpm/signals.py
@@ -8,7 +8,7 @@ from django.dispatch import receiver
from rest_framework import exceptions
from apps.wpm.models import WProduct, WproductFlow, WprouctTicket
from apps.wpm.models import OperationWproduct
-from apps.wpm.services import WpmServies
+from apps.wpm.services import WpmService
@receiver(post_save, sender=Ticket)
@@ -34,7 +34,7 @@ def handleTicket(sender, instance, created, **kwargs):
# 工单绑定半成品
wproduct.ticket = instance
wproduct.save()
- WpmServies.add_wproduct_flow_log(wproduct, 'ticket_create')
+ WpmService.add_wproduct_flow_log(wproduct, 'ticket_create')
elif instance.act_state == Ticket.TICKET_ACT_STATE_FINISH:
@@ -77,7 +77,7 @@ def handleTicket(sender, instance, created, **kwargs):
wp.save()
# 添加日志
- WpmServies.add_wproduct_flow_log(wp, 'ticket_finish')
+ WpmService.add_wproduct_flow_log(wp, 'ticket_finish')
# 更新子计划合格进度
- WpmServies.update_subproduction_progress_main(sp=wp.subproduction_plan)
+ WpmService.update_subproduction_progress_main(sp=wp.subproduction_plan)
diff --git a/hb_server/apps/wpm/urls.py b/hb_server/apps/wpm/urls.py
index b617c02..40614fd 100644
--- a/hb_server/apps/wpm/urls.py
+++ b/hb_server/apps/wpm/urls.py
@@ -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 CuttingListViewSet, DoFormInit, DoFormSubmit, OperationEquipViewSet, OperationMaterialInputViewSet, OperationMaterialOutputViewSet, OperationMaterialToolViewSet, OperationRecordViewSet, OperationViewSet, OperationWproductViewSet, WMaterialViewSet, WPlanViewSet, WProductViewSet, WproductTicketViewSet
+from apps.wpm.views import CuttingListViewSet, OperationEquipViewSet, OperationMaterialInputViewSet, OperationMaterialOutputViewSet, OperationMaterialToolViewSet, OperationRecordViewSet, OperationViewSet, OperationWproductViewSet, WMaterialViewSet, WPlanViewSet, WProductViewSet, WproductTicketViewSet
router = DefaultRouter()
router.register('wmaterial', WMaterialViewSet, basename='wmaterial')
@@ -19,8 +19,6 @@ router.register('operation_tool', OperationMaterialToolViewSet, basename='operat
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()),
path('', include(router.urls)),
]
diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py
index 7696562..43d9cee 100644
--- a/hb_server/apps/wpm/views.py
+++ b/hb_server/apps/wpm/views.py
@@ -32,7 +32,7 @@ from apps.wpm.serializers import CuttingListSerializer, OperationEquipListSerial
from rest_framework.response import Response
from django.db import transaction
from rest_framework import exceptions, serializers
-from apps.wpm.services import WpmServies
+from apps.wpm.services import WpmService
from django.utils import timezone
from rest_framework import status
from django.db.models import Count
@@ -105,7 +105,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
m.update_by = request.user
m.update_time = timezone.now()
m.save()
- WpmServies.add_wproduct_flow_log(
+ WpmService.add_wproduct_flow_log(
instance=m, change_str='pick_half')
pw = PickWproduct()
pw.pick = pick
@@ -151,7 +151,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
perms_map = {'*': '*'}
queryset = WProduct.objects.select_related('step', 'material',
'subproduction_plan', 'warehouse', 'subproduction_plan__production_plan__order',
- 'to_order').prefetch_related('wproduct_child')
+ 'to_order').prefetch_related('wp_child')
serializer_class = WProductListSerializer
filterset_class = WProductFilterSet
search_fields = ['number']
@@ -188,7 +188,6 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
WProduct.WPR_ACT_STATE_TORETEST, WProduct.WPR_ACT_STATE_TOFINALTEST,
WProduct.WPR_ACT_STATE_TOCOMBTEST]:
raise exceptions.APIException('该产品当前状态不可检验')
-
savedict = dict(
create_by=request.user,
wproduct=wproduct,
@@ -208,13 +207,16 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
savedict['type'] = TestRecord.TEST_FINAL
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOCOMBTEST:
savedict['type'] = TestRecord.TEST_COMB
+ elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and\
+ wproduct.step != wproduct.pre_step: # 如果是工序内检验
+ savedict['is_midtesting'] = True
tr = TestRecord.objects.create(**savedict)
# 更新wproduct
wproduct.test = tr
wproduct.update_by = request.user
wproduct.update_time = timezone.now()
wproduct.save()
- WpmServies.add_wproduct_flow_log(wproduct, 'test_init')
+ WpmService.add_wproduct_flow_log(wproduct, 'test_init')
# 创建检验条目
for i in RecordFormField.objects.filter(form=form, is_deleted=False):
tri = TestRecordItem()
@@ -224,6 +226,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
tri.create_by = request.user
tri.save()
return Response(TestRecordDetailSerializer(instance=tr).data)
+
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=WproductPutInsSerializer)
@transaction.atomic
@@ -281,7 +284,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
i.update_by = request.user
i.update_time = timezone.now()
i.save()
- WpmServies.add_wproduct_flow_log(i, 'putins')
+ WpmService.add_wproduct_flow_log(i, 'putins')
return Response()
@action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=WproductPutInSerializer)
@@ -328,7 +331,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
wproduct.act_state = WProduct.WPR_ACT_STATE_INM
wproduct.warehouse = warehouse
wproduct.save()
- WpmServies.add_wproduct_flow_log(wproduct, 'putin')
+ WpmService.add_wproduct_flow_log(wproduct, 'putin')
return Response()
@action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=ScrapSerializer)
@@ -354,9 +357,9 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
obj.update_by = request.user
obj.update_time = timezone.now()
obj.save()
- WpmServies.add_wproduct_flow_log(obj, 'scrap')
+ WpmService.add_wproduct_flow_log(obj, 'scrap')
if obj.step.process.id == 1: # 如果是冷加工
- WpmServies.update_cutting_list_with_operation(obj.coperation)
+ WpmService.update_cutting_list_with_operation(obj.coperation)
return Response()
# @action(methods=['get'], detail=False, perms_map={'get':'*'})
@@ -411,14 +414,14 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
is_mtestok = request.data.get('is_mtestok')
obj.is_mtestok = is_mtestok
if is_mtestok:
- WpmServies.update_plan_state_by_mtestok(
+ WpmService.update_plan_state_by_mtestok(
obj.subproduction_plan.production_plan)
obj.update_by = request.user
obj.save()
change_str = 'mtest_notok'
if is_mtestok:
change_str = 'mtest_ok'
- WpmServies.add_wproduct_flow_log(instance=obj, change_str=change_str)
+ WpmService.add_wproduct_flow_log(instance=obj, change_str=change_str)
return Response()
@action(methods=['get'], detail=True, perms_map={'get': '*'})
@@ -461,7 +464,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
i.need_to_order = True
i.update_by = request.user
i.save()
- WpmServies.add_wproduct_flow_log(i, change_str='need_to_order')
+ WpmService.add_wproduct_flow_log(i, change_str='need_to_order')
return Response()
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=WproductToOrderSerializer)
@@ -486,7 +489,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
i.to_order = order
i.update_by = request.user
i.save()
- WpmServies.add_wproduct_flow_log(i,change_str='to_order')
+ WpmService.add_wproduct_flow_log(i,change_str='to_order')
return Response()
class WproductTicketViewSet(ListModelMixin, GenericViewSet):
@@ -544,7 +547,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
i.act_state = WProduct.WPR_ACT_STATE_DOWAIT
i.update_by = request.user
i.save()
- WpmServies.add_wproduct_flow_log(i, 'operation_delete')
+ WpmService.add_wproduct_flow_log(i, 'operation_delete')
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
@@ -565,14 +568,14 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
# 创建操作所用半成品关联记录
if 'wproducts' in vdata:
owps = []
- splans = WpmServies.get_subplans_queryset_from_wproducts(
+ splans = WpmService.get_subplans_queryset_from_wproducts(
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')
+ WpmService.add_wproduct_flow_log(wpd, 'operation_create')
owp = {}
owp['operation'] = op
owp['wproduct'] = wpd
@@ -583,7 +586,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
owps.append(OperationWproduct(**owp))
OperationWproduct.objects.bulk_create(owps)
else:
- splans = WpmServies.get_subplans_queryset_from_wproducts(
+ splans = WpmService.get_subplans_queryset_from_wproducts(
vdata['wproducts'])
# 查询需要填写的自定义表格
forms = RecordForm.objects.filter(
@@ -677,22 +680,31 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
wsp = i.subproduction_plan
# 获取下一步子工序
- newstep, hasNext = WpmServies.get_next_step(wsp, step)
+ newstep, needTest = WpmService.get_next_step(wsp, step)
wp.step = newstep
wp.pre_step = step
- if hasNext:
- wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT
- else:
+
+ if step == newstep:
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
wp.material = wsp.product
+ if wp.test:# 如果有正在进行的工序中检验
+ wp.test.is_midtesting = False
+ wp.test.is_submited = False
+ wp.test.save()
+ else:
+ wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT
+ if needTest:
+ wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
+ wp.material_check = wsp.product
+
wp.operation = None
wp.update_by = request.user
wp.save()
- WpmServies.add_wproduct_flow_log(wp, 'operation_submit')
+ WpmService.add_wproduct_flow_log(wp, 'operation_submit')
for i in ows.values('subproduction_plan').distinct():
# 更新进度
- WpmServies.update_subproduction_progress_main(sp=wsp)
+ WpmService.update_subproduction_progress_main(sp=wsp)
elif step.type == Step.STEP_TYPE_DIV:
# 更新物料产出情况
@@ -700,7 +712,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
raise exceptions.APIException('请选择物料产出')
for i in omos:
if i.subproduction_progress.is_main:
- newstep, _ = WpmServies.get_next_step(
+ newstep, _ = WpmService.get_next_step(
i.subproduction_plan, step)
wpr = dict(material=i.material, step=newstep,
act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='',
@@ -709,33 +721,41 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
for x in range(i.count):
ins = WProduct.objects.create(**wpr)
# 添加日志
- WpmServies.add_wproduct_flow_log(
+ WpmService.add_wproduct_flow_log(
ins, 'wproduct_create')
# 更新进度
- WpmServies.update_subproduction_progress_main(
+ WpmService.update_subproduction_progress_main(
sp=i.subproduction_plan)
elif step.type == Step.STEP_TYPE_COMB:
oms_w = omos.filter(subproduction_progress__is_main=True)
if len(oms_w) == 1:
oms_w = oms_w[0]
# 校验单片数量是否正确, 暂时未写
- newstep, hasNext = WpmServies.get_next_step(
+ newstep, needTest = WpmService.get_next_step(
oms_w.subproduction_plan, step)
wproduct = WProduct()
wproduct.material = oms_w.material
wproduct.step = newstep
wproduct.subproduction_plan = oms_w.subproduction_plan
- if hasNext:
- wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
- else:
+ if step == newstep:
wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
- # 更新子计划进度
- WpmServies.update_subproduction_progress_main(
- sp=oms_w.subproduction_plan)
+ if wproduct.test:# 如果有正在进行的工序中检验
+ wproduct.test.is_midtesting = False
+ wproduct.test.is_submited = False
+ wproduct.test.save()
+ else:
+ wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
+ if needTest:
+ wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
+ wproduct.material_check = wproduct.product
+
+ # 更新子计划进度
+ WpmService.update_subproduction_progress_main(
+ sp=oms_w.subproduction_plan)
wproduct.create_by = request.user
wproduct.coperation = op
wproduct.save()
- WpmServies.add_wproduct_flow_log(wproduct, 'wproduct_create')
+ WpmService.add_wproduct_flow_log(wproduct, 'wproduct_create')
# 隐藏原半成品
wps = WProduct.objects.filter(ow_wproduct__operation=op)
wps.update(is_hidden=True, child=wproduct,
@@ -747,7 +767,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
# 如果是冷加工
if step.process.id == 1:
- WpmServies.update_cutting_list_with_operation(op=op)
+ WpmService.update_cutting_list_with_operation(op=op)
return Response()
@@ -971,213 +991,3 @@ class OperationMaterialToolViewSet(ListModelMixin, CreateModelMixin, DestroyMode
return Response()
-class DoFormInit(CreateAPIView, GenericAPIView):
- perms_map = {'*': '*'}
- serializer_class = OperationInitSerializer
-
- def post(self, request, format=None):
- """
- 调用操作表单
- """
- data = request.data
- serializer = OperationInitSerializer(data=data)
- serializer.is_valid(raise_exception=True)
- vdata = serializer.validated_data
- ret = {}
- ret_0 = {}
- ret_0['step'] = data['step']
- splans = []
- ret_0['input'] = []
- # ret_0['subproduction_plan'] = data['subproduction_plan']
- if 'wproducts' in data and data['wproducts']:
- ret_0['wproducts'] = data['wproducts']
- splans = WProduct.objects.filter(id__in=data['wproducts']).values_list(
- 'subproduction_plan', flat=True)
- # 调出所属子计划现有物料
- ret_0['input'] = WMaterialListSerializer(instance=WMaterial.objects.filter(
- subproduction_plan__in=splans), many=True).data
- else:
- if 'subproduction_plan' in vdata:
- splans = [vdata['subproduction_plan']]
- else:
- splans = SubProductionPlan.objects.filter(is_deleted=False,
- subproduction__usedstep_subproduction__step=vdata[
- 'step'],
- state=3)
- ret_0['wproducts'] = []
- ret_0['input'] = WMaterialListSerializer(instance=WMaterial.objects.filter(
- subproduction_plan__in=splans), many=True).data
-
- for i in ret_0['input']:
- i['count_input'] = 0
- # 需要输出的物料
- if ret_0['wproducts']:
- # 排除主要产物, 因为已经放到半成品里了, 由半成品进行处理, 夹层可能需要特殊处理
- o_objs = SubProductionProgress.objects.filter(
- subproduction_plan__in=splans, type=SubprodctionMaterial.SUB_MA_TYPE_OUT).exclude(is_main=True)
-
- else:
- # 此时显示所有子计划需要输出的物料
- o_objs = SubProductionProgress.objects.filter(
- subproduction_plan__in=splans, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
- ret_0['output'] = list(o_objs.values(
- 'subproduction_plan', 'material', 'material__name', 'material__number'))
- for i in ret_0['output']:
- i['count_output'] = 0
- ret['forms'] = []
- ret_0['id'] = 0
- ret_0['name'] = '基本信息'
- # 查询工具工装
- ret_0['tools'] = SubprodctionMaterialListSerializer(
- instance=SubprodctionMaterial.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL,
- subproduction__subplan_subprod__in=splans), many=True).data
- # 查询技术文档
- ret_0['techdocs'] = TechDocListSerializer(
- instance=TechDoc.objects.filter(
- subproduction__subplan_subprod__in=splans, enabled=True)
- .distinct(), many=True).data
-
- ret['forms'].append(ret_0)
- forms = RecordForm.objects.filter(
- step=vdata['step'], type=RecordForm.RF_TYPE_DO)
- if forms.exists():
- ret['forms'].extend(RecordFormDetailSerializer(
- instance=forms, many=True).data)
- return Response(ret)
-
-
-class DoFormSubmit(CreateAPIView, GenericAPIView):
- perms_map = {'*': '*'}
- serializer_class = OperationSubmitSerializer
-
- @transaction.atomic
- def post(self, request, format=None):
- """
- 提交操作表单
- """
- data = request.data
- serializer = OperationSubmitSerializer(
- data=data, context={'request': self.request})
- serializer.is_valid(raise_exception=True)
- vdata = serializer.validated_data # 校验之后的数据
-
- # 创建一个生产操作记录
- action_obj = Operation()
- action_obj.step = vdata['step']
- action_obj.remark = vdata.get('remark', '') # 操作备注
- action_obj.create_by = request.user
- action_obj.use_scrap = vdata.get('use_scrap', False)
- action_obj.save()
-
- # 保存关联半成品
- if 'wproducts' in data and data['wproducts']:
- owps = []
- for i in data['wproducts']:
- owp = {}
- owp['operation'] = action_obj
- wp = WProduct.objects.get(pk=i)
- owp['wproduct'] = wp
- owp['number'] = wp.number
- owp['material'] = wp.material
- owp['subproduction_plan'] = wp.subproduction_plan
- owps.append(OperationWproduct(**owp))
- OperationWproduct.objects.bulk_create(owps)
-
- # 保存物料消耗
- for i in vdata['input']:
- if i['count_input']: # 如果有消耗
- i_wmat = i['id']
- OperationMaterial.objects.create(type=1, operation=action_obj,
- wmaterial=i_wmat, count=i['count_input'])
- # 更新车间物料
- i_wmat.count = i_wmat.count - i['count_input']
- i_wmat.save()
- # 更新子计划物料消耗情况
- sp = SubProductionProgress.objects.get(subproduction_plan=i_wmat.subproduction_plan,
- material=i_wmat.material)
- sp.count_real = sp.count_real + i['count_input']
- sp.save()
-
- # 物料产出
- if 'output' in data and data['output']:
- for i in vdata['output']: # 已经序列化好的数据
- ma = i['material']
- if i['subproduction_plan'].product == ma: # 如果是该计划主产物
- # 如果是切割
- # 获取下一步子工序
- if vdata['step'].type == Step.STEP_TYPE_DIV:
- newstep, _ = WpmServies.get_next_step(
- i['subproduction_plan'], vdata['step'])
- wpr = dict(material=ma, step=newstep,
- act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='',
- subproduction_plan=i['subproduction_plan'])
- for x in range(i['count_output']):
- WProduct.objects.create(**wpr)
- else:
- # 更新操作产出物料表
- OperationMaterial.objects.create(type=2, operation=action_obj,
- material=ma, count=i['count_output'])
- # 更新车间物料表
- ins, _ = WMaterial.objects.get_or_create(subproduction_plan=i['subproduction_plan'],
- material=ma)
- ins.count = ins.count + i['count_output']
- ins.save()
- # 更新子计划进度表
- sp = SubProductionProgress.objects.get(subproduction_plan=i['subproduction_plan'],
- material=ma)
- sp.count_real = sp.count_real + i['count_input']
- sp.save()
-
- # 更新动态产品表
- if 'wproducts' in vdata and vdata['wproducts']:
- if vdata['step'].type == Step.STEP_TYPE_COMB:
- wproducts = vdata['wproducts']
- if 'suproduction_plan' in vdata:
- wproducts.update(is_hidden=True) # 隐藏
- newstep, hasNext = WpmServies.get_next_step(
- i['subproduction_plan'], vdata['step'])
- wproduct = WProduct()
- wproduct.material = vdata['subproduction_plan'].product
- wproduct.step = newstep
- wproduct.subproduction_plan = vdata['subproduction_plan']
- wproduct.parent = data['wproducts']
- if hasNext:
- wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
- else:
- wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
- wproduct.save()
- else:
- raise exceptions.APIException('请指定子计划')
- else:
- for wproduct in vdata['wproducts']:
- # 获取下一步子工序
- newstep, hasNext = WpmServies.get_next_step(
- wproduct.subproduction_plan, vdata['step'])
- wproduct.step = newstep
- wproduct.pre_step = vdata['step']
- if hasNext:
- wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
- else:
- wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
- wproduct.material = wproduct.subproduction_plan.product
- wproduct.save()
-
- # 保存自定义表单结果
- for i in vdata['forms']:
- wr = OperationRecord()
- wr.form = i['form']
- wr.create_by = request.user
- wr.operation = action_obj
- wr.save()
- wrds = []
- for m in i['record_data']: # 保存记录详情
- form_field = m['form_field']
- m['field_name'] = form_field.field_name
- m['field_key'] = form_field.field_key
- m['field_type'] = form_field.field_type
- m['field_value'] = m['field_value']
- m['sort'] = form_field.sort
- m['operation_record'] = wr
- wrds.append(OperationRecordItem(**m))
- OperationRecordItem.objects.bulk_create(wrds)
- return Response()