feat: 生产日志追踪到个完善

This commit is contained in:
caoqianming 2025-01-06 10:23:51 +08:00
parent f8b056cadb
commit d784ac8a3c
6 changed files with 103 additions and 21 deletions

View File

@ -0,0 +1,19 @@
# Generated by Django 3.2.12 on 2025-01-06 02:20
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('wpm', '0079_auto_20250103_1652'),
]
operations = [
migrations.AddField(
model_name='mlogb',
name='mlogb_to',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='wpm.mlogb', verbose_name='生成的'),
),
]

View File

@ -292,6 +292,7 @@ class Mlog(CommonADModel):
return mlog_count_fields
class Mlogb(BaseModel):
mlogb_to = models.ForeignKey("self", verbose_name='生成的', on_delete=models.SET_NULL, null=True, blank=True)
mlog = models.ForeignKey(Mlog, verbose_name='关联日志',
on_delete=models.CASCADE, related_name='b_mlog')
note = models.TextField('备注', default='', blank=True)

View File

@ -570,7 +570,16 @@ class MlogbInUpdateSerializer(CustomModelSerializer):
class MlogbwCreateUpdateSerializer(CustomModelSerializer):
class Meta:
model = Mlogbw
fields = ["id", "number", "note", "mlogb"]
fields = ["id", "number", "wpr", "note", "mlogb"]
def validate(self, attrs):
mlogb:Mlogb = attrs["mlogb"]
material_in:Material = mlogb.material_in
material_out:Material = mlogb.material_out
if material_in and material_in.tracking != Material.MA_TRACKING_SINGLE:
raise ParseError("非追踪单件无需填写")
if material_out and material_out.tracking != Material.MA_TRACKING_SINGLE:
raise ParseError("非追踪单件无需填写")
def update(self, instance, validated_data):
validated_data.pop("mlogb")

View File

@ -274,7 +274,9 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
if item.wpr:
Wpr.change_or_new(wpr=item.wpr, wm=wm)
else:
Wpr.change_or_new(number=item.number, wm=wm)
wpr = Wpr.change_or_new(number=item.number, wm=wm)
item.wpr = wpr
item.save()
mlog.submit_time = now
mlog.submit_user = user
@ -399,7 +401,9 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
if item.wpr:
Wpr.change_or_new(wpr=item.wpr, wm=wm)
else:
Wpr.change_or_new(number=item.number, wm=wm)
wpr = Wpr.change_or_new(number=item.number, wm=wm)
item.wpr = wpr
item.save()
# 针对加工前不良的暂时额外处理
for item in m_ins_bl_list:

View File

