feat: 增加组合件出入库
This commit is contained in:
parent
38ad10d445
commit
bc2a16a9a4
|
@ -0,0 +1,13 @@
|
||||||
|
from django_filters import rest_framework as filters
|
||||||
|
from apps.inm.models import MaterialBatch
|
||||||
|
|
||||||
|
|
||||||
|
class MaterialBatchFilter(filters.FilterSet):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MaterialBatch
|
||||||
|
fields = {
|
||||||
|
"warehouse": ["exact"],
|
||||||
|
"material": ["exact"],
|
||||||
|
"count": ["exact", "gte", "lte"]
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
# Generated by Django 3.2.12 on 2023-10-24 02:25
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mtm', '0017_auto_20231018_1033'),
|
||||||
|
('inm', '0004_auto_20230927_1700'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='MIOItemA',
|
||||||
|
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='批次号')),
|
||||||
|
('rate', models.PositiveIntegerField(default=1, verbose_name='比例')),
|
||||||
|
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料')),
|
||||||
|
('mioitem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='a_mioitem', to='inm.mioitem', verbose_name='关联出入库明细')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='MaterialBatchA',
|
||||||
|
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=100, verbose_name='批次号')),
|
||||||
|
('rate', models.PositiveIntegerField(default=1, verbose_name='比例')),
|
||||||
|
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料')),
|
||||||
|
('mb', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='a_mb', to='inm.materialbatch', verbose_name='关联物料批次')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -29,6 +29,18 @@ class MaterialBatch(BaseModel):
|
||||||
expiration_date = models.DateField('有效期', null=True, blank=True)
|
expiration_date = models.DateField('有效期', null=True, blank=True)
|
||||||
|
|
||||||
|
|
||||||
|
class MaterialBatchA(BaseModel):
|
||||||
|
"""
|
||||||
|
组合件物料批次
|
||||||
|
"""
|
||||||
|
batch = models.CharField('批次号', max_length=100)
|
||||||
|
material = models.ForeignKey(
|
||||||
|
Material, on_delete=models.CASCADE, verbose_name='物料')
|
||||||
|
rate = models.PositiveIntegerField('比例', default=1)
|
||||||
|
mb = models.ForeignKey(
|
||||||
|
MaterialBatch, verbose_name='关联物料批次', on_delete=models.CASCADE, related_name='a_mb')
|
||||||
|
|
||||||
|
|
||||||
class MIO(CommonBDModel):
|
class MIO(CommonBDModel):
|
||||||
"""
|
"""
|
||||||
出入库记录
|
出入库记录
|
||||||
|
@ -89,3 +101,15 @@ class MIOItem(BaseModel):
|
||||||
Material, verbose_name='物料', on_delete=models.CASCADE)
|
Material, verbose_name='物料', on_delete=models.CASCADE)
|
||||||
batch = models.CharField('批次号', max_length=50)
|
batch = models.CharField('批次号', max_length=50)
|
||||||
count = models.PositiveIntegerField('数量', default=0)
|
count = models.PositiveIntegerField('数量', default=0)
|
||||||
|
|
||||||
|
|
||||||
|
class MIOItemA(BaseModel):
|
||||||
|
"""
|
||||||
|
组合件出入库明细
|
||||||
|
"""
|
||||||
|
material = models.ForeignKey(
|
||||||
|
Material, verbose_name='物料', on_delete=models.CASCADE)
|
||||||
|
batch = models.CharField('批次号', max_length=50)
|
||||||
|
rate = models.PositiveIntegerField('比例', default=1)
|
||||||
|
mioitem = models.ForeignKey(
|
||||||
|
MIOItem, verbose_name='关联出入库明细', on_delete=models.CASCADE, related_name='a_mioitem')
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.exceptions import ValidationError
|
from rest_framework.exceptions import ValidationError, ParseError
|
||||||
|
|
||||||
from apps.mtm.serializers import MaterialSerializer
|
from apps.mtm.serializers import MaterialSerializer
|
||||||
from apps.pum.models import PuOrder
|
from apps.pum.models import PuOrder
|
||||||
|
@ -8,7 +8,8 @@ from apps.system.models import Dept, User
|
||||||
from apps.utils.constants import EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS_DEPT, EXCLUDE_FIELDS
|
from apps.utils.constants import EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS_DEPT, EXCLUDE_FIELDS
|
||||||
from apps.utils.serializers import CustomModelSerializer
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
|
|
||||||
from .models import MIO, MaterialBatch, MIOItem, WareHouse
|
from .models import MIO, MaterialBatch, MIOItem, WareHouse, MIOItemA, MaterialBatchA
|
||||||
|
from django.db import transaction
|
||||||
|
|
||||||
|
|
||||||
class WareHourseSerializer(CustomModelSerializer):
|
class WareHourseSerializer(CustomModelSerializer):
|
||||||
|
@ -18,6 +19,14 @@ class WareHourseSerializer(CustomModelSerializer):
|
||||||
read_only_fields = EXCLUDE_FIELDS_DEPT
|
read_only_fields = EXCLUDE_FIELDS_DEPT
|
||||||
|
|
||||||
|
|
||||||
|
class MaterialBatchAListSerializer(CustomModelSerializer):
|
||||||
|
material_ = MaterialSerializer(source='material', read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MaterialBatchA
|
||||||
|
fields = ['material', 'batch', 'rate', 'mb', 'id', 'material_']
|
||||||
|
|
||||||
|
|
||||||
class MaterialBatchSerializer(CustomModelSerializer):
|
class MaterialBatchSerializer(CustomModelSerializer):
|
||||||
warehouse_name = serializers.CharField(
|
warehouse_name = serializers.CharField(
|
||||||
source='warehouse.name', read_only=True)
|
source='warehouse.name', read_only=True)
|
||||||
|
@ -31,6 +40,20 @@ class MaterialBatchSerializer(CustomModelSerializer):
|
||||||
read_only_fields = EXCLUDE_FIELDS_BASE
|
read_only_fields = EXCLUDE_FIELDS_BASE
|
||||||
|
|
||||||
|
|
||||||
|
class MaterialBatchDetailSerializer(CustomModelSerializer):
|
||||||
|
warehouse_name = serializers.CharField(
|
||||||
|
source='warehouse.name', read_only=True)
|
||||||
|
material_name = serializers.CharField(
|
||||||
|
source='material.name', read_only=True)
|
||||||
|
material_ = MaterialSerializer(source='material', read_only=True)
|
||||||
|
assemb = MaterialBatchAListSerializer(
|
||||||
|
source='a_mb', read_only=True, many=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MaterialBatch
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class MIOListSerializer(CustomModelSerializer):
|
class MIOListSerializer(CustomModelSerializer):
|
||||||
create_by_name = serializers.CharField(
|
create_by_name = serializers.CharField(
|
||||||
source='create_by.name', read_only=True)
|
source='create_by.name', read_only=True)
|
||||||
|
@ -78,20 +101,61 @@ class MIOListSerializer(CustomModelSerializer):
|
||||||
# return super().update(instance, validated_data)
|
# return super().update(instance, validated_data)
|
||||||
|
|
||||||
|
|
||||||
|
class MIOItemACreateSerializer(CustomModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = MIOItem
|
||||||
|
fields = ['material', 'batch']
|
||||||
|
|
||||||
|
|
||||||
|
class MIOItemCreateSerializer(CustomModelSerializer):
|
||||||
|
assemb = MIOItemACreateSerializer(
|
||||||
|
label='组合件信息', many=True, write_only=True, required=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MIOItem
|
||||||
|
fields = ['mio', 'warehouse', 'material', 'batch', 'count', 'assemb']
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
mio = validated_data['mio']
|
||||||
|
material = validated_data['material']
|
||||||
|
if mio.state != MIO.MIO_CREATE:
|
||||||
|
raise ValidationError('出入库记录非创建中不可新增')
|
||||||
|
with transaction.atomic():
|
||||||
|
assemb = validated_data.pop('assemb', [])
|
||||||
|
instance = super().create(validated_data)
|
||||||
|
assemb_dict = {}
|
||||||
|
for i in assemb:
|
||||||
|
assemb_dict[i['material'].id] = i
|
||||||
|
if material.is_assemb and '_in' in mio.type: # 仅入库且是组合件的时候需要填写下一级
|
||||||
|
components = material.components
|
||||||
|
for k, v in components.items():
|
||||||
|
if k in assemb_dict:
|
||||||
|
mia = assemb_dict[k]
|
||||||
|
MIOItemA.objects.create(
|
||||||
|
mioitem=instance, material=mia['material'], batch=mio['batch'], count=v)
|
||||||
|
else:
|
||||||
|
raise ParseError('缺少组合件')
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
class MIOItemAListSerializer(CustomModelSerializer):
|
||||||
|
material_ = MaterialSerializer(source='material', read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MIOItemA
|
||||||
|
fields = ['material', 'batch', 'rate', 'mioitem', 'id', 'material_']
|
||||||
|
|
||||||
|
|
||||||
class MIOItemSerializer(CustomModelSerializer):
|
class MIOItemSerializer(CustomModelSerializer):
|
||||||
warehouse_name = serializers.CharField(source='warehouse', read_only=True)
|
warehouse_name = serializers.CharField(source='warehouse', read_only=True)
|
||||||
material_ = MaterialSerializer(source='material', read_only=True)
|
material_ = MaterialSerializer(source='material', read_only=True)
|
||||||
|
assemb = MIOItemAListSerializer(
|
||||||
|
source='a_mioitem', read_only=True, many=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = MIOItem
|
model = MIOItem
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
def create(self, validated_data):
|
|
||||||
mio = validated_data['mio']
|
|
||||||
if mio.state != MIO.MIO_CREATE:
|
|
||||||
raise ValidationError('出入库记录非创建中不可新增')
|
|
||||||
return super().create(validated_data)
|
|
||||||
|
|
||||||
|
|
||||||
class MIODoSerializer(CustomModelSerializer):
|
class MIODoSerializer(CustomModelSerializer):
|
||||||
belong_dept = serializers.PrimaryKeyRelatedField(
|
belong_dept = serializers.PrimaryKeyRelatedField(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from apps.inm.models import MIO, MIOItem, MaterialBatch
|
from apps.inm.models import MIO, MIOItem, MaterialBatch, MaterialBatchA, MIOItemA
|
||||||
from rest_framework.exceptions import ValidationError
|
from rest_framework.exceptions import ValidationError, ParseError
|
||||||
from django.db.models.aggregates import Sum
|
from django.db.models.aggregates import Sum
|
||||||
from apps.wpm.services import do_out, do_in
|
from apps.wpm.services import do_out, do_in
|
||||||
from apps.mtm.models import Material
|
from apps.mtm.models import Material
|
||||||
|
@ -35,20 +35,27 @@ class InmService:
|
||||||
for i in MIOItem.objects.filter(mio=instance):
|
for i in MIOItem.objects.filter(mio=instance):
|
||||||
material = i.material
|
material = i.material
|
||||||
warehouse = i.warehouse
|
warehouse = i.warehouse
|
||||||
mb, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,
|
mb, is_created = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,
|
||||||
defaults={'material': material, 'warehouse': warehouse, 'count': 0, 'batch': i.batch})
|
defaults={'material': material, 'warehouse': warehouse, 'count': 0, 'batch': i.batch})
|
||||||
if in_or_out == 1:
|
if in_or_out == 1:
|
||||||
mb.count = mb.count + i.count
|
mb.count = mb.count + i.count
|
||||||
# if mb.expiration_date is None:
|
# if mb.expiration_date is None:
|
||||||
# mb.expiration_date = i.expiration_date
|
# mb.expiration_date = i.expiration_date
|
||||||
mb.save()
|
mb.save()
|
||||||
|
mias = MIOItemA.objects.filter(mioitem=i)
|
||||||
|
if mias.exists(): # 组合件入库
|
||||||
|
if not is_created:
|
||||||
|
raise ParseError('该批次组合件已存在')
|
||||||
|
for mia in mias:
|
||||||
|
MaterialBatchA.objects.create(
|
||||||
|
mb=mb, material=mia.material, batch=mia.batch, count=mia.count)
|
||||||
elif in_or_out == -1:
|
elif in_or_out == -1:
|
||||||
mb.count = mb.count - i.count
|
mb.count = mb.count - i.count
|
||||||
if mb.count < 0:
|
if mb.count < 0:
|
||||||
raise ValidationError('批次库存不足,操作失败')
|
raise ParseError('批次库存不足,操作失败')
|
||||||
mb.save()
|
mb.save()
|
||||||
else:
|
else:
|
||||||
raise ValidationError('不支持的操作')
|
raise ParseError('不支持的操作')
|
||||||
material_count = MaterialBatch.objects.filter(
|
material_count = MaterialBatch.objects.filter(
|
||||||
material=material).aggregate(total=Sum('count')).get('total', 0)
|
material=material).aggregate(total=Sum('count')).get('total', 0)
|
||||||
Material.objects.filter(id=material.id).update(
|
Material.objects.filter(id=material.id).update(
|
||||||
|
|
|
@ -9,11 +9,13 @@ from rest_framework.response import Response
|
||||||
|
|
||||||
from apps.inm.models import WareHouse, MaterialBatch, MIO, MIOItem
|
from apps.inm.models import WareHouse, MaterialBatch, MIO, MIOItem
|
||||||
from apps.inm.serializers import (
|
from apps.inm.serializers import (
|
||||||
MaterialBatchSerializer, WareHourseSerializer, MIOListSerializer, MIOItemSerializer, MIODoSerializer, MIOSaleSerializer, MIOPurSerializer, MIOOtherSerializer)
|
MaterialBatchSerializer, WareHourseSerializer, MIOListSerializer, MIOItemSerializer,
|
||||||
|
MIODoSerializer, MIOSaleSerializer, MIOPurSerializer, MIOOtherSerializer, MIOItemCreateSerializer, MaterialBatchDetailSerializer)
|
||||||
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
||||||
from apps.inm.services import InmService
|
from apps.inm.services import InmService
|
||||||
from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin, BulkUpdateModelMixin
|
from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin, BulkUpdateModelMixin
|
||||||
from apps.utils.permission import has_perm
|
from apps.utils.permission import has_perm
|
||||||
|
from .filters import MaterialBatchFilter
|
||||||
|
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
@ -43,8 +45,9 @@ class MaterialBatchViewSet(ListModelMixin, CustomGenericViewSet):
|
||||||
perms_map = {'get': '*'}
|
perms_map = {'get': '*'}
|
||||||
queryset = MaterialBatch.objects.all()
|
queryset = MaterialBatch.objects.all()
|
||||||
serializer_class = MaterialBatchSerializer
|
serializer_class = MaterialBatchSerializer
|
||||||
|
retrieve_serializer_class = MaterialBatchDetailSerializer
|
||||||
select_related_fields = ['warehouse', 'material']
|
select_related_fields = ['warehouse', 'material']
|
||||||
filterset_fields = ['warehouse', 'material']
|
filterset_class = MaterialBatchFilter
|
||||||
search_fields = ['material__name']
|
search_fields = ['material__name']
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,6 +171,7 @@ class MIOItemViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin
|
||||||
perms_map = {'get': '*', 'post': '*', 'delete': '*'}
|
perms_map = {'get': '*', 'post': '*', 'delete': '*'}
|
||||||
queryset = MIOItem.objects.all()
|
queryset = MIOItem.objects.all()
|
||||||
serializer_class = MIOItemSerializer
|
serializer_class = MIOItemSerializer
|
||||||
|
create_serializer_class = MIOItemCreateSerializer
|
||||||
select_related_fields = ['warehouse', 'mio', 'material']
|
select_related_fields = ['warehouse', 'mio', 'material']
|
||||||
filterset_fields = ['warehouse', 'mio', 'material']
|
filterset_fields = ['warehouse', 'mio', 'material']
|
||||||
ordering = ['create_time']
|
ordering = ['create_time']
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from django_filters import rest_framework as filters
|
from django_filters import rest_framework as filters
|
||||||
from apps.wpm.models import SfLog, SfLogExp
|
from apps.wpm.models import SfLog, SfLogExp, WMaterial
|
||||||
['mgroup', 'shift', 'team', 'leader', 'team__belong_dept']
|
['mgroup', 'shift', 'team', 'leader', 'team__belong_dept']
|
||||||
|
|
||||||
|
|
||||||
class SfLogFilter(filters.FilterSet):
|
class SfLogFilter(filters.FilterSet):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SfLog
|
model = SfLog
|
||||||
|
@ -14,8 +16,10 @@ class SfLogFilter(filters.FilterSet):
|
||||||
"start_time": ["gte"]
|
"start_time": ["gte"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SfLogExpFilter(filters.FilterSet):
|
class SfLogExpFilter(filters.FilterSet):
|
||||||
is_st = filters.BooleanFilter(method='filter_is_st', label='是否停机')
|
is_st = filters.BooleanFilter(method='filter_is_st', label='是否停机')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SfLogExp
|
model = SfLogExp
|
||||||
fields = {
|
fields = {
|
||||||
|
@ -28,8 +32,20 @@ class SfLogExpFilter(filters.FilterSet):
|
||||||
"stlog__start_time": ["day", "month", "year"],
|
"stlog__start_time": ["day", "month", "year"],
|
||||||
"stlog__end_time": ["day", "month", "year"]
|
"stlog__end_time": ["day", "month", "year"]
|
||||||
}
|
}
|
||||||
|
|
||||||
def filter_is_st(self, queryset, name, value):
|
def filter_is_st(self, queryset, name, value):
|
||||||
if value:
|
if value:
|
||||||
return queryset.exclude(stlog=None)
|
return queryset.exclude(stlog=None)
|
||||||
return queryset.filter(stlog=None)
|
return queryset.filter(stlog=None)
|
||||||
|
|
||||||
|
|
||||||
|
class WMaterialFilter(filters.FilterSet):
|
||||||
|
class Meta:
|
||||||
|
model = WMaterial
|
||||||
|
fields = {
|
||||||
|
"material": ["exact", "in"],
|
||||||
|
"belong_dept": ["exact"],
|
||||||
|
"belong_dept__name": ["exact"],
|
||||||
|
"batch": ["exact"],
|
||||||
|
"count": ["gte", "lte", "exact"]
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
|
||||||
|
|
||||||
from rest_framework.exceptions import ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
|
|
||||||
from apps.inm.models import MIO, MIOItem
|
from apps.inm.models import MIO, MIOItem, MIOItemA
|
||||||
from apps.pm.models import Mtask
|
from apps.pm.models import Mtask
|
||||||
from apps.mtm.models import Mgroup, Shift, Material
|
from apps.mtm.models import Mgroup, Shift, Material
|
||||||
|
|
||||||
|
@ -80,28 +80,38 @@ def do_out(mio: MIO):
|
||||||
|
|
||||||
def do_in(mio: MIO):
|
def do_in(mio: MIO):
|
||||||
"""
|
"""
|
||||||
生产入库
|
生产入库后更新车间物料
|
||||||
"""
|
"""
|
||||||
belong_dept = mio.belong_dept
|
belong_dept = mio.belong_dept
|
||||||
do_user = mio.do_user
|
do_user = mio.do_user
|
||||||
mioitems = MIOItem.objects.filter(mio=mio)
|
mioitems = MIOItem.objects.filter(mio=mio)
|
||||||
for item in mioitems:
|
for item in mioitems:
|
||||||
try:
|
action_list = []
|
||||||
wm = WMaterial.objects.get(
|
mias = MIOItemA.objects.filter(mioitem=item)
|
||||||
batch=item.batch, material=item.material, belong_dept=belong_dept)
|
if mias.exists(): # 组合件入库
|
||||||
except ObjectDoesNotExist:
|
action_list = list(mias.values_list('material', 'batch', 'rate'))
|
||||||
raise ParseError('车间物料不存在!')
|
for i in action_list:
|
||||||
except MultipleObjectsReturned:
|
i[2] = i[2]*item.count
|
||||||
raise ParseError('存在多行车间物料!')
|
|
||||||
new_count = wm.count - item.count
|
|
||||||
if new_count > 0:
|
|
||||||
wm.count = new_count
|
|
||||||
wm.update_by = do_user
|
|
||||||
wm.save()
|
|
||||||
elif new_count == 0:
|
|
||||||
wm.delete()
|
|
||||||
else:
|
else:
|
||||||
raise ParseError('车间物料不足')
|
action_list = [item.material, item.batch, item.count]
|
||||||
|
for al in action_list:
|
||||||
|
xmaterial, xbatch, xcount = al
|
||||||
|
try:
|
||||||
|
wm = WMaterial.objects.get(
|
||||||
|
batch=xbatch, material=xmaterial, belong_dept=belong_dept)
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
raise ParseError('车间物料不存在!')
|
||||||
|
except MultipleObjectsReturned:
|
||||||
|
raise ParseError('存在多行车间物料!')
|
||||||
|
new_count = wm.count - xcount
|
||||||
|
if new_count > 0:
|
||||||
|
wm.count = new_count
|
||||||
|
wm.update_by = do_user
|
||||||
|
wm.save()
|
||||||
|
elif new_count == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise ParseError('车间物料不足')
|
||||||
|
|
||||||
|
|
||||||
def mlog_confirm(mlog: Mlog):
|
def mlog_confirm(mlog: Mlog):
|
||||||
|
|
|
@ -10,7 +10,7 @@ from apps.pm.models import Mtask
|
||||||
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
||||||
from apps.utils.mixins import BulkCreateModelMixin
|
from apps.utils.mixins import BulkCreateModelMixin
|
||||||
|
|
||||||
from .filters import SfLogExpFilter, SfLogFilter
|
from .filters import SfLogExpFilter, SfLogFilter, WMaterialFilter
|
||||||
from .models import SfLog, SfLogExp, StLog, WMaterial, Mlog
|
from .models import SfLog, SfLogExp, StLog, WMaterial, Mlog
|
||||||
from .serializers import SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer, MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer
|
from .serializers import SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer, MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ class WMaterialViewSet(ListModelMixin, CustomGenericViewSet):
|
||||||
select_related_fields = ['material', 'belong_dept']
|
select_related_fields = ['material', 'belong_dept']
|
||||||
search_fields = ['material__name',
|
search_fields = ['material__name',
|
||||||
'material__number', 'material__specification']
|
'material__number', 'material__specification']
|
||||||
filterset_fields = ['material', 'belong_dept']
|
filterset_class = WMaterialFilter
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=DeptBatchSerializer)
|
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=DeptBatchSerializer)
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
|
|
Loading…
Reference in New Issue