批量入库remark非必填
This commit is contained in:
parent
43a936b7d9
commit
ef007e728a
|
|
@ -1,5 +1,6 @@
|
|||
.vscode/
|
||||
.vs/
|
||||
.idea/
|
||||
venv/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class WareHouse(CommonAModel):
|
|||
number = models.CharField('仓库编号', max_length=20, unique=True)
|
||||
name = models.CharField('仓库名称', max_length=20, unique=True)
|
||||
place = models.CharField('具体地点', max_length=50)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '仓库信息'
|
||||
verbose_name_plural = verbose_name
|
||||
|
|
@ -24,32 +25,39 @@ class WareHouse(CommonAModel):
|
|||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class Inventory(BaseModel):
|
||||
"""
|
||||
库存物料
|
||||
"""
|
||||
material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息')
|
||||
material = models.ForeignKey(
|
||||
Material, on_delete=models.CASCADE, verbose_name='物料信息')
|
||||
count = models.PositiveIntegerField('仓库物料存量', default=0)
|
||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||
warehouse = models.ForeignKey(
|
||||
WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||
|
||||
class Meta:
|
||||
verbose_name = '库存表'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
|
||||
class MaterialBatch(BaseModel):
|
||||
"""
|
||||
物料批次
|
||||
"""
|
||||
material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息')
|
||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||
material = models.ForeignKey(
|
||||
Material, on_delete=models.CASCADE, verbose_name='物料信息')
|
||||
warehouse = models.ForeignKey(
|
||||
WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||
count = models.PositiveIntegerField('存量', default=0)
|
||||
batch = models.CharField('批次号', max_length=100, default='')
|
||||
expiration_date = models.DateField('有效期', null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '库存表'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
|
||||
|
||||
class FIFO(CommonADModel):
|
||||
"""
|
||||
出入库记录
|
||||
|
|
@ -66,7 +74,8 @@ class FIFO(CommonADModel):
|
|||
)
|
||||
type = models.IntegerField('出入库类型', default=1)
|
||||
is_audited = models.BooleanField('是否审核', default=False)
|
||||
auditor = models.ForeignKey(User, verbose_name='审核人', on_delete=models.CASCADE, null=True, blank=True)
|
||||
auditor = models.ForeignKey(
|
||||
User, verbose_name='审核人', on_delete=models.CASCADE, null=True, blank=True)
|
||||
inout_date = models.DateField('出入库日期')
|
||||
remark = models.CharField('备注', max_length=1000, default='')
|
||||
|
||||
|
|
@ -75,38 +84,46 @@ class FIFOItem(BaseModel):
|
|||
"""
|
||||
出入库详细条目
|
||||
"""
|
||||
need_test = models.BooleanField('是否需要检验', default=False)
|
||||
is_tested = models.BooleanField('是否已检验', default=False)
|
||||
is_testok = models.BooleanField('是否检验合格', default=False)
|
||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
|
||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||
warehouse = models.ForeignKey(
|
||||
WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
|
||||
material = models.ForeignKey(
|
||||
Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||
count = models.PositiveIntegerField('数量', default=0)
|
||||
batch = models.CharField('批次号', max_length=100, default='')
|
||||
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE)
|
||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
|
||||
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库',
|
||||
on_delete=models.CASCADE)
|
||||
subproduction_plan = models.ForeignKey(
|
||||
SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
|
||||
|
||||
|
||||
class IProduct(BaseModel):
|
||||
"""
|
||||
具体产品条目
|
||||
"""
|
||||
number = models.CharField('物品编号', unique=True, max_length=50)
|
||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||
material = models.ForeignKey(
|
||||
Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||
warehouse = models.ForeignKey(
|
||||
WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||
batch = models.CharField('所属批次号', max_length=100, default='')
|
||||
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False,
|
||||
null=True, blank=True, related_name='iproduct_wproduct')
|
||||
is_saled = models.BooleanField('是否售出', default=False)
|
||||
|
||||
|
||||
class FIFOItemProduct(BaseModel):
|
||||
"""
|
||||
出入库产品
|
||||
"""
|
||||
fifoitem = models.ForeignKey(FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
|
||||
fifoitem = models.ForeignKey(
|
||||
FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
|
||||
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True,
|
||||
related_name='fifoitem_wproduct')
|
||||
number = models.CharField('物品编号', max_length=50)
|
||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||
iproduct = models.ForeignKey(IProduct, verbose_name='关联库存产品', null=True, blank=True, on_delete=models.SET_NULL)
|
||||
|
||||
|
||||
|
||||
|
||||
material = models.ForeignKey(
|
||||
Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||
iproduct = models.ForeignKey(
|
||||
IProduct, verbose_name='关联库存产品', null=True, blank=True, on_delete=models.SET_NULL)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveMod
|
|||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||
from apps.inm.filters import IProductFilterSet, MbFilterSet
|
||||
|
||||
from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse,Inventory
|
||||
from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, IProductListSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer
|
||||
from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse, Inventory
|
||||
from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, IProductListSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer, InventorySerializer
|
||||
from apps.inm.signals import update_inm
|
||||
from apps.mtm.models import Material
|
||||
from apps.pm.services import PmService
|
||||
|
|
@ -16,10 +16,13 @@ from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
|||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from django.db import transaction
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.wpm.services import WpmServies
|
||||
|
||||
# Create your views here.
|
||||
|
||||
|
||||
class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||
"""
|
||||
仓库-增删改查
|
||||
|
|
@ -37,21 +40,25 @@ class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
|||
return WareHouseCreateUpdateSerializer
|
||||
return WareHouseSerializer
|
||||
|
||||
|
||||
class InventoryViewSet(ListModelMixin, GenericViewSet):
|
||||
"""
|
||||
仓库物料表
|
||||
"""
|
||||
perms_map = {'*': '*'}
|
||||
queryset = Inventory.objects.select_related('material', 'warehouse').filter(count__gt=0).all()
|
||||
queryset = Inventory.objects.select_related(
|
||||
'material', 'warehouse').filter(count__gt=0).all()
|
||||
serializer_class = InventorySerializer
|
||||
filterset_fields = ['material', 'warehouse']
|
||||
search_fields = []
|
||||
ordering_fields = ['create_time']
|
||||
ordering = ['-create_time']
|
||||
|
||||
|
||||
class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
|
||||
perms_map = {'*': '*'}
|
||||
queryset = MaterialBatch.objects.select_related('material', 'warehouse').filter(count__gt=0).all()
|
||||
queryset = MaterialBatch.objects.select_related(
|
||||
'material', 'warehouse').filter(count__gt=0).all()
|
||||
serializer_class = MaterialBatchSerializer
|
||||
# filterset_fields = ['material', 'warehouse']
|
||||
filterset_class = MbFilterSet
|
||||
|
|
@ -59,7 +66,7 @@ class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
|
|||
ordering_fields = ['create_time']
|
||||
ordering = ['-create_time']
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=MaterialBatchQuerySerializer)
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MaterialBatchQuerySerializer)
|
||||
def query(self, request, pk=None):
|
||||
"""
|
||||
复杂查询
|
||||
|
|
@ -67,9 +74,11 @@ class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
|
|||
data = request.data
|
||||
serializer = MaterialBatchQuerySerializer(data=data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
queryset = self.queryset.filter(warehouse__id=data['warehouse'], material__id__in=data['materials'])
|
||||
queryset = self.queryset.filter(
|
||||
warehouse__id=data['warehouse'], material__id__in=data['materials'])
|
||||
return Response(MaterialBatchSerializer(instance=queryset, many=True).data)
|
||||
|
||||
|
||||
class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||
"""
|
||||
出入库记录详情表
|
||||
|
|
@ -77,7 +86,8 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
|||
perms_map = {'*': '*'}
|
||||
queryset = FIFOItem.objects.select_related('material', 'fifo').all()
|
||||
serializer_class = FIFOItemSerializer
|
||||
filterset_fields = ['material', 'fifo', 'fifo__type', 'is_tested', 'is_testok']
|
||||
filterset_fields = ['material', 'fifo',
|
||||
'fifo__type', 'is_tested', 'is_testok']
|
||||
search_fields = []
|
||||
ordering_fields = ['create_time']
|
||||
ordering = ['-create_time']
|
||||
|
|
@ -87,7 +97,7 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
|||
raise APIException('该出入库记录已通过审核, 无法删除')
|
||||
return super().perform_destroy(instance)
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=InmTestRecordCreateSerializer)
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=InmTestRecordCreateSerializer)
|
||||
def test(self, request, pk=None):
|
||||
"""
|
||||
检验
|
||||
|
|
@ -99,7 +109,7 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
|||
if 'is_testok' not in vdata:
|
||||
raise APIException('未填写检验结论')
|
||||
with transaction.atomic():
|
||||
obj = serializer.save(create_by = self.request.user)
|
||||
obj = serializer.save(create_by=self.request.user)
|
||||
tris = []
|
||||
for m in record_data: # 保存记录详情
|
||||
m['field_value'] = m['field_value']
|
||||
|
|
@ -115,6 +125,7 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
|||
obj.fifo_item.save()
|
||||
return Response()
|
||||
|
||||
|
||||
class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||
"""
|
||||
出入库记录
|
||||
|
|
@ -138,7 +149,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': '*'}, serializer_class=FIFOInPurSerializer)
|
||||
def in_pur(self, request, pk=None):
|
||||
"""
|
||||
采购入库
|
||||
|
|
@ -148,7 +159,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': '*'}, serializer_class=serializers.Serializer)
|
||||
def audit(self, request, pk=None):
|
||||
"""
|
||||
审核通过
|
||||
|
|
@ -162,6 +173,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
|||
with transaction.atomic():
|
||||
obj.is_audited = True
|
||||
obj.auditor = request.user
|
||||
obj.inout_date = timezone.now() # 也是审核日期
|
||||
obj.save()
|
||||
update_inm(obj) # 更新库存
|
||||
return Response()
|
||||
|
|
@ -172,7 +184,8 @@ class IProductViewSet(ListModelMixin, GenericViewSet):
|
|||
半成品库存表
|
||||
"""
|
||||
perms_map = {'*': '*'}
|
||||
queryset = IProduct.objects.select_related('material', 'warehouse', 'wproduct__subproduction_plan__production_plan__order')
|
||||
queryset = IProduct.objects.select_related(
|
||||
'material', 'warehouse', 'wproduct__subproduction_plan__production_plan__order')
|
||||
serializer_class = IProductListSerializer
|
||||
filterset_class = IProductFilterSet
|
||||
search_fields = []
|
||||
|
|
|
|||
|
|
@ -4,39 +4,50 @@ from apps.mtm.models import Material, Step
|
|||
from apps.wpm.services import WpmServies
|
||||
from .models import Operation, OperationMaterial, OperationRecord, WMaterial, WProduct
|
||||
|
||||
|
||||
class WMaterialFilterSet(filters.FilterSet):
|
||||
|
||||
operation = filters.NumberFilter(method='filter_operation')
|
||||
|
||||
class Meta:
|
||||
model = WMaterial
|
||||
fields = ['material', 'subproduction_plan', 'subproduction_plan__process', 'subproduction_plan__workshop', 'operation']
|
||||
fields = ['material', 'subproduction_plan', 'subproduction_plan__process',
|
||||
'subproduction_plan__workshop', 'operation']
|
||||
|
||||
def filter_operation(self, queryset, name, value):
|
||||
operation = Operation.objects.get(pk=value)
|
||||
wproducts = WProduct.objects.filter(ow_wproduct__operation=value)
|
||||
step = operation.step
|
||||
if wproducts.exists():
|
||||
subplans = WpmServies.get_subplans_queryset_from_wproducts(wproducts)
|
||||
subplans = WpmServies.get_subplans_queryset_from_wproducts(
|
||||
wproducts)
|
||||
else:
|
||||
subplans = WpmServies.get_subplans_queyset_from_step(step)
|
||||
queryset = queryset.filter(subproduction_plan__in=subplans).exclude(material__type=Material.MA_TYPE_HALFGOOD)
|
||||
queryset = queryset.filter(subproduction_plan__in=subplans).exclude(
|
||||
material__type=Material.MA_TYPE_HALFGOOD)
|
||||
return queryset
|
||||
|
||||
|
||||
class WProductFilterSet(filters.FilterSet):
|
||||
tag = filters.CharFilter(method='filter_tag')
|
||||
production_plan = filters.NumberFilter(field_name='subproduction_plan__production_plan')
|
||||
production_plan = filters.NumberFilter(
|
||||
field_name='subproduction_plan__production_plan')
|
||||
|
||||
class Meta:
|
||||
model = WProduct
|
||||
fields = ['step', 'subproduction_plan', 'material', 'step__process', 'act_state', 'material__type']
|
||||
fields = ['step', 'subproduction_plan', 'material',
|
||||
'step__process', 'act_state', 'material__type']
|
||||
|
||||
def filter_tag(self, queryset, name, value):
|
||||
if value == 'no_scrap':
|
||||
queryset = queryset.exclude(act_state=WProduct.WPR_ACT_STATE_SCRAP)
|
||||
return queryset
|
||||
|
||||
|
||||
class CuttingFilterSet(filters.FilterSet):
|
||||
production_plan = filters.NumberFilter(field_name='subproduction_plan__production_plan')
|
||||
production_plan = filters.NumberFilter(
|
||||
field_name='subproduction_plan__production_plan')
|
||||
|
||||
class Meta:
|
||||
model = OperationMaterial
|
||||
fields = ['operation', 'subproduction_plan', 'material']
|
||||
|
|
@ -44,6 +55,7 @@ class CuttingFilterSet(filters.FilterSet):
|
|||
|
||||
class OperationRecordFilterSet(filters.FilterSet):
|
||||
wproduct = filters.NumberFilter(method='filter_wproduct')
|
||||
|
||||
class Meta:
|
||||
model = OperationRecord
|
||||
fields = ['operation', 'form']
|
||||
|
|
|
|||
|
|
@ -13,15 +13,20 @@ from utils.model import SoftModel, BaseModel
|
|||
from simple_history.models import HistoricalRecords
|
||||
from apps.mtm.models import Material, Process, RecordFormField, Step, RecordForm, SubprodctionMaterial
|
||||
from apps.em.models import Equipment
|
||||
|
||||
|
||||
class WMaterial(BaseModel):
|
||||
"""
|
||||
车间生产物料
|
||||
"""
|
||||
subproduction_plan = models.ForeignKey(SubProductionPlan, 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)
|
||||
material = models.ForeignKey(
|
||||
Material, verbose_name='关联物料', on_delete=models.CASCADE)
|
||||
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
|
||||
count = models.PositiveIntegerField('当前数量', default=0)
|
||||
|
||||
|
||||
class WProduct(CommonAModel):
|
||||
"""
|
||||
动态半成品/成品表
|
||||
|
|
@ -37,7 +42,7 @@ class WProduct(CommonAModel):
|
|||
WPR_ACT_STATE_TOFINALTEST = 60
|
||||
WPR_ACT_STATE_SCRAP = 70
|
||||
WPR_ACT_STATE_SELLED = 80
|
||||
act_state_choices=(
|
||||
act_state_choices = (
|
||||
(WPR_ACT_STATE_TORETEST, '待复检'),
|
||||
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
||||
(WPR_ACT_STATE_DOING, '操作进行中'),
|
||||
|
|
@ -80,20 +85,30 @@ class WProduct(CommonAModel):
|
|||
(NG_BACK_FROM, '退回供方'),
|
||||
(NG_RECALL, '召回')
|
||||
)
|
||||
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
|
||||
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
||||
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_step')
|
||||
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='w_step')
|
||||
act_state = models.IntegerField('进行状态', default=0, choices=act_state_choices)
|
||||
number = models.CharField(
|
||||
'物品编号', unique=True, null=True, blank=True, max_length=50)
|
||||
material = models.ForeignKey(
|
||||
Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
||||
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True,
|
||||
on_delete=models.CASCADE, related_name='w_pre_step')
|
||||
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True,
|
||||
related_name='w_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')
|
||||
child = models.ForeignKey('self', blank=True, null=True,
|
||||
on_delete=models.CASCADE, related_name='wproduct_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')
|
||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE,
|
||||
related_name='wproduct_subplan')
|
||||
|
||||
scrap_reason = models.IntegerField('报废原因', choices=scrap_reason_choices, null=True, blank=True)
|
||||
ng_sign = models.PositiveSmallIntegerField('不合格标记', choices=ng_choices, null=True, blank=True)
|
||||
scrap_reason = models.IntegerField(
|
||||
'报废原因', choices=scrap_reason_choices, null=True, blank=True)
|
||||
ng_sign = models.PositiveSmallIntegerField(
|
||||
'不合格标记', choices=ng_choices, null=True, blank=True)
|
||||
|
||||
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
warehouse = models.ForeignKey(
|
||||
WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
|
||||
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
|
||||
|
|
@ -123,34 +138,52 @@ class WprouctTicket(CommonAModel):
|
|||
"""
|
||||
|
||||
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||
wproduct = models.ForeignKey(WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
|
||||
material = models.ForeignKey(Material, 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)
|
||||
wproduct = models.ForeignKey(
|
||||
WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
|
||||
material = models.ForeignKey(
|
||||
Material, 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)
|
||||
|
||||
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')
|
||||
decision = models.PositiveSmallIntegerField(
|
||||
'最终决定', choices=WProduct.ng_choices, null=True, blank=True)
|
||||
|
||||
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')
|
||||
decision = models.PositiveSmallIntegerField('最终决定', choices=WProduct.ng_choices, null=True, blank=True)
|
||||
|
||||
class WproductFlow(CommonAModel):
|
||||
"""
|
||||
动态产品表日志
|
||||
"""
|
||||
wproduct = models.ForeignKey(WProduct, on_delete=models.CASCADE, verbose_name='关联产品', null=True, blank=True)
|
||||
wproduct = models.ForeignKey(
|
||||
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)
|
||||
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='wl_pre_step')
|
||||
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='wl_step')
|
||||
act_state = models.IntegerField('进行状态', default=0, choices=WProduct.act_state_choices)
|
||||
material = models.ForeignKey(
|
||||
Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
||||
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True,
|
||||
on_delete=models.CASCADE, related_name='wl_pre_step')
|
||||
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True,
|
||||
related_name='wl_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')
|
||||
child = models.ForeignKey('self', blank=True, null=True,
|
||||
on_delete=models.CASCADE, related_name='wproduct_child')
|
||||
remark = models.CharField('备注', max_length=200, null=True, blank=True)
|
||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE)
|
||||
subproduction_plan = models.ForeignKey(
|
||||
SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE)
|
||||
|
||||
scrap_reason = models.IntegerField('报废原因', choices= WProduct.scrap_reason_choices, null=True, blank=True)
|
||||
ng_sign = models.PositiveSmallIntegerField('不合格标记', choices= WProduct.ng_choices, null=True, blank=True)
|
||||
scrap_reason = models.IntegerField(
|
||||
'报废原因', choices=WProduct.scrap_reason_choices, null=True, blank=True)
|
||||
ng_sign = models.PositiveSmallIntegerField(
|
||||
'不合格标记', choices=WProduct.ng_choices, null=True, blank=True)
|
||||
|
||||
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
warehouse = models.ForeignKey(
|
||||
WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_operation')
|
||||
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
|
||||
|
|
@ -179,63 +212,86 @@ class Pick(CommonADModel):
|
|||
(PICK_FROM_WAREHOUSE, '仓库领取'),
|
||||
(PICK_FROM_WPRODUCT, '半成品领取'),
|
||||
)
|
||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE)
|
||||
type = models.PositiveSmallIntegerField(choices=type_choice, default=PICK_FROM_WAREHOUSE)
|
||||
fifo = models.ForeignKey(FIFO, verbose_name='关联的出入库记录', on_delete=models.CASCADE, null=True, blank=True)
|
||||
subproduction_plan = models.ForeignKey(
|
||||
SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE)
|
||||
type = models.PositiveSmallIntegerField(
|
||||
choices=type_choice, default=PICK_FROM_WAREHOUSE)
|
||||
fifo = models.ForeignKey(
|
||||
FIFO, verbose_name='关联的出入库记录', on_delete=models.CASCADE, null=True, blank=True)
|
||||
|
||||
|
||||
class PickWproduct(BaseModel):
|
||||
"""
|
||||
领取半成品时详情
|
||||
"""
|
||||
pick = models.ForeignKey(Pick, verbose_name='关联领料', on_delete=models.CASCADE)
|
||||
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='pw_wproduct')
|
||||
pick = models.ForeignKey(Pick, verbose_name='关联领料',
|
||||
on_delete=models.CASCADE)
|
||||
wproduct = models.ForeignKey(
|
||||
WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='pw_wproduct')
|
||||
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||
material = models.ForeignKey(Material, verbose_name='领取时的物料状态', on_delete=models.CASCADE)
|
||||
subproduction_plan = models.ForeignKey(SubProductionPlan, 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)
|
||||
|
||||
|
||||
class Operation(CommonADModel):
|
||||
"""
|
||||
生产操作
|
||||
"""
|
||||
step = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True)
|
||||
step = models.ForeignKey(Step, verbose_name='操作步骤',
|
||||
on_delete=models.CASCADE, null=True, blank=True)
|
||||
remark = models.CharField('操作备注', max_length=200, null=True, blank=True)
|
||||
is_submited = models.BooleanField('是否提交', default=False)
|
||||
|
||||
|
||||
class OperationWproduct(BaseModel):
|
||||
"""
|
||||
生产操作半成品关联表
|
||||
"""
|
||||
operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='ow_operation')
|
||||
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='ow_wproduct')
|
||||
operation = models.ForeignKey(
|
||||
Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='ow_operation')
|
||||
wproduct = models.ForeignKey(
|
||||
WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='ow_wproduct')
|
||||
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||
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')
|
||||
ng_sign = models.PositiveSmallIntegerField('当时的不合格标记', choices= WProduct.ng_choices, null=True, blank=True)
|
||||
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')
|
||||
ng_sign = models.PositiveSmallIntegerField(
|
||||
'当时的不合格标记', choices=WProduct.ng_choices, null=True, blank=True)
|
||||
place = models.CharField('摆放位置', null=True, blank=True, max_length=200)
|
||||
|
||||
class Meta:
|
||||
unique_together = (
|
||||
('operation','wproduct')
|
||||
('operation', 'wproduct')
|
||||
)
|
||||
|
||||
|
||||
class OperationMaterial(BaseModel):
|
||||
"""
|
||||
生产操作物料消耗产出表
|
||||
"""
|
||||
type = models.IntegerField('类型', default=0, choices=SubprodctionMaterial.type_choices)
|
||||
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE, related_name='om_operation')
|
||||
type = models.IntegerField(
|
||||
'类型', default=0, choices=SubprodctionMaterial.type_choices)
|
||||
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE,
|
||||
related_name='om_operation')
|
||||
|
||||
material = models.ForeignKey(Material, verbose_name='可能产出的产品', on_delete=models.CASCADE,
|
||||
null=True, blank=True, related_name='om_material')
|
||||
count = models.PositiveSmallIntegerField('消耗或产出数量', null=True, blank=True)
|
||||
|
||||
wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
|
||||
subproduction_progress = models.ForeignKey(SubProductionProgress, verbose_name='关联的生产进度', on_delete=models.CASCADE, null=True, blank=True)
|
||||
wmaterial = models.ForeignKey(
|
||||
WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
|
||||
subproduction_progress = models.ForeignKey(SubProductionProgress, 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)
|
||||
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)
|
||||
use_scrap = models.BooleanField('是否使用的边角料', default=False)
|
||||
|
||||
#以下为冷加工下料清单所用字段
|
||||
# 以下为冷加工下料清单所用字段
|
||||
from_material = models.ForeignKey(Material, verbose_name='源物料', on_delete=models.CASCADE,
|
||||
null=True, blank=True, related_name='om_fmaterial')
|
||||
from_batch = models.CharField('源批次', max_length=100, null=True, blank=True)
|
||||
|
|
@ -249,26 +305,35 @@ class OperationMaterial(BaseModel):
|
|||
|
||||
class Meta:
|
||||
unique_together = (
|
||||
('operation','material', 'batch')
|
||||
('operation', 'material', 'batch')
|
||||
)
|
||||
|
||||
|
||||
class OperationRecord(BaseModel):
|
||||
"""
|
||||
记录表格
|
||||
"""
|
||||
form = models.ForeignKey(RecordForm, verbose_name='所用的生产记录表格', on_delete=models.CASCADE, related_name='or_form')
|
||||
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE, related_name='or_operation')
|
||||
form = models.ForeignKey(RecordForm, verbose_name='所用的生产记录表格',
|
||||
on_delete=models.CASCADE, related_name='or_form')
|
||||
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE,
|
||||
related_name='or_operation')
|
||||
is_filled = models.BooleanField('是否填写', default=True)
|
||||
|
||||
|
||||
class OperationRecordItem(BaseModel):
|
||||
"""
|
||||
记录表格字段值
|
||||
"""
|
||||
form_field = models.ForeignKey(RecordFormField, verbose_name='关联字段', on_delete=models.CASCADE, related_name='ori_form_field')
|
||||
form_field = models.ForeignKey(RecordFormField, verbose_name='关联字段', on_delete=models.CASCADE,
|
||||
related_name='ori_form_field')
|
||||
field_value = models.JSONField('录入值', null=True, blank=True)
|
||||
operation_record = models.ForeignKey(OperationRecord, verbose_name='关联的生产记录', on_delete=models.CASCADE, related_name='item_operation_record')
|
||||
operation_record = models.ForeignKey(OperationRecord, verbose_name='关联的生产记录', on_delete=models.CASCADE,
|
||||
related_name='item_operation_record')
|
||||
|
||||
|
||||
class OperationEquip(BaseModel):
|
||||
operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='oe_operation')
|
||||
equip = models.ForeignKey(Equipment, verbose_name='生产设备', on_delete=models.CASCADE, related_name='oe_equip')
|
||||
operation = models.ForeignKey(
|
||||
Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='oe_operation')
|
||||
equip = models.ForeignKey(Equipment, verbose_name='生产设备',
|
||||
on_delete=models.CASCADE, related_name='oe_equip')
|
||||
remark = models.TextField('备注', null=True, blank=True)
|
||||
|
|
@ -418,12 +418,12 @@ class WplanPutInSerializer(serializers.Serializer):
|
|||
|
||||
class WproductPutInSerializer(serializers.Serializer):
|
||||
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
|
||||
remark = serializers.CharField(label="入库备注", required =False)
|
||||
remark = serializers.CharField(label="入库备注", required =False, default="")
|
||||
|
||||
class WproductPutInsSerializer(serializers.Serializer):
|
||||
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
|
||||
wproducts = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), label='半成品ID', many=True)
|
||||
remark = serializers.CharField(label="入库备注", required =False, allow_null=True)
|
||||
remark = serializers.CharField(label="入库备注", required =False, default="")
|
||||
|
||||
|
||||
class OperationEquipListSerializer(serializers.Serializer):
|
||||
|
|
|
|||
|
|
@ -1,66 +1,77 @@
|
|||
from django.db.models.expressions import F
|
||||
from django.shortcuts import render
|
||||
from rest_framework.generics import CreateAPIView, GenericAPIView
|
||||
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||
from rest_framework.utils import serializer_helpers
|
||||
from rest_framework.utils.field_mapping import get_relation_kwargs
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse
|
||||
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, \
|
||||
ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||
from rest_framework.viewsets import GenericViewSet
|
||||
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct
|
||||
from apps.inm.signals import update_inm
|
||||
from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc
|
||||
from apps.mtm.serializers import RecordFormDetailSerializer, SubprodctionMaterialListSerializer, TechDocListSerializer
|
||||
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||
from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
|
||||
from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionProgressSerializer
|
||||
from apps.qm.models import TestRecord, TestRecordItem
|
||||
from apps.qm.serializers import TestRecordDetailSerializer
|
||||
|
||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||
from apps.system.mixins import CreateUpdateModelAMixin
|
||||
from rest_framework.decorators import action
|
||||
from apps.wf.models import Workflow
|
||||
from apps.wf.serializers import WorkflowSimpleSerializer
|
||||
from apps.wpm.filters import CuttingFilterSet, OperationRecordFilterSet, 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 CuttingListSerializer, OperationEquipListSerializer, OperationEquipUpdateSerializer, \
|
||||
OperationMaterialCreate1ListSerailizer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2ListSerailizer, \
|
||||
OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, \
|
||||
OperationRecordDetailSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, \
|
||||
OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, \
|
||||
OperationListSerializer, OperationWproductUpdateSerializer, PickHalfsSerializer, \
|
||||
PickSerializer, OperationInitSerializer, OperationSubmitSerializer, ScrapSerializer, WMaterialListSerializer, \
|
||||
WProductCardSerializer, WProductDetailSerializer, WProductListSerializer, \
|
||||
WpmTestFormInitSerializer, WproductMtestSerializer, 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, OperationWproductUpdateSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, ScrapSerializer, WMaterialListSerializer, WProductCardSerializer, WProductDetailSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestFormInitSerializer, WpmTestRecordCreateSerializer, WproductMtestSerializer, WproductPutInSerializer, WproductPutInsSerializer, WproductTicketListSerializer
|
||||
from rest_framework.response import Response
|
||||
from django.db import transaction
|
||||
from rest_framework import exceptions, serializers
|
||||
|
||||
from apps.wpm.services import WpmServies
|
||||
from django.utils import timezone
|
||||
from utils.tools import ranstr
|
||||
from rest_framework import status
|
||||
from django.db.models import Count
|
||||
|
||||
|
||||
# Create your views here.
|
||||
|
||||
|
||||
class WPlanViewSet(ListModelMixin, GenericViewSet):
|
||||
"""
|
||||
车间生产计划
|
||||
"""
|
||||
perms_map = {'*': '*'}
|
||||
queryset = SubProductionPlan.objects.select_related('process', 'workshop', 'subproduction', 'product').exclude(state=0)
|
||||
queryset = SubProductionPlan.objects.select_related(
|
||||
'process', 'workshop', 'subproduction', 'product').exclude(state=0)
|
||||
search_fields = []
|
||||
serializer_class = SubProductionPlanListSerializer
|
||||
filterset_fields = ['production_plan', 'process', 'state', 'product', 'workshop']
|
||||
filterset_fields = ['production_plan',
|
||||
'process', 'state', 'product', 'workshop']
|
||||
ordering_fields = []
|
||||
ordering = ['-update_time']
|
||||
|
||||
@action(methods=['post', 'get'], detail=True, perms_map={'post':'*', 'get':'*'}, serializer_class=PickHalfsSerializer)
|
||||
@action(methods=['post', 'get'], detail=True, perms_map={'post': '*', 'get': '*'}, serializer_class=PickHalfsSerializer)
|
||||
@transaction.atomic
|
||||
def pick_half(self, request, pk=None):
|
||||
"""
|
||||
领半成品
|
||||
"""
|
||||
sp = self.get_object()
|
||||
if request.method=='GET':
|
||||
if request.method == 'GET':
|
||||
"""
|
||||
领半成品
|
||||
"""
|
||||
spps = SubProductionProgress.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN,
|
||||
material__type=Material.MA_TYPE_HALFGOOD, subproduction_plan=sp).select_related('material')
|
||||
material__type=Material.MA_TYPE_HALFGOOD,
|
||||
subproduction_plan=sp).select_related('material')
|
||||
return Response(SubProductionProgressSerializer(instance=spps, many=True).data)
|
||||
elif request.method=='POST':
|
||||
serializer= PickHalfsSerializer(data=request.data)
|
||||
elif request.method == 'POST':
|
||||
serializer = PickHalfsSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.validated_data
|
||||
first_step = Step.objects.get(pk=sp.steps[0]['id'])
|
||||
|
|
@ -71,13 +82,14 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
|
|||
pick.create_by = request.user
|
||||
pick.save()
|
||||
for i in vdata:
|
||||
if 'wproducts' in i and len(i['wproducts'])>0:
|
||||
if 'wproducts' in i and len(i['wproducts']) > 0:
|
||||
spp = i['id']
|
||||
spp.count_pick = spp.count_pick + len(i['wproducts'])
|
||||
# if spp.count_pick > spp.count:
|
||||
# raise exceptions.APIException('超过计划数')
|
||||
spp.save()
|
||||
wps = WProduct.objects.filter(pk__in=[x.id for x in i['wproducts']], act_state=WProduct.WPR_ACT_STATE_OK)
|
||||
wps = WProduct.objects.filter(
|
||||
pk__in=[x.id for x in i['wproducts']], act_state=WProduct.WPR_ACT_STATE_OK)
|
||||
wps.update(step=first_step,
|
||||
act_state=WProduct.WPR_ACT_STATE_TORETEST, is_hidden=False, warehouse=None,
|
||||
subproduction_plan=sp, update_by=request.user, update_time=timezone.now())
|
||||
|
|
@ -91,9 +103,10 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
|
|||
m.update_by = request.user
|
||||
m.update_time = timezone.now()
|
||||
m.save()
|
||||
WpmServies.add_wproduct_flow_log(instance=m, change_str='pick_half')
|
||||
WpmServies.add_wproduct_flow_log(
|
||||
instance=m, change_str='pick_half')
|
||||
pw = PickWproduct()
|
||||
pw.pick =pick
|
||||
pw.pick = pick
|
||||
pw.wproduct = m
|
||||
pw.number = m.number
|
||||
pw.material = m.material
|
||||
|
|
@ -105,91 +118,35 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
|
|||
return Response()
|
||||
|
||||
|
||||
# @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WplanPutInSerializer)
|
||||
# @transaction.atomic
|
||||
# def putin(self, request, pk=None):
|
||||
# """
|
||||
# 半成品入库
|
||||
# """
|
||||
# serializer= WplanPutInSerializer(data=request.data)
|
||||
# serializer.is_valid(raise_exception=True)
|
||||
# vdata = serializer.validated_data
|
||||
# subplan = self.get_object()
|
||||
# material = subplan.product
|
||||
# batch = subplan.number
|
||||
# warehouse = vdata['warehouse']
|
||||
# wproducts = WProduct.objects.filter(subproduction_plan=subplan,
|
||||
# act_state=WProduct.WPR_ACT_STATE_OK, material=material, is_deleted=False)
|
||||
# if wproducts.exists():
|
||||
# # 创建入库记录
|
||||
# remark = vdata.get('remark', '')
|
||||
# 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)
|
||||
# # 创建入库明细
|
||||
# fifoitem = FIFOItem()
|
||||
# fifoitem.is_tested = True
|
||||
# fifoitem.is_testok = True
|
||||
# fifoitem.warehouse = warehouse
|
||||
# fifoitem.material = material
|
||||
# fifoitem.count = wproducts.count()
|
||||
# fifoitem.batch = batch
|
||||
# fifoitem.fifo = fifo
|
||||
# fifoitem.subproduction_plan = subplan
|
||||
# fifoitem.save()
|
||||
# # 创建入库明细半成品
|
||||
# ips = []
|
||||
# for i in wproducts:
|
||||
# ip = {}
|
||||
# ip['fifoitem'] = fifoitem
|
||||
# ip['wproduct'] = i
|
||||
# ip['number'] = i.number
|
||||
# ip['material'] = material
|
||||
# ips.append(FIFOItemProduct(**ip))
|
||||
# FIFOItemProduct.objects.bulk_create(ips)
|
||||
# # 创建IProduct
|
||||
# ips2 = []
|
||||
# for i in wproducts:
|
||||
# ip = {}
|
||||
# ip['warehouse'] = warehouse
|
||||
# ip['batch'] = batch
|
||||
# ip['wproduct'] = i
|
||||
# ip['number'] = i.number
|
||||
# ip['material'] = material
|
||||
# ips2.append(IProduct(**ip))
|
||||
# IProduct.objects.bulk_create(ips2)
|
||||
# # 更新库存并修改半成品进行状态
|
||||
# update_inm(fifo)
|
||||
# wproducts.update(act_sate=WProduct.WPR_ACT_STATE_INM, warehouse=warehouse, update_by=request.user, update_time=timezone.now())
|
||||
|
||||
# return Response()
|
||||
|
||||
|
||||
class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
|
||||
"""
|
||||
车间物料表
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
queryset = WMaterial.objects.select_related('material', 'subproduction_plan').filter(count__gt=0)
|
||||
perms_map = {'*': '*'}
|
||||
queryset = WMaterial.objects.select_related(
|
||||
'material', 'subproduction_plan').filter(count__gt=0)
|
||||
serializer_class = WMaterialListSerializer
|
||||
filterset_class = WMaterialFilterSet
|
||||
ordering_fields = ['material__number']
|
||||
ordering = ['material__number']
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=PickSerializer)
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=PickSerializer)
|
||||
def pick(self, request, pk=None):
|
||||
"""
|
||||
领料
|
||||
"""
|
||||
serializer= PickSerializer(data=request.data, context={'request': request})
|
||||
serializer = PickSerializer(
|
||||
data=request.data, context={'request': request})
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
return Response()
|
||||
|
||||
|
||||
class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||
"""
|
||||
半成品
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
perms_map = {'*': '*'}
|
||||
queryset = WProduct.objects.select_related('step', 'material',
|
||||
'subproduction_plan', 'warehouse').prefetch_related('wproduct_child')
|
||||
serializer_class = WProductListSerializer
|
||||
|
|
@ -209,7 +166,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
queryset = queryset.filter(is_hidden=False)
|
||||
return queryset
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestFormInitSerializer)
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=WpmTestFormInitSerializer)
|
||||
@transaction.atomic
|
||||
def test_init(self, request, pk=None):
|
||||
"""
|
||||
|
|
@ -225,11 +182,12 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
|
||||
# 根据情况创建一条检验记录
|
||||
if wproduct.act_state not in [WProduct.WPR_ACT_STATE_TOTEST,
|
||||
WProduct.WPR_ACT_STATE_TORETEST, WProduct.WPR_ACT_STATE_TOFINALTEST, WProduct.WPR_ACT_STATE_TOCOMBTEST]:
|
||||
WProduct.WPR_ACT_STATE_TORETEST, WProduct.WPR_ACT_STATE_TOFINALTEST,
|
||||
WProduct.WPR_ACT_STATE_TOCOMBTEST]:
|
||||
raise exceptions.APIException('该产品当前状态不可检验')
|
||||
|
||||
savedict = dict(
|
||||
create_by = self.request.user,
|
||||
create_by=self.request.user,
|
||||
wproduct=wproduct,
|
||||
material=wproduct.material,
|
||||
number=wproduct.number,
|
||||
|
|
@ -263,26 +221,29 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
tri.save()
|
||||
return Response(TestRecordDetailSerializer(instance=tr).data)
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WproductPutInsSerializer)
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=WproductPutInsSerializer)
|
||||
@transaction.atomic
|
||||
def putins(self, request, pk=None):
|
||||
"""
|
||||
半成品批量入库
|
||||
"""
|
||||
serializer= WproductPutInsSerializer(data=request.data)
|
||||
serializer = WproductPutInsSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.validated_data
|
||||
wproducts = WProduct.objects.filter(pk__in=[x.id for x in vdata['wproducts']])
|
||||
wproducts = WProduct.objects.filter(
|
||||
pk__in=[x.id for x in vdata['wproducts']])
|
||||
warehouse = vdata['warehouse']
|
||||
for i in wproducts:
|
||||
if i.act_state is not WProduct.WPR_ACT_STATE_OK:
|
||||
raise exceptions.APIException('存在不可入库半成品')
|
||||
# 聚合一下
|
||||
wproducts_a = wproducts.values('subproduction_plan', 'material', 'subproduction_plan__number').annotate(total=Count('id'))
|
||||
wproducts_a = wproducts.values(
|
||||
'subproduction_plan', 'material', 'subproduction_plan__number').annotate(total=Count('id'))
|
||||
# 创建入库记录
|
||||
remark = vdata.get('remark', '')
|
||||
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)
|
||||
# 创建入库明细
|
||||
for i in wproducts_a:
|
||||
spi = SubProductionPlan.objects.get(pk=i['subproduction_plan'])
|
||||
|
|
@ -297,7 +258,8 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
fifoitem.subproduction_plan = spi
|
||||
fifoitem.save()
|
||||
|
||||
wproducts_items = wproducts.filter(subproduction_plan=i['subproduction_plan'], material=i['material'])
|
||||
wproducts_items = wproducts.filter(
|
||||
subproduction_plan=i['subproduction_plan'], material=i['material'])
|
||||
ips = []
|
||||
for i in wproducts_items:
|
||||
# 创建入库明细半成品
|
||||
|
|
@ -319,13 +281,13 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
WpmServies.add_wproduct_flow_log(i, 'putins')
|
||||
return Response()
|
||||
|
||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer)
|
||||
@action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=WproductPutInSerializer)
|
||||
@transaction.atomic
|
||||
def putin(self, request, pk=None):
|
||||
"""
|
||||
半成品入库
|
||||
"""
|
||||
serializer= WproductPutInSerializer(data=request.data)
|
||||
serializer = WproductPutInSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.validated_data
|
||||
wproduct = self.get_object()
|
||||
|
|
@ -337,7 +299,8 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
# 创建入库记录
|
||||
remark = vdata.get('remark', '')
|
||||
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.is_tested = True
|
||||
|
|
@ -361,13 +324,13 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
FIFOItemProduct.objects.bulk_create(ips)
|
||||
# 更新库存并修改半成品进行状态
|
||||
update_inm(fifo)
|
||||
wproduct.act_state=WProduct.WPR_ACT_STATE_INM
|
||||
wproduct.warehouse=warehouse
|
||||
wproduct.act_state = WProduct.WPR_ACT_STATE_INM
|
||||
wproduct.warehouse = warehouse
|
||||
wproduct.save()
|
||||
WpmServies.add_wproduct_flow_log(wproduct, 'putin')
|
||||
return Response()
|
||||
|
||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=ScrapSerializer)
|
||||
@action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=ScrapSerializer)
|
||||
def scrap(self, request, pk=None):
|
||||
"""
|
||||
报废操作
|
||||
|
|
@ -391,7 +354,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
obj.update_time = timezone.now()
|
||||
obj.save()
|
||||
WpmServies.add_wproduct_flow_log(obj, 'scrap')
|
||||
if obj.step.process.id == 1: #如果是冷加工
|
||||
if obj.step.process.id == 1: # 如果是冷加工
|
||||
WpmServies.update_cutting_list_with_operation(obj.coperation)
|
||||
return Response()
|
||||
|
||||
|
|
@ -403,34 +366,36 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
# wfs = Workflow.objects.filter(key__startswith= 'wp_')
|
||||
# return WorkflowSimpleSerializer(instance=wfs, many=True).data
|
||||
|
||||
@action(methods=['get'], detail=True, perms_map={'get':'*'})
|
||||
@action(methods=['get'], detail=True, perms_map={'get': '*'})
|
||||
def wf_bhg(self, request, pk=None):
|
||||
"""
|
||||
发起不合格审理单
|
||||
"""
|
||||
obj = self.get_object()
|
||||
if obj.act_state != WProduct.WPR_ACT_STATE_NOTOK or obj.ng_sign is not None\
|
||||
if obj.act_state != WProduct.WPR_ACT_STATE_NOTOK or obj.ng_sign is not None \
|
||||
or obj.ticket is not None:
|
||||
raise exceptions.APIException('该产品不可发起不合格审理')
|
||||
workflow = Workflow.objects.filter(name='不合格品审理单', is_deleted=False).first()
|
||||
workflow = Workflow.objects.filter(
|
||||
name='不合格品审理单', is_deleted=False).first()
|
||||
if workflow:
|
||||
test_record = TestRecord.objects.filter(wproduct=obj, is_deleted=False, is_testok=False).order_by('-id').first()
|
||||
test_record = TestRecord.objects.filter(
|
||||
wproduct=obj, is_deleted=False, is_testok=False).order_by('-id').first()
|
||||
exist_data = {
|
||||
'wproduct':obj.id,
|
||||
'wproduct_number':obj.number,
|
||||
'wproduct_name':obj.material.name,
|
||||
'wproduct_specification':obj.material.specification,
|
||||
'finder':request.user.id,
|
||||
'find_process':obj.step.process.id,
|
||||
'tester':test_record.create_by.id
|
||||
'wproduct': obj.id,
|
||||
'wproduct_number': obj.number,
|
||||
'wproduct_name': obj.material.name,
|
||||
'wproduct_specification': obj.material.specification,
|
||||
'finder': request.user.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
|
||||
return Response(ret)
|
||||
else:
|
||||
raise exceptions.APIException('未找到对应审批流程')
|
||||
|
||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductMtestSerializer)
|
||||
@action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=WproductMtestSerializer)
|
||||
@transaction.atomic
|
||||
def mtest(self, request, pk=None):
|
||||
"""
|
||||
|
|
@ -446,7 +411,8 @@ 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(obj.subproduction_plan.production_plan)
|
||||
WpmServies.update_plan_state_by_mtestok(
|
||||
obj.subproduction_plan.production_plan)
|
||||
obj.save()
|
||||
change_str = 'mtest_notok'
|
||||
if is_mtestok:
|
||||
|
|
@ -454,7 +420,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
WpmServies.add_wproduct_flow_log(instance=obj, change_str=change_str)
|
||||
return Response()
|
||||
|
||||
@action(methods=['get'], detail=True, perms_map={'get':'*'})
|
||||
@action(methods=['get'], detail=True, perms_map={'get': '*'})
|
||||
def card(self, request, pk=None):
|
||||
"""
|
||||
流程卡
|
||||
|
|
@ -469,35 +435,40 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
|||
ret.append(line1)
|
||||
steps_list_full_1 = card_data['parents'][0]['step_list_full']
|
||||
for index, item in enumerate(steps_list_full_1):
|
||||
linex = [str(index+1), item['step_name']]
|
||||
linex = [str(index + 1), item['step_name']]
|
||||
for i in card_data['parents']:
|
||||
linex.append(i['step_list_full'][index]['actions'])
|
||||
ret.append(linex)
|
||||
ret.append(['序号', '工序', card_data['number']])
|
||||
step_list_full = card_data['step_list_full']
|
||||
for index, item in enumerate(step_list_full):
|
||||
ret.append([str(index+1), item['step_name'], item['actions']])
|
||||
ret.append([str(index + 1), item['step_name'], item['actions']])
|
||||
return Response(ret)
|
||||
|
||||
|
||||
class WproductTicketViewSet(ListModelMixin, GenericViewSet):
|
||||
"""
|
||||
玻璃审批工单
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
perms_map = {'*': '*'}
|
||||
queryset = WprouctTicket.objects.select_related('step', 'material', 'subproduction_plan',
|
||||
'resp_process', 'subproduction_plan__production_plan__order', 'subproduction_plan__production_plan')
|
||||
'resp_process', 'subproduction_plan__production_plan__order',
|
||||
'subproduction_plan__production_plan')
|
||||
serializer_class = WproductTicketListSerializer
|
||||
filterset_fields = ['step', 'material', 'subproduction_plan', 'resp_process']
|
||||
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):
|
||||
"""
|
||||
生产操作记录
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
queryset = Operation.objects.select_related('step').prefetch_related('ow_operation', 'oe_operation', 'or_operation').all()
|
||||
perms_map = {'*': '*'}
|
||||
queryset = Operation.objects.select_related('step').prefetch_related(
|
||||
'ow_operation', 'oe_operation', 'or_operation').all()
|
||||
serializer_class = OperationListSerializer
|
||||
filterset_fields = ['step', 'step__process', 'is_submited']
|
||||
ordering_fields = ['id']
|
||||
|
|
@ -537,9 +508,10 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
@transaction.atomic
|
||||
def create(self, request, *args, **kwargs):
|
||||
data = request.data
|
||||
serializer = OperationCreateSerializer(data=data, context={'request':self.request})
|
||||
serializer = OperationCreateSerializer(
|
||||
data=data, context={'request': self.request})
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.validated_data #校验之后的数据
|
||||
vdata = serializer.validated_data # 校验之后的数据
|
||||
step = vdata['step']
|
||||
op = Operation()
|
||||
op.step = step
|
||||
|
|
@ -550,9 +522,10 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
# 创建操作所用半成品关联记录
|
||||
if 'wproducts' in vdata:
|
||||
owps = []
|
||||
splans = WpmServies.get_subplans_queryset_from_wproducts(vdata['wproducts'])
|
||||
splans = WpmServies.get_subplans_queryset_from_wproducts(
|
||||
vdata['wproducts'])
|
||||
for wpd in vdata['wproducts']:
|
||||
wpd.operation= op
|
||||
wpd.operation = op
|
||||
wpd.act_state = WProduct.WPR_ACT_STATE_DOING
|
||||
wpd.update_by = request.user
|
||||
wpd.save()
|
||||
|
|
@ -567,9 +540,11 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
owps.append(OperationWproduct(**owp))
|
||||
OperationWproduct.objects.bulk_create(owps)
|
||||
else:
|
||||
splans = WpmServies.get_subplans_queryset_from_wproducts(vdata['wproducts'])
|
||||
splans = WpmServies.get_subplans_queryset_from_wproducts(
|
||||
vdata['wproducts'])
|
||||
# 查询需要填写的自定义表格
|
||||
forms = RecordForm.objects.filter(step=step, type=RecordForm.RF_TYPE_DO, enabled=True)
|
||||
forms = RecordForm.objects.filter(
|
||||
step=step, type=RecordForm.RF_TYPE_DO, enabled=True)
|
||||
for i in forms:
|
||||
opr = OperationRecord()
|
||||
opr.operation = op
|
||||
|
|
@ -591,7 +566,8 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
ope.save()
|
||||
# 查询所需的工具工装
|
||||
for i in SubprodctionMaterial.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL,
|
||||
subproduction__subplan_subprod__in = splans, is_deleted=False).distinct():
|
||||
subproduction__subplan_subprod__in=splans,
|
||||
is_deleted=False).distinct():
|
||||
opm = OperationMaterial()
|
||||
opm.operation = op
|
||||
opm.material = i.material
|
||||
|
|
@ -599,7 +575,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
opm.save()
|
||||
return Response()
|
||||
|
||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
|
||||
@action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=serializers.Serializer)
|
||||
@transaction.atomic
|
||||
def submit(self, request, pk=None):
|
||||
"""
|
||||
|
|
@ -616,7 +592,8 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
# 校验消耗产出是否正确填写
|
||||
if op.step.type == Step.STEP_TYPE_DIV:
|
||||
sps_omi_l = omis.values_list('subproduction_plan', flat=True)
|
||||
sps_omo_l = omos.filter(use_scrap=False).values_list('subproduction_plan', flat=True)
|
||||
sps_omo_l = omos.filter(use_scrap=False).values_list(
|
||||
'subproduction_plan', flat=True)
|
||||
if set(list(sps_omi_l)) != set(list(sps_omo_l)):
|
||||
raise exceptions.APIException('消耗与产出不一致')
|
||||
|
||||
|
|
@ -629,7 +606,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
for i in omis:
|
||||
# 更新车间物料
|
||||
i_wmat = i.wmaterial
|
||||
i_wmat.count = i_wmat.count- i.count
|
||||
i_wmat.count = i_wmat.count - i.count
|
||||
i_wmat.save()
|
||||
# 更新子计划物料消耗情况
|
||||
spp = SubProductionProgress.objects.get(subproduction_plan=i_wmat.subproduction_plan,
|
||||
|
|
@ -640,7 +617,8 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
for i in omos:
|
||||
if not i.subproduction_progress.is_main:
|
||||
# 更新车间物料产出情况
|
||||
ins, _ = WMaterial.objects.get_or_create(subproduction_plan=i.subproduction_plan, material=i.material)
|
||||
ins, _ = WMaterial.objects.get_or_create(
|
||||
subproduction_plan=i.subproduction_plan, material=i.material)
|
||||
ins.count = ins.count + i.count
|
||||
ins.save()
|
||||
# 更新子计划物料产出情况
|
||||
|
|
@ -659,7 +637,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
wp.step = newstep
|
||||
wp.pre_step = step
|
||||
if hasNext:
|
||||
wp.act_state= WProduct.WPR_ACT_STATE_DOWAIT
|
||||
wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
||||
else:
|
||||
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
||||
wp.material = wsp.product
|
||||
|
|
@ -678,7 +656,8 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
raise exceptions.APIException('请选择物料产出')
|
||||
for i in omos:
|
||||
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,
|
||||
act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='',
|
||||
subproduction_plan=i.subproduction_plan,
|
||||
|
|
@ -686,15 +665,18 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
for x in range(i.count):
|
||||
ins = WProduct.objects.create(**wpr)
|
||||
# 添加日志
|
||||
WpmServies.add_wproduct_flow_log(ins, 'wproduct_create')
|
||||
WpmServies.add_wproduct_flow_log(
|
||||
ins, 'wproduct_create')
|
||||
# 更新进度
|
||||
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:
|
||||
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(oms_w.subproduction_plan, step)
|
||||
newstep, hasNext = WpmServies.get_next_step(
|
||||
oms_w.subproduction_plan, step)
|
||||
wproduct = WProduct()
|
||||
wproduct.material = oms_w.material
|
||||
wproduct.step = newstep
|
||||
|
|
@ -704,32 +686,34 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
else:
|
||||
wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
||||
# 更新子计划进度
|
||||
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.coperation = op
|
||||
wproduct.save()
|
||||
WpmServies.add_wproduct_flow_log(wproduct, 'wproduct_create')
|
||||
# 隐藏原半成品
|
||||
wps = WProduct.objects.filter(ow_wproduct__operation = op)
|
||||
wps.update(is_hidden=True, child=wproduct, update_by=request.user, update_time=timezone.now())
|
||||
wps = WProduct.objects.filter(ow_wproduct__operation=op)
|
||||
wps.update(is_hidden=True, child=wproduct,
|
||||
update_by=request.user, update_time=timezone.now())
|
||||
else:
|
||||
raise exceptions.APIException('产出物料未填写或填写错误')
|
||||
op.is_submited = True
|
||||
op.save()
|
||||
|
||||
# 如果是冷加工
|
||||
if step.process.id==1:
|
||||
if step.process.id == 1:
|
||||
WpmServies.update_cutting_list_with_operation(op=op)
|
||||
return Response()
|
||||
|
||||
|
||||
|
||||
class OperationWproductViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet):
|
||||
"""
|
||||
操作使用的半成品
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
queryset = OperationWproduct.objects.select_related('subproduction_plan', 'material').all()
|
||||
perms_map = {'*': '*'}
|
||||
queryset = OperationWproduct.objects.select_related(
|
||||
'subproduction_plan', 'material').all()
|
||||
serializer_class = OperationWproductListSerializer
|
||||
filterset_fields = ['material', 'subproduction_plan', 'operation']
|
||||
ordering_fields = ['id']
|
||||
|
|
@ -751,12 +735,14 @@ class OperationWproductViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMix
|
|||
wp.save()
|
||||
return Response()
|
||||
|
||||
|
||||
class OperationEquipViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet):
|
||||
"""
|
||||
操作使用的设备
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
queryset = OperationEquip.objects.select_related('operation', 'equip').all()
|
||||
perms_map = {'*': '*'}
|
||||
queryset = OperationEquip.objects.select_related(
|
||||
'operation', 'equip').all()
|
||||
serializer_class = OperationEquipListSerializer
|
||||
filterset_fields = ['operation', 'equip']
|
||||
ordering_fields = ['id']
|
||||
|
|
@ -781,12 +767,14 @@ class OperationEquipViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin,
|
|||
instance.delete()
|
||||
return Response()
|
||||
|
||||
|
||||
class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||
"""
|
||||
操作使用的自定义表格
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
queryset = OperationRecord.objects.select_related('operation', 'form').all()
|
||||
perms_map = {'*': '*'}
|
||||
queryset = OperationRecord.objects.select_related(
|
||||
'operation', 'form').all()
|
||||
serializer_class = OperationRecordListSerializer
|
||||
filterset_class = OperationRecordFilterSet
|
||||
ordering_fields = ['id']
|
||||
|
|
@ -798,6 +786,7 @@ class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin
|
|||
elif self.action == 'retrieve':
|
||||
return OperationRecordDetailSerializer
|
||||
return super().get_serializer_class()
|
||||
|
||||
@transaction.atomic()
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
|
|
@ -806,7 +795,6 @@ class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin
|
|||
instance.delete()
|
||||
return Response()
|
||||
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
serializer = OperationRecordSubmitSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
|
@ -828,8 +816,9 @@ class OperationMaterialInputViewSet(ListModelMixin, CreateModelMixin, DestroyMod
|
|||
"""
|
||||
消耗物料
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
queryset = OperationMaterial.objects.select_related('operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN)
|
||||
perms_map = {'*': '*'}
|
||||
queryset = OperationMaterial.objects.select_related(
|
||||
'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN)
|
||||
serializer_class = OperationMaterialListSerializer
|
||||
filterset_fields = ['operation', 'subproduction_plan']
|
||||
ordering_fields = ['id']
|
||||
|
|
@ -840,7 +829,8 @@ class OperationMaterialInputViewSet(ListModelMixin, CreateModelMixin, DestroyMod
|
|||
return OperationMaterialCreate1Serailizer
|
||||
return super().get_serializer_class()
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=OperationMaterialCreate1ListSerailizer)
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'},
|
||||
serializer_class=OperationMaterialCreate1ListSerailizer)
|
||||
def creates(self, request, pk=None):
|
||||
"""
|
||||
批量创建消耗物料
|
||||
|
|
@ -850,7 +840,6 @@ class OperationMaterialInputViewSet(ListModelMixin, CreateModelMixin, DestroyMod
|
|||
serializer.save()
|
||||
return Response()
|
||||
|
||||
|
||||
@transaction.atomic()
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
|
|
@ -859,13 +848,16 @@ class OperationMaterialInputViewSet(ListModelMixin, CreateModelMixin, DestroyMod
|
|||
instance.delete()
|
||||
return Response()
|
||||
|
||||
|
||||
class CuttingListViewSet(ListModelMixin, GenericViewSet):
|
||||
"""
|
||||
下料清单
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
perms_map = {'*': '*'}
|
||||
queryset = OperationMaterial.objects.select_related('operation',
|
||||
'subproduction_plan', 'material', 'operation__create_by').filter(operation__step__id=1, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||
'subproduction_plan', 'material',
|
||||
'operation__create_by').filter(operation__step__id=1,
|
||||
type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||
serializer_class = CuttingListSerializer
|
||||
filterset_class = CuttingFilterSet
|
||||
ordering_fields = ['id']
|
||||
|
|
@ -876,8 +868,9 @@ class OperationMaterialOutputViewSet(ListModelMixin, CreateModelMixin, DestroyMo
|
|||
"""
|
||||
产出物料
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
queryset = OperationMaterial.objects.select_related('operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||
perms_map = {'*': '*'}
|
||||
queryset = OperationMaterial.objects.select_related(
|
||||
'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||
serializer_class = OperationMaterialListSerializer
|
||||
filterset_fields = ['operation', 'subproduction_plan']
|
||||
ordering_fields = ['id']
|
||||
|
|
@ -888,7 +881,8 @@ class OperationMaterialOutputViewSet(ListModelMixin, CreateModelMixin, DestroyMo
|
|||
return OperationMaterialCreate2Serailizer
|
||||
return super().get_serializer_class()
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=OperationMaterialCreate2ListSerailizer)
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'},
|
||||
serializer_class=OperationMaterialCreate2ListSerailizer)
|
||||
def creates(self, request, pk=None):
|
||||
"""
|
||||
批量创建产出物料
|
||||
|
|
@ -906,12 +900,14 @@ class OperationMaterialOutputViewSet(ListModelMixin, CreateModelMixin, DestroyMo
|
|||
instance.delete()
|
||||
return Response()
|
||||
|
||||
|
||||
class OperationMaterialToolViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
|
||||
"""
|
||||
工具工装
|
||||
"""
|
||||
perms_map={'*':'*'}
|
||||
queryset = OperationMaterial.objects.select_related('operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL)
|
||||
perms_map = {'*': '*'}
|
||||
queryset = OperationMaterial.objects.select_related(
|
||||
'operation', 'subproduction_plan').filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL)
|
||||
serializer_class = OperationMaterialListSerializer
|
||||
filterset_fields = ['operation', 'subproduction_plan']
|
||||
ordering_fields = ['id']
|
||||
|
|
@ -930,9 +926,11 @@ class OperationMaterialToolViewSet(ListModelMixin, CreateModelMixin, DestroyMode
|
|||
instance.delete()
|
||||
return Response()
|
||||
|
||||
|
||||
class DoFormInit(CreateAPIView, GenericAPIView):
|
||||
perms_map={'*':'*'}
|
||||
serializer_class=OperationInitSerializer
|
||||
perms_map = {'*': '*'}
|
||||
serializer_class = OperationInitSerializer
|
||||
|
||||
def post(self, request, format=None):
|
||||
"""
|
||||
调用操作表单
|
||||
|
|
@ -944,23 +942,27 @@ class DoFormInit(CreateAPIView, GenericAPIView):
|
|||
ret = {}
|
||||
ret_0 = {}
|
||||
ret_0['step'] = data['step']
|
||||
splans =[]
|
||||
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)
|
||||
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
|
||||
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)
|
||||
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
|
||||
|
||||
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
|
||||
|
|
@ -974,30 +976,34 @@ class DoFormInit(CreateAPIView, GenericAPIView):
|
|||
# 此时显示所有子计划需要输出的物料
|
||||
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'))
|
||||
ret_0['output'] = list(o_objs.values(
|
||||
'subproduction_plan', 'material', 'material__name', 'material__number'))
|
||||
for i in ret_0['output']:
|
||||
i['count_output']=0
|
||||
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['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)\
|
||||
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)
|
||||
forms = RecordForm.objects.filter(
|
||||
step=vdata['step'], type=RecordForm.RF_TYPE_DO)
|
||||
if forms.exists():
|
||||
ret['forms'].extend(RecordFormDetailSerializer(instance=forms, many=True).data)
|
||||
ret['forms'].extend(RecordFormDetailSerializer(
|
||||
instance=forms, many=True).data)
|
||||
return Response(ret)
|
||||
|
||||
|
||||
class DoFormSubmit(CreateAPIView, GenericAPIView):
|
||||
perms_map={'*':'*'}
|
||||
perms_map = {'*': '*'}
|
||||
serializer_class = OperationSubmitSerializer
|
||||
|
||||
@transaction.atomic
|
||||
|
|
@ -1006,9 +1012,10 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
|
|||
提交操作表单
|
||||
"""
|
||||
data = request.data
|
||||
serializer = OperationSubmitSerializer(data=data, context={'request':self.request})
|
||||
serializer = OperationSubmitSerializer(
|
||||
data=data, context={'request': self.request})
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.validated_data #校验之后的数据
|
||||
vdata = serializer.validated_data # 校验之后的数据
|
||||
|
||||
# 创建一个生产操作记录
|
||||
action_obj = Operation()
|
||||
|
|
@ -1034,12 +1041,12 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
|
|||
|
||||
# 保存物料消耗
|
||||
for i in vdata['input']:
|
||||
if i['count_input']: #如果有消耗
|
||||
if i['count_input']: # 如果有消耗
|
||||
i_wmat = i['id']
|
||||
OperationMaterial.objects.create(type=1, operation=action_obj,
|
||||
wmaterial= i_wmat, count=i['count_input'])
|
||||
wmaterial=i_wmat, count=i['count_input'])
|
||||
# 更新车间物料
|
||||
i_wmat.count = 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,
|
||||
|
|
@ -1055,7 +1062,8 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
|
|||
# 如果是切割
|
||||
# 获取下一步子工序
|
||||
if vdata['step'].type == Step.STEP_TYPE_DIV:
|
||||
newstep, _ = WpmServies.get_next_step(i['subproduction_plan'], vdata['step'])
|
||||
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'])
|
||||
|
|
@ -1064,7 +1072,7 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
|
|||
else:
|
||||
# 更新操作产出物料表
|
||||
OperationMaterial.objects.create(type=2, operation=action_obj,
|
||||
material= ma, count=i['count_output'])
|
||||
material=ma, count=i['count_output'])
|
||||
# 更新车间物料表
|
||||
ins, _ = WMaterial.objects.get_or_create(subproduction_plan=i['subproduction_plan'],
|
||||
material=ma)
|
||||
|
|
@ -1082,30 +1090,32 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
|
|||
wproducts = vdata['wproducts']
|
||||
if 'suproduction_plan' in vdata:
|
||||
wproducts.update(is_hidden=True) # 隐藏
|
||||
newstep, hasNext = WpmServies.get_next_step(i['subproduction_plan'], vdata['step'])
|
||||
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.subproduction_plan = vdata['subproduction_plan']
|
||||
wproduct.parent = data['wproducts']
|
||||
if hasNext:
|
||||
wproduct.act_state=WProduct.WPR_ACT_STATE_DOWAIT
|
||||
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
||||
else:
|
||||
wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST
|
||||
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'])
|
||||
newstep, hasNext = WpmServies.get_next_step(
|
||||
wproduct.subproduction_plan, vdata['step'])
|
||||
wproduct.step = newstep
|
||||
wproduct.pre_step=vdata['step']
|
||||
wproduct.pre_step = vdata['step']
|
||||
if hasNext:
|
||||
wproduct.act_state=WProduct.WPR_ACT_STATE_DOWAIT
|
||||
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
||||
else:
|
||||
wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST
|
||||
wproduct.material=wproduct.subproduction_plan.product
|
||||
wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
||||
wproduct.material = wproduct.subproduction_plan.product
|
||||
wproduct.save()
|
||||
|
||||
# 保存自定义表单结果
|
||||
|
|
@ -1127,5 +1137,3 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
|
|||
wrds.append(OperationRecordItem(**m))
|
||||
OperationRecordItem.objects.bulk_create(wrds)
|
||||
return Response()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue