feature<master> feat:新增资质情况和更新记录功能
This commit is contained in:
parent
94ef5e3121
commit
4a06a9d68a
|
@ -0,0 +1,57 @@
|
||||||
|
# Generated by Django 3.2.12 on 2024-04-09 06:02
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('system', '0023_alter_user_first_name'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('information', '0018_auto_20240407_1622'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Qualification',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('company_name', models.CharField(blank=True, max_length=20, null=True, verbose_name='公司名称')),
|
||||||
|
('name', models.CharField(blank=True, max_length=20, null=True, verbose_name='资质名称')),
|
||||||
|
('quali_type', models.CharField(choices=[('国家级', '国家级'), ('省级', '省级')], max_length=20, verbose_name='资质类型')),
|
||||||
|
('org', models.CharField(blank=True, max_length=20, null=True, verbose_name='发证单位')),
|
||||||
|
('org_date', models.DateField(blank=True, null=True, verbose_name='发证日期')),
|
||||||
|
('expiration_date', models.DateField(blank=True, null=True, verbose_name='截至日期')),
|
||||||
|
('scope', models.TextField(blank=True, null=True, verbose_name='资质范围')),
|
||||||
|
('number', models.IntegerField(blank=True, null=True, verbose_name='参数数量')),
|
||||||
|
('cie_path', models.CharField(blank=True, max_length=100, null=True, verbose_name='证书路径')),
|
||||||
|
('create_date', models.DateTimeField(auto_now_add=True, null=True)),
|
||||||
|
('update_date', models.DateTimeField(auto_now=True, null=True)),
|
||||||
|
('department', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='system.organization', verbose_name='所属单位')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': '资质情况',
|
||||||
|
'db_table': 'qfn_info',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='AuditLog',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||||
|
('action', models.CharField(max_length=20, verbose_name='动作')),
|
||||||
|
('instance_id', models.CharField(editable=False, max_length=20, verbose_name='记录ID')),
|
||||||
|
('change_reason', models.CharField(default='', max_length=50, verbose_name='变更原因')),
|
||||||
|
('change_time', models.DateTimeField(verbose_name='变更时间')),
|
||||||
|
('val_new', models.JSONField(default=dict, verbose_name='变更后完整数据')),
|
||||||
|
('difference', models.JSONField(default=list, verbose_name='变更情况')),
|
||||||
|
('change_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='操作人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': '资质变更情况',
|
||||||
|
'db_table': 'qfn_change_info',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,6 +1,47 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from apps.system.models import Organization
|
from apps.system.models import Organization
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
class Qualification(models.Model):
|
||||||
|
quali_options = (('国家级','国家级'),('省级','省级'))
|
||||||
|
company_name = models.CharField(max_length=20, verbose_name='公司名称', null=True, blank=True)
|
||||||
|
name = models.CharField(max_length=20, verbose_name='资质名称',null=True, blank=True)
|
||||||
|
quali_type = models.CharField(max_length=20, choices=quali_options, verbose_name='资质类型')
|
||||||
|
org = models.CharField(max_length=20, verbose_name='发证单位', null=True, blank=True)
|
||||||
|
org_date = models.DateField(verbose_name='发证日期', null=True, blank=True)
|
||||||
|
expiration_date = models.DateField(verbose_name='截至日期', null=True, blank=True)
|
||||||
|
scope = models.TextField(verbose_name='资质范围', null=True, blank=True)
|
||||||
|
number = models.IntegerField(verbose_name='参数数量', null=True, blank=True)
|
||||||
|
cie_path = models.CharField(max_length=100, verbose_name='证书路径', null=True, blank=True)
|
||||||
|
create_date = models.DateTimeField(auto_now_add=True, null=True)
|
||||||
|
update_date = models.DateTimeField(auto_now=True, null=True)
|
||||||
|
department = models.ForeignKey(Organization, on_delete=models.PROTECT, null=True, verbose_name='所属单位')
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
if not self.id:
|
||||||
|
self.create_date = timezone.now()
|
||||||
|
# update_date将自动设置为当前时间,因为auto_now=True
|
||||||
|
super(Qualification, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = '资质情况'
|
||||||
|
db_table = 'qfn_info'
|
||||||
|
|
||||||
|
|
||||||
|
class AuditLog(models.Model):
|
||||||
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
|
action = models.CharField('动作', max_length=20)
|
||||||
|
instance_id = models.CharField('记录ID', max_length=20, editable=False)
|
||||||
|
change_reason = models.CharField('变更原因', default='', max_length=50)
|
||||||
|
change_user = models.ForeignKey('system.user', on_delete=models.SET_NULL, verbose_name='操作人', null=True, blank=True)
|
||||||
|
change_time = models.DateTimeField('变更时间')
|
||||||
|
val_new = models.JSONField('变更后完整数据', default=dict)
|
||||||
|
difference = models.JSONField('变更情况', default=list)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = '资质变更情况'
|
||||||
|
db_table = 'qfn_change_info'
|
||||||
|
|
||||||
|
|
||||||
class AbilityReview(models.Model):
|
class AbilityReview(models.Model):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from apps.system.serializers import OrganizationSimpleSerializer
|
from apps.system.serializers import OrganizationSimpleSerializer
|
||||||
from .models import AbilityReview, QualityCommendation, QualityActivities, Contact, ExternalAuditors
|
from .models import AbilityReview, QualityCommendation, QualityActivities, Contact, ExternalAuditors, AuditLog, Qualification
|
||||||
|
|
||||||
|
|
||||||
class AbilityReviewSerializer(serializers.ModelSerializer):
|
class AbilityReviewSerializer(serializers.ModelSerializer):
|
||||||
|
@ -35,4 +35,15 @@ class ExternalAuditorsSerializer(serializers.ModelSerializer):
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class QualificationSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Qualification
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class AuditLogSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = AuditLog
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
from .views import AbilityReviewViewSet, QualityCommendationViewSet, QualityActivitiesViewSet, ContactViewSet, ExternalAuditorsViewSet
|
from .views import AbilityReviewViewSet, QualityCommendationViewSet, QualityActivitiesViewSet, ContactViewSet, ExternalAuditorsViewSet, QualificationViewSet
|
||||||
|
|
||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.register('ar', AbilityReviewViewSet, basename='abilityreviews')
|
router.register('ar', AbilityReviewViewSet, basename='abilityreviews')
|
||||||
|
@ -8,6 +8,7 @@ router.register('qc', QualityCommendationViewSet, basename='qualitycommendation'
|
||||||
router.register('qa', QualityActivitiesViewSet, basename='qualityactivities')
|
router.register('qa', QualityActivitiesViewSet, basename='qualityactivities')
|
||||||
router.register('contact', ContactViewSet, basename='contact')
|
router.register('contact', ContactViewSet, basename='contact')
|
||||||
router.register('ea', ExternalAuditorsViewSet, basename='externalauditors')
|
router.register('ea', ExternalAuditorsViewSet, basename='externalauditors')
|
||||||
|
router.register('faq', QualificationViewSet, basename='faq')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', include(router.urls))
|
path('', include(router.urls))
|
||||||
]
|
]
|
|
@ -1,11 +1,6 @@
|
||||||
|
|
||||||
from rest_framework import viewsets, mixins
|
|
||||||
from rest_framework.viewsets import ViewSet
|
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.views import APIView
|
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
from utils.queryset import get_child_queryset2
|
from utils.queryset import get_child_queryset2
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
@ -47,6 +42,7 @@ class AbilityReviewViewSet(ModelViewSet):
|
||||||
|
|
||||||
#根据日期过滤数据
|
#根据日期过滤数据
|
||||||
@action(detail=False, methods=['post'])
|
@action(detail=False, methods=['post'])
|
||||||
|
@transaction.atomic
|
||||||
def filter_by_date(self, request, *args, **kwargs):
|
def filter_by_date(self, request, *args, **kwargs):
|
||||||
father_dept = request.user.dept
|
father_dept = request.user.dept
|
||||||
child_dept = get_child_queryset2(father_dept)
|
child_dept = get_child_queryset2(father_dept)
|
||||||
|
@ -137,6 +133,7 @@ class ImpMixin:
|
||||||
|
|
||||||
return Response({'uploaded': 'File uploaded successfully'}, status=status.HTTP_201_CREATED)
|
return Response({'uploaded': 'File uploaded successfully'}, status=status.HTTP_201_CREATED)
|
||||||
|
|
||||||
|
|
||||||
class QualityCommendationViewSet(ModelViewSet):
|
class QualityCommendationViewSet(ModelViewSet):
|
||||||
queryset = QualityCommendation.objects.all()
|
queryset = QualityCommendation.objects.all()
|
||||||
serializer_class = QualityCommendationSerializer
|
serializer_class = QualityCommendationSerializer
|
||||||
|
@ -153,13 +150,6 @@ class QualityCommendationViewSet(ModelViewSet):
|
||||||
else:
|
else:
|
||||||
raise ParseError("获奖单位不存在")
|
raise ParseError("获奖单位不存在")
|
||||||
|
|
||||||
# # 导入表格
|
|
||||||
# @action(methods=['post'], detail=False)
|
|
||||||
# @transaction.atomic
|
|
||||||
# def imp(self, request, *args, **kwargs):
|
|
||||||
# return self.gen_imp_view(request, 5, QualityCommendationSerializer, 'qt')
|
|
||||||
|
|
||||||
#构造导入的数据格式
|
|
||||||
def build_qt_data(self, sheet):
|
def build_qt_data(self, sheet):
|
||||||
data_list = []
|
data_list = []
|
||||||
for row in sheet.iter_rows(min_row=2, values_only=True): # 假设第一行是表头,从第二行开始读取数据
|
for row in sheet.iter_rows(min_row=2, values_only=True): # 假设第一行是表头,从第二行开始读取数据
|
||||||
|
@ -186,7 +176,6 @@ class QualityCommendationViewSet(ModelViewSet):
|
||||||
data_list.append(serializer_data)
|
data_list.append(serializer_data)
|
||||||
return data_list
|
return data_list
|
||||||
|
|
||||||
|
|
||||||
# 查询子以及已经本公司的质量表彰
|
# 查询子以及已经本公司的质量表彰
|
||||||
@action(detail=False, methods=['get'])
|
@action(detail=False, methods=['get'])
|
||||||
def commentdation_info(self, request, *args, **kwargs):
|
def commentdation_info(self, request, *args, **kwargs):
|
||||||
|
@ -199,6 +188,7 @@ class QualityCommendationViewSet(ModelViewSet):
|
||||||
|
|
||||||
#根据日期过滤数据
|
#根据日期过滤数据
|
||||||
@action(detail=False, methods=['post'])
|
@action(detail=False, methods=['post'])
|
||||||
|
@transaction.atomic
|
||||||
def filter_by_date(self, request, *args, **kwargs):
|
def filter_by_date(self, request, *args, **kwargs):
|
||||||
father_dept = request.user.dept
|
father_dept = request.user.dept
|
||||||
child_dept = get_child_queryset2(father_dept)
|
child_dept = get_child_queryset2(father_dept)
|
||||||
|
@ -249,6 +239,7 @@ class QualityActivitiesViewSet(ModelViewSet):
|
||||||
|
|
||||||
#根据日期过滤数据
|
#根据日期过滤数据
|
||||||
@action(detail=False, methods=['post'])
|
@action(detail=False, methods=['post'])
|
||||||
|
@transaction.atomic
|
||||||
def filter_by_date(self, request, *args, **kwargs):
|
def filter_by_date(self, request, *args, **kwargs):
|
||||||
father_dept = request.user.dept
|
father_dept = request.user.dept
|
||||||
child_dept = get_child_queryset2(father_dept)
|
child_dept = get_child_queryset2(father_dept)
|
||||||
|
@ -281,6 +272,7 @@ class ContactViewSet(ModelViewSet):
|
||||||
queryset = Contact.objects.all()
|
queryset = Contact.objects.all()
|
||||||
serializer_class = ContactSerializer
|
serializer_class = ContactSerializer
|
||||||
|
|
||||||
|
|
||||||
class ExternalAuditorsViewSet(ModelViewSet):
|
class ExternalAuditorsViewSet(ModelViewSet):
|
||||||
queryset = ExternalAuditors.objects.all()
|
queryset = ExternalAuditors.objects.all()
|
||||||
serializer_class = ExternalAuditorsSerializer
|
serializer_class = ExternalAuditorsSerializer
|
||||||
|
@ -294,7 +286,7 @@ class ExternalAuditorsViewSet(ModelViewSet):
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return Response(serializer.data, status = status.HTTP_201_CREATED)
|
return Response(serializer.data, status = status.HTTP_201_CREATED)
|
||||||
else:
|
else:
|
||||||
raise ParseError("组织单位不存在")
|
raise ParseError("公司名称不存在")
|
||||||
|
|
||||||
# 查询子以及已经本公司的质量活动
|
# 查询子以及已经本公司的质量活动
|
||||||
@action(detail=False, methods=['get'])
|
@action(detail=False, methods=['get'])
|
||||||
|
@ -307,6 +299,7 @@ class ExternalAuditorsViewSet(ModelViewSet):
|
||||||
|
|
||||||
#根据日期过滤数据
|
#根据日期过滤数据
|
||||||
@action(detail=False, methods=['post'])
|
@action(detail=False, methods=['post'])
|
||||||
|
@transaction.atomic
|
||||||
def filter_by_date(self, request, *args, **kwargs):
|
def filter_by_date(self, request, *args, **kwargs):
|
||||||
father_dept = request.user.dept
|
father_dept = request.user.dept
|
||||||
child_dept = get_child_queryset2(father_dept)
|
child_dept = get_child_queryset2(father_dept)
|
||||||
|
@ -331,3 +324,57 @@ class ExternalAuditorsViewSet(ModelViewSet):
|
||||||
new_data_list.append(new_dict)
|
new_data_list.append(new_dict)
|
||||||
data = {'count':len(serializer.data), 'results':new_data_list}
|
data = {'count':len(serializer.data), 'results':new_data_list}
|
||||||
return Response(data, status = status.HTTP_200_OK)
|
return Response(data, status = status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class QualificationViewSet(ModelViewSet):
|
||||||
|
queryset = Qualification.objects.all()
|
||||||
|
serializer_class = QualificationSerializer
|
||||||
|
|
||||||
|
#重写保存方法
|
||||||
|
def create(self, request):
|
||||||
|
if Organization.objects.filter(name=request.data['company_name']).exists():
|
||||||
|
department_id = Organization.objects.filter(name=request.data['company_name']).first().id
|
||||||
|
request.data['department'] = department_id
|
||||||
|
serializer = self.get_serializer(data=request.data)
|
||||||
|
if serializer.is_valid(raise_exception=True):
|
||||||
|
serializer.save()
|
||||||
|
return Response(serializer.data, status = status.HTTP_201_CREATED)
|
||||||
|
else:
|
||||||
|
raise ParseError("公司名称不存在")
|
||||||
|
|
||||||
|
# 重写更新的方法
|
||||||
|
def partial_update(self, request, pk=None):
|
||||||
|
#获取需要更新的实列
|
||||||
|
instance = self.get_object()
|
||||||
|
# 数据比较
|
||||||
|
ignore_fields = ['create_by', 'create_date', 'update_date', 'id']
|
||||||
|
origin_dict = QualificationSerializer(instance=instance).data
|
||||||
|
diff = []
|
||||||
|
for k, v in request.data.items():
|
||||||
|
if k not in ignore_fields:
|
||||||
|
origin_value = origin_dict.get(k)
|
||||||
|
if origin_value != v:
|
||||||
|
diff.append({k:{'old':origin_value, 'new':v}})
|
||||||
|
serializers = self.get_serializer(instance, data=request.data, partial=True)
|
||||||
|
serializers.is_valid(raise_exception=True)
|
||||||
|
self.perform_update(serializers)
|
||||||
|
if diff:
|
||||||
|
AuditLog.objects.create(
|
||||||
|
action='update',
|
||||||
|
instance_id=instance.id,
|
||||||
|
change_time = datetime.now(),
|
||||||
|
change_user=request.user,
|
||||||
|
val_new=serializers.data,
|
||||||
|
difference=diff
|
||||||
|
)
|
||||||
|
return Response(serializers.data, status = status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
|
# 查询子以及已经本公司的资质情况
|
||||||
|
@action(detail=False, methods=['get'])
|
||||||
|
def activate_info(self, request, *args, **kwargs):
|
||||||
|
child_dept = get_child_queryset2(request.user.dept)
|
||||||
|
query = Qualification.objects.filter(department__in=child_dept)
|
||||||
|
serializer = QualificationSerializer(query, many=True)
|
||||||
|
data = {'count':len(serializer.data), 'results':serializer.data}
|
||||||
|
return Response(data, status = status.HTTP_200_OK)
|
||||||
|
|
Loading…
Reference in New Issue