Merge branch 'master' of http://gitea.xxhhcty.xyz:8080/zcdsj/factory
This commit is contained in:
commit
aff39f3e31
|
@ -9,7 +9,6 @@ from django.utils.timezone import now
|
|||
from user_agents import parse
|
||||
import logging
|
||||
from rest_framework.response import Response
|
||||
from django.db import transaction
|
||||
from rest_framework.exceptions import ParseError, ValidationError
|
||||
from apps.utils.errors import PKS_ERROR
|
||||
from rest_framework.generics import get_object_or_404
|
||||
|
@ -19,6 +18,7 @@ from apps.utils.serializers import PkSerializer
|
|||
from rest_framework.decorators import action
|
||||
from apps.utils.serializers import ComplexSerializer
|
||||
from django.db.models import F
|
||||
from django.db import transaction
|
||||
|
||||
# 实例化myLogger
|
||||
myLogger = logging.getLogger('log')
|
||||
|
@ -81,7 +81,8 @@ class BulkCreateModelMixin(CreateModelMixin):
|
|||
|
||||
def after_bulk_create(self, objs):
|
||||
pass
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def create(self, request, *args, **kwargs):
|
||||
"""创建(支持批量)
|
||||
|
||||
|
@ -91,10 +92,9 @@ class BulkCreateModelMixin(CreateModelMixin):
|
|||
many = False
|
||||
if isinstance(rdata, list):
|
||||
many = True
|
||||
with transaction.atomic():
|
||||
sr = self.get_serializer(data=rdata, many=many)
|
||||
sr.is_valid(raise_exception=True)
|
||||
self.perform_create(sr)
|
||||
sr = self.get_serializer(data=rdata, many=many)
|
||||
sr.is_valid(raise_exception=True)
|
||||
self.perform_create(sr)
|
||||
if many:
|
||||
self.after_bulk_create(sr.data)
|
||||
return Response(sr.data, status=201)
|
||||
|
@ -105,6 +105,7 @@ class BulkUpdateModelMixin(UpdateModelMixin):
|
|||
def after_bulk_update(self, objs):
|
||||
pass
|
||||
|
||||
@transaction.atomic
|
||||
def partial_update(self, request, *args, **kwargs):
|
||||
"""部分更新(支持批量)
|
||||
|
||||
|
@ -113,6 +114,7 @@ class BulkUpdateModelMixin(UpdateModelMixin):
|
|||
kwargs['partial'] = True
|
||||
return self.update(request, *args, **kwargs)
|
||||
|
||||
@transaction.atomic
|
||||
def update(self, request, *args, **kwargs):
|
||||
"""更新(支持批量)
|
||||
|
||||
|
@ -124,16 +126,15 @@ class BulkUpdateModelMixin(UpdateModelMixin):
|
|||
queryset = self.filter_queryset(self.get_queryset())
|
||||
objs = []
|
||||
if isinstance(request.data, list):
|
||||
with transaction.atomic():
|
||||
for ind, item in enumerate(request.data):
|
||||
obj = get_object_or_404(queryset, id=item['id'])
|
||||
sr = self.get_serializer(obj, data=item, partial=partial)
|
||||
if not sr.is_valid():
|
||||
err_dict = { f'第{ind+1}': sr.errors}
|
||||
raise ValidationError(err_dict)
|
||||
self.perform_update(sr) # 用自带的更新,可能需要做其他操作
|
||||
objs.append(sr.data)
|
||||
self.after_bulk_update(objs)
|
||||
for ind, item in enumerate(request.data):
|
||||
obj = get_object_or_404(queryset, id=item['id'])
|
||||
sr = self.get_serializer(obj, data=item, partial=partial)
|
||||
if not sr.is_valid():
|
||||
err_dict = { f'第{ind+1}': sr.errors}
|
||||
raise ValidationError(err_dict)
|
||||
self.perform_update(sr) # 用自带的更新,可能需要做其他操作
|
||||
objs.append(sr.data)
|
||||
self.after_bulk_update(objs)
|
||||
else:
|
||||
raise ParseError('提交数据非列表')
|
||||
return Response(objs)
|
||||
|
@ -148,6 +149,7 @@ class BulkUpdateModelMixin(UpdateModelMixin):
|
|||
class BulkDestroyModelMixin(DestroyModelMixin):
|
||||
|
||||
@swagger_auto_schema(request_body=PkSerializer)
|
||||
@transaction.atomic
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
"""删除(支持批量)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
from django.core.cache import cache
|
||||
from django.http import StreamingHttpResponse
|
||||
from django.http import StreamingHttpResponse, Http404
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import ParseError
|
||||
from rest_framework.mixins import RetrieveModelMixin
|
||||
|
@ -18,7 +18,8 @@ from apps.utils.serializers import ComplexSerializer
|
|||
from rest_framework.throttling import UserRateThrottle
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
import json
|
||||
|
||||
from django.db import connection
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
class CustomGenericViewSet(MyLoggingMixin, GenericViewSet):
|
||||
"""
|
||||
|
@ -89,6 +90,34 @@ class CustomGenericViewSet(MyLoggingMixin, GenericViewSet):
|
|||
elif hash_v_e:
|
||||
return Response(hash_v_e)
|
||||
|
||||
def get_object(self, force_lock=False):
|
||||
"""
|
||||
智能加锁的get_object
|
||||
- 只读请求:普通查询
|
||||
- 非只读请求且在事务中:加锁查询
|
||||
- 非只读请求但不在事务中:普通查询(带警告)
|
||||
"""
|
||||
# 只读方法列表
|
||||
read_only_methods = ['GET', 'HEAD', 'OPTIONS']
|
||||
|
||||
if self.request.method not in read_only_methods and connection.in_atomic_block:
|
||||
if force_lock:
|
||||
raise ParseError("当前操作需要在事务中进行,请使用事务装饰器")
|
||||
# 非只读请求且在事务中:加锁查询
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
|
||||
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
|
||||
|
||||
try:
|
||||
obj = queryset.select_for_update().get(**filter_kwargs)
|
||||
self.check_object_permissions(self.request, obj)
|
||||
return obj
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404
|
||||
else:
|
||||
# 其他情况:普通查询
|
||||
return super().get_object()
|
||||
|
||||
def get_serializer_class(self):
|
||||
action_serializer_name = f"{self.action}_serializer_class"
|
||||
action_serializer_class = getattr(self, action_serializer_name, None)
|
||||
|
@ -193,5 +222,4 @@ class CustomModelViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, CustomListM
|
|||
CustomRetrieveModelMixin, BulkDestroyModelMixin, ComplexQueryMixin, CustomGenericViewSet):
|
||||
"""
|
||||
增强的ModelViewSet
|
||||
"""
|
||||
pass
|
||||
"""
|
|
@ -738,7 +738,6 @@ class BatchSt(BaseModel):
|
|||
# return ins, True
|
||||
|
||||
@classmethod
|
||||
@transaction.atomic
|
||||
def init_dag(cls, batch:str):
|
||||
"""
|
||||
更新批次数据关系链(初步)
|
||||
|
|
|
@ -885,7 +885,6 @@ class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
|||
ftest_sr.update(instance=ftest, validated_data=ftest_data)
|
||||
return mlogbw
|
||||
|
||||
@transaction.atomic
|
||||
def create(self, validated_data):
|
||||
wpr: Wpr = validated_data.get("wpr", None)
|
||||
if wpr:
|
||||
|
@ -898,7 +897,6 @@ class MlogbwCreateUpdateSerializer(CustomModelSerializer):
|
|||
mlogbw = self.save_ftest(mlogbw, ftest_data)
|
||||
return mlogbw
|
||||
|
||||
@transaction.atomic
|
||||
def update(self, instance, validated_data):
|
||||
validated_data.pop("mlogb")
|
||||
ftest_data = validated_data.pop("ftest", None)
|
||||
|
@ -1078,7 +1076,6 @@ class MlogbOutUpdateSerializer(CustomModelSerializer):
|
|||
# else:
|
||||
# raise ParseError("mlogbdefect仅支持批次件")
|
||||
# return ins
|
||||
@transaction.atomic
|
||||
def update(self, instance, validated_data):
|
||||
mlogbdefect = validated_data.pop("mlogbdefect", None)
|
||||
with transaction.atomic():
|
||||
|
|
|
@ -37,14 +37,12 @@ from django.db.models import Q
|
|||
from apps.utils.tools import convert_ordereddict, update_dict
|
||||
from django.db.models import Count
|
||||
from datetime import datetime, timedelta
|
||||
from apps.utils.lock import lock_model_record_d_method
|
||||
from apps.em.models import Equipment
|
||||
from django.db.models import Prefetch
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from drf_yasg import openapi
|
||||
|
||||
|
||||
|
||||
# Create your views here.
|
||||
|
||||
|
||||
|
@ -155,7 +153,6 @@ class WMaterialViewSet(ListModelMixin, CustomGenericViewSet):
|
|||
return queryset.exclude(state=WMaterial.WM_SCRAP)
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=DeptBatchSerializer)
|
||||
@transaction.atomic
|
||||
def batchs(self, request):
|
||||
"""获取车间的批次号(废弃)
|
||||
|
||||
|
@ -282,7 +279,6 @@ class MlogViewSet(CustomModelViewSet):
|
|||
item["mlogbw_number_list"] = wpr_dict.get(item["id"], None)
|
||||
return data
|
||||
|
||||
@lock_model_record_d_method(Mlog)
|
||||
def perform_destroy(self, instance):
|
||||
if instance.submit_time is not None:
|
||||
raise ParseError('日志已提交不可变动')
|
||||
|
@ -295,7 +291,6 @@ class MlogViewSet(CustomModelViewSet):
|
|||
instance.delete()
|
||||
Ftest.objects.filter(id__in=ftestIds).delete()
|
||||
|
||||
@transaction.atomic
|
||||
def perform_update(self, serializer):
|
||||
ins = serializer.instance
|
||||
if ins.ticket and ins.ticket.state != State.STATE_TYPE_START:
|
||||
|
@ -318,7 +313,10 @@ class MlogViewSet(CustomModelViewSet):
|
|||
ins = sr.save()
|
||||
return Response(MlogSerializer(ins).data)
|
||||
|
||||
@action(methods=['post'], detail=True, perms_map={'post': 'mlog.update'}, serializer_class=MlogChangeSerializer)
|
||||
@action(methods=['post'], detail=True,
|
||||
perms_map={'post': 'mlog.update'},
|
||||
serializer_class=MlogChangeSerializer)
|
||||
@transaction.atomic
|
||||
def change(self, request, *args, **kwargs):
|
||||
"""修改日志
|
||||
|
||||
|
@ -334,7 +332,9 @@ class MlogViewSet(CustomModelViewSet):
|
|||
sr.save()
|
||||
return Response(MlogSerializer(ins).data)
|
||||
|
||||
@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=Serializer)
|
||||
@transaction.atomic
|
||||
def submit(self, request, *args, **kwargs):
|
||||
"""日志提交(变动车间库存)
|
||||
|
||||
|
@ -349,20 +349,12 @@ class MlogViewSet(CustomModelViewSet):
|
|||
if p.mlog_need_ticket:
|
||||
raise ParseError('该日志需要审批!')
|
||||
mlog_submit_validate(ins)
|
||||
with transaction.atomic():
|
||||
updated_count = Mlog.objects.filter(id=ins.id, submit_time__isnull=True).update(
|
||||
submit_time=now, submit_user=request.user, update_by=request.user)
|
||||
if updated_count == 1:
|
||||
mlog_submit(ins, self.request.user, now)
|
||||
else:
|
||||
raise ParseError('记录正在处理中,请稍后再试')
|
||||
|
||||
vdata_new = MlogSerializer(ins).data
|
||||
# create_auditlog('submit', ins, vdata_new,
|
||||
# vdata_old, now, self.request.user)
|
||||
mlog_submit(ins, self.request.user, now)
|
||||
vdata_new = MlogSerializer(ins).data
|
||||
return Response(vdata_new)
|
||||
|
||||
@action(methods=['post'], detail=True, perms_map={'post': 'mlog.submit'}, serializer_class=MlogRevertSerializer)
|
||||
@transaction.atomic
|
||||
def revert(self, request, *args, **kwargs):
|
||||
"""撤回日志提交
|
||||
|
||||
|
@ -377,20 +369,10 @@ class MlogViewSet(CustomModelViewSet):
|
|||
if user != ins.submit_user:
|
||||
raise ParseError('非提交人不可撤销!')
|
||||
now = timezone.now()
|
||||
with transaction.atomic():
|
||||
updated_count = Mlog.objects.filter(id=ins.id, submit_time__isnull=False).update(
|
||||
submit_time=None, update_time=now, submit_user=None, update_by=request.user)
|
||||
if updated_count == 1:
|
||||
mlog_revert(ins, user, now)
|
||||
else:
|
||||
raise ParseError('记录正在处理中,请稍后再试')
|
||||
|
||||
# create_auditlog('revert', ins, {}, {}, now, user,
|
||||
# request.data.get('change_reason', ''))
|
||||
mlog_revert(ins, user, now)
|
||||
return Response(MlogSerializer(instance=ins).data)
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MlogRelatedSerializer)
|
||||
@transaction.atomic
|
||||
def related_first(self, request, *args, **kwargs):
|
||||
"""获取相关任务的第一道工序日志
|
||||
|
||||
|
@ -508,8 +490,7 @@ class HandoverViewSet(CustomModelViewSet):
|
|||
'material__number', 'material__specification', 'batch', 'material__model', 'b_handover__batch', "new_batch", "wm__batch"]
|
||||
prefetch_related_fields = ["b_handover"]
|
||||
|
||||
@lock_model_record_d_method(Handover)
|
||||
def perform_destroy(self, instance:Handover):
|
||||
def perform_destroy(self, instance):
|
||||
user = self.request.user
|
||||
if instance.submit_time is not None:
|
||||
raise ParseError('该交接记录已提交不可删除')
|
||||
|
@ -520,9 +501,8 @@ class HandoverViewSet(CustomModelViewSet):
|
|||
ticket.delete()
|
||||
instance.delete()
|
||||
|
||||
@transaction.atomic
|
||||
def perform_update(self, serializer):
|
||||
ins:Handover = self.get_object()
|
||||
ins:Handover = serializer.instance
|
||||
if ins.submit_time is not None:
|
||||
raise ParseError('该交接记录已提交!')
|
||||
ticket:Ticket = ins.ticket
|
||||
|
@ -580,7 +560,6 @@ class HandoverViewSet(CustomModelViewSet):
|
|||
return Response()
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=HandoverMgroupSerializer)
|
||||
@transaction.atomic
|
||||
def mgroups(self, request, *args, **kwargs):
|
||||
"""获取可交接到的工段
|
||||
|
||||
|
@ -708,7 +687,6 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
|
|||
serializer_class = MlogbInSerializer
|
||||
update_serializer_class = MlogbInUpdateSerializer
|
||||
|
||||
@transaction.atomic
|
||||
def perform_destroy(self, instance):
|
||||
ins: Mlogb = instance
|
||||
if ins.mlog.submit_time is not None:
|
||||
|
@ -716,7 +694,6 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
|
|||
ins.delete()
|
||||
ins.mlog.cal_mlog_count_from_mlogb()
|
||||
|
||||
@transaction.atomic
|
||||
def perform_update(self, serializer):
|
||||
ins:Mlogb = serializer.save()
|
||||
ins.mlog.cal_mlog_count_from_mlogb()
|
||||
|
@ -883,7 +860,7 @@ class MlogbInViewSet(CreateModelMixin, UpdateModelMixin, DestroyModelMixin, Cust
|
|||
raise ParseError("不支持生成产出物料!")
|
||||
mlog.cal_mlog_count_from_mlogb()
|
||||
|
||||
@transaction.atomic
|
||||
|
||||
def perform_create(self, serializer):
|
||||
mlogbin: Mlogb = serializer.save()
|
||||
MlogbInViewSet.p_create_after(mlogbin)
|
||||
|
@ -925,7 +902,6 @@ class MlogbOutViewSet(UpdateModelMixin, CustomGenericViewSet):
|
|||
queryset = Mlogb.objects.filter(material_out__isnull=False)
|
||||
serializer_class = MlogbOutUpdateSerializer
|
||||
|
||||
@transaction.atomic
|
||||
def perform_update(self, serializer):
|
||||
material_out = serializer.validated_data.get('material_out')
|
||||
if material_out and material_out.tracking == Material.MA_TRACKING_SINGLE:
|
||||
|
@ -985,7 +961,6 @@ class MlogbwViewSet(CustomModelViewSet):
|
|||
# raise ParseError('请指定所属消耗/产出明细')
|
||||
# return super().filter_queryset(queryset)
|
||||
|
||||
@transaction.atomic
|
||||
def perform_create(self, serializer):
|
||||
ins:Mlogbw = serializer.save()
|
||||
mlog:Mlog = None
|
||||
|
@ -1061,7 +1036,6 @@ class MlogbwViewSet(CustomModelViewSet):
|
|||
raise ParseError("该个号不可产生该批")
|
||||
mlog.cal_mlog_count_from_mlogb()
|
||||
|
||||
@transaction.atomic
|
||||
def perform_update(self, serializer):
|
||||
mlogbw = serializer.save()
|
||||
if isinstance(mlogbw, list):
|
||||
|
@ -1079,7 +1053,6 @@ class MlogbwViewSet(CustomModelViewSet):
|
|||
mlog = mlogb.mlog
|
||||
mlog.cal_mlog_count_from_mlogb()
|
||||
|
||||
@transaction.atomic
|
||||
def perform_destroy(self, instance:Mlogbw):
|
||||
mlogb:Mlogb = instance.mlogb
|
||||
if mlogb.material_out is not None and instance.wpr is not None:
|
||||
|
|
Loading…
Reference in New Issue