diff --git a/apps/inm/services.py b/apps/inm/services.py index d736b355..edcdb208 100644 --- a/apps/inm/services.py +++ b/apps/inm/services.py @@ -63,6 +63,8 @@ def do_out(item: MIOItem): xbatch:str = al[1] xcount:str = al[2] xbatches.append(xbatch) + if xcount <= 0: + raise ParseError("存在非正数!") mb = None if not is_zhj: try: @@ -140,6 +142,8 @@ def do_in(item: MIOItem): xbatchs = [] for al in action_list: xmaterial, xbatch, xcount = al + if xcount <= 0: + raise ParseError("存在非正数!") xbatchs.append(xbatch) # 扣减车间库存 wm_qs = WMaterial.objects.filter( @@ -228,8 +232,9 @@ class InmService: 更新物料数量 """ # 统计物料数量 - m_ids = MIOItem.objects.filter(mio=instance).values_list('material_id', flat=True) - cal_material_count(m_ids) + m_ids = list(MIOItem.objects.filter(mio=instance).values_list('material_id', flat=True)) + m_ids2 = list(MIOItemA.objects.filter(mioitem__mio=instance).values_list('material_id', flat=True)) + cal_material_count(m_ids+m_ids2) @classmethod def update_inm(cls, instance: MIO, is_reverse: bool = False): @@ -242,7 +247,10 @@ class InmService: BatchLog.clear(mio=instance) else: for item in MIOItem.objects.filter(mio=instance): - BatchSt.g_create(batch=item.batch, mio=instance, material_start=item.material) + if item.mb: # 说明录入到已有批次 + BatchSt.g_create(batch=item.batch) + else: + BatchSt.g_create(batch=item.batch, mio=instance, material_start=item.material) from apps.pum.services import PumService if is_reverse: cls.update_mb(instance, -1) @@ -254,7 +262,10 @@ class InmService: BatchLog.clear(mio=instance) else: for item in MIOItem.objects.filter(mio=instance): - BatchSt.g_create(batch=item, mio=instance, material_start=item.material) + if item.mb: + BatchSt.g_create(batch=item.batch) + else: + BatchSt.g_create(batch=item.batch, mio=instance, material_start=item.material) if is_reverse: cls.update_mb(instance, -1) else: @@ -346,7 +357,7 @@ class InmService: for material, warehouse, batch, change_count, defect, mioitem in m_list: if change_count <= 0: - continue + raise ParseError("存在非正数!") state = WMaterial.WM_OK if defect: state = WMaterial.WM_NOTOK diff --git a/apps/inm/views.py b/apps/inm/views.py index 57e05bf3..51fe7854 100644 --- a/apps/inm/views.py +++ b/apps/inm/views.py @@ -286,6 +286,7 @@ class MIOItemViewSet(CustomListModelMixin, BulkCreateModelMixin, BulkDestroyMode sr.save() # 开始变动库存 InmService.update_mb_item(ins, -1, 'count_notok') + InmService.update_material_count(ins.mio) return Response() @action(methods=['post'], detail=True, perms_map={'post': 'mioitem.test'}, serializer_class=serializers.Serializer) @@ -303,6 +304,7 @@ class MIOItemViewSet(CustomListModelMixin, BulkCreateModelMixin, BulkDestroyMode pass ins.test_date = None ins.save() + InmService.update_material_count(ins.mio) return Response() @action(methods=['post'], detail=True, perms_map={'post': 'mioitem.test'}, serializer_class=MIOItemPurInTestSerializer) @@ -320,6 +322,7 @@ class MIOItemViewSet(CustomListModelMixin, BulkCreateModelMixin, BulkDestroyMode sr = MIOItemPurInTestSerializer(instance=ins, data=request.data) sr.is_valid(raise_exception=True) sr.save() + InmService.update_material_count(ins.mio) return Response() @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MioItemAnaSerializer) diff --git a/apps/mtm/views.py b/apps/mtm/views.py index 30810262..f942419a 100644 --- a/apps/mtm/views.py +++ b/apps/mtm/views.py @@ -59,6 +59,18 @@ class MaterialViewSet(CustomModelViewSet): daoru_material(settings.BASE_DIR + request.data.get('path', '')) return Response() + @action(methods=['post'], detail=True, serializer_class=Serializer, perms_map={'post': 'material.create'}) + @transaction.atomic + def cal_count(self, request, *args, **kwargs): + """统计数量 + + 统计数量 + """ + ins = self.get_object() + from apps.mtm.services_2 import cal_material_count + cal_material_count([ins.id]) + return Response() + @action(methods=['put'], detail=True, serializer_class=Serializer, perms_map={'put': '*'}) @transaction.atomic def set_week_esitimate_consume(self, request, *args, **kwargs): diff --git a/apps/utils/fields.py b/apps/utils/fields.py index f93a46d5..f29fb573 100644 --- a/apps/utils/fields.py +++ b/apps/utils/fields.py @@ -1,5 +1,9 @@ from django.conf import settings from rest_framework import serializers +from django.db.models import DecimalField +from django.core.validators import MinValueValidator +from django.utils.functional import cached_property +from decimal import Decimal class MyFilePathField(serializers.CharField): @@ -8,3 +12,9 @@ class MyFilePathField(serializers.CharField): if 'http' in value: return str(value) return settings.BASE_URL + str(value) + +class PositiveDecimalField(DecimalField): + + @cached_property + def validators(self): + return [MinValueValidator(Decimal('0.0'))] + super().validators \ No newline at end of file diff --git a/apps/wpm/services.py b/apps/wpm/services.py index 04621267..d59d9905 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -23,6 +23,7 @@ from ..qm.models import Defect, Ftest from django.db.models import Count, Q from apps.utils.tasks import ctask_run from apps.mtm.models import Process +from apps.mtm.services_2 import cal_material_count myLogger = logging.getLogger('log') @@ -199,6 +200,8 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): m_ins_list = [(material_in, mlog.batch, mlog.count_use, None, mlog)] for mi in m_ins_list: mi_ma, mi_batch, mi_count, defect, mlog_or_b = mi + if mi_count <= 0: + raise ParseError('存在非正数!') # 需要判断领用数是否合理 # 优先使用工段库存 if isinstance(mlog_or_b, Mlogb) and mlog_or_b.wm_in: @@ -238,18 +241,19 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): if need_store_notok: for item in m_ins_bl_list: material, batch, count, defect, mi_ = item - if count> 0: - lookup = {'batch': batch, 'material': material, 'mgroup': mgroup, 'defect': defect, 'state': WMaterial.WM_NOTOK} - wm, is_create = WMaterial.objects.get_or_create(**lookup, defaults={"belong_dept": belong_dept}) - wm.count = wm.count + count - if is_create: - wm.create_by = user - wm.batch_ofrom = mi_.batch_ofrom - wm.material_ofrom = mi_.material_ofrom - wm.update_by = user - wm.save() - if material.tracking == Material.MA_TRACKING_SINGLE: - raise ParseError("加工前不良的物料暂不支持单件追踪") + if count <= 0: + raise ParseError('存在非正数!') + lookup = {'batch': batch, 'material': material, 'mgroup': mgroup, 'defect': defect, 'state': WMaterial.WM_NOTOK} + wm, is_create = WMaterial.objects.get_or_create(**lookup, defaults={"belong_dept": belong_dept}) + wm.count = wm.count + count + if is_create: + wm.create_by = user + wm.batch_ofrom = mi_.batch_ofrom + wm.material_ofrom = mi_.material_ofrom + wm.update_by = user + wm.save() + if material.tracking == Material.MA_TRACKING_SINGLE: + raise ParseError("加工前不良的物料暂不支持单件追踪") if material_out or is_fix: # 需要入车间库存 @@ -294,7 +298,9 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): # 一次填写的暂时不处理不合格品 for mo in m_outs_list: mo_ma, mo_batch, mo_count, mo_count_eweight, notok_sign_or_defect, mlog_or_b = mo - if mo_count <= 0: + if mo_count < 0: + raise ParseError('存在负数!') + elif mo_count == 0: continue if is_fix: wm_state = WMaterial.WM_REPAIRED @@ -435,7 +441,9 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): for mo in m_outs_list: mo_ma, mo_batch, mo_count, _, notok_sign_or_defect, mlog_or_b = mo - if mo_count == 0: + if mo_count < 0: + raise ParseError('存在负数!') + elif mo_count == 0: continue if is_fix: wm_state = WMaterial.WM_REPAIRED @@ -500,6 +508,8 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): m_ins_list = [(material_in, mlog.batch, mlog.count_use, mlog.wm_in, mlog)] for mi in m_ins_list: mi_ma, mi_batch, mi_count, defect_or, mlog_or_b = mi + if mi_count <= 0: + raise ParseError('存在非正数!') if isinstance(mlog_or_b, Mlogb) and mlog_or_b.wm_in: wm = WMaterial.objects.get(id=mlog_or_b.wm_in.id) else: @@ -531,19 +541,20 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): if stored_notok: for item in m_ins_bl_list: material, batch, count, defect, mi_ = item - if count> 0: - lookup = {'batch': batch, 'material': material, 'mgroup': mgroup, 'defect': defect, 'state': WMaterial.WM_NOTOK} - wm, is_create = WMaterial.objects.get_or_create(**lookup, defaults={**lookup, "belong_dept": belong_dept}) - wm.count = wm.count - count - if wm.count < 0: - raise ParseError('加工前不良数量大于库存量') - if is_create: - wm.create_by = user - else: - wm.update_by = user - wm.save() - if material.tracking == Material.MA_TRACKING_SINGLE: - raise ParseError("加工前不良的物料暂不支持单件回退") + if count <= 0: + raise ParseError('存在非正数!') + lookup = {'batch': batch, 'material': material, 'mgroup': mgroup, 'defect': defect, 'state': WMaterial.WM_NOTOK} + wm, is_create = WMaterial.objects.get_or_create(**lookup, defaults={**lookup, "belong_dept": belong_dept}) + wm.count = wm.count - count + if wm.count < 0: + raise ParseError('加工前不良数量大于库存量') + if is_create: + wm.create_by = user + else: + wm.update_by = user + wm.save() + if material.tracking == Material.MA_TRACKING_SINGLE: + raise ParseError("加工前不良的物料暂不支持单件回退") mlog.submit_time = None mlog.submit_user = None @@ -723,9 +734,13 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime, raise ParseError("合并批次时请提供新批次号") new_target = None + mids = [] for item in handoverb_list: wmId, xcount, handover_or_b = item + if xcount <= 0: + raise ParseError("存在非正数!") wm_from = WMaterial.objects.get(id=wmId) + mids.append(wm_from.material.id) # 合并为新批 if mtype == Handover.H_MERGE: @@ -897,6 +912,12 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime, if batches: for batch in batches: MyThread(target=get_alldata_with_batch_and_store, args=(batch,)).start() + + # 如果是改版交接需要触发统计数量 + if handover.type == Handover.H_CHANGE: + mids.append(handover.material_changed.id) + cal_material_count(mids) + def handover_revert(handover:Handover): BatchLog.clear(handover=handover)