批量入库remark非必填

This commit is contained in:
caoqianming 2022-01-14 15:12:48 +08:00
parent 43a936b7d9
commit ef007e728a
7 changed files with 507 additions and 391 deletions

View File

@ -1,5 +1,6 @@
.vscode/
.vs/
.idea/
venv/
__pycache__/
*.pyc

View File

@ -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,37 +25,44 @@ 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):
"""
出入库记录
"""
FIFO_TYPE_DO_OUT = 1 # 生产领料
FIFO_TYPE_DO_OUT = 1 # 生产领料
FIFO_TYPE_SALE_OUT = 2
FIFO_TYPE_PUR_IN = 3
FIFO_TYPE_DO_IN = 4
@ -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')
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')
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)

View File

@ -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):
"""
仓库-增删改查
@ -32,26 +35,30 @@ class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
ordering_fields = ['create_time']
ordering = ['-create_time']
def get_serializer_class(self):
def get_serializer_class(self):
if self.action in ['create', 'update']:
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,9 +109,9 @@ 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: # 保存记录详情
for m in record_data: # 保存记录详情
m['field_value'] = m['field_value']
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
m['test_record'] = obj
@ -115,6 +125,7 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
obj.fifo_item.save()
return Response()
class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
"""
出入库记录
@ -131,14 +142,14 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
if self.action == 'list':
return FIFOListSerializer
return super().get_serializer_class()
def destroy(self, request, *args, **kwargs):
obj = self.get_object()
if obj.is_submited:
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,19 +173,21 @@ 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) # 更新库存
update_inm(obj) # 更新库存
return Response()
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 = []
ordering_fields = ['create_time']
ordering = ['-create_time']
ordering = ['-create_time']

View File

@ -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,10 +55,11 @@ class CuttingFilterSet(filters.FilterSet):
class OperationRecordFilterSet(filters.FilterSet):
wproduct = filters.NumberFilter(method='filter_wproduct')
class Meta:
model = OperationRecord
fields = ['operation', 'form']
def filter_wproduct(self, queryset, name, value):
queryset = queryset.filter(operation__ow_operation__wproduct__id=value)
return queryset
return queryset

View File

@ -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, '操作进行中'),
@ -69,7 +74,7 @@ class WProduct(CommonAModel):
NG_DOWN = 60
NG_BACK_FROM = 70
NG_RECALL = 80
ng_choices = (
(NG_BACK_WORK, '返工'),
(NG_BACK_FIX, '返修'),
@ -80,29 +85,39 @@ 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')
scrap_reason = models.IntegerField('报废原因', choices=scrap_reason_choices, null=True, blank=True)
ng_sign = models.PositiveSmallIntegerField('不合格标记', choices=ng_choices, null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE,
related_name='wproduct_subplan')
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='当前操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_coperation')
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')
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')
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_coperation')
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_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()
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)
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)
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)
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)
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='创建所关联操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_coperation')
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
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)
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='创建所关联操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_coperation')
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
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_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
@ -179,65 +212,88 @@ 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')
material = models.ForeignKey(Material, verbose_name='可能产出的产品', on_delete=models.CASCADE,
null=True, blank=True, related_name='om_material')
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_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)
count_cut = models.PositiveIntegerField('切裁片数', default=0)
count_real = models.PositiveIntegerField('生产片数', default=0)
@ -246,29 +302,38 @@ class OperationMaterial(BaseModel):
count_podian = models.PositiveIntegerField('破点甩片', default=0)
count_hua = models.PositiveIntegerField('划伤甩片', default=0)
count_other = models.PositiveIntegerField('其他甩片', default=0)
class Meta:
unique_together = (
('operation','material', 'batch')
('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')
remark = models.TextField('备注', null=True, blank=True)
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)

View File

@ -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):

File diff suppressed because it is too large Load Diff