feat: 根据光芯需求对wpm做兼容性处理
This commit is contained in:
parent
3c52125440
commit
d579a7358d
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.12 on 2024-06-28 10:41
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mtm', '0030_route_hour_work'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='process',
|
||||
name='into_wm_mgroup',
|
||||
field=models.BooleanField(default=False, verbose_name='交接到工段'),
|
||||
),
|
||||
]
|
|
@ -8,12 +8,14 @@ class Process(CommonBModel):
|
|||
"""
|
||||
工序
|
||||
"""
|
||||
|
||||
name = models.CharField('工序名称', max_length=100)
|
||||
cate = models.CharField('大类', max_length=10, default='')
|
||||
sort = models.PositiveSmallIntegerField('排序', default=1)
|
||||
instruction = models.ForeignKey(
|
||||
File, verbose_name='指导书', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
instruction_content = models.TextField('指导书内容', null=True, blank=True)
|
||||
into_wm_mgroup = models.BooleanField('交接到工段', default=False)
|
||||
|
||||
class Meta:
|
||||
verbose_name = '工序'
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from django_filters import rest_framework as filters
|
||||
from apps.wpm.models import SfLog, StLog, WMaterial, Mlog, Handover
|
||||
['mgroup', 'shift', 'team', 'leader', 'team__belong_dept']
|
||||
|
||||
|
||||
class SfLogFilter(filters.FilterSet):
|
||||
|
@ -41,11 +40,12 @@ class WMaterialFilter(filters.FilterSet):
|
|||
"material__process__name": ["exact", "contains", "in"],
|
||||
"belong_dept": ["exact"],
|
||||
"belong_dept__name": ["exact", "in"],
|
||||
"batch": ["exact", "in"],
|
||||
"batch": ["exact", "contains"],
|
||||
"mgroup": ["exact", "in"],
|
||||
"mgroup__name": ["exact", "in"],
|
||||
"count": ["gte", "lte", "exact"]
|
||||
}
|
||||
|
||||
|
||||
class MlogFilter(filters.FilterSet):
|
||||
class Meta:
|
||||
model = Mlog
|
||||
|
@ -78,5 +78,8 @@ class HandoverFilter(filters.FilterSet):
|
|||
"material__type": ["exact", "in"],
|
||||
"submit_time": ["isnull"],
|
||||
"mlog": ["isnull"],
|
||||
"send_mgroup": ["exact"]
|
||||
"send_mgroup": ["exact"],
|
||||
"send_mgroup__name": ["exact"],
|
||||
"recive_mgroup": ["exact"],
|
||||
"recive_mgroup__name": ["exact"],
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
# Generated by Django 3.2.12 on 2024-07-01 01:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pm', '0018_mtask_hour_work'),
|
||||
('mtm', '0031_process_into_wm_mgroup'),
|
||||
('system', '0004_auto_20240605_1011'),
|
||||
('wpm', '0049_auto_20240522_1447'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='handover',
|
||||
name='recive_mgroup',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='handover_recive_mgroup', to='mtm.mgroup', verbose_name='接收工段'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mlog',
|
||||
name='hour_work',
|
||||
field=models.FloatField(blank=True, null=True, verbose_name='预计工时'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mlog',
|
||||
name='work_end_time',
|
||||
field=models.DateTimeField(blank=True, null=True, verbose_name='生产结束时间'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mlog',
|
||||
name='work_start_time',
|
||||
field=models.DateTimeField(blank=True, null=True, verbose_name='生产开始时间'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mlogb',
|
||||
name='batch',
|
||||
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='批次号'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mlogb',
|
||||
name='count_real',
|
||||
field=models.PositiveIntegerField(default=0, verbose_name='实际生产数'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mlogb',
|
||||
name='count_use',
|
||||
field=models.PositiveIntegerField(default=0, verbose_name='领用数量'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mlogb',
|
||||
name='material_in',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='mlogb_material_in', to='mtm.material', verbose_name='投入物料'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='mlogb',
|
||||
name='mtask',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='mlogb_mtask', to='pm.mtask', verbose_name='关联任务'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='wmaterial',
|
||||
name='mgroup',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.mgroup', verbose_name='所在工段'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='mlog',
|
||||
name='handle_date',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='操作日期'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='mlogb',
|
||||
name='material_out',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='mlogb_material_out', to='mtm.material', verbose_name='产物'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='wmaterial',
|
||||
unique_together={('material', 'batch', 'belong_dept', 'mgroup')},
|
||||
),
|
||||
]
|
|
@ -90,18 +90,23 @@ class WMaterial(CommonBDModel):
|
|||
"""
|
||||
material = models.ForeignKey(
|
||||
Material, verbose_name='物料', on_delete=models.CASCADE)
|
||||
mgroup = models.ForeignKey(Mgroup, verbose_name='所在工段', on_delete=models.CASCADE, null=True, blank=True)
|
||||
batch = models.CharField('批次号', max_length=50)
|
||||
count = models.PositiveIntegerField('当前数量', default=0)
|
||||
count_eweight = models.FloatField('单数重量', default=0)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('material', 'batch', 'belong_dept')
|
||||
|
||||
unique_together = ('material', 'batch', 'belong_dept', 'mgroup')
|
||||
|
||||
class Mlog(CommonADModel):
|
||||
"""
|
||||
生产日志
|
||||
"""
|
||||
# 变成父级的字段
|
||||
work_start_time = models.DateTimeField('生产开始时间', null=True, blank=True)
|
||||
work_end_time = models.DateTimeField('生产结束时间', null=True, blank=True)
|
||||
hour_work = models.FloatField('预计工时', null=True, blank=True)
|
||||
|
||||
mtask = models.ForeignKey(
|
||||
Mtask, verbose_name='关联任务', on_delete=models.CASCADE, null=True, blank=True, related_name='mlog_mtask')
|
||||
mgroup = models.ForeignKey(
|
||||
|
@ -157,7 +162,7 @@ class Mlog(CommonADModel):
|
|||
count_n_thhs = models.PositiveIntegerField('退火后碎', default=0)
|
||||
count_n_qt = models.PositiveIntegerField('其他', default=0)
|
||||
|
||||
handle_date = models.DateField('操作日期')
|
||||
handle_date = models.DateField('操作日期', null=True, blank=True)
|
||||
handle_user = models.ForeignKey(
|
||||
User, verbose_name='操作人', on_delete=models.CASCADE, related_name='mlog_handle_user', null=True, blank=True) # 成型人
|
||||
handle_user_2 = models.ForeignKey(
|
||||
|
@ -168,7 +173,7 @@ class Mlog(CommonADModel):
|
|||
User, verbose_name='班长', on_delete=models.CASCADE, null=True, blank=True, related_name='mlog_handle_leader')
|
||||
note = models.TextField('备注', default='', blank=True)
|
||||
material_outs = models.ManyToManyField(
|
||||
Material, verbose_name='多个产出', blank=True, through='wpm.mlogb', related_name='mlog_material_outs')
|
||||
Material, verbose_name='多个产出', blank=True, through='wpm.mlogb', related_name='mlog_material_outs', through_fields=('mlog', 'material_out'))
|
||||
|
||||
submit_time = models.DateTimeField('提交时间', null=True, blank=True)
|
||||
submit_user = models.ForeignKey(
|
||||
|
@ -176,7 +181,7 @@ class Mlog(CommonADModel):
|
|||
|
||||
@property
|
||||
def mlogb(self):
|
||||
return Mlogb.objects.filter(mlog=self)
|
||||
return Mlogb.objects.filter(mlog=self).exclude(material_out=None)
|
||||
|
||||
@property
|
||||
def audit_ignore_fields(self):
|
||||
|
@ -187,8 +192,15 @@ class Mlog(CommonADModel):
|
|||
class Mlogb(BaseModel):
|
||||
mlog = models.ForeignKey(Mlog, verbose_name='关联日志',
|
||||
on_delete=models.CASCADE, related_name='b_mlog')
|
||||
batch = models.CharField('批次号', max_length=50, null=True, blank=True)
|
||||
mtask = models.ForeignKey(Mtask, verbose_name='关联任务',
|
||||
on_delete=models.CASCADE, related_name='mlogb_mtask', null=True, blank=True)
|
||||
material_in = models.ForeignKey(
|
||||
Material, verbose_name='投入物料', on_delete=models.CASCADE, related_name='mlogb_material_in', null=True, blank=True)
|
||||
material_out = models.ForeignKey(
|
||||
Material, verbose_name='产物', on_delete=models.CASCADE, related_name='mlogb_material_out')
|
||||
Material, verbose_name='产物', on_delete=models.CASCADE, related_name='mlogb_material_out', null=True, blank=True)
|
||||
count_use = models.PositiveIntegerField('领用数量', default=0)
|
||||
count_real = models.PositiveIntegerField('实际生产数', default=0)
|
||||
count_ok = models.PositiveIntegerField('合格数量', default=0)
|
||||
|
||||
|
||||
|
@ -200,8 +212,7 @@ class Handover(CommonADModel):
|
|||
send_user = models.ForeignKey(
|
||||
User, verbose_name='交送人', on_delete=models.CASCADE, related_name='handover_send_user')
|
||||
send_mgroup = models.ForeignKey(
|
||||
Mgroup, verbose_name='送料工段', on_delete=models.CASCADE, null=True, blank=True
|
||||
)
|
||||
Mgroup, verbose_name='送料工段', on_delete=models.CASCADE, null=True, blank=True)
|
||||
send_dept = models.ForeignKey(
|
||||
Dept, verbose_name='送料部门', on_delete=models.CASCADE, related_name='handover_send_dept')
|
||||
batch = models.CharField('批次号', max_length=50)
|
||||
|
@ -211,6 +222,7 @@ class Handover(CommonADModel):
|
|||
count_eweight = models.FloatField('单数重量', default=0)
|
||||
recive_dept = models.ForeignKey(
|
||||
Dept, verbose_name='接收部门', on_delete=models.CASCADE, related_name='handover_recive_dept')
|
||||
recive_mgroup = models.ForeignKey(Mgroup, verbose_name='接收工段', on_delete=models.CASCADE, related_name='handover_recive_mgroup', null=True, blank=True)
|
||||
recive_user = models.ForeignKey(
|
||||
User, verbose_name='接收人', on_delete=models.CASCADE, related_name='handover_recive_user')
|
||||
wm = models.ForeignKey(WMaterial, verbose_name='关联车间库存', on_delete=models.SET_NULL,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from apps.utils.constants import EXCLUDE_FIELDS
|
||||
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE
|
||||
from apps.utils.serializers import CustomModelSerializer
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError, ParseError
|
||||
|
@ -169,6 +169,7 @@ class WMaterialSerializer(CustomModelSerializer):
|
|||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||
material_name = serializers.StringRelatedField(
|
||||
source='material', read_only=True)
|
||||
mgroup_name = serializers.StringRelatedField(source='mgroup.name', read_only=True)
|
||||
belong_dept_name = serializers.CharField(
|
||||
source='belong_dept.name', read_only=True)
|
||||
|
||||
|
@ -187,7 +188,8 @@ class MlogbSerializer(CustomModelSerializer):
|
|||
model = Mlogb
|
||||
fields = ['id', 'material_out', 'count_ok',
|
||||
'material_out_', 'material_out_name']
|
||||
|
||||
extra_kwargs = {
|
||||
'material_out': {'required': True, 'allow_null': False}}
|
||||
|
||||
class MlogSerializer(CustomModelSerializer):
|
||||
belong_dept = serializers.CharField(
|
||||
|
@ -244,38 +246,27 @@ class MlogSerializer(CustomModelSerializer):
|
|||
|
||||
def create(self, validated_data):
|
||||
mtask: Mtask = validated_data.get('mtask', None)
|
||||
# batch = validated_data['batch']
|
||||
# handle_date = validated_data['handle_date']
|
||||
# handle_user = validated_data.get('handle_user', None)
|
||||
if mtask:
|
||||
validated_data['mgroup'] = mtask.mgroup
|
||||
validated_data['material_in'] = mtask.material_in
|
||||
material_out = mtask.material_out
|
||||
validated_data['material_out'] = material_out
|
||||
validated_data['handle_date'] = mtask.start_date
|
||||
# if not WMaterial.objects.filter(batch=batch).exists():
|
||||
# raise ValidationError('批次号不存在')
|
||||
validated_data['handle_date'] = mtask.end_date
|
||||
else:
|
||||
mgroup = validated_data['mgroup']
|
||||
material_out = validated_data['material_out']
|
||||
if not (mgroup and material_out):
|
||||
raise ValidationError('缺少工段或产物!')
|
||||
# if handle_user:
|
||||
# if Mlog.objects.filter(mtask=mtask, batch=batch, handle_date=handle_date, handle_user=handle_user).exists():
|
||||
# raise ValidationError('存在相同的日志记录')
|
||||
# else:
|
||||
# if Mlog.objects.filter(mtask=mtask, batch=batch, handle_date=handle_date).exists():
|
||||
# raise ValidationError('存在相同的日志记录')
|
||||
with transaction.atomic():
|
||||
mlogb = validated_data.pop('mlogb', [])
|
||||
instance = super().create(validated_data)
|
||||
instance: Mlog = super().create(validated_data)
|
||||
brotherId_should_list = material_out.brothers
|
||||
if brotherId_should_list:
|
||||
if mlogb:
|
||||
for item in mlogb:
|
||||
if item['material_out'].id in brotherId_should_list:
|
||||
Mlogb.objects.create(
|
||||
mlog=instance, material_out=item['material_out'], count_ok=item['count_ok'])
|
||||
mlog=instance, batch=instance.batch, mtask=instance.mtask, material_out=item['material_out'], count_ok=item['count_ok'])
|
||||
else:
|
||||
raise ValidationError('缺少产出物信息')
|
||||
return instance
|
||||
|
@ -290,7 +281,7 @@ class MlogSerializer(CustomModelSerializer):
|
|||
mlogb = validated_data.pop('mlogb', [])
|
||||
instance = super().update(instance, validated_data)
|
||||
if mlogb:
|
||||
Mlogb.objects.filter(mlog=instance).update(count_ok=0)
|
||||
Mlogb.objects.filter(mlog=instance, material_out__isnull=False).update(count_ok=0)
|
||||
for item in mlogb:
|
||||
Mlogb.objects.filter(mlog=instance, material_out=item['material_out']).update(
|
||||
count_ok=item['count_ok'])
|
||||
|
@ -332,10 +323,10 @@ class DeptBatchSerializer(serializers.Serializer):
|
|||
|
||||
|
||||
class HandoverSerializer(CustomModelSerializer):
|
||||
wm = serializers.PrimaryKeyRelatedField(
|
||||
label='车间库存ID', queryset=WMaterial.objects.all())
|
||||
material = serializers.PrimaryKeyRelatedField(
|
||||
required=True, label='物料ID', queryset=Material.objects.all())
|
||||
# wm = serializers.PrimaryKeyRelatedField(
|
||||
# label='车间库存ID', queryset=WMaterial.objects.all())
|
||||
# material = serializers.PrimaryKeyRelatedField(
|
||||
# required=True, label='物料ID', queryset=Material.objects.all())
|
||||
send_user_name = serializers.CharField(
|
||||
source='send_user.name', read_only=True)
|
||||
recive_user_name = serializers.CharField(
|
||||
|
@ -347,17 +338,26 @@ class HandoverSerializer(CustomModelSerializer):
|
|||
source='material', read_only=True)
|
||||
|
||||
def validate(self, attrs):
|
||||
if attrs.get('mlog', None):
|
||||
attrs['send_mgroup'] = attrs['mlog'].mgroup
|
||||
attrs['send_dept'] = attrs['mlog'].mgroup.belong_dept
|
||||
elif attrs.get('wm', None):
|
||||
material: Material = attrs['material']
|
||||
if material.process.into_wm_mgroup and 'recive_mgroup' not in attrs:
|
||||
raise ValidationError('必须指定交接工段')
|
||||
if attrs.get('wm', None):
|
||||
attrs['send_dept'] = attrs['wm'].belong_dept
|
||||
return super().validate(attrs)
|
||||
attrs['send_mgroup'] = attrs['wm'].mgroup
|
||||
if attrs.get('recive_mgroup', None):
|
||||
attrs['recive_dept'] = attrs['recive_mgroup'].belong_dept
|
||||
if 'recive_dept' not in attrs and 'recive_mgroup' not in attrs:
|
||||
raise ValidationError('交送车间和交送工段必须有一个')
|
||||
return attrs
|
||||
|
||||
class Meta:
|
||||
model = Handover
|
||||
fields = '__all__'
|
||||
read_only_fields = EXCLUDE_FIELDS
|
||||
read_only_fields = EXCLUDE_FIELDS + ["batch", "material", "send_dept", "send_mgroup", "mlog"]
|
||||
extra_kwargs = {
|
||||
"wm": {"required": True},
|
||||
"recive_mgroup": {"required": False}
|
||||
}
|
||||
|
||||
|
||||
class GenHandoverSerializer(serializers.Serializer):
|
||||
|
|
|
@ -14,6 +14,7 @@ from apps.pm.models import Mtask
|
|||
from apps.mtm.models import Mgroup, Shift, Material, Route
|
||||
|
||||
from .models import SfLog, SfLogExp, WMaterial, Mlog, Mlogb, Handover
|
||||
from apps.mtm.models import Process
|
||||
|
||||
|
||||
def get_sflog(mgroup: Mgroup, happen_time: datetime):
|
||||
|
@ -89,7 +90,7 @@ def do_out(mio: MIO):
|
|||
for item in mioitems:
|
||||
# 用于混料的原料不与车间库存交互
|
||||
material = item.material
|
||||
if material.type in [Material.MA_TYPE_MAINSO, Material.MA_TYPE_HELPSO]:
|
||||
if material.type in [Material.MA_TYPE_MAINSO, Material.MA_TYPE_HELPSO]: # hard code
|
||||
continue
|
||||
action_list = []
|
||||
mias = MIOItemA.objects.filter(mioitem=item)
|
||||
|
@ -127,7 +128,7 @@ def do_in(mio: MIO):
|
|||
for item in mioitems:
|
||||
# 用于混料的原料不与车间库存交互
|
||||
material = item.material
|
||||
if material.type in [Material.MA_TYPE_MAINSO, Material.MA_TYPE_HELPSO]:
|
||||
if material.type in [Material.MA_TYPE_MAINSO, Material.MA_TYPE_HELPSO]: # hard code
|
||||
continue
|
||||
action_list = []
|
||||
mias = MIOItemA.objects.filter(mioitem=item)
|
||||
|
@ -169,48 +170,65 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
|||
now = timezone.now()
|
||||
if now.date() < mlog.handle_date:
|
||||
raise ParseError('不可提交未来的日志')
|
||||
belong_dept = mlog.mgroup.belong_dept
|
||||
|
||||
mgroup = mlog.mgroup
|
||||
belong_dept = mgroup.belong_dept
|
||||
material_out = mlog.material_out
|
||||
material_in = mlog.material_in
|
||||
|
||||
if material_in: # 需要进行车间库存管理
|
||||
# 需要判断领用数是否合理
|
||||
material_has_qs = WMaterial.objects.filter(
|
||||
batch=mlog.batch, material=material_in, belong_dept=belong_dept)
|
||||
count_x = material_has_qs.count()
|
||||
if count_x == 1:
|
||||
material_has = material_has_qs.first()
|
||||
elif count_x == 0:
|
||||
raise ParseError(
|
||||
f'{str(material_in)}-{mlog.batch}-批次库存不存在!')
|
||||
into_wm_mgroup = material_in.process.into_wm_mgroup
|
||||
m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False)
|
||||
if m_ins.exists():
|
||||
m_ins_list = [(mi.material_in, mi.batch, mi.count_use) for mi in m_ins.all()]
|
||||
else:
|
||||
raise ParseError(
|
||||
f'{str(material_in)}-{mlog.batch}-存在多个相同批次!')
|
||||
if mlog.count_use > material_has.count:
|
||||
raise ParseError(
|
||||
f'{str(material_in)}-{mlog.batch}-该批次车间库存不足!')
|
||||
else:
|
||||
material_has.count = material_has.count - mlog.count_use
|
||||
if material_has.count == 0:
|
||||
material_has.delete()
|
||||
m_ins_list = [(material_in, mlog.batch, mlog.count_use)]
|
||||
for mi in m_ins_list:
|
||||
mi_ma, mi_batch, mi_count = mi
|
||||
# 需要判断领用数是否合理
|
||||
lookup = {'batch': mi_batch, 'material': mi_ma, 'mgroup': None}
|
||||
if into_wm_mgroup:
|
||||
lookup['mgroup'] = mgroup
|
||||
else:
|
||||
material_has.save()
|
||||
lookup['belong_dept'] = belong_dept
|
||||
material_has_qs = WMaterial.objects.filter(**lookup)
|
||||
count_x = material_has_qs.count()
|
||||
if count_x == 1:
|
||||
material_has = material_has_qs.first()
|
||||
elif count_x == 0:
|
||||
raise ParseError(
|
||||
f'{str(mi_ma)}-{mi_batch}-批次库存不存在!')
|
||||
else:
|
||||
raise ParseError(
|
||||
f'{str(mi_ma)}-{mi_batch}-存在多个相同批次!')
|
||||
if mi_count > material_has.count:
|
||||
raise ParseError(
|
||||
f'{str(mi_ma)}-{mi_batch}-该批次车间库存不足!')
|
||||
else:
|
||||
material_has.count = material_has.count - mi_count
|
||||
if material_has.count == 0:
|
||||
material_has.delete()
|
||||
else:
|
||||
material_has.save()
|
||||
if material_out: # 需要入车间库存
|
||||
# 有多个产物的情况
|
||||
if material_out.brothers and Mlogb.objects.filter(mlog=mlog).exists():
|
||||
for item in Mlogb.objects.filter(mlog=mlog):
|
||||
wmaterial, _ = WMaterial.objects.get_or_create(batch=mlog.batch, material=item.material_out, belong_dept=belong_dept, defaults={
|
||||
'batch': mlog.batch, 'material': item.material_out, 'belong_dept': belong_dept
|
||||
})
|
||||
wmaterial.count = wmaterial.count + item.count_ok
|
||||
if hasattr(item, 'count_real_eweight'):
|
||||
wmaterial.count_eweight = item.count_real_eweight
|
||||
wmaterial.save()
|
||||
into_wm_mgroup = material_out.process.into_wm_mgroup
|
||||
m_outs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False)
|
||||
if m_outs.exists():
|
||||
m_outs_list = [(mo.material, mo.batch if mo.batch else mlog.batch, mo.count_ok, mlog.count_real_eweight) for mo in m_outs.all()]
|
||||
else:
|
||||
wmaterial, _ = WMaterial.objects.get_or_create(batch=mlog.batch, material=material_out, belong_dept=belong_dept, defaults={
|
||||
'batch': mlog.batch, 'material': material_out, 'belong_dept': belong_dept
|
||||
})
|
||||
wmaterial.count = wmaterial.count + mlog.count_ok
|
||||
wmaterial.count_eweight = mlog.count_real_eweight
|
||||
m_outs_list = [(material_out, mlog.batch, mlog.count_ok, mlog.count_real_eweight)]
|
||||
|
||||
for mo in m_outs_list:
|
||||
mo_ma, mo_batch, mo_count, mo_count_eweight = mo
|
||||
lookup = {'batch': mo_batch, 'material': mo_ma, 'mgroup': None}
|
||||
if into_wm_mgroup:
|
||||
lookup['mgroup'] = mgroup
|
||||
else:
|
||||
lookup['belong_dept'] = belong_dept
|
||||
if mo_count > 0:
|
||||
wmaterial, _ = WMaterial.objects.get_or_create(**lookup, defaults=lookup)
|
||||
wmaterial.count = wmaterial.count + mo_count
|
||||
wmaterial.count_eweight = mo_count_eweight
|
||||
wmaterial.save()
|
||||
mlog.submit_time = now
|
||||
mlog.submit_user = user
|
||||
|
@ -224,34 +242,48 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]):
|
|||
return
|
||||
if now is None:
|
||||
now = timezone.now()
|
||||
belong_dept = mlog.mgroup.belong_dept
|
||||
|
||||
mgroup = mlog.mgroup
|
||||
belong_dept = mgroup.belong_dept
|
||||
material_out = mlog.material_out
|
||||
material_in = mlog.material_in
|
||||
if material_in:
|
||||
# 领用数退回
|
||||
wmaterial, _ = WMaterial.objects.get_or_create(batch=mlog.batch, material=material_in, belong_dept=belong_dept, defaults={
|
||||
'batch': mlog.batch, 'material': material_in, 'belong_dept': belong_dept})
|
||||
wmaterial.count = wmaterial.count + mlog.count_use
|
||||
wmaterial.save()
|
||||
into_wm_mgroup = material_in.process.into_wm_mgroup
|
||||
m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False)
|
||||
if m_ins.exists():
|
||||
m_ins_list = [(mi.material_in, mi.batch, mi.count_use) for mi in m_ins.all()]
|
||||
else:
|
||||
m_ins_list = [(material_in, mlog.batch, mlog.count_use)]
|
||||
for mi in m_ins_list:
|
||||
mi_ma, mi_batch, mi_count = mi
|
||||
lookup = {'batch': mi_batch, 'material': mi_ma, 'mgroup': None}
|
||||
if into_wm_mgroup:
|
||||
lookup['mgroup'] = mgroup
|
||||
else:
|
||||
lookup['belong_dept'] = belong_dept
|
||||
|
||||
wmaterial, _ = WMaterial.objects.get_or_create(**lookup, defaults=lookup)
|
||||
wmaterial.count = wmaterial.count + mi_count
|
||||
wmaterial.save()
|
||||
if material_out: # 产物退回
|
||||
# 有多个产物的情况
|
||||
if material_out.brothers and Mlogb.objects.filter(mlog=mlog).exists():
|
||||
for item in Mlogb.objects.filter(mlog=mlog):
|
||||
wmaterial, _ = WMaterial.objects.get_or_create(batch=mlog.batch, material=item.material_out, belong_dept=belong_dept, defaults={
|
||||
'batch': mlog.batch, 'material': item.material_out, 'belong_dept': belong_dept
|
||||
})
|
||||
wmaterial.count = wmaterial.count - item.count_ok
|
||||
if wmaterial.count < 0:
|
||||
raise ParseError('车间库存不足, 产物无法回退')
|
||||
elif wmaterial.count == 0:
|
||||
wmaterial.delete()
|
||||
else:
|
||||
wmaterial.save()
|
||||
into_wm_mgroup = material_out.process.into_wm_mgroup
|
||||
m_outs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False)
|
||||
if m_outs.exists():
|
||||
m_outs_list = [(mo.material, mo.batch if mo.batch else mlog.batch, mo.count_ok, mlog.count_real_eweight) for mo in m_outs.all()]
|
||||
else:
|
||||
wmaterial, _ = WMaterial.objects.get_or_create(batch=mlog.batch, material=material_out, belong_dept=belong_dept, defaults={
|
||||
'batch': mlog.batch, 'material': material_out, 'belong_dept': belong_dept
|
||||
})
|
||||
wmaterial.count = wmaterial.count - mlog.count_ok
|
||||
m_outs_list = [(material_out, mlog.batch, mlog.count_ok, mlog.count_real_eweight)]
|
||||
|
||||
for mo in m_outs_list:
|
||||
mo_ma, mo_batch, mo_count, _ = mo
|
||||
lookup = {'batch': mo_batch, 'material': mo_ma, 'mgroup': None}
|
||||
if into_wm_mgroup:
|
||||
lookup['mgroup'] = mgroup
|
||||
else:
|
||||
lookup['belong_dept'] = belong_dept
|
||||
wmaterial, _ = WMaterial.objects.get_or_create(**lookup, defaults=lookup)
|
||||
wmaterial.count = wmaterial.count - mo_count
|
||||
if wmaterial.count < 0:
|
||||
raise ParseError('车间库存不足, 产物无法回退')
|
||||
elif wmaterial.count == 0:
|
||||
|
@ -296,11 +328,9 @@ def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime
|
|||
wm_from_need_delete = False
|
||||
material = handover.material
|
||||
batch = handover.batch
|
||||
try:
|
||||
wm_from = WMaterial.objects.get(
|
||||
material=material, batch=batch, belong_dept=handover.send_dept)
|
||||
except Exception as e:
|
||||
raise ParseError(f'找不到车间库存:{e}')
|
||||
wm_from = handover.wm
|
||||
if wm_from is None:
|
||||
raise ParseError('找不到车间库存')
|
||||
if '混料' in material.name: # hard code
|
||||
need_add = False
|
||||
count_x = wm_from.count - handover.count
|
||||
|
@ -312,9 +342,14 @@ def handover_submit(handover: Handover, user: User, now: Union[datetime.datetime
|
|||
wm_from.count = count_x
|
||||
wm_from.save()
|
||||
if need_add:
|
||||
wm_to, _ = WMaterial.objects.get_or_create(batch=batch, material=material, belong_dept=handover.recive_dept, defaults={
|
||||
'batch': batch, 'material': material, 'belong_dept': handover.recive_dept
|
||||
})
|
||||
if handover.recive_mgroup:
|
||||
wm_to, _ = WMaterial.objects.get_or_create(batch=batch, material=material, mgroup=handover.recive_mgroup, defaults={
|
||||
'batch': batch, 'material': material, 'mgroup': handover.recive_mgroup, 'belong_dept': handover.recive_dept
|
||||
})
|
||||
else:
|
||||
wm_to, _ = WMaterial.objects.get_or_create(batch=batch, material=material, belong_dept=handover.recive_dept, defaults={
|
||||
'batch': batch, 'material': material, 'belong_dept': handover.recive_dept
|
||||
})
|
||||
wm_to.count = wm_to.count + handover.count
|
||||
wm_to.count_eweight = handover.count_eweight
|
||||
wm_to.save()
|
||||
|
|
Loading…
Reference in New Issue