feat: mlog日志撤回

This commit is contained in:
caoqianming 2023-12-18 09:18:06 +08:00
parent 845a510068
commit 625074049e
5 changed files with 79 additions and 24 deletions

View File

@ -15,7 +15,7 @@ def delete_auditlog(model, instance_id):
instance_id=instance_id).delete() 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 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) app_label_model_name = get_model_info(instance)
if val_old is None: if val_old is None:
val_old = {} val_old = {}
if ignore_fields is None:
ignore_fields = getattr(instance, 'audit_ignore_fields', [
'create_by', 'update_by', 'create_time', 'update_time', 'id'])
difference = [] difference = []
has_changed = False has_changed = False
if action == 'create': if action == 'create':
has_changed = True has_changed = True
change_user = instance.create_by change_user_l = change_user if change_user else instance.create_by
change_time = instance.create_time change_time_l = change_time if change_time else instance.create_time
elif action == 'delete': elif action == 'delete':
has_changed = True has_changed = True
change_user = delete_user if delete_user else instance.update_by change_user_l = change_user if change_user else instance.update_by
change_time = delete_time if delete_time else instance.update_time change_time_l = change_time if change_time else instance.update_time
else: else:
change_user = instance.update_by change_user_l = change_user
change_time = instance.update_time change_time_l = change_time
for k, v in val_new.items(): 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: if k not in val_old:
difference.append( difference.append(
{'field': k, 'action': 'create', 'val_old': None, 'val_new': v}) {'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, val_new=val_new,
difference=difference, difference=difference,
change_reason=change_reason, change_reason=change_reason,
change_user=change_user, change_user=change_user_l,
change_time=change_time change_time=change_time_l
) )

View File

@ -148,6 +148,11 @@ class Mlog(CommonADModel):
def mlogb(self): def mlogb(self):
return Mlogb.objects.filter(mlog=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): class Mlogb(BaseModel):
mlog = models.ForeignKey(Mlog, verbose_name='关联日志', mlog = models.ForeignKey(Mlog, verbose_name='关联日志',

View File

@ -289,6 +289,10 @@ class MlogSerializer(CustomModelSerializer):
return attrs return attrs
class MlogRevertSerializer(serializers.Serializer):
change_reason = serializers.CharField(label='撤回原因')
class MlogRelatedSerializer(serializers.Serializer): class MlogRelatedSerializer(serializers.Serializer):
mtask = serializers.PrimaryKeyRelatedField( mtask = serializers.PrimaryKeyRelatedField(
label='小任务ID', queryset=Mtask.objects.all()) label='小任务ID', queryset=Mtask.objects.all())

View File

@ -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: if now is None:
now = timezone.now() now = timezone.now()
if now.date() < mlog.handle_date: 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.submit_user = user
mlog.save() 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): def update_mtask(mtask: Mtask):
from apps.pm.models import Utask from apps.pm.models import Utask

View File

@ -7,6 +7,7 @@ from rest_framework.mixins import DestroyModelMixin, ListModelMixin, UpdateModel
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.serializers import Serializer from rest_framework.serializers import Serializer
from django.db.models import Sum from django.db.models import Sum
from django.utils import timezone
from apps.mtm.models import Material from apps.mtm.models import Material
from apps.pm.models import Mtask 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 .filters import StLogFilter, SfLogFilter, WMaterialFilter, MlogFilter, HandoverFilter
from .models import SfLog, SfLogExp, StLog, WMaterial, Mlog, Handover, Mlogb, AttLog, OtherLog 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, MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer, HandoverSerializer,
GenHandoverSerializer, GenHandoverWmSerializer, MlogAnaSerializer, AttLogSerializer, OtherLogSerializer) 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 from apps.monitor.services import create_auditlog, delete_auditlog
# Create your views here. # Create your views here.
@ -166,15 +167,18 @@ class MlogViewSet(CustomModelViewSet):
""" """
ins: Mlog = self.get_object() ins: Mlog = self.get_object()
vdata_old = MlogSerializer(ins).data vdata_old = MlogSerializer(ins).data
if ins.submit_time is None: now = timezone.now()
mlog_submit(ins, self.request.user, None) if ins.submit_time:
raise ParseError('该日志已提交!')
mlog_submit(ins, self.request.user, now)
if ins.mtask: if ins.mtask:
update_mtask(ins.mtask) update_mtask(ins.mtask)
vdata_new = MlogSerializer(ins).data vdata_new = MlogSerializer(ins).data
create_auditlog('submit', ins, vdata_new, vdata_old) create_auditlog('submit', ins, vdata_new,
vdata_old, now, self.request.user)
return Response() 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 @transaction.atomic
def revert(self, request, *args, **kwargs): def revert(self, request, *args, **kwargs):
"""撤回日志提交 """撤回日志提交
@ -183,9 +187,16 @@ class MlogViewSet(CustomModelViewSet):
""" """
ins: Mlog = self.get_object() ins: Mlog = self.get_object()
user = request.user user = request.user
if ins.submit_time is None:
raise ParseError('日志未提交不可撤销')
if user != ins.submit_user: if user != ins.submit_user:
raise ParseError('非提交人不可撤销!') 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() return Response()
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MlogRelatedSerializer) @action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MlogRelatedSerializer)