@ -24,6 +24,7 @@ from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer,
from .services import mlog_submit, handover_submit, mlog_revert
from apps.wpm.services import mlog_submit_validate, generate_new_batch
from apps.wf.models import State
from apps.wpmw.models import Wpr
# Create your views here.
@ -478,21 +479,35 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
@transaction.atomic
def perform_create(self, serializer):
ins: Mlogb = serializer.save()
mlog: Mlog = ins.mlog
mlogbin: Mlogb = serializer.save()
mlog: Mlog = mlogbin.mlog
# 创建输出
if ins.mtask and ins.material_in:
material_out = mlog.material_out
# 以及mlogbw
if mlogbin.mtask and mlogbin.material_in:
material_in:Material = mlogbin.material_in
material_out:Material = mlog.material_out
if material_out is None:
raise ParseError('产物不可为空')
m_dict = {
"mtask": ins.mtask,
"mlog": ins.mlog,
"material_out": ins.mlog.material_out
"mtask": mlogbin.mtask,
"mlog": mlog,
"material_out": material_out,
}
m_dict['batch'] = generate_new_batch(ins.batch, mlog)
wm_in: WMaterial = ins.wm_in
Mlogb.objects.get_or_create(**m_dict, defaults={"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom})
m_dict['batch'] = generate_new_batch(mlogbin.batch, mlog)
wm_in: WMaterial = mlogbin.wm_in
mlogbout, _ = Mlogb.objects.get_or_create(**m_dict, defaults={"batch_ofrom": wm_in.batch_ofrom,
"material_ofrom": wm_in.material_ofrom})
mlogbin.mlogb_to = mlogbout
mlogbin.save()
if material_out.tracking == Material.MA_TRACKING_SINGLE:
if material_in.tracking == Material.MA_TRACKING_SINGLE:
if mlogbin.count_use == wm_in.count: # 自动创建mlogbw
# 先暂时不考虑合并与拆分
mlogbout.count_real = wm_in.count
mlogbout.save()
for wpr in Wpr.objects.filter(wm=wm_in).order_by("number"):
Mlogbw.objects.get_or_create(wpr=wpr, mlogb=mlogbin, defaults={"number": wpr.number})
Mlogbw.objects.get_or_create(wpr=wpr, mlogb=mlogbout, defaults={"number": wpr.number})
class MlogbOutViewSet(UpdateModelMixin, CustomGenericViewSet):
@ -544,20 +559,46 @@ class MlogbwViewSet(CustomModelViewSet):
return super().filter_queryset(queryset)
def cal_mlogb_count(self, mlogb):
count_real = Mlogbw.objects.filter(mlogb=mlogb).count()
mlogb.count_real = count_real
mlogb.count_ok = count_real
count = Mlogbw.objects.filter(mlogb=mlogb).count()
# 此处先不管检验问题
# todo
if mlogb.material_in:
mlogb.count_use = count
elif mlogb.material_out:
mlogb.count_real = count
mlogb.count_ok = count
mlogb.save()
@transaction.atomic
def perform_create(self, serializer):
ins = serializer.save()
self.cal_mlogb_count(ins.mlogb)
ins:Mlogbw = serializer.save()
mlogb:Mlogb = ins.mlogb
self.cal_mlogb_count(mlogb)
# 如果是输入且输出追踪到个,需同步创建
material_in:Material = mlogb.material_in
if material_in is not None:
mlogb_to = mlogb.mlogb_to
material_out:Material = mlogb.mlog.material_out
if mlogb_to and material_out.tracking == Material.MA_TRACKING_SINGLE:
for item in Mlogbw.objects.filter(mlogb=mlogb).order_by("number"):
Mlogbw.objects.get_or_create(mlogb=mlogb_to, wpr=item.wpr, defaults={"number": item.number})
self.cal_mlogb_count(mlogb_to)
@transaction.atomic
def perform_destroy(self, instance):
mlogb = instance.mlogb
instance.delete()
self.cal_mlogb_count(mlogb)
# 如果是输入且输出追踪到个,需同步创建
material_in: Material = mlogb.material_in
if material_in is not None:
mlogb_to = mlogb.mlogb_to
material_out: Material = mlogb.mlog.material_out
if mlogb_to and material_out.tracking == Material.MA_TRACKING_SINGLE:
number_list = Mlogbw.objects.filter(mlogb=mlogb).values_list("number", flat=True)
wprId_list = Mlogbw.objects.filter(mlogb=mlogb).values_list("wpr__id", flat=True)
Mlogbw.objects.filter(mlogb=mlogb_to, number__in=number_list).delete()
Mlogbw.objects.filter(mlogb=mlogb_to, wpr__id__in=wprId_list).delete()
self.cal_mlogb_count(mlogb_to)

View File

@ -25,18 +25,26 @@ class Wpr(BaseModel):
if mb and wm:
raise ParseError("所属仓库批次和车间批次不可同时存在")
ins = wpr if wpr else cls.objects.filter(number=number).first()
if ins is None:
ins = cls(number=number)
if wpr:
ins = wpr
elif number:
try:
ins = cls.objects.get(number=number)
except cls.DoesNotExist:
ins = cls(number=number)
if old_mb and ins.mb != old_mb:
raise ParseError(f"请检查-{ins.number}-所属仓库批次")
if old_wm and ins.wm != old_wm:
raise ParseError(f"请检查-{ins.number}-所属车间批次")
if number:
ins.number = number
ins.mb = mb
if mb:
ins.material = mb.material
ins.wm = wm
if wm:
ins.material = wm.material