项目制定

This commit is contained in:
caoqianming 2020-08-21 15:52:15 +08:00
parent 0a551786c3
commit 0487fac0c2
15 changed files with 348 additions and 20 deletions

View File

@ -22,7 +22,7 @@ class Standard(CommonAModel):
verbose_name_plural = verbose_name
def __str__(self):
return self.name
return self.code + '-' + self.name
class ImplementRule(CommonAModel):
@ -44,7 +44,7 @@ class ImplementRule(CommonAModel):
verbose_name_plural = verbose_name
def __str__(self):
return self.name
return self.code +'-'+ self.name
class UnitType(CommonAModel):

View File

@ -6,31 +6,50 @@ from apps.system.serializers import DictSerializer
class StandardSerializer(serializers.ModelSerializer):
fullname = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Standard
fields = '__all__'
def get_fullname(self, obj):
fullname = obj.code + ' ' + obj.name
if obj.code in obj.name:
fullname = obj.name
return fullname
class ImplementRuleSerializer(serializers.ModelSerializer):
cert_field_ = DictSerializer(source='cert_field', read_only=True)
fullname = serializers.SerializerMethodField(read_only=True)
class Meta:
model = ImplementRule
fields = '__all__'
def get_fullname(self, obj):
fullname = obj.code + ' ' + obj.name
if obj.code in obj.name:
fullname = obj.name
return fullname
class ImplementRuleListSerializer(serializers.ModelSerializer):
pv_scope = DictSerializer()
pv_class = DictSerializer()
cert_field = DictSerializer()
ccc_list = DictSerializer(many=True)
fullname = serializers.SerializerMethodField(read_only=True)
class Meta:
model = ImplementRule
fields = ['id', 'code', 'name', 'cert_field', 'pv_scope', 'pv_class', 'create_time', 'ccc_list']
fields = ['id', 'code', 'name', 'cert_field', 'pv_scope', 'pv_class', 'create_time', 'ccc_list', 'fullname']
@staticmethod
def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.select_related('pv_scope','pv_class', 'cert_field')
queryset = queryset.prefetch_related('ccc_list',)
return queryset
def get_fullname(self, obj):
fullname = obj.code + ' ' + obj.name
if obj.code in obj.name:
fullname = obj.name
return fullname
# def get_cert_field(self, obj):
# return obj.get_cert_field_display()

View File

@ -21,7 +21,7 @@ class ImplementRuleViewSet(CreateUpdateCustomMixin, OptimizationMixin, ModelView
queryset = ImplementRule.objects.all()
serializer_class = ImplementRuleSerializer
search_fields = ['name', 'code', 'cert_field']
filterset_fields = ['pv_scope', 'cert_field', 'cert_field__code']
filterset_fields = ['pv_scope', 'cert_field', 'cert_field__code', 'ccc_list']
ordering = ['-create_time']
def get_serializer_class(self):

View File

@ -0,0 +1,8 @@
from django_filters import rest_framework as filters
from .models import *
class CertAppFilter(filters.FilterSet):
noproject = filters.BooleanFilter(field_name='project', lookup_expr='isnull')
class Meta:
model = CertApp
fields = ['status', 'noproject']

View File

@ -0,0 +1,20 @@
# Generated by Django 3.0.7 on 2020-08-17 01:48
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('certset', '0016_auto_20200805_1435'),
('project', '0019_auto_20200813_1744'),
]
operations = [
migrations.AddField(
model_name='unit',
name='standard',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='certset.Standard', verbose_name='采用标准'),
),
]

View File

@ -0,0 +1,33 @@
# Generated by Django 3.0.7 on 2020-08-18 03:53
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('certset', '0016_auto_20200805_1435'),
('project', '0020_unit_standard'),
]
operations = [
migrations.AddField(
model_name='unit',
name='implementrule',
field=models.ForeignKey(default=6, on_delete=django.db.models.deletion.DO_NOTHING, to='certset.ImplementRule', verbose_name='采用规则'),
preserve_default=False,
),
migrations.AlterField(
model_name='unit',
name='standard',
field=models.ForeignKey(default=2, on_delete=django.db.models.deletion.DO_NOTHING, to='certset.Standard', verbose_name='采用标准'),
preserve_default=False,
),
migrations.AlterField(
model_name='unit',
name='unittype',
field=models.ForeignKey(default=4, on_delete=django.db.models.deletion.DO_NOTHING, to='certset.UnitType', verbose_name='单元类型'),
preserve_default=False,
),
]

View File

@ -0,0 +1,47 @@
# Generated by Django 3.0.7 on 2020-08-18 09:04
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('crm', '0011_enterprise_parent'),
('project', '0021_auto_20200818_1153'),
]
operations = [
migrations.AddField(
model_name='certapp',
name='scope',
field=models.TextField(blank=True, null=True, verbose_name='认证范围'),
),
migrations.AddField(
model_name='project',
name='assign_date',
field=models.DateField(blank=True, null=True, verbose_name='下达日期'),
),
migrations.AddField(
model_name='project',
name='auditee',
field=models.ForeignKey(default=43, on_delete=django.db.models.deletion.DO_NOTHING, related_name='project_auditee', to='crm.Enterprise', verbose_name='受审核方'),
preserve_default=False,
),
migrations.AddField(
model_name='project',
name='auditee_v',
field=django.contrib.postgres.fields.jsonb.JSONField(default=dict, verbose_name='受审核方'),
),
migrations.AddField(
model_name='project',
name='number',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='项目编号'),
),
migrations.AddField(
model_name='project',
name='remark',
field=models.TextField(blank=True, null=True, verbose_name='备注'),
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 3.0.7 on 2020-08-21 01:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('project', '0022_auto_20200818_1704'),
]
operations = [
migrations.AlterModelOptions(
name='project',
options={'verbose_name': '认证项目', 'verbose_name_plural': '认证项目'},
),
migrations.AddField(
model_name='project',
name='status',
field=models.CharField(choices=[('待下达', '待下达'), ('待派差', '待派差'), ('进行中', '进行中'), ('已中止', '已中止'), ('已完成', '已完成')], default='待下达', max_length=50, verbose_name='项目状态'),
),
]

View File

@ -0,0 +1,21 @@
# Generated by Django 3.0.7 on 2020-08-21 02:04
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('project', '0023_auto_20200821_0957'),
]
operations = [
migrations.AddField(
model_name='project',
name='assign_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='下达人'),
),
]

View File

@ -0,0 +1,46 @@
# Generated by Django 3.0.7 on 2020-08-21 07:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('system', '0028_auto_20200807_1018'),
('project', '0024_project_assign_by'),
]
operations = [
migrations.AddField(
model_name='project',
name='can_paichai',
field=models.BooleanField(default=False, verbose_name='是否可派差'),
),
migrations.CreateModel(
name='Plan',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('name', models.CharField(max_length=1000, verbose_name='计划名称')),
('month', models.DateField(blank=True, null=True, verbose_name='计划审核月份')),
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plan_belong_dept', to='system.Organization', verbose_name='所属部门')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plan_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='plan_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'verbose_name': '审核计划',
'verbose_name_plural': '审核计划',
},
),
migrations.AddField(
model_name='project',
name='plan',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='project.Plan', verbose_name='所属计划'),
),
]

View File

@ -4,17 +4,54 @@ from django.db import models
from rest_framework.exceptions import ParseError
from simple_history.models import HistoricalRecords
from apps.certset.models import ImplementRule, UnitType, EvaluationItem
from apps.certset.models import ImplementRule, UnitType, EvaluationItem, Standard
from apps.crm.models import Enterprise
from apps.system.models import CommonAModel, CommonBModel, Dict, User
# Create your models here.
class Plan(CommonBModel):
"""
计划(项目组)
"""
name = models.CharField('计划名称', max_length = 1000)
month = models.DateField('计划审核月份', null=True, blank=True)
class Meta:
verbose_name = '审核计划'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Project(CommonBModel):
"""
认证项目
"""
pass
status_choices = (
('待下达', '待下达'),
('待派差', '待派差'),
('进行中', '进行中'),
('已中止', '已中止'),
('已完成', '已完成')
)
status = models.CharField('项目状态', choices=status_choices, default='待下达', max_length=50)
number = models.CharField('项目编号', max_length = 100, null=True, blank=True)
auditee = models.ForeignKey(Enterprise, related_name='project_auditee', on_delete=models.DO_NOTHING, verbose_name='受审核方')
auditee_v = JSONField(verbose_name='受审核方', default=dict)
remark = models.TextField('备注', null=True, blank=True)
assign_date = models.DateField('下达日期', null=True, blank=True)
assign_by = models.ForeignKey(User, verbose_name='下达人', on_delete=models.SET_NULL, null=True, blank=True)
can_paichai = models.BooleanField('是否可派差', default = False)
plan = models.ForeignKey(Plan, verbose_name='所属计划', on_delete=models.SET_NULL, null=True, blank=True)
class Meta:
verbose_name = '认证项目'
verbose_name_plural = verbose_name
def __str__(self):
return self.number
class CertApp(CommonBModel):
"""
@ -60,6 +97,7 @@ class CertApp(CommonBModel):
manufacture_v = JSONField(verbose_name='制造商', null=True)
factory = models.ForeignKey(Enterprise, on_delete=models.CASCADE, related_name='certapp_factory', null=True, blank=True)
factory_v = JSONField(verbose_name='生产厂', null=True)
scope = models.TextField('认证范围', null=True, blank=True)
class Meta:
verbose_name = '认证受理'
@ -161,7 +199,9 @@ class Unit(CommonBModel):
"""
name = models.CharField('单元名称', max_length=200)
description = models.TextField('单元描述', blank=True)
unittype = models.ForeignKey(UnitType, verbose_name='单元类型', on_delete = models.SET_NULL, null=True, blank=True)
implementrule = models.ForeignKey(ImplementRule, verbose_name='采用规则', on_delete=models.DO_NOTHING)
unittype = models.ForeignKey(UnitType, verbose_name='单元类型', on_delete = models.DO_NOTHING)
standard = models.ForeignKey(Standard, verbose_name='采用标准', on_delete = models.DO_NOTHING)
certapp = models.ForeignKey(CertApp, verbose_name='所属业务', on_delete = models.CASCADE)
class Meta:
@ -171,3 +211,10 @@ class Unit(CommonBModel):
def __str__(self):
return self.name
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
obj = self.certapp
objs = Unit.objects.filter(certapp=obj, is_deleted=False).values_list('name', flat=True)
obj.scope = obj.factory_v['address'] + ':' + ';'.join(objs)
obj.save()

View File

@ -3,7 +3,7 @@ from rest_framework import serializers
from .models import *
from apps.system.serializers import DictSerializer, UserListSerializer
# from apps.certset.serializers import ImplementRuleSerializer
from apps.certset.serializers import StandardSerializer
class ApplicationCreateSerializer(serializers.ModelSerializer):
number = serializers.CharField(required=False)
@ -46,6 +46,20 @@ class CertappSerializer(serializers.ModelSerializer):
fields = '__all__'
class UnitSerializer(serializers.ModelSerializer):
standard_ = StandardSerializer(source='standard', read_only=True)
class Meta:
model = Unit
fields = '__all__'
fields = '__all__'
class ProjectSerializer(serializers.ModelSerializer):
create_by_ = UserListSerializer(source='create_by', read_only=True)
certapps = serializers.SerializerMethodField()
class Meta:
model = Project
fields = '__all__'
def get_certapps(self, obj):
certapps = []
for i in CertApp.objects.filter(is_deleted=False, project=obj):
certapps.append(i.cert_field.code +'(' + i.cccpv_class.name +')')
return certapps

View File

@ -7,6 +7,7 @@ router.register('application', ApplicationViewSet, basename="application")
router.register('subapplication', SubApplicationViewSet, basename="subapplication")
router.register('certapp', CertappViewset, basename="certapp")
router.register('unit', UnitViewSet, basename="unit")
router.register('project', ProjectViewSet, basename="project")
urlpatterns = [
path('', include(router.urls))
]

View File

@ -10,9 +10,10 @@ from apps.system.models import Dict
from apps.system.permission_data import RbacFilterSet
from apps.system.mixins import CreateUpdateCustomMixin, OptimizationMixin
import random
from rest_framework.decorators import action
from .filters import *
# Create your views here.
class ApplicationViewSet(CreateUpdateCustomMixin, ModelViewSet):
class ApplicationViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
"""
认证申请
"""
@ -30,7 +31,7 @@ class ApplicationViewSet(CreateUpdateCustomMixin, ModelViewSet):
def perform_create(self, serializer):
serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept, number=random.randrange(1000,2000))
class SubApplicationViewSet(CreateUpdateCustomMixin, ModelViewSet):
class SubApplicationViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
"""
子认证申请
"""
@ -61,7 +62,7 @@ class SubApplicationViewSet(CreateUpdateCustomMixin, ModelViewSet):
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
class CertappViewset(CreateUpdateCustomMixin, ModelViewSet):
class CertappViewset(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
"""
申请受理
"""
@ -69,24 +70,75 @@ class CertappViewset(CreateUpdateCustomMixin, ModelViewSet):
queryset = CertApp.objects.all()
serializer_class = CertappSerializer
ordering = ['-create_time']
filterset_fields = ['status', 'project']
# filterset_class = CertAppFilter
def paginate_queryset(self, queryset):
if ((not self.request.query_params.get('page', None)) and (self.request.query_params.get('status', None))) or (self.paginator is None):
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
return queryset
def create(self, request, *args, **kwargs):
postdata = request.data
postdata['number'] = random.randrange(1000,2000)
if postdata.get('field_code', None):
postdata['cert_field'] = Dict.objects.get(code=postdata['field_code']).id
print(postdata)
serializer = self.get_serializer(data=postdata)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
class UnitViewSet(CreateUpdateCustomMixin, ModelViewSet):
@action(methods=['put'], detail=True, perms_map={'put':'complete_certapp'},
url_name='complete_certapp')
def complete(self, request, pk=None):
"""
完成受理
"""
obj = self.get_object()
obj.status = '已受理'
obj.save()
return Response(status=status.HTTP_200_OK)
class UnitViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
"""
产品单元
"""
perms_map = {'get': 'certapp_view', 'post':'certapp_create', 'put':'certapp_update','delete': 'certapp_delete'}
queryset = Unit.objects.all()
serializer_class = UnitSerializer
ordering = ['-create_time']
ordering = ['pk']
filterset_fields = ['certapp']
class ProjectViewSet(CreateUpdateCustomMixin, RbacFilterSet, ModelViewSet):
perms_map = {'get': 'project_view', 'post':'project_create', 'put':'project_update','delete': 'project_delete'}
queryset = Project.objects.all()
serializer_class = ProjectSerializer
ordering = ['pk']
def create(self, request, *args, **kwargs):
postdata = request.data
postdata['number'] = random.randrange(8000,9000)
serializer = self.get_serializer(data=postdata)
serializer.is_valid(raise_exception=True)
instance = serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept)
if 'certapps' in postdata and postdata['certapps']:
CertApp.objects.filter(pk__in = postdata['certapps']).update(project=instance, status='进行中')
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
@action(methods=['put'], detail=True, perms_map={'put':'project_assgin'},
url_name='project_assgin')
def assgin(self, request, pk=None):
"""
下达项目
"""
obj = self.get_object()
if obj.status == '待下达':
obj.status = '待派差'
obj.save()
return Response(status=status.HTTP_200_OK)
else:
return Response('状态有误', status=status.HTTP_400_BAD_REQUEST)

View File

@ -50,9 +50,7 @@ class RbacFilterSet(CreateUpdateModelBMixin, object):
return queryset
elif '仅本人' in data_range:
queryset = queryset.filter(Q(create_by=user)|Q(update_by=user))
return queryset
if hasattr(self.get_serializer_class(), 'setup_eager_loading'):
queryset = self.get_serializer_class().setup_eager_loading(queryset) # 性能优化
return queryset
return queryset