Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
9e91c90213
|
@ -9,7 +9,7 @@ from django.db.models.query import Prefetch
|
||||||
|
|
||||||
class EmployeeSerializer(DynamicFieldsSerializerMixin, ModelSerializer):
|
class EmployeeSerializer(DynamicFieldsSerializerMixin, ModelSerializer):
|
||||||
name = serializers.CharField(source='user.name', read_only=True)
|
name = serializers.CharField(source='user.name', read_only=True)
|
||||||
dept_ = OrganizationSimpleSerializer(source='user.dept_', read_only=True)
|
dept_ = OrganizationSimpleSerializer(source='user.dept', read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Employee
|
model = Employee
|
||||||
exclude = ['face_data']
|
exclude = ['face_data']
|
||||||
|
|
|
@ -21,7 +21,7 @@ class HRMService:
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
except:
|
except:
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
return None, '头像解码失败'
|
return None, '人脸识别失败'
|
||||||
|
|
||||||
# 匹配人脸库
|
# 匹配人脸库
|
||||||
face_datas = cache.get('face_datas')
|
face_datas = cache.get('face_datas')
|
||||||
|
@ -32,20 +32,21 @@ class HRMService:
|
||||||
results = face_recognition.compare_faces(face_datas,
|
results = face_recognition.compare_faces(face_datas,
|
||||||
unknown_face_encoding, tolerance=0.5)
|
unknown_face_encoding, tolerance=0.5)
|
||||||
except:
|
except:
|
||||||
return None, '识别失败'
|
return None, '人脸匹配失败'
|
||||||
for index, value in enumerate(results):
|
for index, value in enumerate(results):
|
||||||
if value:
|
if value:
|
||||||
# 识别成功
|
# 识别成功
|
||||||
user = User.objects.get(id=face_users[index])
|
user = User.objects.get(id=face_users[index])
|
||||||
return user, ''
|
return user, ''
|
||||||
return None, '识别失败'
|
return None, '人脸匹配失败'
|
||||||
|
|
||||||
def get_facedata_from_img(cls, img_rpath):
|
@classmethod
|
||||||
|
def get_facedata_from_img(cls, img_path):
|
||||||
try:
|
try:
|
||||||
photo_path = settings.BASE_DIR + img_rpath
|
photo_path = settings.BASE_DIR + img_path
|
||||||
picture_of_me = face_recognition.load_image_file(photo_path)
|
picture_of_me = face_recognition.load_image_file(photo_path)
|
||||||
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
|
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
|
||||||
face_data_list = my_face_encoding.tolist()
|
face_data_list = my_face_encoding.tolist()
|
||||||
return face_data_list
|
return face_data_list, ''
|
||||||
except:
|
except:
|
||||||
return None
|
return None, '人脸识别失败'
|
|
@ -20,11 +20,11 @@ from rest_framework import exceptions
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
from apps.system.serializers import UserSimpleSerializer
|
from apps.system.serializers import UserSimpleSerializer
|
||||||
from rest_framework.permissions import AllowAny
|
from rest_framework.permissions import AllowAny
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, RetrieveModelMixin, GenericViewSet):
|
class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
员工详细信息
|
员工详细信息
|
||||||
"""
|
"""
|
||||||
|
@ -32,6 +32,7 @@ class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMix
|
||||||
queryset = Employee.objects.all()
|
queryset = Employee.objects.all()
|
||||||
filterset_class = EmployeeFilterSet
|
filterset_class = EmployeeFilterSet
|
||||||
serializer_class = EmployeeSerializer
|
serializer_class = EmployeeSerializer
|
||||||
|
search_fields = ['user__name', 'number', 'user__username']
|
||||||
ordering = ['-pk']
|
ordering = ['-pk']
|
||||||
|
|
||||||
def update(self, request, *args, **kwargs):
|
def update(self, request, *args, **kwargs):
|
||||||
|
@ -42,13 +43,13 @@ class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMix
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
photo = data.get('photo', None)
|
photo = data.get('photo', None)
|
||||||
if instance.photo != photo:
|
if instance.photo != photo:
|
||||||
f_l = HRMService.get_facedata_from_img(photo)
|
f_l, msg = HRMService.get_facedata_from_img(img_path=photo)
|
||||||
if f_l:
|
if f_l:
|
||||||
serializer.save(update_by=request.user, face_data = f_l)
|
serializer.save(update_by=request.user, face_data = f_l)
|
||||||
# 更新人脸缓存
|
# 更新人脸缓存
|
||||||
update_all_user_facedata_cache.delay()
|
update_all_user_facedata_cache.delay()
|
||||||
return Response()
|
return Response()
|
||||||
return Response('头像识别失败', status=status.HTTP_400_BAD_REQUEST)
|
return Response(msg, status=status.HTTP_400_BAD_REQUEST)
|
||||||
serializer.save(update_by=request.user)
|
serializer.save(update_by=request.user)
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
@ -79,16 +80,16 @@ class ClockRecordViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):
|
||||||
user, msg = HRMService.face_compare_from_base64(base64_data)
|
user, msg = HRMService.face_compare_from_base64(base64_data)
|
||||||
if user:
|
if user:
|
||||||
ins, created = ClockRecord.objects.get_or_create(
|
ins, created = ClockRecord.objects.get_or_create(
|
||||||
create_by=request.user, create_time__hour__range = [8,18],
|
create_by = user, create_time__hour__range = [8,18],
|
||||||
create_time__year=now.year, create_time__month=now.month,
|
create_time__year=now_local.year, create_time__month=now_local.month,
|
||||||
create_time__day=now.day,
|
create_time__day=now_local.day,
|
||||||
defaults={
|
defaults={
|
||||||
'type':ClockRecord.ClOCK_WORK1,
|
'type':ClockRecord.ClOCK_WORK1,
|
||||||
'create_by':user,
|
'create_by':user,
|
||||||
'create_time':now
|
'create_time':now
|
||||||
})
|
})
|
||||||
if not created:
|
if not created:
|
||||||
ins.create_time = now
|
ins.update_time = now
|
||||||
ins.save()
|
ins.save()
|
||||||
# 设为在岗
|
# 设为在岗
|
||||||
user.is_atwork = True
|
user.is_atwork = True
|
||||||
|
|
|
@ -42,6 +42,8 @@ class SaleViewSet(CreateUpdateModelAMixin, ListModelMixin, RetrieveModelMixin, C
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
iproducts = vdata.pop('iproducts')
|
iproducts = vdata.pop('iproducts')
|
||||||
vdata['count'] = len(iproducts)
|
vdata['count'] = len(iproducts)
|
||||||
|
if vdata['count'] + vdata['order'].delivered_count > vdata['order'].count:
|
||||||
|
raise exceptions.APIException('超过订单所需数量')
|
||||||
sale = Sale.objects.create(**vdata)
|
sale = Sale.objects.create(**vdata)
|
||||||
i_l = []
|
i_l = []
|
||||||
for i in iproducts:
|
for i in iproducts:
|
||||||
|
|
|
@ -23,4 +23,9 @@ class PlanGanttSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class ProcessYieldSerializer(serializers.Serializer):
|
class ProcessYieldSerializer(serializers.Serializer):
|
||||||
datetime_start = serializers.DateField(label='开始时间', required=False, allow_null=True)
|
datetime_start = serializers.DateField(label='开始时间', required=False, allow_null=True)
|
||||||
datetime_end = serializers.DateField(label='结束时间', required=False, allow_null=True)
|
datetime_end = serializers.DateField(label='结束时间', required=False, allow_null=True)
|
||||||
|
|
||||||
|
|
||||||
|
class AtWorkCountSerializer(serializers.Serializer):
|
||||||
|
year = serializers.IntegerField(label='年')
|
||||||
|
month = serializers.IntegerField(label='月')
|
|
@ -3,12 +3,13 @@ from rest_framework import urlpatterns
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
from apps.srm.views import GanttPlan, ProcessYieldView
|
from apps.srm.views import AtWorkCountView, GanttPlan, ProcessYieldView
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('gantt/plan/', GanttPlan.as_view()),
|
path('gantt/plan/', GanttPlan.as_view()),
|
||||||
path('process/yield/', ProcessYieldView.as_view()),
|
path('process/yield/', ProcessYieldView.as_view()),
|
||||||
|
path('at_work/', AtWorkCountView.as_view()),
|
||||||
path('', include(router.urls)),
|
path('', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,12 @@ from rest_framework import serializers
|
||||||
from rest_framework.generics import ListAPIView, CreateAPIView
|
from rest_framework.generics import ListAPIView, CreateAPIView
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
from apps.hrm.models import ClockRecord
|
||||||
from apps.mtm.models import Process, Step
|
from apps.mtm.models import Process, Step
|
||||||
from apps.pm.models import ProductionPlan, SubProductionPlan
|
from apps.pm.models import ProductionPlan, SubProductionPlan
|
||||||
from apps.srm.serializers import PlanGanttSerializer, ProcessYieldSerializer
|
from apps.srm.serializers import AtWorkCountSerializer, PlanGanttSerializer, ProcessYieldSerializer
|
||||||
from apps.wpm.models import WProduct, WproductFlow
|
from apps.wpm.models import WProduct, WproductFlow
|
||||||
from django.db.models import Count
|
from django.db.models import Count, F
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
class GanttPlan(ListAPIView):
|
class GanttPlan(ListAPIView):
|
||||||
|
@ -65,3 +66,26 @@ class ProcessYieldView(CreateAPIView):
|
||||||
return Response(ret)
|
return Response(ret)
|
||||||
|
|
||||||
|
|
||||||
|
class AtWorkCountView(CreateAPIView):
|
||||||
|
"""
|
||||||
|
到岗天数统计
|
||||||
|
"""
|
||||||
|
perms_map = {'get':'*'}
|
||||||
|
serializer_class = AtWorkCountSerializer
|
||||||
|
|
||||||
|
def create(self, request, *args, **kwargs):
|
||||||
|
serializer = self.get_serializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
vdata = serializer.validated_data
|
||||||
|
ret = ClockRecord.objects.filter(
|
||||||
|
create_time__year = vdata['year'],
|
||||||
|
create_time__month = vdata['month']
|
||||||
|
).values(
|
||||||
|
user_id = F('create_by'),
|
||||||
|
username = F('create_by__username'),
|
||||||
|
name = F('create_by__name'),
|
||||||
|
dept_name = F('create_by__dept__name')).annotate(
|
||||||
|
count = Count('id')
|
||||||
|
)
|
||||||
|
return Response(list(ret))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue