Merge branch 'master' of http://gitea.xxhhcty.xyz:8080/zcdsj/factory
This commit is contained in:
commit
6e5db774b7
|
|
@ -212,11 +212,18 @@ class MIOItemCreateSerializer(CustomModelSerializer):
|
||||||
mio_type = mio.type
|
mio_type = mio.type
|
||||||
if mio_type != "pur_in" and mio_type != "other_in":
|
if mio_type != "pur_in" and mio_type != "other_in":
|
||||||
wprIds = [i["wpr"].id for i in mioitemw]
|
wprIds = [i["wpr"].id for i in mioitemw]
|
||||||
|
if instance.mb:
|
||||||
mb_ids = list(Wpr.objects.filter(id__in=wprIds).values_list("mb__id", flat=True).distinct())
|
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:
|
if len(mb_ids) == 1 and mb_ids[0] == instance.mb.id:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise ParseError(f'{batch}物料明细中存在{len(mb_ids)}个不同物料批次')
|
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:
|
for item in mioitemw:
|
||||||
if item.get("wpr", None) is None and mio_type != "pur_in" and mio_type != "other_in":
|
if item.get("wpr", None) is None and mio_type != "pur_in" and mio_type != "other_in":
|
||||||
raise ParseError(f'{item["number"]}_请提供产品明细ID')
|
raise ParseError(f'{item["number"]}_请提供产品明细ID')
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
from django.db import models
|
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.mtm.models import Material
|
||||||
|
from apps.wf.models import Ticket
|
||||||
|
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
@ -15,6 +16,15 @@ class Supplier(CommonBModel):
|
||||||
address = models.CharField('地址', max_length=200, default='', blank=True)
|
address = models.CharField('地址', max_length=200, default='', blank=True)
|
||||||
can_outsource = models.BooleanField('是否可外协', default=False)
|
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):
|
class PuPlan(CommonBModel):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,12 @@ from apps.utils.serializers import CustomModelSerializer
|
||||||
from apps.utils.constants import EXCLUDE_FIELDS_DEPT, EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS
|
from apps.utils.constants import EXCLUDE_FIELDS_DEPT, EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS
|
||||||
from rest_framework.exceptions import ValidationError
|
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 apps.mtm.serializers import MaterialSerializer, MaterialSimpleSerializer
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from .services import PumService
|
from .services import PumService
|
||||||
|
from apps.wf.serializers import TicketSimpleSerializer
|
||||||
|
from apps.system.serializers import FileSerializer
|
||||||
|
|
||||||
|
|
||||||
class SupplierSerializer(CustomModelSerializer):
|
class SupplierSerializer(CustomModelSerializer):
|
||||||
|
|
@ -139,3 +141,13 @@ class AddSerializer(serializers.Serializer):
|
||||||
label='采购订单ID', queryset=PuOrder.objects.all())
|
label='采购订单ID', queryset=PuOrder.objects.all())
|
||||||
pu_planitems = serializers.PrimaryKeyRelatedField(
|
pu_planitems = serializers.PrimaryKeyRelatedField(
|
||||||
label='计划明细ID', queryset=PuPlanItem.objects.all(), many=True)
|
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__"
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
from rest_framework.exceptions import ValidationError
|
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 django.db.models import F, Sum
|
||||||
from apps.inm.models import MIO, MIOItem
|
from apps.inm.models import MIO, MIOItem
|
||||||
from rest_framework.exceptions import ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
|
from apps.wf.models import Ticket, Transition
|
||||||
|
|
||||||
class PumService:
|
class PumService:
|
||||||
|
|
||||||
|
|
@ -95,3 +95,18 @@ class PumService:
|
||||||
puplan.state = PuPlan.PUPLAN_DONE
|
puplan.state = PuPlan.PUPLAN_DONE
|
||||||
puplan.save()
|
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()
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
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/'
|
API_BASE_URL = 'api/pum/'
|
||||||
HTML_BASE_URL = 'dhtml/pum/'
|
HTML_BASE_URL = 'dhtml/pum/'
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register('supplier', SupplierViewSet, basename='supplier')
|
router.register('supplier', SupplierViewSet, basename='supplier')
|
||||||
|
router.register('supplieraudit', SupplierAuditViewSet, basename='supplieraudit')
|
||||||
router.register('pu_plan', PuPlanViewSet, basename='pu_plan')
|
router.register('pu_plan', PuPlanViewSet, basename='pu_plan')
|
||||||
router.register('pu_planitem', PuPlanItemViewSet, basename='pu_planitem')
|
router.register('pu_planitem', PuPlanItemViewSet, basename='pu_planitem')
|
||||||
router.register('pu_order', PuOrderViewSet, basename='pu_order')
|
router.register('pu_order', PuOrderViewSet, basename='pu_order')
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem
|
from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem, SupplierAudit
|
||||||
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet, EuModelViewSet
|
||||||
from apps.pum.serializers import (SupplierSerializer, PuPlanSerializer, PuPlanItemSerializer,
|
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.exceptions import ParseError, PermissionDenied
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
@ -11,6 +11,7 @@ from django.db import transaction
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from apps.pum.services import PumService
|
from apps.pum.services import PumService
|
||||||
|
from apps.wf.models import Ticket
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,6 +31,23 @@ class SupplierViewSet(CustomModelViewSet):
|
||||||
raise ParseError('该供应商存在采购订单不可删除')
|
raise ParseError('该供应商存在采购订单不可删除')
|
||||||
instance.delete()
|
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):
|
class PuPlanViewSet(CustomModelViewSet):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,12 @@ class BulkCreateModelMixin(CreateModelMixin):
|
||||||
rdata = request.data
|
rdata = request.data
|
||||||
many = False
|
many = False
|
||||||
if isinstance(rdata, list):
|
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
|
many = True
|
||||||
sr = self.get_serializer(data=rdata, many=many)
|
sr = self.get_serializer(data=rdata, many=many)
|
||||||
sr.is_valid(raise_exception=True)
|
sr.is_valid(raise_exception=True)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue