Merge branch 'master' of http://gitea.xxhhcty.xyz:8080/zcdsj/factory
This commit is contained in:
commit
afa3b8b9ad
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.12 on 2026-01-04 06:15
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('ofm', '0004_auto_20251218_1636'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='vehicleuse',
|
||||||
|
name='end_km',
|
||||||
|
field=models.PositiveIntegerField(default=0, verbose_name='归还公里数'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -60,7 +60,7 @@ class VehicleUse(CommonBDModel):
|
||||||
via = models.CharField('途经地点', null=True, blank=True, max_length=100)
|
via = models.CharField('途经地点', null=True, blank=True, max_length=100)
|
||||||
destination = models.CharField('到达地点', null=True, blank=True, max_length=100)
|
destination = models.CharField('到达地点', null=True, blank=True, max_length=100)
|
||||||
start_km = models.PositiveIntegerField('出发公里数', null=True, blank=True)
|
start_km = models.PositiveIntegerField('出发公里数', null=True, blank=True)
|
||||||
end_km = models.PositiveIntegerField('归还公里数')
|
end_km = models.PositiveIntegerField('归还公里数', default=0)
|
||||||
actual_km = models.PositiveIntegerField('实际行驶公里数', editable=False)
|
actual_km = models.PositiveIntegerField('实际行驶公里数', editable=False)
|
||||||
is_city = models.BooleanField('是否市内用车', default=True)
|
is_city = models.BooleanField('是否市内用车', default=True)
|
||||||
reason = models.CharField('用车事由', max_length=100)
|
reason = models.CharField('用车事由', max_length=100)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Generated by Django 3.2.12 on 2025-12-26 07:29
|
||||||
|
|
||||||
|
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),
|
||||||
|
('wf', '0006_auto_20251215_1645'),
|
||||||
|
('pum', '0009_supplieraudit'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='QuotationApply',
|
||||||
|
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='删除标记')),
|
||||||
|
('customer_name', models.CharField(max_length=50, verbose_name='客户名称')),
|
||||||
|
('product_name', models.CharField(max_length=50, verbose_name='产品名称')),
|
||||||
|
('contact_person', models.CharField(max_length=50, verbose_name='联系人')),
|
||||||
|
('contact_phone', models.CharField(blank=True, max_length=20, null=True, verbose_name='联系电话')),
|
||||||
|
('receive_address', models.CharField(blank=True, max_length=100, null=True, verbose_name='收件地址')),
|
||||||
|
('product_spec_quantity', models.TextField(blank=True, null=True, verbose_name='产品规格/数量')),
|
||||||
|
('quotation_basis', models.TextField(blank=True, null=True, verbose_name='报价依据')),
|
||||||
|
('suggested_price_calc', models.TextField(blank=True, null=True, verbose_name='建议价格及计算方式')),
|
||||||
|
('quotation_range', models.CharField(blank=True, max_length=100, null=True, verbose_name='报价区间')),
|
||||||
|
('quoter', models.CharField(blank=True, max_length=50, null=True, verbose_name='报价人')),
|
||||||
|
('apply_date', models.DateField(auto_now_add=True, verbose_name='申请日期')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quotationapply_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('ticket', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='quo_ticket', to='wf.ticket', verbose_name='关联工单')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quotationapply_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -107,3 +107,22 @@ class PuPlanItem(CommonBDModel):
|
||||||
null=True, blank=True, related_name='item_puplan')
|
null=True, blank=True, related_name='item_puplan')
|
||||||
pu_order = models.ForeignKey(PuOrder, verbose_name='关联采购订单',
|
pu_order = models.ForeignKey(PuOrder, verbose_name='关联采购订单',
|
||||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='puplan_item_puorder')
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='puplan_item_puorder')
|
||||||
|
|
||||||
|
|
||||||
|
class QuotationApply(CommonADModel):
|
||||||
|
"""
|
||||||
|
TN:报价申请表
|
||||||
|
"""
|
||||||
|
customer_name = models.CharField(max_length=50,verbose_name="客户名称")
|
||||||
|
product_name = models.CharField(max_length=50,verbose_name="产品名称")
|
||||||
|
contact_person = models.CharField(max_length=50,verbose_name="联系人")
|
||||||
|
contact_phone = models.CharField(max_length=20,verbose_name="联系电话", null=True, blank=True)
|
||||||
|
receive_address = models.CharField(max_length=100,verbose_name="收件地址", null=True, blank=True)
|
||||||
|
product_spec_quantity = models.TextField(verbose_name="产品规格/数量", null=True, blank=True)
|
||||||
|
quotation_basis = models.TextField(verbose_name="报价依据", null=True, blank=True)
|
||||||
|
suggested_price_calc = models.TextField(verbose_name="建议价格及计算方式", null=True, blank=True)
|
||||||
|
quotation_range = models.CharField(max_length=100,verbose_name="报价区间", null=True, blank=True)
|
||||||
|
quoter = models.CharField(max_length=50,verbose_name="报价人", null=True, blank=True)
|
||||||
|
apply_date = models.DateField(verbose_name="申请日期",auto_now_add=True)
|
||||||
|
ticket = models.OneToOneField('wf.ticket', verbose_name='关联工单',
|
||||||
|
on_delete=models.CASCADE, related_name='quo_ticket', null=True, blank=True)
|
||||||
|
|
@ -3,7 +3,7 @@ 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, ParseError
|
from rest_framework.exceptions import ValidationError, ParseError
|
||||||
|
|
||||||
from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem, SupplierAudit
|
from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem, SupplierAudit, QuotationApply
|
||||||
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
|
||||||
|
|
@ -158,3 +158,10 @@ class SupplierAuditSerializer(CustomModelSerializer):
|
||||||
if Supplier.objects.filter(name=name).exists():
|
if Supplier.objects.filter(name=name).exists():
|
||||||
raise ParseError('供应商名称已存在')
|
raise ParseError('供应商名称已存在')
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
class QuotationApplySerializer(CustomModelSerializer):
|
||||||
|
ticket_ = TicketSimpleSerializer(source='ticket', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = QuotationApply
|
||||||
|
fields = "__all__"
|
||||||
|
read_only_fields = EXCLUDE_FIELDS
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
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, SupplierAuditViewSet)
|
from apps.pum.views import (SupplierViewSet, PuPlanViewSet, PuPlanItemViewSet, PuOrderViewSet, PuOrderItemViewSet, SupplierAuditViewSet, QuotationApplyViewSet)
|
||||||
|
# from apps.pum.views import SupplierViewSet, PuPlanViewSet, PuPlanItemViewSet, PuOrderViewSet, PuOrderItemViewSet
|
||||||
|
|
||||||
API_BASE_URL = 'api/pum/'
|
API_BASE_URL = 'api/pum/'
|
||||||
HTML_BASE_URL = 'dhtml/pum/'
|
HTML_BASE_URL = 'dhtml/pum/'
|
||||||
|
|
@ -12,6 +13,7 @@ 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')
|
||||||
router.register('pu_orderitem', PuOrderItemViewSet, basename='pu_orderitem')
|
router.register('pu_orderitem', PuOrderItemViewSet, basename='pu_orderitem')
|
||||||
|
router.register('quotation', QuotationApplyViewSet, basename='quotation')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path(API_BASE_URL, include(router.urls)),
|
path(API_BASE_URL, include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem, SupplierAudit
|
from apps.pum.models import Supplier, PuPlan, PuPlanItem, PuOrder, PuOrderItem, SupplierAudit, QuotationApply
|
||||||
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet, EuModelViewSet
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet, EuModelViewSet
|
||||||
from apps.pum.serializers import (SupplierSerializer, PuPlanSerializer, PuPlanItemSerializer,
|
from apps.pum.serializers import (SupplierSerializer, PuPlanSerializer, PuPlanItemSerializer, QuotationApplySerializer,
|
||||||
PuOrderSerializer, PuOrderItemSerializer, AddSerializer, SupplierAuditSerializer)
|
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
|
||||||
|
|
@ -210,3 +210,16 @@ class PuOrderItemViewSet(CustomModelViewSet):
|
||||||
item.pu_order = puorder
|
item.pu_order = puorder
|
||||||
item.save()
|
item.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
class QuotationApplyViewSet(TicketMixin, CustomModelViewSet):
|
||||||
|
"""
|
||||||
|
list: 报价申请
|
||||||
|
|
||||||
|
报价申请
|
||||||
|
"""
|
||||||
|
queryset = QuotationApply.objects.all()
|
||||||
|
serializer_class = QuotationApplySerializer
|
||||||
|
filterset_fields = ['product_name', 'customer_name','apply_date', 'quoter']
|
||||||
|
search_fields = ['product_name', 'customer_name','contact_person']
|
||||||
|
ordering = ['create_time']
|
||||||
|
workflow_key = "wf_quotation"
|
||||||
Loading…
Reference in New Issue