批量入库remark非必填
This commit is contained in:
parent
43a936b7d9
commit
ef007e728a
|
|
@ -1,5 +1,6 @@
|
||||||
.vscode/
|
.vscode/
|
||||||
.vs/
|
.vs/
|
||||||
|
.idea/
|
||||||
venv/
|
venv/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ class WareHouse(CommonAModel):
|
||||||
number = models.CharField('仓库编号', max_length=20, unique=True)
|
number = models.CharField('仓库编号', max_length=20, unique=True)
|
||||||
name = models.CharField('仓库名称', max_length=20, unique=True)
|
name = models.CharField('仓库名称', max_length=20, unique=True)
|
||||||
place = models.CharField('具体地点', max_length=50)
|
place = models.CharField('具体地点', max_length=50)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '仓库信息'
|
verbose_name = '仓库信息'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
@ -24,37 +25,44 @@ class WareHouse(CommonAModel):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class Inventory(BaseModel):
|
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)
|
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:
|
class Meta:
|
||||||
verbose_name = '库存表'
|
verbose_name = '库存表'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
|
|
||||||
class MaterialBatch(BaseModel):
|
class MaterialBatch(BaseModel):
|
||||||
"""
|
"""
|
||||||
物料批次
|
物料批次
|
||||||
"""
|
"""
|
||||||
material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息')
|
material = models.ForeignKey(
|
||||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
Material, on_delete=models.CASCADE, verbose_name='物料信息')
|
||||||
|
warehouse = models.ForeignKey(
|
||||||
|
WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||||
count = models.PositiveIntegerField('存量', default=0)
|
count = models.PositiveIntegerField('存量', default=0)
|
||||||
batch = models.CharField('批次号', max_length=100, default='')
|
batch = models.CharField('批次号', max_length=100, default='')
|
||||||
expiration_date = models.DateField('有效期', null=True, blank=True)
|
expiration_date = models.DateField('有效期', null=True, blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '库存表'
|
verbose_name = '库存表'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FIFO(CommonADModel):
|
class FIFO(CommonADModel):
|
||||||
"""
|
"""
|
||||||
出入库记录
|
出入库记录
|
||||||
"""
|
"""
|
||||||
FIFO_TYPE_DO_OUT = 1 # 生产领料
|
FIFO_TYPE_DO_OUT = 1 # 生产领料
|
||||||
FIFO_TYPE_SALE_OUT = 2
|
FIFO_TYPE_SALE_OUT = 2
|
||||||
FIFO_TYPE_PUR_IN = 3
|
FIFO_TYPE_PUR_IN = 3
|
||||||
FIFO_TYPE_DO_IN = 4
|
FIFO_TYPE_DO_IN = 4
|
||||||
|
|
@ -66,7 +74,8 @@ class FIFO(CommonADModel):
|
||||||
)
|
)
|
||||||
type = models.IntegerField('出入库类型', default=1)
|
type = models.IntegerField('出入库类型', default=1)
|
||||||
is_audited = models.BooleanField('是否审核', default=False)
|
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('出入库日期')
|
inout_date = models.DateField('出入库日期')
|
||||||
remark = models.CharField('备注', max_length=1000, default='')
|
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_tested = models.BooleanField('是否已检验', default=False)
|
||||||
is_testok = models.BooleanField('是否检验合格', default=False)
|
is_testok = models.BooleanField('是否检验合格', default=False)
|
||||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
|
warehouse = models.ForeignKey(
|
||||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
|
||||||
|
material = models.ForeignKey(
|
||||||
|
Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||||
count = models.PositiveIntegerField('数量', default=0)
|
count = models.PositiveIntegerField('数量', default=0)
|
||||||
batch = models.CharField('批次号', max_length=100, default='')
|
batch = models.CharField('批次号', max_length=100, default='')
|
||||||
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE)
|
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库',
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
|
on_delete=models.CASCADE)
|
||||||
|
subproduction_plan = models.ForeignKey(
|
||||||
|
SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
|
||||||
|
|
||||||
class IProduct(BaseModel):
|
class IProduct(BaseModel):
|
||||||
"""
|
"""
|
||||||
具体产品条目
|
具体产品条目
|
||||||
"""
|
"""
|
||||||
number = models.CharField('物品编号', unique=True, max_length=50)
|
number = models.CharField('物品编号', unique=True, max_length=50)
|
||||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
material = models.ForeignKey(
|
||||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||||
|
warehouse = models.ForeignKey(
|
||||||
|
WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||||
batch = models.CharField('所属批次号', max_length=100, default='')
|
batch = models.CharField('所属批次号', max_length=100, default='')
|
||||||
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False,
|
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False,
|
||||||
null=True, blank=True, related_name='iproduct_wproduct')
|
null=True, blank=True, related_name='iproduct_wproduct')
|
||||||
is_saled = models.BooleanField('是否售出', default=False)
|
is_saled = models.BooleanField('是否售出', default=False)
|
||||||
|
|
||||||
|
|
||||||
class FIFOItemProduct(BaseModel):
|
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,
|
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True,
|
||||||
related_name='fifoitem_wproduct')
|
related_name='fifoitem_wproduct')
|
||||||
number = models.CharField('物品编号', max_length=50)
|
number = models.CharField('物品编号', max_length=50)
|
||||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
material = models.ForeignKey(
|
||||||
iproduct = models.ForeignKey(IProduct, verbose_name='关联库存产品', null=True, blank=True, on_delete=models.SET_NULL)
|
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 rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
from apps.inm.filters import IProductFilterSet, MbFilterSet
|
from apps.inm.filters import IProductFilterSet, MbFilterSet
|
||||||
|
|
||||||
from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse,Inventory
|
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.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, IProductListSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer, InventorySerializer
|
||||||
from apps.inm.signals import update_inm
|
from apps.inm.signals import update_inm
|
||||||
from apps.mtm.models import Material
|
from apps.mtm.models import Material
|
||||||
from apps.pm.services import PmService
|
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.decorators import action
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from apps.wpm.services import WpmServies
|
from apps.wpm.services import WpmServies
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
"""
|
"""
|
||||||
仓库-增删改查
|
仓库-增删改查
|
||||||
|
|
@ -32,26 +35,30 @@ class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
ordering_fields = ['create_time']
|
ordering_fields = ['create_time']
|
||||||
ordering = ['-create_time']
|
ordering = ['-create_time']
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action in ['create', 'update']:
|
if self.action in ['create', 'update']:
|
||||||
return WareHouseCreateUpdateSerializer
|
return WareHouseCreateUpdateSerializer
|
||||||
return WareHouseSerializer
|
return WareHouseSerializer
|
||||||
|
|
||||||
|
|
||||||
class InventoryViewSet(ListModelMixin, GenericViewSet):
|
class InventoryViewSet(ListModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
仓库物料表
|
仓库物料表
|
||||||
"""
|
"""
|
||||||
perms_map = {'*': '*'}
|
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
|
serializer_class = InventorySerializer
|
||||||
filterset_fields = ['material', 'warehouse']
|
filterset_fields = ['material', 'warehouse']
|
||||||
search_fields = []
|
search_fields = []
|
||||||
ordering_fields = ['create_time']
|
ordering_fields = ['create_time']
|
||||||
ordering = ['-create_time']
|
ordering = ['-create_time']
|
||||||
|
|
||||||
|
|
||||||
class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
|
class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
|
||||||
perms_map = {'*': '*'}
|
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
|
serializer_class = MaterialBatchSerializer
|
||||||
# filterset_fields = ['material', 'warehouse']
|
# filterset_fields = ['material', 'warehouse']
|
||||||
filterset_class = MbFilterSet
|
filterset_class = MbFilterSet
|
||||||
|
|
@ -59,7 +66,7 @@ class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
|
||||||
ordering_fields = ['create_time']
|
ordering_fields = ['create_time']
|
||||||
ordering = ['-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):
|
def query(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
复杂查询
|
复杂查询
|
||||||
|
|
@ -67,9 +74,11 @@ class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
|
||||||
data = request.data
|
data = request.data
|
||||||
serializer = MaterialBatchQuerySerializer(data=data)
|
serializer = MaterialBatchQuerySerializer(data=data)
|
||||||
serializer.is_valid(raise_exception=True)
|
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)
|
return Response(MaterialBatchSerializer(instance=queryset, many=True).data)
|
||||||
|
|
||||||
|
|
||||||
class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
出入库记录详情表
|
出入库记录详情表
|
||||||
|
|
@ -77,7 +86,8 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
perms_map = {'*': '*'}
|
perms_map = {'*': '*'}
|
||||||
queryset = FIFOItem.objects.select_related('material', 'fifo').all()
|
queryset = FIFOItem.objects.select_related('material', 'fifo').all()
|
||||||
serializer_class = FIFOItemSerializer
|
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 = []
|
search_fields = []
|
||||||
ordering_fields = ['create_time']
|
ordering_fields = ['create_time']
|
||||||
ordering = ['-create_time']
|
ordering = ['-create_time']
|
||||||
|
|
@ -87,7 +97,7 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
raise APIException('该出入库记录已通过审核, 无法删除')
|
raise APIException('该出入库记录已通过审核, 无法删除')
|
||||||
return super().perform_destroy(instance)
|
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):
|
def test(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
检验
|
检验
|
||||||
|
|
@ -99,9 +109,9 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
if 'is_testok' not in vdata:
|
if 'is_testok' not in vdata:
|
||||||
raise APIException('未填写检验结论')
|
raise APIException('未填写检验结论')
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
obj = serializer.save(create_by = self.request.user)
|
obj = serializer.save(create_by=self.request.user)
|
||||||
tris = []
|
tris = []
|
||||||
for m in record_data: # 保存记录详情
|
for m in record_data: # 保存记录详情
|
||||||
m['field_value'] = m['field_value']
|
m['field_value'] = m['field_value']
|
||||||
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
|
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
|
||||||
m['test_record'] = obj
|
m['test_record'] = obj
|
||||||
|
|
@ -115,6 +125,7 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
obj.fifo_item.save()
|
obj.fifo_item.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
出入库记录
|
出入库记录
|
||||||
|
|
@ -131,14 +142,14 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
if self.action == 'list':
|
if self.action == 'list':
|
||||||
return FIFOListSerializer
|
return FIFOListSerializer
|
||||||
return super().get_serializer_class()
|
return super().get_serializer_class()
|
||||||
|
|
||||||
def destroy(self, request, *args, **kwargs):
|
def destroy(self, request, *args, **kwargs):
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
if obj.is_submited:
|
if obj.is_submited:
|
||||||
raise exceptions.APIException('该记录已审核,不可删除')
|
raise exceptions.APIException('该记录已审核,不可删除')
|
||||||
return super().destroy(request, *args, **kwargs)
|
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):
|
def in_pur(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
采购入库
|
采购入库
|
||||||
|
|
@ -148,7 +159,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
serializer.save(create_by=request.user)
|
serializer.save(create_by=request.user)
|
||||||
return Response()
|
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):
|
def audit(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
审核通过
|
审核通过
|
||||||
|
|
@ -162,19 +173,21 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
obj.is_audited = True
|
obj.is_audited = True
|
||||||
obj.auditor = request.user
|
obj.auditor = request.user
|
||||||
|
obj.inout_date = timezone.now() # 也是审核日期
|
||||||
obj.save()
|
obj.save()
|
||||||
update_inm(obj) # 更新库存
|
update_inm(obj) # 更新库存
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
class IProductViewSet(ListModelMixin, GenericViewSet):
|
class IProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
半成品库存表
|
半成品库存表
|
||||||
"""
|
"""
|
||||||
perms_map = {'*': '*'}
|
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
|
serializer_class = IProductListSerializer
|
||||||
filterset_class = IProductFilterSet
|
filterset_class = IProductFilterSet
|
||||||
search_fields = []
|
search_fields = []
|
||||||
ordering_fields = ['create_time']
|
ordering_fields = ['create_time']
|
||||||
ordering = ['-create_time']
|
ordering = ['-create_time']
|
||||||
|
|
|
||||||
|
|
@ -4,39 +4,50 @@ from apps.mtm.models import Material, Step
|
||||||
from apps.wpm.services import WpmServies
|
from apps.wpm.services import WpmServies
|
||||||
from .models import Operation, OperationMaterial, OperationRecord, WMaterial, WProduct
|
from .models import Operation, OperationMaterial, OperationRecord, WMaterial, WProduct
|
||||||
|
|
||||||
|
|
||||||
class WMaterialFilterSet(filters.FilterSet):
|
class WMaterialFilterSet(filters.FilterSet):
|
||||||
|
|
||||||
operation = filters.NumberFilter(method='filter_operation')
|
operation = filters.NumberFilter(method='filter_operation')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WMaterial
|
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):
|
def filter_operation(self, queryset, name, value):
|
||||||
operation = Operation.objects.get(pk=value)
|
operation = Operation.objects.get(pk=value)
|
||||||
wproducts = WProduct.objects.filter(ow_wproduct__operation=value)
|
wproducts = WProduct.objects.filter(ow_wproduct__operation=value)
|
||||||
step = operation.step
|
step = operation.step
|
||||||
if wproducts.exists():
|
if wproducts.exists():
|
||||||
subplans = WpmServies.get_subplans_queryset_from_wproducts(wproducts)
|
subplans = WpmServies.get_subplans_queryset_from_wproducts(
|
||||||
|
wproducts)
|
||||||
else:
|
else:
|
||||||
subplans = WpmServies.get_subplans_queyset_from_step(step)
|
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
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class WProductFilterSet(filters.FilterSet):
|
class WProductFilterSet(filters.FilterSet):
|
||||||
tag = filters.CharFilter(method='filter_tag')
|
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:
|
class Meta:
|
||||||
model = WProduct
|
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):
|
def filter_tag(self, queryset, name, value):
|
||||||
if value == 'no_scrap':
|
if value == 'no_scrap':
|
||||||
queryset = queryset.exclude(act_state=WProduct.WPR_ACT_STATE_SCRAP)
|
queryset = queryset.exclude(act_state=WProduct.WPR_ACT_STATE_SCRAP)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class CuttingFilterSet(filters.FilterSet):
|
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:
|
class Meta:
|
||||||
model = OperationMaterial
|
model = OperationMaterial
|
||||||
fields = ['operation', 'subproduction_plan', 'material']
|
fields = ['operation', 'subproduction_plan', 'material']
|
||||||
|
|
@ -44,10 +55,11 @@ class CuttingFilterSet(filters.FilterSet):
|
||||||
|
|
||||||
class OperationRecordFilterSet(filters.FilterSet):
|
class OperationRecordFilterSet(filters.FilterSet):
|
||||||
wproduct = filters.NumberFilter(method='filter_wproduct')
|
wproduct = filters.NumberFilter(method='filter_wproduct')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OperationRecord
|
model = OperationRecord
|
||||||
fields = ['operation', 'form']
|
fields = ['operation', 'form']
|
||||||
|
|
||||||
def filter_wproduct(self, queryset, name, value):
|
def filter_wproduct(self, queryset, name, value):
|
||||||
queryset = queryset.filter(operation__ow_operation__wproduct__id=value)
|
queryset = queryset.filter(operation__ow_operation__wproduct__id=value)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,20 @@ from utils.model import SoftModel, BaseModel
|
||||||
from simple_history.models import HistoricalRecords
|
from simple_history.models import HistoricalRecords
|
||||||
from apps.mtm.models import Material, Process, RecordFormField, Step, RecordForm, SubprodctionMaterial
|
from apps.mtm.models import Material, Process, RecordFormField, Step, RecordForm, SubprodctionMaterial
|
||||||
from apps.em.models import Equipment
|
from apps.em.models import Equipment
|
||||||
|
|
||||||
|
|
||||||
class WMaterial(BaseModel):
|
class WMaterial(BaseModel):
|
||||||
"""
|
"""
|
||||||
车间生产物料
|
车间生产物料
|
||||||
"""
|
"""
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子计划', on_delete=models.CASCADE)
|
subproduction_plan = models.ForeignKey(
|
||||||
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
|
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)
|
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
|
||||||
count = models.PositiveIntegerField('当前数量', default=0)
|
count = models.PositiveIntegerField('当前数量', default=0)
|
||||||
|
|
||||||
|
|
||||||
class WProduct(CommonAModel):
|
class WProduct(CommonAModel):
|
||||||
"""
|
"""
|
||||||
动态半成品/成品表
|
动态半成品/成品表
|
||||||
|
|
@ -37,7 +42,7 @@ class WProduct(CommonAModel):
|
||||||
WPR_ACT_STATE_TOFINALTEST = 60
|
WPR_ACT_STATE_TOFINALTEST = 60
|
||||||
WPR_ACT_STATE_SCRAP = 70
|
WPR_ACT_STATE_SCRAP = 70
|
||||||
WPR_ACT_STATE_SELLED = 80
|
WPR_ACT_STATE_SELLED = 80
|
||||||
act_state_choices=(
|
act_state_choices = (
|
||||||
(WPR_ACT_STATE_TORETEST, '待复检'),
|
(WPR_ACT_STATE_TORETEST, '待复检'),
|
||||||
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
||||||
(WPR_ACT_STATE_DOING, '操作进行中'),
|
(WPR_ACT_STATE_DOING, '操作进行中'),
|
||||||
|
|
@ -69,7 +74,7 @@ class WProduct(CommonAModel):
|
||||||
NG_DOWN = 60
|
NG_DOWN = 60
|
||||||
NG_BACK_FROM = 70
|
NG_BACK_FROM = 70
|
||||||
NG_RECALL = 80
|
NG_RECALL = 80
|
||||||
|
|
||||||
ng_choices = (
|
ng_choices = (
|
||||||
(NG_BACK_WORK, '返工'),
|
(NG_BACK_WORK, '返工'),
|
||||||
(NG_BACK_FIX, '返修'),
|
(NG_BACK_FIX, '返修'),
|
||||||
|
|
@ -80,29 +85,39 @@ class WProduct(CommonAModel):
|
||||||
(NG_BACK_FROM, '退回供方'),
|
(NG_BACK_FROM, '退回供方'),
|
||||||
(NG_RECALL, '召回')
|
(NG_RECALL, '召回')
|
||||||
)
|
)
|
||||||
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
|
number = models.CharField(
|
||||||
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
'物品编号', unique=True, null=True, blank=True, max_length=50)
|
||||||
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_step')
|
material = models.ForeignKey(
|
||||||
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='w_step')
|
Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
||||||
act_state = models.IntegerField('进行状态', default=0, choices=act_state_choices)
|
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)
|
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)
|
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)
|
|
||||||
|
|
||||||
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, 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)
|
||||||
|
|
||||||
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
warehouse = models.ForeignKey(
|
||||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
|
WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
|
|
||||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_coperation')
|
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
||||||
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
|
||||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_test')
|
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
|
||||||
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_coperation')
|
||||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_ticket')
|
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
|
||||||
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_test')
|
||||||
|
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
|
||||||
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_ticket')
|
||||||
|
|
||||||
is_mtested = models.BooleanField('是否军检', default=False)
|
is_mtested = models.BooleanField('是否军检', default=False)
|
||||||
is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
|
is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
|
||||||
|
|
@ -115,50 +130,68 @@ class WProduct(CommonAModel):
|
||||||
最后提交的工序自检
|
最后提交的工序自检
|
||||||
"""
|
"""
|
||||||
return self.test_wproduct.filter(type=TestRecord.TEST_PROCESS, is_submited=True).order_by('-id').first()
|
return self.test_wproduct.filter(type=TestRecord.TEST_PROCESS, is_submited=True).order_by('-id').first()
|
||||||
|
|
||||||
|
|
||||||
class WprouctTicket(CommonAModel):
|
class WprouctTicket(CommonAModel):
|
||||||
"""
|
"""
|
||||||
玻璃审批工单
|
玻璃审批工单
|
||||||
"""
|
"""
|
||||||
|
|
||||||
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||||
wproduct = models.ForeignKey(WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
|
wproduct = models.ForeignKey(
|
||||||
material = models.ForeignKey(Material, verbose_name='所在物料状态', on_delete=models.CASCADE)
|
WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
|
||||||
step = models.ForeignKey(Step, verbose_name='所在步骤/发现步骤', on_delete=models.CASCADE)
|
material = models.ForeignKey(
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE)
|
Material, verbose_name='所在物料状态', on_delete=models.CASCADE)
|
||||||
|
step = models.ForeignKey(
|
||||||
resp_process = models.ForeignKey(Process, verbose_name='责任工序', on_delete=models.CASCADE, null=True, blank=True)
|
Step, verbose_name='所在步骤/发现步骤', on_delete=models.CASCADE)
|
||||||
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket')
|
subproduction_plan = models.ForeignKey(
|
||||||
decision = models.PositiveSmallIntegerField('最终决定', choices=WProduct.ng_choices, null=True, blank=True)
|
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)
|
||||||
|
|
||||||
|
|
||||||
class WproductFlow(CommonAModel):
|
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)
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||||
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
material = models.ForeignKey(
|
||||||
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='wl_pre_step')
|
Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
||||||
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='wl_step')
|
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True,
|
||||||
act_state = models.IntegerField('进行状态', default=0, choices=WProduct.act_state_choices)
|
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)
|
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)
|
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)
|
scrap_reason = models.IntegerField(
|
||||||
ng_sign = models.PositiveSmallIntegerField('不合格标记', choices= WProduct.ng_choices, null=True, blank=True)
|
'报废原因', 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(
|
||||||
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_operation')
|
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
||||||
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_operation')
|
||||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_coperation')
|
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
|
||||||
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_coperation')
|
||||||
on_delete=models.SET_NULL, null=True, blank=True)
|
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
|
||||||
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
|
on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
on_delete=models.SET_NULL, null=True, blank=True)
|
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
|
||||||
|
on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
|
||||||
is_mtested = models.BooleanField('是否军检', default=False)
|
is_mtested = models.BooleanField('是否军检', default=False)
|
||||||
is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
|
is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
|
||||||
|
|
@ -179,65 +212,88 @@ class Pick(CommonADModel):
|
||||||
(PICK_FROM_WAREHOUSE, '仓库领取'),
|
(PICK_FROM_WAREHOUSE, '仓库领取'),
|
||||||
(PICK_FROM_WPRODUCT, '半成品领取'),
|
(PICK_FROM_WPRODUCT, '半成品领取'),
|
||||||
)
|
)
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE)
|
subproduction_plan = models.ForeignKey(
|
||||||
type = models.PositiveSmallIntegerField(choices=type_choice, default=PICK_FROM_WAREHOUSE)
|
SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE)
|
||||||
fifo = models.ForeignKey(FIFO, verbose_name='关联的出入库记录', on_delete=models.CASCADE, null=True, blank=True)
|
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):
|
class PickWproduct(BaseModel):
|
||||||
"""
|
"""
|
||||||
领取半成品时详情
|
领取半成品时详情
|
||||||
"""
|
"""
|
||||||
pick = models.ForeignKey(Pick, verbose_name='关联领料', on_delete=models.CASCADE)
|
pick = models.ForeignKey(Pick, verbose_name='关联领料',
|
||||||
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='pw_wproduct')
|
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)
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||||
material = models.ForeignKey(Material, verbose_name='领取时的物料状态', on_delete=models.CASCADE)
|
material = models.ForeignKey(
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='领取时所属子生产计划', on_delete=models.CASCADE)
|
Material, verbose_name='领取时的物料状态', on_delete=models.CASCADE)
|
||||||
|
subproduction_plan = models.ForeignKey(
|
||||||
|
SubProductionPlan, verbose_name='领取时所属子生产计划', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
class Operation(CommonADModel):
|
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)
|
remark = models.CharField('操作备注', max_length=200, null=True, blank=True)
|
||||||
is_submited = models.BooleanField('是否提交', default=False)
|
is_submited = models.BooleanField('是否提交', default=False)
|
||||||
|
|
||||||
|
|
||||||
class OperationWproduct(BaseModel):
|
class OperationWproduct(BaseModel):
|
||||||
"""
|
"""
|
||||||
生产操作半成品关联表
|
生产操作半成品关联表
|
||||||
"""
|
"""
|
||||||
operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='ow_operation')
|
operation = models.ForeignKey(
|
||||||
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='ow_wproduct')
|
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)
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||||
material = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE)
|
material = models.ForeignKey(
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='ow_subplan')
|
Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE)
|
||||||
ng_sign = models.PositiveSmallIntegerField('当时的不合格标记', choices= WProduct.ng_choices, null=True, blank=True)
|
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)
|
place = models.CharField('摆放位置', null=True, blank=True, max_length=200)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = (
|
unique_together = (
|
||||||
('operation','wproduct')
|
('operation', 'wproduct')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class OperationMaterial(BaseModel):
|
class OperationMaterial(BaseModel):
|
||||||
"""
|
"""
|
||||||
生产操作物料消耗产出表
|
生产操作物料消耗产出表
|
||||||
"""
|
"""
|
||||||
type = models.IntegerField('类型', default=0, choices=SubprodctionMaterial.type_choices)
|
type = models.IntegerField(
|
||||||
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE, related_name='om_operation')
|
'类型', default=0, choices=SubprodctionMaterial.type_choices)
|
||||||
|
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE,
|
||||||
material = models.ForeignKey(Material, verbose_name='可能产出的产品', on_delete=models.CASCADE,
|
related_name='om_operation')
|
||||||
null=True, blank=True, related_name='om_material')
|
|
||||||
|
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)
|
count = models.PositiveSmallIntegerField('消耗或产出数量', null=True, blank=True)
|
||||||
|
|
||||||
wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
|
wmaterial = models.ForeignKey(
|
||||||
subproduction_progress = models.ForeignKey(SubProductionProgress, verbose_name='关联的生产进度', on_delete=models.CASCADE, null=True, blank=True)
|
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)
|
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
|
||||||
use_scrap = models.BooleanField('是否使用的边角料', default=False)
|
use_scrap = models.BooleanField('是否使用的边角料', default=False)
|
||||||
|
|
||||||
#以下为冷加工下料清单所用字段
|
# 以下为冷加工下料清单所用字段
|
||||||
from_material = models.ForeignKey(Material, verbose_name='源物料', on_delete=models.CASCADE,
|
from_material = models.ForeignKey(Material, verbose_name='源物料', on_delete=models.CASCADE,
|
||||||
null=True, blank=True, related_name='om_fmaterial')
|
null=True, blank=True, related_name='om_fmaterial')
|
||||||
from_batch = models.CharField('源批次', max_length=100, null=True, blank=True)
|
from_batch = models.CharField('源批次', max_length=100, null=True, blank=True)
|
||||||
count_cut = models.PositiveIntegerField('切裁片数', default=0)
|
count_cut = models.PositiveIntegerField('切裁片数', default=0)
|
||||||
count_real = models.PositiveIntegerField('生产片数', default=0)
|
count_real = models.PositiveIntegerField('生产片数', default=0)
|
||||||
|
|
@ -246,29 +302,38 @@ class OperationMaterial(BaseModel):
|
||||||
count_podian = models.PositiveIntegerField('破点甩片', default=0)
|
count_podian = models.PositiveIntegerField('破点甩片', default=0)
|
||||||
count_hua = models.PositiveIntegerField('划伤甩片', default=0)
|
count_hua = models.PositiveIntegerField('划伤甩片', default=0)
|
||||||
count_other = models.PositiveIntegerField('其他甩片', default=0)
|
count_other = models.PositiveIntegerField('其他甩片', default=0)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = (
|
unique_together = (
|
||||||
('operation','material', 'batch')
|
('operation', 'material', 'batch')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class OperationRecord(BaseModel):
|
class OperationRecord(BaseModel):
|
||||||
"""
|
"""
|
||||||
记录表格
|
记录表格
|
||||||
"""
|
"""
|
||||||
form = models.ForeignKey(RecordForm, verbose_name='所用的生产记录表格', on_delete=models.CASCADE, related_name='or_form')
|
form = models.ForeignKey(RecordForm, verbose_name='所用的生产记录表格',
|
||||||
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE, related_name='or_operation')
|
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)
|
is_filled = models.BooleanField('是否填写', default=True)
|
||||||
|
|
||||||
|
|
||||||
class OperationRecordItem(BaseModel):
|
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)
|
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):
|
class OperationEquip(BaseModel):
|
||||||
operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='oe_operation')
|
operation = models.ForeignKey(
|
||||||
equip = models.ForeignKey(Equipment, verbose_name='生产设备', on_delete=models.CASCADE, related_name='oe_equip')
|
Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='oe_operation')
|
||||||
remark = models.TextField('备注', null=True, blank=True)
|
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):
|
class WproductPutInSerializer(serializers.Serializer):
|
||||||
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
|
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):
|
class WproductPutInsSerializer(serializers.Serializer):
|
||||||
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
|
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
|
||||||
wproducts = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), label='半成品ID', many=True)
|
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):
|
class OperationEquipListSerializer(serializers.Serializer):
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue