feat: 增加车间库存并完成生产领料

This commit is contained in:
caoqianming 2023-09-27 15:41:36 +08:00
parent 8934186460
commit 9504b527cb
13 changed files with 275 additions and 74 deletions

View File

@ -0,0 +1,26 @@
# Generated by Django 3.2.12 on 2023-09-27 07:16
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('inm', '0002_mio_mioitem'),
]
operations = [
migrations.AddField(
model_name='mio',
name='pick_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='领料人'),
),
migrations.AlterField(
model_name='mioitem',
name='batch',
field=models.CharField(max_length=50, verbose_name='批次号'),
),
]

View File

@ -3,8 +3,10 @@ from apps.utils.models import BaseModel, CommonBModel, CommonBDModel
from apps.pum.models import Supplier, PuOrder
from apps.sam.models import Customer, Order
from apps.mtm.models import Material
from apps.system.models import User
# Create your models here.
class WareHouse(CommonBModel):
"""
仓库信息
@ -31,7 +33,7 @@ class MIO(CommonBDModel):
"""
出入库记录
"""
MIO_TYPE_DO_OUT = 'do_out'
MIO_TYPE_DO_OUT = 'do_out'
MIO_TYPE_SALE_OUT = 'sale_out'
MIO_TYPE_PUR_IN = 'pur_in'
MIO_TYPE_DO_IN = 'do_in'
@ -53,24 +55,35 @@ class MIO(CommonBDModel):
(MIO_SUBMITED, '已提交')
)
number = models.CharField('编号', max_length=20)
state = models.PositiveSmallIntegerField('状态', choices=MIO_STATES, default=10, help_text=str(MIO_CREATE))
type = models.CharField('出入库类型', max_length=10, default=MIO_TYPE_DO_OUT, choices=MIO_TYPES, help_text=str(MIO_TYPES))
state = models.PositiveSmallIntegerField(
'状态', choices=MIO_STATES, default=10, help_text=str(MIO_CREATE))
type = models.CharField('出入库类型', max_length=10, default=MIO_TYPE_DO_OUT,
choices=MIO_TYPES, help_text=str(MIO_TYPES))
inout_date = models.DateField('出入库日期', null=True, blank=True)
supplier = models.ForeignKey(Supplier, verbose_name='供应商', on_delete=models.CASCADE, null=True, blank=True)
customer = models.ForeignKey(Customer, verbose_name='客户', on_delete=models.CASCADE, null=True, blank=True)
pu_order = models.ForeignKey(PuOrder, verbose_name='关联采购订单', on_delete=models.CASCADE, null=True, blank=True)
order = models.ForeignKey(Order, verbose_name='关联订单', on_delete=models.CASCADE, null=True, blank=True)
supplier = models.ForeignKey(
Supplier, verbose_name='供应商', on_delete=models.CASCADE, null=True, blank=True)
customer = models.ForeignKey(
Customer, verbose_name='客户', on_delete=models.CASCADE, null=True, blank=True)
pu_order = models.ForeignKey(
PuOrder, verbose_name='关联采购订单', on_delete=models.CASCADE, null=True, blank=True)
order = models.ForeignKey(
Order, verbose_name='关联订单', on_delete=models.CASCADE, null=True, blank=True)
note = models.CharField('备注', max_length=1000, default='')
expiration_date = models.DateField('有效期', null=True, blank=True)
submit_time = models.DateTimeField('提交时间', null=True, blank=True)
pick_user = models.ForeignKey(
User, verbose_name='领料人', on_delete=models.CASCADE, null=True, blank=True)
class MIOItem(BaseModel):
"""
出入库明细
"""
mio = models.ForeignKey(MIO, 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)
batch = models.CharField('批次号', max_length=20)
count = models.PositiveIntegerField('数量', default=0)
mio = models.ForeignKey(MIO, 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)
batch = models.CharField('批次号', max_length=50)
count = models.PositiveIntegerField('数量', default=0)

View File

@ -1,10 +1,13 @@
from rest_framework import serializers
from apps.utils.serializers import CustomModelSerializer
from apps.inm.models import WareHouse, MaterialBatch, MIO, MIOItem
from apps.utils.constants import EXCLUDE_FIELDS_DEPT, EXCLUDE_FIELDS_BASE
from apps.pum.models import PuOrder
from rest_framework.exceptions import ValidationError
from apps.mtm.serializers import MaterialSerializer
from apps.pum.models import PuOrder
from apps.system.models import Dept, User
from apps.utils.constants import EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS_DEPT
from apps.utils.serializers import CustomModelSerializer
from .models import MIO, MaterialBatch, MIOItem, WareHouse
class WareHourseSerializer(CustomModelSerializer):
@ -15,8 +18,11 @@ class WareHourseSerializer(CustomModelSerializer):
class MaterialBatchSerializer(CustomModelSerializer):
warehouse_name = serializers.CharField(source='warehouse.name', read_only=True)
material_name = serializers.CharField(source='material.name', read_only=True)
warehouse_name = serializers.CharField(
source='warehouse.name', read_only=True)
material_name = serializers.CharField(
source='material.name', read_only=True)
class Meta:
model = MaterialBatch
fields = '__all__'
@ -24,12 +30,14 @@ class MaterialBatchSerializer(CustomModelSerializer):
class MIOSerializer(CustomModelSerializer):
create_by_name = serializers.CharField(source='create_by.name', read_only=True)
create_by_name = serializers.CharField(
source='create_by.name', read_only=True)
class Meta:
model = MIO
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS_DEPT + ['state', 'submit_time']
def validate(self, attrs):
if 'pu_order' in attrs and attrs['pu_order']:
attrs['supplier'] = attrs['pu_order'].supplier
@ -46,15 +54,16 @@ class MIOSerializer(CustomModelSerializer):
else:
raise ValidationError('该采购订单不可选')
return super().create(validated_data)
def update(self, instance, validated_data):
validated_data.pop('type')
return super().update(instance, validated_data)
class MIOItemSerializer(CustomModelSerializer):
warehouse_name = serializers.CharField(source='warehouse', read_only=True)
material_ = MaterialSerializer(source='material', read_only=True)
class Meta:
model = MIOItem
fields = '__all__'
@ -64,3 +73,23 @@ class MIOItemSerializer(CustomModelSerializer):
if mio.state != MIO.MIO_CREATE:
raise ValidationError('出入库记录非创建中不可新增')
return super().create(validated_data)
class PickSerializer(CustomModelSerializer):
belong_dept = serializers.PrimaryKeyRelatedField(
label="领料车间", queryset=Dept.objects.all(), required=True)
pick_user = serializers.PrimaryKeyRelatedField(
label="领料人", queryset=User.objects.all(), required=True)
class Meta:
model = MIO
fields = ['number', 'note', 'pick_user', 'belong_dept']
def create(self, validated_data):
validated_data['type'] = MIO.MIO_TYPE_DO_OUT
return super().create(validated_data)
def update(self, instance, validated_data):
if instance.state != MIO.MIO_CREATE:
raise ValidationError('记录非创建中')
return super().update(instance, validated_data)

View File

@ -4,33 +4,36 @@ from django.db.models.aggregates import Sum
class InmService:
@classmethod
def update_inm(cls, instance: MIO):
"""
更新库存, 暂不支持反向操作
"""
if instance.type in [MIO.MIO_TYPE_PUR_IN, MIO.MIO_TYPE_DO_IN, MIO.MIO_TYPE_OTHER_IN]: # 采购入库, 生产入库, 其他入库
if instance.type in [MIO.MIO_TYPE_PUR_IN, MIO.MIO_TYPE_DO_IN, MIO.MIO_TYPE_OTHER_IN]: # 采购入库, 生产入库, 其他入库
cls.update_mb(instance)
if instance.type == MIO.MIO_TYPE_PUR_IN: # 需要更新订单
from apps.pum.services import PumService
PumService.mio_purin(instance)
elif instance.type in [MIO.MIO_TYPE_DO_OUT, MIO.MIO_TYPE_SALE_OUT, MIO.MIO_TYPE_OTHER_OUT]: # 生产领料 销售出库
elif instance.type in [MIO.MIO_TYPE_DO_OUT, MIO.MIO_TYPE_SALE_OUT, MIO.MIO_TYPE_OTHER_OUT]: # 生产领料 销售出库
cls.update_mb(instance, -1)
if instance.type == MIO.MIO_TYPE_SALE_OUT:
from apps.sam.services import SamService
SamService.mio_saleout(instance)
elif instance.type == MIO.MIO_TYPE_DO_OUT:
from apps.wpm.services import pick
pick(instance)
@classmethod
def update_mb(cls, instance: MIO, in_or_out: int =1):
def update_mb(cls, instance: MIO, in_or_out: int = 1):
"""
更新物料批次
"""
for i in MIOItem.objects.filter(mio=instance):
material = i.material
warehouse = i.warehouse
mb, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,\
defaults={'material':material, 'warehouse':warehouse, 'count':0, 'batch':i.batch})
mb, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,
defaults={'material': material, 'warehouse': warehouse, 'count': 0, 'batch': i.batch})
if in_or_out == 1:
mb.count = mb.count + i.count
if mb.expiration_date is None:
@ -43,5 +46,6 @@ class InmService:
mb.save()
else:
raise ValidationError('不支持的操作')
material.count = MaterialBatch.objects.filter(material=material).aggregate(total=Sum('count')).get('total', 0)
material.save()
material.count = MaterialBatch.objects.filter(
material=material).aggregate(total=Sum('count')).get('total', 0)
material.save()

View File

@ -8,7 +8,8 @@ from django.utils import timezone
from rest_framework.response import Response
from apps.inm.models import WareHouse, MaterialBatch, MIO, MIOItem
from apps.inm.serializers import (MaterialBatchSerializer, WareHourseSerializer, MIOSerializer, MIOItemSerializer)
from apps.inm.serializers import (
MaterialBatchSerializer, WareHourseSerializer, MIOSerializer, MIOItemSerializer, PickSerializer)
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from apps.inm.services import InmService
from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin
@ -60,7 +61,19 @@ class MIOViewSet(ListModelMixin, DestroyModelMixin, CustomGenericViewSet):
if instance.state != MIO.MIO_CREATE:
raise ParseError('非创建中不可删除')
return super().perform_destroy(instance)
@action(methods=['post'], detail=False, perms_map={'post': 'mio.pick'}, serializer_class=PickSerializer)
@transaction.atomic
def pick(self, request, *args, **kwargs):
"""生产领料
生产领料
"""
sr = PickSerializer(data=request.data)
sr.is_valid(raise_exception=True)
sr.save()
return Response()
@action(methods=['post'], detail=True, perms_map={'post': 'mio.update'}, serializer_class=serializers.Serializer)
@transaction.atomic
def submit(self, request, *args, **kwargs):
@ -70,16 +83,17 @@ class MIOViewSet(ListModelMixin, DestroyModelMixin, CustomGenericViewSet):
"""
ins = self.get_object()
user = request.user
if ins.create_by != user:
if ins.state != MIO.MIO_TYPE_DO_OUT and ins.create_by != user:
raise PermissionDenied('非创建人不可提交')
if ins.state != MIO.MIO_CREATE:
raise ParseError('订单非创建中')
raise ParseError('记录状态异常')
ins.submit_time = timezone.now()
ins.state = MIO.MIO_SUBMITED
ins.save()
InmService.update_inm(ins)
return Response()
class MIOItemViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomGenericViewSet):
"""
list: 出入库明细
@ -91,8 +105,8 @@ class MIOItemViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin
select_related_fields = ['warehouse', 'mio', 'material']
filterset_fields = ['warehouse', 'mio', 'material']
ordering = ['create_time']
def perform_destroy(self, instance):
if instance.state != MIO.MIO_CREATE:
raise ParseError('出入库记录非创建中不可删除')
return super().perform_destroy(instance)
return super().perform_destroy(instance)

View File

@ -62,7 +62,7 @@ class Material(CommonAModel):
ordering = ['sort', '-create_time']
def __str__(self):
return self.name
return f'{self.specification}-{self.name}'
class Shift(CommonAModel):

View File

@ -26,12 +26,11 @@ class CustomGenericViewSet(MyLoggingMixin, GenericViewSet):
"""
增强的GenericViewSet
"""
perms_map = {} # 权限标识
perms_map = {'get': '*'} # 权限标识
throttle_classes = [UserRateThrottle]
logging_methods = ['POST', 'PUT', 'PATCH', 'DELETE']
ordering_fields = '__all__'
ordering = '-create_time'
filterset_fields = []
create_serializer_class = None
update_serializer_class = None
partial_update_serializer_class = None
@ -44,15 +43,18 @@ class CustomGenericViewSet(MyLoggingMixin, GenericViewSet):
data_filter_field = 'belong_dept'
hash_k = None
cache_seconds = 5 # 接口缓存时间默认5秒
filterset_fields = select_related_fields
def finalize_response(self, request, response, *args, **kwargs):
if self.hash_k and self.cache_seconds:
cache.set(self.hash_k, response.data, timeout=self.cache_seconds) # 将结果存入缓存,设置超时时间
cache.set(self.hash_k, response.data,
timeout=self.cache_seconds) # 将结果存入缓存,设置超时时间
return super().finalize_response(request, response, *args, **kwargs)
def initial(self, request, *args, **kwargs):
super().initial(request, *args, **kwargs)
cache_seconds = getattr(self, f"{self.action}_cache_seconds", getattr(self, 'cache_seconds', 0))
cache_seconds = getattr(
self, f"{self.action}_cache_seconds", getattr(self, 'cache_seconds', 0))
if cache_seconds:
self.cache_seconds = cache_seconds
rdata = {}
@ -164,6 +166,7 @@ class CustomModelViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, ListModelMi
"""
增强的ModelViewSet
"""
def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)
# 增加默认权限标识
@ -210,4 +213,3 @@ class CustomModelViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, ListModelMi
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(new_qs, many=True)
return Response(serializer.data)

View File

@ -0,0 +1,37 @@
# Generated by Django 3.2.12 on 2023-09-27 07:16
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('mtm', '0014_alter_process_options'),
('system', '0002_myschedule'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('wpm', '0010_auto_20230808_1413'),
]
operations = [
migrations.CreateModel(
name='WMaterial',
fields=[
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('batch', models.CharField(max_length=50, verbose_name='批次号')),
('count', models.PositiveIntegerField(default=0, verbose_name='当前数量')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wmaterial_belong_dept', to='system.dept', verbose_name='所属部门')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wmaterial_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wmaterial_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
]

View File

@ -1,6 +1,6 @@
from django.db import models
from apps.utils.models import CommonADModel
from apps.mtm.models import Mgroup, Team, Shift
from apps.utils.models import CommonADModel, CommonBDModel
from apps.mtm.models import Mgroup, Team, Shift, Material
from django.utils.timezone import localtime
# Create your models here.
@ -63,3 +63,13 @@ class SfLogExp(CommonADModel):
handler = models.CharField('处理人', default='', max_length=100)
is_current_down = models.BooleanField('是否本班停机', default=False)
duration = models.FloatField('停机时长(h)', null=True, blank=True)
class WMaterial(CommonBDModel):
"""
belong_dept是所在车间
"""
material = models.ForeignKey(
Material, verbose_name='物料', on_delete=models.CASCADE)
batch = models.CharField('批次号', max_length=50)
count = models.PositiveIntegerField('当前数量', default=0)

View File

@ -2,12 +2,15 @@ from apps.utils.constants import EXCLUDE_FIELDS
from apps.utils.serializers import CustomModelSerializer
from rest_framework import serializers
from apps.wpm.models import SfLog, StLog, SfLogExp
from .models import SfLog, StLog, SfLogExp, WMaterial
from apps.system.models import Dictionary
from apps.wpm.tasks import cal_enstat_when_pcoal_heat_change, cal_enstat_when_team_change
from apps.mtm.serializers import MaterialSerializer
class StLogSerializer(CustomModelSerializer):
mgroup_name = serializers.CharField(source='mgroup.name', read_only=True)
class Meta:
model = StLog
fields = '__all__'
@ -18,10 +21,12 @@ class SfLogSerializer(CustomModelSerializer):
team_name = serializers.CharField(source='team.name', read_only=True)
shift_name = serializers.CharField(source='shift.name', read_only=True)
leader_name = serializers.CharField(source='leader.name', read_only=True)
class Meta:
model = SfLog
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS + ['mgroup', 'start_time', 'end_time', 'belong_dept']
read_only_fields = EXCLUDE_FIELDS + \
['mgroup', 'start_time', 'end_time', 'belong_dept']
extra_kwargs = {
'team': {'required': True},
'leader': {'required': True}
@ -48,11 +53,23 @@ class SfLogSerializer(CustomModelSerializer):
class SflogExpSerializer(CustomModelSerializer):
mgroup = serializers.CharField(source='sflog.mgroup.id', read_only=True)
mgroup_name = serializers.CharField(source='sflog.mgroup.name', read_only=True)
mgroup_name = serializers.CharField(
source='sflog.mgroup.name', read_only=True)
stlog_ = StLogSerializer(source='stlog', read_only=True)
happen_time = serializers.DateTimeField(required=True, label='发生时间')
cate = serializers.CharField(required=True, label='原因类别')
class Meta:
model = SfLogExp
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS + ['stlog', 'is_current_down']
read_only_fields = EXCLUDE_FIELDS + ['stlog', 'is_current_down']
class WMaterialSerializer(CustomModelSerializer):
material_ = MaterialSerializer(source='material', read_only=True)
belong_dept_name = serializers.CharField(
source='belong_dept.name', read_only=True)
class Meta:
model = WMaterial
fields = '__all__'

View File

@ -1,9 +1,14 @@
from apps.wpm.models import SfLog, SfLogExp
from apps.mtm.models import Shift, Mgroup
import datetime
from django.utils.timezone import localtime
from django.db.models import Sum
from django.core.cache import cache
from django.db.models import Sum
from django.utils.timezone import localtime
from apps.inm.models import MIO, MIOItem
from apps.mtm.models import Mgroup, Shift
from .models import SfLog, SfLogExp, WMaterial
def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.date):
for shift in Shift.objects.all():
@ -24,6 +29,7 @@ def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.da
})
current_date = current_date + datetime.timedelta(days=1)
def get_pcoal_heat(year_s: int, month_s: int, day_s: int):
"""
获取煤粉热值
@ -36,11 +42,33 @@ def get_pcoal_heat(year_s: int, month_s: int, day_s: int):
else:
try:
qs = SfLog.objects.get(end_time__year=year_s, end_time__month=month_s, end_time__day=day_s,
mgroup__name='回转窑', shift__name='白班')
mgroup__name='回转窑', shift__name='白班')
if qs.pcoal_heat is None:
qs.pcoal_heat = 0
qs.save()
cache.set(f'pgoal_val_{year_s}_{month_s}_{day_s}', qs.pcoal_heat)
return qs.pcoal_heat
except:
except Exception:
return 0
def pick(mio: MIO):
"""
生产领料到车间
"""
belong_dept = mio.belong_dept
pick_user = mio.pick_user
mioitems = MIOItem.objects.filter(mio=mio)
for item in mioitems:
wm, new_create = WMaterial.objects.get_or_create(batch=item.batch, material=item.material,
belong_dept=belong_dept, defaults={
"batch": item.batch,
"material": item.material,
"count": item.count,
"create_by": pick_user,
"belong_dept": belong_dept
})
if not new_create:
wm.count = wm.count + item.count
wm.update_by = pick_user
wm.save()

View File

@ -1,7 +1,7 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from apps.wpm.views import SfLogViewSet, StLogViewSet, SfLogExpViewSet
from apps.wpm.views import SfLogViewSet, StLogViewSet, SfLogExpViewSet, WMaterialViewSet
API_BASE_URL = 'api/wpm/'
@ -11,7 +11,7 @@ router = DefaultRouter()
router.register('sflog', SfLogViewSet, basename='sflog')
router.register('stlog', StLogViewSet, basename='stlog')
router.register('sflogexp', SfLogExpViewSet, basename='sflogexp')
router.register('wmaterial', WMaterialViewSet, basename='wmaterial')
urlpatterns = [
path(API_BASE_URL, include(router.urls)),
]
]

View File

@ -1,18 +1,20 @@
from django.shortcuts import render
from rest_framework.mixins import ListModelMixin, UpdateModelMixin
from rest_framework.decorators import action
from django.db import transaction
from rest_framework.response import Response
from django.shortcuts import render
from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
from rest_framework.mixins import DestroyModelMixin, UpdateModelMixin, ListModelMixin
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, UpdateModelMixin
from rest_framework.response import Response
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from apps.wpm.models import SfLog, StLog, SfLogExp
from apps.wpm.serializers import SfLogSerializer, StLogSerializer, SflogExpSerializer
from apps.wpm.filters import SfLogFilter, SfLogExpFilter
from apps.mtm.models import Material
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from .filters import SfLogExpFilter, SfLogFilter
from .models import SfLog, SfLogExp, StLog, WMaterial
from .serializers import SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer
# Create your views here.
class StLogViewSet(ListModelMixin, CustomGenericViewSet):
"""
list:停机记录
@ -51,16 +53,21 @@ class SfLogViewSet(UpdateModelMixin, ListModelMixin, DestroyModelMixin, CustomGe
from apps.qm.models import QuaStat, TestItem
from apps.qm.serializers import QuaStatSerializer
obj = self.get_object()
test_materials = Material.objects.filter(id__in=obj.mgroup.test_materials).order_by('sort', '-create_time')
test_materials = Material.objects.filter(
id__in=obj.mgroup.test_materials).order_by('sort', '-create_time')
for material in test_materials:
testitems = TestItem.objects.filter(id__in=material.testitems).order_by('sort', '-create_time')
testitems = TestItem.objects.filter(
id__in=material.testitems).order_by('sort', '-create_time')
for testitem in testitems:
params = {'material': material, 'testitem': testitem, 'sflog': obj}
QuaStat.objects.get_or_create(**params, defaults={**params, **{'create_by': request.user, 'belong_dept': obj.mgroup.belong_dept}})
qs = QuaStat.objects.filter(sflog=obj).order_by('material__sort', 'material__create_time', 'testitem__sort', 'testitem__create_time')
params = {'material': material,
'testitem': testitem, 'sflog': obj}
QuaStat.objects.get_or_create(
**params, defaults={**params, **{'create_by': request.user, 'belong_dept': obj.mgroup.belong_dept}})
qs = QuaStat.objects.filter(sflog=obj).order_by(
'material__sort', 'material__create_time', 'testitem__sort', 'testitem__create_time')
sr = QuaStatSerializer(instance=qs, many=True)
return Response(sr.data)
class SfLogExpViewSet(CustomModelViewSet):
"""
@ -71,4 +78,18 @@ class SfLogExpViewSet(CustomModelViewSet):
queryset = SfLogExp.objects.all()
serializer_class = SflogExpSerializer
select_related_fields = ['sflog', 'sflog__mgroup', 'stlog']
filterset_class = SfLogExpFilter
filterset_class = SfLogExpFilter
class WMaterialViewSet(ListModelMixin, CustomGenericViewSet):
"""
list: 车间库存
车间库存
"""
queryset = WMaterial.objects.all()
serializer_class = WMaterialSerializer
select_related_fields = ['material', 'belong_dept']
search_fields = ['material__name',
'material__number', 'material__specification']
filterset_fields = ['material', 'belong_dept']