feat: mlog日志撤回
This commit is contained in:
parent
845a510068
commit
625074049e
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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='关联日志',
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
if ins.mtask:
|
raise ParseError('该日志已提交!')
|
||||||
update_mtask(ins.mtask)
|
mlog_submit(ins, self.request.user, now)
|
||||||
vdata_new = MlogSerializer(ins).data
|
if ins.mtask:
|
||||||
create_auditlog('submit', ins, vdata_new, vdata_old)
|
update_mtask(ins.mtask)
|
||||||
|
vdata_new = MlogSerializer(ins).data
|
||||||
|
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)
|
||||||
|
|
Loading…
Reference in New Issue