From 625074049e1cf8846390ca2313064093bcae15ea Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 18 Dec 2023 09:18:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20mlog=E6=97=A5=E5=BF=97=E6=92=A4?= =?UTF-8?q?=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/monitor/services.py | 23 +++++++++++++---------- apps/wpm/models.py | 5 +++++ apps/wpm/serializers.py | 4 ++++ apps/wpm/services.py | 40 ++++++++++++++++++++++++++++++++++++---- apps/wpm/views.py | 31 +++++++++++++++++++++---------- 5 files changed, 79 insertions(+), 24 deletions(-) diff --git a/apps/monitor/services.py b/apps/monitor/services.py index d1c83ff1..592c646e 100644 --- a/apps/monitor/services.py +++ b/apps/monitor/services.py @@ -15,7 +15,7 @@ def delete_auditlog(model, instance_id): instance_id=instance_id).delete() -def create_auditlog(action: str, instance, val_new: dict, val_old: dict = None, change_reason: str = '', delete_time: datetime = None, delete_user: User = None): +def create_auditlog(action: str, instance, val_new: dict, val_old: dict = None, change_time: datetime = None, change_user: User = None, change_reason: str = '', ignore_fields: list = None): """ 生成审计日志 action: create/update/delete/其他action @@ -23,21 +23,24 @@ def create_auditlog(action: str, instance, val_new: dict, val_old: dict = None, app_label_model_name = get_model_info(instance) if val_old is None: val_old = {} + if ignore_fields is None: + ignore_fields = getattr(instance, 'audit_ignore_fields', [ + 'create_by', 'update_by', 'create_time', 'update_time', 'id']) difference = [] has_changed = False if action == 'create': has_changed = True - change_user = instance.create_by - change_time = instance.create_time + change_user_l = change_user if change_user else instance.create_by + change_time_l = change_time if change_time else instance.create_time elif action == 'delete': has_changed = True - change_user = delete_user if delete_user else instance.update_by - change_time = delete_time if delete_time else instance.update_time + change_user_l = change_user if change_user else instance.update_by + change_time_l = change_time if change_time else instance.update_time else: - change_user = instance.update_by - change_time = instance.update_time + change_user_l = change_user + change_time_l = change_time for k, v in val_new.items(): - if k not in ['create_by', 'update_by', 'create_time', 'update_time', 'id']: + if k not in ignore_fields: if k not in val_old: difference.append( {'field': k, 'action': 'create', 'val_old': None, 'val_new': v}) @@ -54,8 +57,8 @@ def create_auditlog(action: str, instance, val_new: dict, val_old: dict = None, val_new=val_new, difference=difference, change_reason=change_reason, - change_user=change_user, - change_time=change_time + change_user=change_user_l, + change_time=change_time_l ) diff --git a/apps/wpm/models.py b/apps/wpm/models.py index c535fe2e..4ac2f5d0 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -148,6 +148,11 @@ class Mlog(CommonADModel): def mlogb(self): return Mlogb.objects.filter(mlog=self) + @property + def audit_ignore_fields(self): + return ['create_by', 'update_by', + 'create_time', 'update_time', 'id'] + class Mlogb(BaseModel): mlog = models.ForeignKey(Mlog, verbose_name='关联日志', diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index b41ec8cc..8332a2ae 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -289,6 +289,10 @@ class MlogSerializer(CustomModelSerializer): return attrs +class MlogRevertSerializer(serializers.Serializer): + change_reason = serializers.CharField(label='撤回原因') + + class MlogRelatedSerializer(serializers.Serializer): mtask = serializers.PrimaryKeyRelatedField( label='小任务ID', queryset=Mtask.objects.all()) diff --git a/apps/wpm/services.py b/apps/wpm/services.py index de1f4c14..0e4a5b75 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -140,8 +140,6 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): """ 生产日志提交后需要执行的操作 """ - if mlog.submit_time is not None: # 说明已经做过操作了 - return if now is None: now = timezone.now() if now.date() < mlog.handle_date: @@ -184,10 +182,44 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): mlog.submit_user = user mlog.save() -def mlog_revert(mlog: Mlog): + +def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): """日志撤回 """ - pass + if now is None: + now = timezone.now() + belong_dept = mlog.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() + 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('车间库存不足, 产物无法回退') + wmaterial.save() + 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 + if wmaterial.count < 0: + raise ParseError('车间库存不足, 产物无法回退') + wmaterial.save() + mlog.submit_time = None + mlog.submit_user = None + mlog.save() + def update_mtask(mtask: Mtask): from apps.pm.models import Utask diff --git a/apps/wpm/views.py b/apps/wpm/views.py index 9df354d8..c4738dd9 100644 --- a/apps/wpm/views.py +++ b/apps/wpm/views.py @@ -7,6 +7,7 @@ from rest_framework.mixins import DestroyModelMixin, ListModelMixin, UpdateModel from rest_framework.response import Response from rest_framework.serializers import Serializer from django.db.models import Sum +from django.utils import timezone from apps.mtm.models import Material from apps.pm.models import Mtask @@ -15,10 +16,10 @@ from apps.utils.mixins import BulkCreateModelMixin from .filters import StLogFilter, SfLogFilter, WMaterialFilter, MlogFilter, HandoverFilter from .models import SfLog, SfLogExp, StLog, WMaterial, Mlog, Handover, Mlogb, AttLog, OtherLog -from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer, +from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer, MlogRevertSerializer, MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer, HandoverSerializer, GenHandoverSerializer, GenHandoverWmSerializer, MlogAnaSerializer, AttLogSerializer, OtherLogSerializer) -from .services import mlog_submit, update_mtask, handover_submit +from .services import mlog_submit, update_mtask, handover_submit, mlog_revert from apps.monitor.services import create_auditlog, delete_auditlog # Create your views here. @@ -166,15 +167,18 @@ class MlogViewSet(CustomModelViewSet): """ ins: Mlog = self.get_object() vdata_old = MlogSerializer(ins).data - if ins.submit_time is None: - mlog_submit(ins, self.request.user, None) - if ins.mtask: - update_mtask(ins.mtask) - vdata_new = MlogSerializer(ins).data - create_auditlog('submit', ins, vdata_new, vdata_old) + now = timezone.now() + if ins.submit_time: + raise ParseError('该日志已提交!') + mlog_submit(ins, self.request.user, now) + if ins.mtask: + update_mtask(ins.mtask) + vdata_new = MlogSerializer(ins).data + create_auditlog('submit', ins, vdata_new, + vdata_old, now, self.request.user) return Response() - @action(methods=['post'], detail=True, perms_map={'post': 'mlog.submit'}, serializer_class=Serializer) + @action(methods=['post'], detail=True, perms_map={'post': 'mlog.submit'}, serializer_class=MlogRevertSerializer) @transaction.atomic def revert(self, request, *args, **kwargs): """撤回日志提交 @@ -183,9 +187,16 @@ class MlogViewSet(CustomModelViewSet): """ ins: Mlog = self.get_object() user = request.user + if ins.submit_time is None: + raise ParseError('日志未提交不可撤销') if user != ins.submit_user: raise ParseError('非提交人不可撤销!') - + now = timezone.now() + mlog_revert(ins, user, now) + if ins.mtask: + update_mtask(ins.mtask) + create_auditlog('revert', ins, {}, {}, now, user, + request.data.get('change_reason', '')) return Response() @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MlogRelatedSerializer)