diff --git a/server/apps/certset/apps.py b/server/apps/certset/apps.py index 4ff05bc..ac08dcc 100644 --- a/server/apps/certset/apps.py +++ b/server/apps/certset/apps.py @@ -3,3 +3,4 @@ from django.apps import AppConfig class CertsetConfig(AppConfig): name = 'certset' + verbose_name = '认证配置' diff --git a/server/apps/certset/migrations/0010_auto_20200731_1418.py b/server/apps/certset/migrations/0010_auto_20200731_1418.py new file mode 100644 index 0000000..09e78bf --- /dev/null +++ b/server/apps/certset/migrations/0010_auto_20200731_1418.py @@ -0,0 +1,44 @@ +# Generated by Django 3.0.7 on 2020-07-31 06:18 + +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 = [ + ('system', '0024_auto_20200716_0927'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('certset', '0009_auto_20200709_1522'), + ] + + operations = [ + migrations.AlterField( + model_name='implementrule', + name='ccc_list', + field=models.ManyToManyField(blank=True, related_name='implementrule_ccc_list', to='system.Dict', verbose_name='CCC产品分类'), + ), + migrations.AlterField( + model_name='implementrule', + name='pv_scope', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='implementrule_pv_scope', to='system.Dict', verbose_name='自愿性产品认证专业范围'), + ), + migrations.CreateModel( + name='EvaluationItem', + 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='删除标记')), + ('content', models.TextField(blank=True, verbose_name='内容')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='evaluationitem_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='evaluationitem_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'verbose_name': '评审表项目', + 'verbose_name_plural': '评审表项目', + }, + ), + ] diff --git a/server/apps/certset/models.py b/server/apps/certset/models.py index 65e6f34..3645c69 100644 --- a/server/apps/certset/models.py +++ b/server/apps/certset/models.py @@ -60,23 +60,8 @@ class UnitType(CommonAModel): def __str__(self): return self.name -class EvaluationSheet(CommonAModel): - """ - 评审表 - """ - cert_field = models.ForeignKey(Dict, verbose_name='涉及认证领域', related_name='application_cert_field', on_delete=models.CASCADE) - major = models.ManyToManyField(Dict, verbose_name='涉及CCC/pv/cnas分类', related_name='application_major') - is_default = models.BooleanField('是否该领域默认', default=False) - class Meta: - verbose_name = '评审表' - verbose_name_plural = verbose_name - - def __str__(self): - return self.name - class EvaluationItem(CommonAModel): content = models.TextField('内容', blank=True) - sheet = models.ForeignKey(EvaluationSheet, verbose_name='所属评审表', on_delete=models.CASCADE) class Meta: verbose_name = '评审表项目' verbose_name_plural = verbose_name diff --git a/server/apps/crm/apps.py b/server/apps/crm/apps.py index d6f91d2..3c8ba1b 100644 --- a/server/apps/crm/apps.py +++ b/server/apps/crm/apps.py @@ -3,3 +3,4 @@ from django.apps import AppConfig class CrmConfig(AppConfig): name = 'crm' + verbose_name = '客户管理' diff --git a/server/apps/project/apps.py b/server/apps/project/apps.py index 2c64289..f309dfa 100644 --- a/server/apps/project/apps.py +++ b/server/apps/project/apps.py @@ -3,3 +3,4 @@ from django.apps import AppConfig class ProjectConfig(AppConfig): name = 'project' + verbose_name = '认证项目' diff --git a/server/apps/project/migrations/0001_initial.py b/server/apps/project/migrations/0001_initial.py new file mode 100644 index 0000000..caf249e --- /dev/null +++ b/server/apps/project/migrations/0001_initial.py @@ -0,0 +1,147 @@ +# Generated by Django 3.0.7 on 2020-07-31 06:48 + +from django.conf import settings +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('system', '0024_auto_20200716_0927'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('crm', '0009_remove_enterpriseaddress_provincecode'), + ('certset', '0010_auto_20200731_1418'), + ] + + operations = [ + migrations.CreateModel( + name='Application', + 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='删除标记')), + ('number', models.CharField(max_length=100, verbose_name='申请编号')), + ('apply_date', models.DateField(blank=True, null=True, verbose_name='申请日期')), + ('accept_date', models.DateField(blank=True, null=True, verbose_name='受理日期')), + ('applicant_v', django.contrib.postgres.fields.jsonb.JSONField(verbose_name='申请方')), + ('manufacturer_v', django.contrib.postgres.fields.jsonb.JSONField(blank=True, verbose_name='制造商')), + ('factory_v', django.contrib.postgres.fields.jsonb.JSONField(blank=True, verbose_name='生产厂')), + ('status', models.CharField(choices=[('草稿', '草稿'), ('已申请', '已申请'), ('已受理', '已受理'), ('进行中', '进行中'), ('已中止', '已中止'), ('已完成', '已完成')], default='草稿', max_length=50, verbose_name='申请状态')), + ('evresult', models.CharField(choices=[('合格', '合格'), ('不合格', '不合格'), ('有条件放行', '有条件放行')], default='合格', max_length=50, verbose_name='评审结论')), + ('evremark', models.TextField(blank=True, verbose_name='备注')), + ('applicant', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='application_applicant', to='crm.Enterprise')), + ('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='application_belong_dept', to='system.Organization', verbose_name='所属部门')), + ('cert_field', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='application_cert_field', to='system.Dict', verbose_name='认证领域')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='application_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ], + options={ + 'verbose_name': '认证主申请', + 'verbose_name_plural': '认证主申请', + }, + ), + migrations.CreateModel( + name='Project', + 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='删除标记')), + ('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='project_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='project_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='project_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Unit', + 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='删除标记')), + ('factory_v', django.contrib.postgres.fields.jsonb.JSONField(blank=True, verbose_name='生产厂')), + ('name', models.CharField(max_length=200, verbose_name='单元名称')), + ('description', models.TextField(blank=True, verbose_name='单元描述')), + ('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='unit_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='unit_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('factory', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='crm.Enterprise')), + ('subapplication', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='project.Application', verbose_name='所属子申请')), + ('unittype', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='certset.UnitType', verbose_name='单元类型')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='unit_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'verbose_name': '认证单元', + 'verbose_name_plural': '认证单元', + }, + ), + migrations.CreateModel( + name='SubApplication', + 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='删除标记')), + ('number', models.CharField(max_length=100, verbose_name='子申请编号')), + ('application', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subapplication_application', to='project.Application')), + ('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subapplication_belong_dept', to='system.Organization', verbose_name='所属部门')), + ('cccpv_class', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='subapplication_cccpv_class', to='system.Dict', verbose_name='涉及CCC/PV分类')), + ('cert_field', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='subapplication_cert_field', to='system.Dict', verbose_name='认证领域')), + ('cnas_scopes', models.ManyToManyField(related_name='subapplication_cnas_sopes', to='system.Dict', verbose_name='涉及cnas分类')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subapplication_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('project', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subapplication_project', to='project.Project')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subapplication_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'verbose_name': '认证子申请', + 'verbose_name_plural': '认证子申请', + }, + ), + migrations.CreateModel( + name='EvaluationDetail', + 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='删除标记')), + ('result', models.CharField(choices=[('符合', '符合'), ('不符合', '不符合'), ('不适用', '不适用'), ('需说明', '需说明')], default='符合', max_length=50, verbose_name='评审结果')), + ('remark', models.TextField(blank=True, verbose_name='备注')), + ('application', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='project.Application')), + ('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='evaluationdetail_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='evaluationdetail_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='certset.EvaluationItem', verbose_name='项目内容')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='evaluationdetail_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'verbose_name': '评审记录详情', + 'verbose_name_plural': '评审记录详情', + }, + ), + migrations.AddField( + model_name='application', + name='evdetail', + field=models.ManyToManyField(through='project.EvaluationDetail', to='certset.EvaluationItem', verbose_name='评审详细记录'), + ), + migrations.AddField( + model_name='application', + name='factory', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='application_factory', to='crm.Enterprise'), + ), + migrations.AddField( + model_name='application', + name='manufacturer', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='application_manufacturer', to='crm.Enterprise'), + ), + migrations.AddField( + model_name='application', + name='update_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='application_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'), + ), + ] diff --git a/server/apps/project/models.py b/server/apps/project/models.py index 5ac50a2..ebba3c2 100644 --- a/server/apps/project/models.py +++ b/server/apps/project/models.py @@ -1,18 +1,24 @@ -from django.db import models -from apps.system.models import CommonAModel, Dict, User, CommonBModel -from apps.certset.models import ImplementRule -from simple_history.models import HistoricalRecords -from rest_framework.exceptions import ParseError -from apps.crm.models import Enterprise +from utils import model from django.contrib.postgres.fields import JSONField +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.crm.models import Enterprise +from apps.system.models import CommonAModel, CommonBModel, Dict, User + # Create your models here. class Project(CommonBModel): + """ + 认证项目 + """ pass - + class Application(CommonBModel): """ - 认证申请 + 主申请 """ status_choices = ( ('草稿', '草稿'), @@ -22,25 +28,86 @@ class Application(CommonBModel): ('已中止', '已中止'), ('已完成', '已完成') ) - number = models.CharField('项目申请编号', max_length = 50) - cert_field = models.ForeignKey(Dict, verbose_name='认证领域', related_name='application_cert_field') - major = models.ForeignKey(Dict, verbose_name='涉及CCC/pv/cnas分类', related_name='application_major') - applicant = JSONField(verbose_name='申请方') + result_choices = ( + ('合格', '合格'), + ('不合格', '不合格'), + ('有条件放行', '有条件放行') + ) + number = models.CharField('申请编号', max_length = 100) apply_date = models.DateField('申请日期', null=True, blank=True) accept_date = models.DateField('受理日期', null=True, blank=True) - manufacturer = JSONField(verbose_name='制造商', blank=True) - factory = JSONField(verbose_name='生产厂', blank=True) - project = models.ForeignKey('归属项目', null=True, blank=True) + + applicant_v = JSONField(verbose_name='申请方') + applicant = models.ForeignKey(Enterprise, related_name='application_applicant', on_delete=models.DO_NOTHING) + manufacturer_v = JSONField(verbose_name='制造商', blank=True) + manufacturer = models.ForeignKey(Enterprise, related_name='application_manufacturer', on_delete=models.SET_NULL, null=True, blank=True) + factory_v = JSONField(verbose_name='生产厂', blank=True) + factory = models.ForeignKey(Enterprise, related_name='application_factory', on_delete=models.SET_NULL, null=True, blank=True) + cert_field = models.ForeignKey(Dict, verbose_name='认证领域', related_name='application_cert_field', on_delete=models.SET_NULL, null=True) + status = models.CharField('申请状态', choices=status_choices, default='草稿', max_length=50) + evdetail = models.ManyToManyField(EvaluationItem, verbose_name='评审详细记录', through='EvaluationDetail') + evresult = models.CharField('评审结论', choices = result_choices, default='合格', max_length=50) + evremark = models.TextField('备注', blank=True) class Meta: - verbose_name = '认证申请' + verbose_name = '认证主申请' verbose_name_plural = verbose_name def __str__(self): return self.number +class SubApplication(CommonBModel): + """ + 子申请 + """ + number = models.CharField('子申请编号', max_length = 100) + application = models.ForeignKey(Application, on_delete=models.CASCADE, related_name='subapplication_application') + cert_field = models.ForeignKey(Dict, verbose_name='认证领域', related_name='subapplication_cert_field', on_delete=models.DO_NOTHING) + cccpv_class = models.ForeignKey(Dict, verbose_name='涉及CCC/PV分类', related_name='subapplication_cccpv_class', on_delete=models.DO_NOTHING) + cnas_scopes = models.ManyToManyField(Dict, verbose_name='涉及cnas分类', related_name='subapplication_cnas_sopes') + project = models.ForeignKey(Project, related_name='subapplication_project', on_delete=models.SET_NULL, null=True) + + class Meta: + verbose_name = '认证子申请' + verbose_name_plural = verbose_name + + def __str__(self): + return self.number + +class EvaluationDetail(CommonBModel): + result_choices = ( + ('符合', '符合'), + ('不符合', '不符合'), + ('不适用', '不适用'), + ('需说明', '需说明') + ) + application = models.ForeignKey(Application, on_delete=models.CASCADE) + item = models.ForeignKey(EvaluationItem, verbose_name='项目内容', on_delete=models.DO_NOTHING) + result = models.CharField('评审结果',choices = result_choices, default='符合', max_length=50) + remark = models.TextField('备注', blank=True) + + class Meta: + verbose_name = '评审记录详情' + verbose_name_plural = verbose_name + + def __str__(self): + return self.application.number + class Unit(CommonBModel): """ - 认证单元 + 认证单元,一个单元一张证书 """ - pass + factory = models.ForeignKey(Enterprise, on_delete=models.DO_NOTHING) + factory_v = JSONField(verbose_name='生产厂', blank=True) + 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) + subapplication = models.ForeignKey(Application, verbose_name='所属子申请', on_delete = models.CASCADE) + + class Meta: + verbose_name = '认证单元' + verbose_name_plural = verbose_name + + def __str__(self): + return self.name + diff --git a/server/server/settings.py b/server/server/settings.py index 19d91a1..29989cc 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -47,7 +47,8 @@ INSTALLED_APPS = [ 'apps.system', 'apps.crm', 'apps.certset', - 'apps.employee' + 'apps.employee', + 'apps.project' ] MIDDLEWARE = [