From 32b39ee423be399517dca4cba4a5a143e776ca1d Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 10 Nov 2025 14:03:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=BE=9B=E5=BA=94?= =?UTF-8?q?=E5=95=86=E5=AE=A1=E6=A0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/pum/migrations/0009_supplieraudit.py | 40 +++++++++++++++++++++++ apps/pum/models.py | 12 ++++++- apps/pum/serializers.py | 14 +++++++- apps/pum/services.py | 19 +++++++++-- apps/pum/urls.py | 3 +- apps/pum/views.py | 24 ++++++++++++-- 6 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 apps/pum/migrations/0009_supplieraudit.py diff --git a/apps/pum/migrations/0009_supplieraudit.py b/apps/pum/migrations/0009_supplieraudit.py new file mode 100644 index 00000000..a702aac4 --- /dev/null +++ b/apps/pum/migrations/0009_supplieraudit.py @@ -0,0 +1,40 @@ +# Generated by Django 3.2.12 on 2025-11-10 02:00 + +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', '0006_auto_20241213_1249'), + ('wf', '0004_workflow_view_path2'), + ('pum', '0008_auto_20240731_1829'), + ] + + operations = [ + migrations.CreateModel( + name='SupplierAudit', + fields=[ + ('id', models.CharField(editable=False, help_text='主键ID', max_length=20, 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=100, verbose_name='供应商名称')), + ('material_name', models.CharField(max_length=100, verbose_name='物料名称')), + ('material_cate', models.CharField(max_length=100, verbose_name='物料类别')), + ('business_license', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='supplier_audit_business_license', to='system.file', verbose_name='营业执照')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='supplieraudit_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('quality_certificate', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='supplier_audit_quality_certificate', to='system.file', verbose_name='质量证书')), + ('survery_form', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='supplier_audit_survey_form', to='system.file', verbose_name='调查表')), + ('ticket', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='wf.ticket', verbose_name='关联工单')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='supplieraudit_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/apps/pum/models.py b/apps/pum/models.py index d27071c4..1515a4a1 100644 --- a/apps/pum/models.py +++ b/apps/pum/models.py @@ -1,6 +1,7 @@ from django.db import models -from apps.utils.models import CommonBModel, BaseModel, CommonBDModel +from apps.utils.models import CommonBModel, BaseModel, CommonBDModel, CommonADModel from apps.mtm.models import Material +from apps.wf.models import Ticket # Create your models here. @@ -15,6 +16,15 @@ class Supplier(CommonBModel): address = models.CharField('地址', max_length=200, default='', blank=True) can_outsource = models.BooleanField('是否可外协', default=False) +class SupplierAudit(CommonADModel): + name = models.CharField('供应商名称', max_length=100) + material_name = models.CharField('物料名称', max_length=100) + material_cate = models.CharField('物料类别', max_length=100) + survery_form = models.ForeignKey('system.file', verbose_name='调查表', on_delete=models.SET_NULL, null=True, blank=True, related_name='supplier_audit_survey_form') + business_license = models.ForeignKey('system.file', verbose_name='营业执照', on_delete=models.SET_NULL, null=True, blank=True, related_name='supplier_audit_business_license') + quality_certificate = models.ForeignKey('system.file', verbose_name='质量证书', on_delete=models.SET_NULL, null=True, blank=True, related_name='supplier_audit_quality_certificate') + ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.SET_NULL, null=True, blank=True) + class PuPlan(CommonBModel): """ diff --git a/apps/pum/serializers.py b/apps/pum/serializers.py index 690395f3..954e16c6 100644 --- a/apps/pum/serializers.py +++ b/apps/pum/serializers.py @@ -3,10 +3,12 @@ from apps.utils.serializers import CustomModelSerializer from apps.utils.constants import EXCLUDE_FIELDS_DEPT, EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS from rest_framework.exceptions import ValidationError -from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem +from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem, SupplierAudit from apps.mtm.serializers import MaterialSerializer, MaterialSimpleSerializer from django.db import transaction from .services import PumService +from apps.wf.serializers import TicketSimpleSerializer +from apps.system.serializers import FileSerializer class SupplierSerializer(CustomModelSerializer): @@ -139,3 +141,13 @@ class AddSerializer(serializers.Serializer): label='采购订单ID', queryset=PuOrder.objects.all()) pu_planitems = serializers.PrimaryKeyRelatedField( label='计划明细ID', queryset=PuPlanItem.objects.all(), many=True) + + +class SupplierAuditSerializer(CustomModelSerializer): + survery_form_ = FileSerializer(source="survery_form", read_only=True) + business_license_ = FileSerializer(source="business_license", read_only=True) + quality_certificate_ = FileSerializer(source="quality_certificate", read_only=True) + ticket_ = TicketSimpleSerializer(source="ticket", read_only=True) + class Meta: + model = SupplierAudit + fields = "__all__" \ No newline at end of file diff --git a/apps/pum/services.py b/apps/pum/services.py index c4954537..fe9fa318 100644 --- a/apps/pum/services.py +++ b/apps/pum/services.py @@ -1,9 +1,9 @@ from rest_framework.exceptions import ValidationError -from apps.pum.models import PuOrderItem, PuPlan, PuPlanItem, PuOrder +from apps.pum.models import PuOrderItem, PuPlan, PuPlanItem, PuOrder, SupplierAudit from django.db.models import F, Sum from apps.inm.models import MIO, MIOItem from rest_framework.exceptions import ParseError - +from apps.wf.models import Ticket, Transition class PumService: @@ -95,3 +95,18 @@ class PumService: puplan.state = PuPlan.PUPLAN_DONE puplan.save() +def bind_supplieraudit(ticket: Ticket, transition: Transition, new_ticket_data: dict): + ins = SupplierAudit.objects.get(id=new_ticket_data['t_id']) + if ins.ticket and ins.ticket.id != ticket.id: + raise ParseError('重复创建工单') + ticket_data = ticket.ticket_data + ticket_data.update({ + 't_model': 'supplier_audit', + 't_id': ins.id, + }) + ticket.ticket_data = ticket_data + ticket.create_by = ins.create_by + ticket.save() + if ins.ticket is None: + ins.ticket = ticket + ins.save() \ No newline at end of file diff --git a/apps/pum/urls.py b/apps/pum/urls.py index 79db9a60..5032da70 100644 --- a/apps/pum/urls.py +++ b/apps/pum/urls.py @@ -1,12 +1,13 @@ from django.urls import path, include from rest_framework.routers import DefaultRouter -from apps.pum.views import (SupplierViewSet, PuPlanViewSet, PuPlanItemViewSet, PuOrderViewSet, PuOrderItemViewSet) +from apps.pum.views import (SupplierViewSet, PuPlanViewSet, PuPlanItemViewSet, PuOrderViewSet, PuOrderItemViewSet, SupplierAuditViewSet) API_BASE_URL = 'api/pum/' HTML_BASE_URL = 'dhtml/pum/' router = DefaultRouter() router.register('supplier', SupplierViewSet, basename='supplier') +router.register('supplieraudit', SupplierAuditViewSet, basename='supplieraudit') router.register('pu_plan', PuPlanViewSet, basename='pu_plan') router.register('pu_planitem', PuPlanItemViewSet, basename='pu_planitem') router.register('pu_order', PuOrderViewSet, basename='pu_order') diff --git a/apps/pum/views.py b/apps/pum/views.py index f06ee5f2..ec668a0b 100644 --- a/apps/pum/views.py +++ b/apps/pum/views.py @@ -1,8 +1,8 @@ from django.shortcuts import render -from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem -from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet +from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem, SupplierAudit +from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet, EuModelViewSet from apps.pum.serializers import (SupplierSerializer, PuPlanSerializer, PuPlanItemSerializer, - PuOrderSerializer, PuOrderItemSerializer, AddSerializer) + PuOrderSerializer, PuOrderItemSerializer, AddSerializer, SupplierAuditSerializer) from rest_framework.exceptions import ParseError, PermissionDenied from rest_framework.decorators import action from rest_framework import serializers @@ -11,6 +11,7 @@ from django.db import transaction from rest_framework.response import Response from django.utils import timezone from apps.pum.services import PumService +from apps.wf.models import Ticket # Create your views here. @@ -30,6 +31,23 @@ class SupplierViewSet(CustomModelViewSet): raise ParseError('该供应商存在采购订单不可删除') instance.delete() +class SupplierAuditViewSet(CustomModelViewSet): + """ + list: 供应商审核 + + 供应商审核 + """ + queryset = SupplierAudit.objects.all() + serializer_class = SupplierAuditSerializer + search_fields = ['name', 'material_name', 'material_cate'] + + def perform_destroy(self, instance): + ticket:Ticket = instance.ticket + if ticket and ticket.state.type != 1: + raise ParseError('该记录关联的工单已被处理,不可删除') + instance.delete() + if ticket: + ticket.delete() class PuPlanViewSet(CustomModelViewSet): """