fix: 生产提交支持单个物料
This commit is contained in:
parent
2c107d4050
commit
ba41228d69
|
@ -98,7 +98,6 @@ class MIOItemwCreateSerializer(CustomModelSerializer):
|
|||
fields = ["number", "note"]
|
||||
|
||||
class MIOItemwSerializer(CustomModelSerializer):
|
||||
test_user_name = serializers.CharField(source='test_user.name', read_only=True)
|
||||
class Meta:
|
||||
model = MIOItemw
|
||||
fields = "__all__"
|
||||
|
@ -119,12 +118,12 @@ class MIOItemwTestSerializer(CustomModelSerializer):
|
|||
class MIOItemCreateSerializer(CustomModelSerializer):
|
||||
assemb = MIOItemACreateSerializer(
|
||||
label='组合件信息', many=True, write_only=True, required=False)
|
||||
wprs = MIOItemwCreateSerializer(many=True, required=False)
|
||||
mioitemw_ = MIOItemwCreateSerializer(many=True, required=False)
|
||||
|
||||
class Meta:
|
||||
model = MIOItem
|
||||
fields = ['mio', 'warehouse', 'material',
|
||||
'batch', 'count', 'assemb', 'is_testok', 'wprs']
|
||||
'batch', 'count', 'assemb', 'is_testok', 'mioitemw_']
|
||||
|
||||
def create(self, validated_data):
|
||||
mio = validated_data['mio']
|
||||
|
@ -143,7 +142,7 @@ class MIOItemCreateSerializer(CustomModelSerializer):
|
|||
count = validated_data["count"]
|
||||
batch = validated_data["batch"]
|
||||
assemb = validated_data.pop('assemb', [])
|
||||
wprs = validated_data.pop('wprs', [])
|
||||
mioitemw_ = validated_data.pop('mioitemw_', [])
|
||||
instance = super().create(validated_data)
|
||||
assemb_dict = {}
|
||||
for i in assemb:
|
||||
|
@ -158,13 +157,13 @@ class MIOItemCreateSerializer(CustomModelSerializer):
|
|||
else:
|
||||
raise ParseError('缺少组合件')
|
||||
if material.tracking == Material.MA_TRACKING_SINGLE:
|
||||
if count == 1 and len(wprs) == 0:
|
||||
if count == 1 and len(mioitemw_) == 0:
|
||||
MIOItemw.objects.create(mioitem=instance, number=batch)
|
||||
elif count == 1 and len(wprs) >= 1:
|
||||
MIOItemw.objects.create(mioitem=instance, number=wprs[0]['number'], note=wprs[0]['note'])
|
||||
elif count > 1 and len(wprs) == count:
|
||||
for w in wprs:
|
||||
MIOItemw.objects.create(mioitem=instance, number=w['number'], note=w['note'])
|
||||
elif count == 1 and len(mioitemw_) >= 1:
|
||||
MIOItemw.objects.create(mioitem=instance, number=mioitemw_[0]['number'], note=mioitemw_[0]['note'])
|
||||
elif count > 1 and len(mioitemw_) == count:
|
||||
for item in mioitemw_:
|
||||
MIOItemw.objects.create(mioitem=instance, number=item['number'], note=item['note'])
|
||||
else:
|
||||
raise ParseError('单个明细信息不匹配')
|
||||
return instance
|
||||
|
@ -191,7 +190,7 @@ class MIOItemSerializer(CustomModelSerializer):
|
|||
source='material', read_only=True)
|
||||
inout_date = serializers.DateField(source='mio.inout_date', read_only=True)
|
||||
test_user_name = serializers.CharField(source='test_user.name', read_only=True)
|
||||
wprs = MIOItemwSerializer(source='w_mioitem', read_only=True, many=True)
|
||||
mioitemw_ = MIOItemwSerializer(source='w_mioitem', read_only=True, many=True)
|
||||
|
||||
class Meta:
|
||||
model = MIOItem
|
||||
|
|
|
@ -26,8 +26,6 @@ class Migration(migrations.Migration):
|
|||
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||
('number', models.TextField(verbose_name='单个编号')),
|
||||
('test_json', models.JSONField(blank=True, default=dict, verbose_name='检验情况')),
|
||||
('defect_json', models.JSONField(blank=True, default=list, verbose_name='缺陷情况')),
|
||||
('note', models.TextField(blank=True, null=True, verbose_name='备注')),
|
||||
('mlogb', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.mlogb', verbose_name='生产记录')),
|
||||
],
|
||||
|
|
|
@ -12,11 +12,6 @@ from django.utils.translation import gettext_lazy as _
|
|||
|
||||
# Create your models here.
|
||||
|
||||
# class Good(BaseModel):
|
||||
# """
|
||||
# 产品状态
|
||||
# """
|
||||
# pass
|
||||
class BatchSt(BaseModel):
|
||||
"""
|
||||
批次统计表
|
||||
|
@ -102,6 +97,7 @@ class WmStateOption(models.IntegerChoices):
|
|||
REPAIR = 30, _("返修")
|
||||
TEST = 40, _("检验")
|
||||
SCRAP = 50, _("报废")
|
||||
|
||||
class WMaterial(CommonBDModel):
|
||||
"""
|
||||
belong_dept是所在车间
|
||||
|
@ -119,10 +115,10 @@ class WMaterial(CommonBDModel):
|
|||
batch = models.TextField('批次号')
|
||||
count = models.PositiveIntegerField('当前数量', default=0)
|
||||
count_eweight = models.FloatField('单数重量', default=0)
|
||||
defect = models.ForeignKey('qm.defect', verbose_name='缺陷', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
notok_sign = models.CharField('不合格标记', max_length=10, null=True, blank=True)
|
||||
material_origin = models.ForeignKey(Material, verbose_name='原始物料', on_delete=models.SET_NULL, null=True, blank=True, related_name='wm_mo')
|
||||
count_xtest = models.PositiveIntegerField('已检数量', null=True, blank=True)
|
||||
|
||||
batch_ofrom = models.TextField('原料批次号', null=True, blank=True)
|
||||
material_ofrom = models.ForeignKey(Material, verbose_name='原料物料', on_delete=models.SET_NULL, null=True, blank=True, related_name='wm_mofrom')
|
||||
|
||||
|
@ -339,6 +335,12 @@ class Mlogb(BaseModel):
|
|||
count_n_qt = models.PositiveIntegerField('其他', default=0)
|
||||
count_notok_json = models.JSONField('不合格情况', default=list, blank=True)
|
||||
|
||||
class Mlogbw(BaseModel):
|
||||
number = models.TextField('单个编号')
|
||||
mlogb = models.ForeignKey(Mlogb, verbose_name='生产记录', on_delete=models.CASCADE)
|
||||
note = models.TextField('备注', null=True, blank=True)
|
||||
|
||||
|
||||
class Handover(CommonADModel):
|
||||
"""
|
||||
交接记录
|
||||
|
@ -388,6 +390,11 @@ class Handoverb(BaseModel):
|
|||
null=True, blank=True, related_name='handoverb_wm')
|
||||
count = models.PositiveIntegerField('送料数', default=0)
|
||||
|
||||
class Handoverbw(BaseModel):
|
||||
handoverb = models.ForeignKey(Handoverb, verbose_name='关联交接记录', on_delete=models.CASCADE)
|
||||
number = models.TextField('单个编号')
|
||||
note = models.TextField('备注', null=True, blank=True)
|
||||
|
||||
class AttLog(CommonADModel):
|
||||
"""
|
||||
到岗记录
|
||||
|
|
|
@ -5,7 +5,8 @@ from rest_framework.exceptions import ValidationError, ParseError
|
|||
from datetime import datetime
|
||||
|
||||
from .models import (SfLog, StLog, SfLogExp, WMaterial, Mlog,
|
||||
Handover, Handoverb, Mlogb, AttLog, OtherLog, Fmlog, BatchSt)
|
||||
Handover, Handoverb, Mlogb, AttLog,
|
||||
OtherLog, Fmlog, BatchSt, Mlogbw)
|
||||
from apps.system.models import Dept, User
|
||||
from apps.system.serializers import UserSimpleSerializer
|
||||
from apps.pm.models import Mtask, Mtaskb
|
||||
|
@ -566,6 +567,12 @@ class MlogbInUpdateSerializer(CustomModelSerializer):
|
|||
model = Mlogb
|
||||
fields = ['id', 'count_use', 'count_break', 'count_pn_jgqbl', 'note']
|
||||
|
||||
class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
||||
class Meta:
|
||||
model = Mlogbw
|
||||
fields = ["number", "note"]
|
||||
|
||||
|
||||
class MlogbOutUpdateSerializer(CustomModelSerializer):
|
||||
class Meta:
|
||||
model = Mlogb
|
||||
|
|
|
@ -11,13 +11,15 @@ from apps.system.models import User
|
|||
from apps.pm.models import Mtask
|
||||
from apps.mtm.models import Mgroup, Shift, Material, Route, RoutePack, Team, Srule
|
||||
|
||||
from .models import SfLog, WMaterial, Mlog, Mlogb, Handover, Handoverb
|
||||
from .models import SfLog, WMaterial, Mlog, Mlogb, Mlogbw, Handover, Handoverb
|
||||
from apps.mtm.services import cal_material_count
|
||||
from apps.wf.models import Ticket
|
||||
from apps.utils.thread import MyThread
|
||||
import logging
|
||||
from apps.wpm.services_2 import get_alldata_with_batch_and_store
|
||||
from datetime import timedelta
|
||||
from apps.wpmw.models import Wpr, WprDefect
|
||||
|
||||
myLogger = logging.getLogger('log')
|
||||
|
||||
def generate_new_batch(old_batch: str, mlog: Mlog):
|
||||
|
@ -151,8 +153,8 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
|||
|
||||
mgroup = mlog.mgroup
|
||||
belong_dept = mgroup.belong_dept
|
||||
material_out = mlog.material_out
|
||||
material_in = mlog.material_in
|
||||
material_out: Material = mlog.material_out
|
||||
material_in: Material = mlog.material_in
|
||||
supplier = mlog.supplier # 外协
|
||||
m_ins_list = []
|
||||
if material_in: # 需要进行车间库存管理
|
||||
|
@ -161,17 +163,17 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
|||
m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False)
|
||||
if m_ins.exists():
|
||||
for mi in m_ins.all():
|
||||
m_ins_list.append((mi.material_in, mi.batch, mi.count_use, mi.wm_in))
|
||||
m_ins_list.append((mi.material_in, mi.batch, mi.count_use, mi))
|
||||
if mi.count_pn_jgqbl > 0:
|
||||
m_ins_bl_list.append((mi.material_in, mi.batch, mi.count_pn_jgqbl, mi))
|
||||
else:
|
||||
m_ins_list = [(material_in, mlog.batch, mlog.count_use, mlog.wm_in)]
|
||||
m_ins_list = [(material_in, mlog.batch, mlog.count_use, mlog)]
|
||||
for mi in m_ins_list:
|
||||
mi_ma, mi_batch, mi_count, mi_wm_in = mi
|
||||
mi_ma, mi_batch, mi_count, mlog_or_b = mi
|
||||
# 需要判断领用数是否合理
|
||||
# 优先使用工段库存
|
||||
if mi_wm_in:
|
||||
wm_qs = WMaterial.objects.filter(id=mi_wm_in.id)
|
||||
if isinstance(mlog_or_b, Mlogb) and mlog_or_b.wm_in:
|
||||
wm_qs = WMaterial.objects.filter(id=mlog_or_b.wm_in.id)
|
||||
else:
|
||||
wm_qs = WMaterial.objects.filter(batch=mi_batch, material=mi_ma, mgroup=mgroup, state=WMaterial.WM_OK)
|
||||
if not wm_qs.exists():
|
||||
|
@ -194,6 +196,12 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
|||
wm.count = wm.count - mi_count
|
||||
wm.update_by = user
|
||||
wm.save()
|
||||
if material_in.tracking == Material.MA_TRACKING_SINGLE:
|
||||
mlogbws = Mlogbw.objects.filter(mlogb=mlog_or_b)
|
||||
if mlogbws.count() != mi.count:
|
||||
raise ParseError("日志与明细数量不一致,操作失败")
|
||||
Wpr.clear([item.number for item in mlogbws])
|
||||
|
||||
# 针对加工前不良的暂时额外处理
|
||||
for item in m_ins_bl_list:
|
||||
material, batch, count_pn_jgqbl, mi_ = item
|
||||
|
@ -207,6 +215,8 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
|||
wm.material_ofrom = mi_.material_ofrom
|
||||
wm.update_by = user
|
||||
wm.save()
|
||||
if material_in.tracking == Material.MA_TRACKING_SINGLE:
|
||||
raise ParseError("加工前不良的物料暂不支持单件")
|
||||
|
||||
|
||||
if material_out: # 需要入车间库存
|
||||
|
@ -255,6 +265,12 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
|||
wm.batch_ofrom = mlog_or_b.batch_ofrom
|
||||
wm.material_ofrom = mlog_or_b.material_ofrom
|
||||
wm.save()
|
||||
if material_out.tracking == Material.MA_TRACKING_SINGLE:
|
||||
mlgbws = Mlogbw.objects.filter(mlogb=mlog_or_b)
|
||||
if mlgbws.count() != mo_count:
|
||||
raise ParseError("日志与明细数量不一致,操作失败")
|
||||
for item in mlgbws:
|
||||
Wpr.change_or_new(item.number, material_out, mb=None, wm=wm)
|
||||
|
||||
mlog.submit_time = now
|
||||
mlog.submit_user = user
|
||||
|
|
|
@ -20,17 +20,23 @@ class Wpr(BaseModel):
|
|||
|
||||
|
||||
@classmethod
|
||||
def change_or_new(cls, number, material, mb=None, wm=None, state=10):
|
||||
def change_or_new(cls, number, material, can_new=False, mb=None, wm=None, state=10):
|
||||
ins = cls.objects.filter(number=number).first()
|
||||
if ins:
|
||||
ins.material = material
|
||||
else:
|
||||
elif can_new:
|
||||
ins = cls(number=number, material=material)
|
||||
else:
|
||||
raise ParseError("物料不存在")
|
||||
ins.state = state
|
||||
ins.mb = mb
|
||||
ins.wm = wm
|
||||
ins.save()
|
||||
|
||||
@classmethod
|
||||
def clear(cls, number_list):
|
||||
cls.objects.filter(number__in=number_list).update(mb=None, wm=None)
|
||||
|
||||
|
||||
class WprDefect(BaseModel):
|
||||
wpr = models.ForeignKey(Wpr, verbose_name="关联产物", on_delete=models.CASCADE)
|
||||
|
|
Loading…
Reference in New Issue