feat: 生产日志追踪到个完善
This commit is contained in:
parent
f8b056cadb
commit
d784ac8a3c
|
@ -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='生成的'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -292,6 +292,7 @@ class Mlog(CommonADModel):
|
||||||
return mlog_count_fields
|
return mlog_count_fields
|
||||||
|
|
||||||
class Mlogb(BaseModel):
|
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='关联日志',
|
mlog = models.ForeignKey(Mlog, verbose_name='关联日志',
|
||||||
on_delete=models.CASCADE, related_name='b_mlog')
|
on_delete=models.CASCADE, related_name='b_mlog')
|
||||||
note = models.TextField('备注', default='', blank=True)
|
note = models.TextField('备注', default='', blank=True)
|
||||||
|
|
|
@ -570,7 +570,16 @@ class MlogbInUpdateSerializer(CustomModelSerializer):
|
||||||
class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Mlogbw
|
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):
|
def update(self, instance, validated_data):
|
||||||
validated_data.pop("mlogb")
|
validated_data.pop("mlogb")
|
||||||
|
|
|
@ -274,7 +274,9 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
||||||
if item.wpr:
|
if item.wpr:
|
||||||
Wpr.change_or_new(wpr=item.wpr, wm=wm)
|
Wpr.change_or_new(wpr=item.wpr, wm=wm)
|
||||||
else:
|
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_time = now
|
||||||
mlog.submit_user = user
|
mlog.submit_user = user
|
||||||
|
@ -399,7 +401,9 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
||||||
if item.wpr:
|
if item.wpr:
|
||||||
Wpr.change_or_new(wpr=item.wpr, wm=wm)
|
Wpr.change_or_new(wpr=item.wpr, wm=wm)
|
||||||
else:
|
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:
|
for item in m_ins_bl_list:
|
||||||
|
|
|
@ -24,6 +24,7 @@ from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer,
|
||||||
from .services import mlog_submit, handover_submit, mlog_revert
|
from .services import mlog_submit, handover_submit, mlog_revert
|
||||||
from apps.wpm.services import mlog_submit_validate, generate_new_batch
|
from apps.wpm.services import mlog_submit_validate, generate_new_batch
|
||||||
from apps.wf.models import State
|
from apps.wf.models import State
|
||||||
|
from apps.wpmw.models import Wpr
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
|
@ -478,21 +479,35 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
ins: Mlogb = serializer.save()
|
mlogbin: Mlogb = serializer.save()
|
||||||
mlog: Mlog = ins.mlog
|
mlog: Mlog = mlogbin.mlog
|
||||||
# 创建输出
|
# 创建输出
|
||||||
if ins.mtask and ins.material_in:
|
# 以及mlogbw
|
||||||
material_out = mlog.material_out
|
if mlogbin.mtask and mlogbin.material_in:
|
||||||
|
material_in:Material = mlogbin.material_in
|
||||||
|
material_out:Material = mlog.material_out
|
||||||
if material_out is None:
|
if material_out is None:
|
||||||
raise ParseError('产物不可为空')
|
raise ParseError('产物不可为空')
|
||||||
m_dict = {
|
m_dict = {
|
||||||
"mtask": ins.mtask,
|
"mtask": mlogbin.mtask,
|
||||||
"mlog": ins.mlog,
|
"mlog": mlog,
|
||||||
"material_out": ins.mlog.material_out
|
"material_out": material_out,
|
||||||
}
|
}
|
||||||
m_dict['batch'] = generate_new_batch(ins.batch, mlog)
|
m_dict['batch'] = generate_new_batch(mlogbin.batch, mlog)
|
||||||
wm_in: WMaterial = ins.wm_in
|
wm_in: WMaterial = mlogbin.wm_in
|
||||||
Mlogb.objects.get_or_create(**m_dict, defaults={"batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom})
|
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):
|
class MlogbOutViewSet(UpdateModelMixin, CustomGenericViewSet):
|
||||||
|
@ -544,20 +559,46 @@ class MlogbwViewSet(CustomModelViewSet):
|
||||||
return super().filter_queryset(queryset)
|
return super().filter_queryset(queryset)
|
||||||
|
|
||||||
def cal_mlogb_count(self, mlogb):
|
def cal_mlogb_count(self, mlogb):
|
||||||
count_real = Mlogbw.objects.filter(mlogb=mlogb).count()
|
count = Mlogbw.objects.filter(mlogb=mlogb).count()
|
||||||
mlogb.count_real = count_real
|
# 此处先不管检验问题
|
||||||
mlogb.count_ok = count_real
|
# todo
|
||||||
|
if mlogb.material_in:
|
||||||
|
mlogb.count_use = count
|
||||||
|
elif mlogb.material_out:
|
||||||
|
mlogb.count_real = count
|
||||||
|
mlogb.count_ok = count
|
||||||
mlogb.save()
|
mlogb.save()
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
ins = serializer.save()
|
ins:Mlogbw = serializer.save()
|
||||||
self.cal_mlogb_count(ins.mlogb)
|
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
|
@transaction.atomic
|
||||||
def perform_destroy(self, instance):
|
def perform_destroy(self, instance):
|
||||||
mlogb = instance.mlogb
|
mlogb = instance.mlogb
|
||||||
instance.delete()
|
instance.delete()
|
||||||
self.cal_mlogb_count(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:
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,12 @@ class Wpr(BaseModel):
|
||||||
if mb and wm:
|
if mb and wm:
|
||||||
raise ParseError("所属仓库批次和车间批次不可同时存在")
|
raise ParseError("所属仓库批次和车间批次不可同时存在")
|
||||||
|
|
||||||
ins = wpr if wpr else cls.objects.filter(number=number).first()
|
if wpr:
|
||||||
if ins is None:
|
ins = wpr
|
||||||
|
elif number:
|
||||||
|
try:
|
||||||
|
ins = cls.objects.get(number=number)
|
||||||
|
except cls.DoesNotExist:
|
||||||
ins = cls(number=number)
|
ins = cls(number=number)
|
||||||
|
|
||||||
if old_mb and ins.mb != old_mb:
|
if old_mb and ins.mb != old_mb:
|
||||||
|
@ -34,9 +38,13 @@ class Wpr(BaseModel):
|
||||||
if old_wm and ins.wm != old_wm:
|
if old_wm and ins.wm != old_wm:
|
||||||
raise ParseError(f"请检查-{ins.number}-所属车间批次")
|
raise ParseError(f"请检查-{ins.number}-所属车间批次")
|
||||||
|
|
||||||
|
if number:
|
||||||
|
ins.number = number
|
||||||
|
|
||||||
ins.mb = mb
|
ins.mb = mb
|
||||||
if mb:
|
if mb:
|
||||||
ins.material = mb.material
|
ins.material = mb.material
|
||||||
|
|
||||||
ins.wm = wm
|
ins.wm = wm
|
||||||
if wm:
|
if wm:
|
||||||
ins.material = wm.material
|
ins.material = wm.material
|
||||||
|
|
Loading…
Reference in New Issue