fix: 生产提交支持单个物料

This commit is contained in:
caoqianming 2025-01-02 14:01:09 +08:00
parent 2c107d4050
commit ba41228d69
6 changed files with 63 additions and 30 deletions

View File

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

View File

@ -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='生产记录')),
],

View File

@ -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):
"""
到岗记录

View File

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

View File

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

View File

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