This commit is contained in:
TianyangZhang 2025-11-10 15:41:38 +08:00
commit 6e5db774b7
8 changed files with 122 additions and 13 deletions

View File

@ -212,11 +212,18 @@ class MIOItemCreateSerializer(CustomModelSerializer):
mio_type = mio.type
if mio_type != "pur_in" and mio_type != "other_in":
wprIds = [i["wpr"].id for i in mioitemw]
mb_ids = list(Wpr.objects.filter(id__in=wprIds).values_list("mb__id", flat=True).distinct())
if len(mb_ids) == 1 and mb_ids[0] == instance.mb.id:
pass
else:
raise ParseError(f'{batch}物料明细中存在{len(mb_ids)}个不同物料批次')
if instance.mb:
mb_ids = list(Wpr.objects.filter(id__in=wprIds).values_list("mb__id", flat=True).distinct())
if len(mb_ids) == 1 and mb_ids[0] == instance.mb.id:
pass
else:
raise ParseError(f'{batch}物料明细中存在{len(mb_ids)}个不同物料批次')
elif instance.wm:
wm_ids = list(Wpr.objects.filter(id__in=wprIds).values_list("wm__id", flat=True).distinct())
if len(wm_ids) == 1 and wm_ids[0] == instance.wm.id:
pass
else:
raise ParseError(f'{batch}物料明细中存在{len(wm_ids)}个不同物料批次')
for item in mioitemw:
if item.get("wpr", None) is None and mio_type != "pur_in" and mio_type != "other_in":
raise ParseError(f'{item["number"]}_请提供产品明细ID')

View File

@ -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,
},
),
]

View File

@ -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):
"""

View File

@ -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__"

View File

@ -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()

View File

@ -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')

View File

@ -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):
"""

View File

@ -91,6 +91,12 @@ class BulkCreateModelMixin(CreateModelMixin):
rdata = request.data
many = False
if isinstance(rdata, list):
for item in rdata:
if "id" in item and item["id"]:
raise ParseError('创建数据中不能包含id字段')
else:
if "id" in rdata and rdata["id"]:
raise ParseError('创建数据中不能包含id字段')
many = True
sr = self.get_serializer(data=rdata, many=many)
sr.is_valid(raise_exception=True)