From ce48b8e97ccdb3f9ac551c0c04b3313cb3baf208 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 8 Oct 2021 15:32:06 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E5=BE=85=E6=8E=92=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/mtm/models.py | 2 +- hb_server/apps/pm/__init__.py | 0 hb_server/apps/pm/admin.py | 3 ++ hb_server/apps/pm/apps.py | 7 ++++ hb_server/apps/pm/models.py | 30 +++++++++++++++++ hb_server/apps/pm/serializers.py | 50 +++++++++++++++++++++++++++ hb_server/apps/pm/tests.py | 3 ++ hb_server/apps/pm/urls.py | 15 +++++++++ hb_server/apps/pm/views.py | 58 ++++++++++++++++++++++++++++++++ hb_server/apps/sam/models.py | 1 + hb_server/apps/sam/views.py | 16 +++++++-- 11 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 hb_server/apps/pm/__init__.py create mode 100644 hb_server/apps/pm/admin.py create mode 100644 hb_server/apps/pm/apps.py create mode 100644 hb_server/apps/pm/models.py create mode 100644 hb_server/apps/pm/serializers.py create mode 100644 hb_server/apps/pm/tests.py create mode 100644 hb_server/apps/pm/urls.py create mode 100644 hb_server/apps/pm/views.py diff --git a/hb_server/apps/mtm/models.py b/hb_server/apps/mtm/models.py index 6fca06f..36f2c04 100644 --- a/hb_server/apps/mtm/models.py +++ b/hb_server/apps/mtm/models.py @@ -129,7 +129,7 @@ class RecordFormField(CommonAModel): class ProductProcess(CommonAModel): """ - 产品生产工艺 + 产品生产工艺集 """ product = models.ForeignKey(Material, verbose_name='产品', on_delete=models.CASCADE) process = models.ForeignKey(Process, verbose_name='工序', on_delete=models.CASCADE) diff --git a/hb_server/apps/pm/__init__.py b/hb_server/apps/pm/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hb_server/apps/pm/admin.py b/hb_server/apps/pm/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/hb_server/apps/pm/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/hb_server/apps/pm/apps.py b/hb_server/apps/pm/apps.py new file mode 100644 index 0000000..c0c4b31 --- /dev/null +++ b/hb_server/apps/pm/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + +class SamConfig(AppConfig): + name = 'apps.pm' + verbose_name = '生产计划管理' + + diff --git a/hb_server/apps/pm/models.py b/hb_server/apps/pm/models.py new file mode 100644 index 0000000..ec6c77f --- /dev/null +++ b/hb_server/apps/pm/models.py @@ -0,0 +1,30 @@ +from apps.system.models import CommonAModel +from django.db import models +from django.contrib.auth.models import AbstractUser +from django.db.models.base import Model +import django.utils.timezone as timezone +from django.db.models.query import QuerySet + +from utils.model import SoftModel, BaseModel +from apps.mtm.models import Material +from apps.sam.models import Order + + +class ProductionPlan(CommonAModel): + """ + 生产计划 + """ + number = models.CharField('编号', max_length=50, unique=True) + order = models.ForeignKey(Order, verbose_name='关联订单', null=True, blank=True, on_delete=models.SET_NULL) + product = models.ForeignKey(Material, verbose_name='生产产品', on_delete=models.CASCADE) + count = models.IntegerField('生产数量', default=0) + start_date = models.DateField('计划开工日期') + end_date = models.DateField('计划完工日期') + + class Meta: + verbose_name = '生产计划' + verbose_name_plural = verbose_name + + def __str__(self): + return self.number + diff --git a/hb_server/apps/pm/serializers.py b/hb_server/apps/pm/serializers.py new file mode 100644 index 0000000..00efa54 --- /dev/null +++ b/hb_server/apps/pm/serializers.py @@ -0,0 +1,50 @@ +from rest_framework import serializers + +from .models import Contract, Customer, Order + +from apps.mtm.serializers import MaterialSimpleSerializer + +class CustomerSerializer(serializers.ModelSerializer): + class Meta: + model = Customer + fields = '__all__' + +class CustomerCreateUpdateSerializer(serializers.ModelSerializer): + class Meta: + model = Customer + fields = ['name', 'address', 'contact', 'contact_phone', 'description'] + +class CustomerSimpleSerializer(serializers.ModelSerializer): + class Meta: + model = Customer + fields = ['id', 'name'] + +class ContractSerializer(serializers.ModelSerializer): + customer_ = CustomerSimpleSerializer(source='customer', read_only=True) + class Meta: + model = Contract + fields = '__all__' + +class ContractSimpleSerializer(serializers.ModelSerializer): + class Meta: + model = Contract + fields = ['id', 'name', 'number'] + +class ContractCreateUpdateSerializer(serializers.ModelSerializer): + class Meta: + model = Contract + fields = ['name', 'number', 'amount', 'customer', 'sign_date', 'description'] + + +class OrderCreateUpdateSerializer(serializers.ModelSerializer): + class Meta: + model = Order + fields = ['number', 'customer', 'contract', 'product', 'count', 'delivery_date'] + +class OrderSerializer(serializers.ModelSerializer): + contract_ = ContractSimpleSerializer(source='contract', read_only=True) + customer_ = CustomerSimpleSerializer(source='customer', read_only=True) + product_ = MaterialSimpleSerializer(source='product', read_only=True) + class Meta: + model = Order + fields = '__all__' diff --git a/hb_server/apps/pm/tests.py b/hb_server/apps/pm/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/hb_server/apps/pm/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/hb_server/apps/pm/urls.py b/hb_server/apps/pm/urls.py new file mode 100644 index 0000000..4aa607f --- /dev/null +++ b/hb_server/apps/pm/urls.py @@ -0,0 +1,15 @@ +from django.db.models import base +from rest_framework import urlpatterns +from apps.sam.views import CustomerViewSet,ContractViewSet,OrderViewSet +from django.urls import path, include +from rest_framework.routers import DefaultRouter + +router = DefaultRouter() +router.register('customer', CustomerViewSet, basename='customer') +router.register('contract', ContractViewSet, basename='contract') +router.register('order', OrderViewSet, basename='order') + +urlpatterns = [ + path('', include(router.urls)), +] + diff --git a/hb_server/apps/pm/views.py b/hb_server/apps/pm/views.py new file mode 100644 index 0000000..8f66873 --- /dev/null +++ b/hb_server/apps/pm/views.py @@ -0,0 +1,58 @@ +from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer +from apps.sam.models import Contract, Customer, Order +from rest_framework.viewsets import ModelViewSet +from apps.system.mixins import CreateUpdateCustomMixin +from django.shortcuts import render + +# Create your views here. +class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet): + """ + 客户-增删改查 + """ + perms_map = {'*': '*'} + queryset = Customer.objects.all() + serializer_class = CustomerSerializer + search_fields = ['name', 'contact'] + filterset_fields = [] + ordering_fields = ['create_time'] + ordering = ['-create_time'] + + def get_serializer_class(self): + if self.action in ['create', 'update']: + return CustomerCreateUpdateSerializer + return CustomerSerializer + + +class ContractViewSet(CreateUpdateCustomMixin, ModelViewSet): + """ + 合同-增删改查 + """ + perms_map = {'*': '*'} + queryset = Contract.objects.select_related('customer').all() + serializer_class = ContractSerializer + search_fields = ['name'] + filterset_fields = [] + ordering_fields = ['create_time'] + ordering = ['-create_time'] + + def get_serializer_class(self): + if self.action in ['create', 'update']: + return ContractCreateUpdateSerializer + return ContractSerializer + +class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet): + """ + 订单-增删改查 + """ + perms_map = {'*': '*'} + queryset = Order.objects.select_related('contract', 'customer').all() + serializer_class = OrderSerializer + search_fields = ['number', 'product'] + filterset_fields = [] + ordering_fields = ['create_time'] + ordering = ['-create_time'] + + def get_serializer_class(self): + if self.action in ['create', 'update']: + return OrderCreateUpdateSerializer + return OrderSerializer \ No newline at end of file diff --git a/hb_server/apps/sam/models.py b/hb_server/apps/sam/models.py index 4683844..1f47f5e 100644 --- a/hb_server/apps/sam/models.py +++ b/hb_server/apps/sam/models.py @@ -62,6 +62,7 @@ class Order(CommonAModel): contract = models.ForeignKey(Contract, verbose_name='所属合同', null=True, blank=True, on_delete=models.SET_NULL) product = models.ForeignKey(Material, verbose_name='所需产品', on_delete=models.CASCADE) count = models.IntegerField('所需数量', default=0) + planed_count = models.IntegerField('已排数量', default=0) delivery_date = models.DateField('交货日期') class Meta: verbose_name = '订单信息' diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index 8f66873..d337b06 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -3,7 +3,9 @@ from apps.sam.models import Contract, Customer, Order from rest_framework.viewsets import ModelViewSet from apps.system.mixins import CreateUpdateCustomMixin from django.shortcuts import render - +from rest_framework.decorators import action +from django.db.models import F +from rest_framework.response import Response # Create your views here. class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet): """ @@ -55,4 +57,14 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet): def get_serializer_class(self): if self.action in ['create', 'update']: return OrderCreateUpdateSerializer - return OrderSerializer \ No newline at end of file + return OrderSerializer + + @action(methods=['get'], detail=True, perms_map={'get':'*'}) + def toplan(self, request, pk=None): + queryset = Order.objects.filter(count__gt=F('planed_count')) + page = self.paginate_queryset(queryset) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + serializer = self.get_serializer(queryset, many=True) + return Response(serializer.data) \ No newline at end of file From 33efd80d997d611d425128c9d8b0442b7123241f Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 8 Oct 2021 15:33:47 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=BE=85=E6=8E=92=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/sam/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index d337b06..d6fc571 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -59,7 +59,7 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet): return OrderCreateUpdateSerializer return OrderSerializer - @action(methods=['get'], detail=True, perms_map={'get':'*'}) + @action(methods=['get'], detail=False, perms_map={'get':'*'}) def toplan(self, request, pk=None): queryset = Order.objects.filter(count__gt=F('planed_count')) page = self.paginate_queryset(queryset) From ccabd5a701a5b96ec53989c40b31ac7622bdda14 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 8 Oct 2021 16:31:11 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=8E=92=E4=BA=A7=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/pm/migrations/0001_initial.py | 41 +++++++++ .../0002_alter_productionplan_count.py | 18 ++++ hb_server/apps/pm/migrations/__init__.py | 0 hb_server/apps/pm/models.py | 2 +- hb_server/apps/pm/serializers.py | 53 ++--------- hb_server/apps/pm/urls.py | 6 +- hb_server/apps/pm/views.py | 92 +++++++++---------- .../sam/migrations/0004_order_planed_count.py | 18 ++++ hb_server/apps/sam/views.py | 2 +- hb_server/server/settings.py | 3 +- hb_server/server/urls.py | 2 +- 11 files changed, 136 insertions(+), 101 deletions(-) create mode 100644 hb_server/apps/pm/migrations/0001_initial.py create mode 100644 hb_server/apps/pm/migrations/0002_alter_productionplan_count.py create mode 100644 hb_server/apps/pm/migrations/__init__.py create mode 100644 hb_server/apps/sam/migrations/0004_order_planed_count.py diff --git a/hb_server/apps/pm/migrations/0001_initial.py b/hb_server/apps/pm/migrations/0001_initial.py new file mode 100644 index 0000000..7f16d5a --- /dev/null +++ b/hb_server/apps/pm/migrations/0001_initial.py @@ -0,0 +1,41 @@ +# Generated by Django 3.2.6 on 2021-10-08 08:02 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('mtm', '0018_material_count'), + ('sam', '0004_order_planed_count'), + ] + + operations = [ + migrations.CreateModel( + name='ProductionPlan', + fields=[ + ('id', models.BigAutoField(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=50, unique=True, verbose_name='编号')), + ('count', models.IntegerField(default=0, verbose_name='生产数量')), + ('start_date', models.DateField(verbose_name='计划开工日期')), + ('end_date', models.DateField(verbose_name='计划完工日期')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='productionplan_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='sam.order', verbose_name='关联订单')), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='生产产品')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='productionplan_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'verbose_name': '生产计划', + 'verbose_name_plural': '生产计划', + }, + ), + ] diff --git a/hb_server/apps/pm/migrations/0002_alter_productionplan_count.py b/hb_server/apps/pm/migrations/0002_alter_productionplan_count.py new file mode 100644 index 0000000..6a41103 --- /dev/null +++ b/hb_server/apps/pm/migrations/0002_alter_productionplan_count.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.6 on 2021-10-08 08:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pm', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='productionplan', + name='count', + field=models.IntegerField(default=1, verbose_name='生产数量'), + ), + ] diff --git a/hb_server/apps/pm/migrations/__init__.py b/hb_server/apps/pm/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hb_server/apps/pm/models.py b/hb_server/apps/pm/models.py index ec6c77f..062e0f1 100644 --- a/hb_server/apps/pm/models.py +++ b/hb_server/apps/pm/models.py @@ -17,7 +17,7 @@ class ProductionPlan(CommonAModel): number = models.CharField('编号', max_length=50, unique=True) order = models.ForeignKey(Order, verbose_name='关联订单', null=True, blank=True, on_delete=models.SET_NULL) product = models.ForeignKey(Material, verbose_name='生产产品', on_delete=models.CASCADE) - count = models.IntegerField('生产数量', default=0) + count = models.IntegerField('生产数量', default=1) start_date = models.DateField('计划开工日期') end_date = models.DateField('计划完工日期') diff --git a/hb_server/apps/pm/serializers.py b/hb_server/apps/pm/serializers.py index 00efa54..6fc6e31 100644 --- a/hb_server/apps/pm/serializers.py +++ b/hb_server/apps/pm/serializers.py @@ -1,50 +1,15 @@ +from apps.pm.models import ProductionPlan from rest_framework import serializers +from apps.sam.serializers import OrderSerializer -from .models import Contract, Customer, Order -from apps.mtm.serializers import MaterialSimpleSerializer - -class CustomerSerializer(serializers.ModelSerializer): +class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer): class Meta: - model = Customer - fields = '__all__' + model = ProductionPlan + fields = ['order', 'number', 'count', 'start_date', 'end_date'] -class CustomerCreateUpdateSerializer(serializers.ModelSerializer): +class ProductionPlanSerializer(serializers.ModelSerializer): + order_ = OrderSerializer(source='order', read_only=True) class Meta: - model = Customer - fields = ['name', 'address', 'contact', 'contact_phone', 'description'] - -class CustomerSimpleSerializer(serializers.ModelSerializer): - class Meta: - model = Customer - fields = ['id', 'name'] - -class ContractSerializer(serializers.ModelSerializer): - customer_ = CustomerSimpleSerializer(source='customer', read_only=True) - class Meta: - model = Contract - fields = '__all__' - -class ContractSimpleSerializer(serializers.ModelSerializer): - class Meta: - model = Contract - fields = ['id', 'name', 'number'] - -class ContractCreateUpdateSerializer(serializers.ModelSerializer): - class Meta: - model = Contract - fields = ['name', 'number', 'amount', 'customer', 'sign_date', 'description'] - - -class OrderCreateUpdateSerializer(serializers.ModelSerializer): - class Meta: - model = Order - fields = ['number', 'customer', 'contract', 'product', 'count', 'delivery_date'] - -class OrderSerializer(serializers.ModelSerializer): - contract_ = ContractSimpleSerializer(source='contract', read_only=True) - customer_ = CustomerSimpleSerializer(source='customer', read_only=True) - product_ = MaterialSimpleSerializer(source='product', read_only=True) - class Meta: - model = Order - fields = '__all__' + model = ProductionPlan + fields ='__all__' diff --git a/hb_server/apps/pm/urls.py b/hb_server/apps/pm/urls.py index 4aa607f..69e52f0 100644 --- a/hb_server/apps/pm/urls.py +++ b/hb_server/apps/pm/urls.py @@ -1,13 +1,11 @@ +from apps.pm.views import ProductionPlanViewSet from django.db.models import base from rest_framework import urlpatterns -from apps.sam.views import CustomerViewSet,ContractViewSet,OrderViewSet from django.urls import path, include from rest_framework.routers import DefaultRouter router = DefaultRouter() -router.register('customer', CustomerViewSet, basename='customer') -router.register('contract', ContractViewSet, basename='contract') -router.register('order', OrderViewSet, basename='order') +router.register('productionplan', ProductionPlanViewSet, basename='productionplan') urlpatterns = [ path('', include(router.urls)), diff --git a/hb_server/apps/pm/views.py b/hb_server/apps/pm/views.py index 8f66873..4745835 100644 --- a/hb_server/apps/pm/views.py +++ b/hb_server/apps/pm/views.py @@ -1,58 +1,52 @@ -from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer -from apps.sam.models import Contract, Customer, Order -from rest_framework.viewsets import ModelViewSet -from apps.system.mixins import CreateUpdateCustomMixin +from apps.system.mixins import CreateUpdateModelAMixin +from apps.pm.serializers import ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer +from rest_framework.mixins import CreateModelMixin, ListModelMixin +from apps.pm.models import ProductionPlan +from rest_framework.viewsets import GenericViewSet, ModelViewSet from django.shortcuts import render - +from apps.sam.models import Order +from rest_framework.exceptions import APIException +from rest_framework.response import Response # Create your views here. -class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet): + +def updateOrderPlanedCount(order): """ - 客户-增删改查 + 更新订单已排数量 + """ + planed_count = 0 + plans = ProductionPlan.objects.filter(order=order) + for i in plans: + planed_count = planed_count + i.count + order.planed_count = planed_count + order.save() + +class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModelMixin, GenericViewSet): + """ + 生产计划 """ perms_map = {'*': '*'} - queryset = Customer.objects.all() - serializer_class = CustomerSerializer - search_fields = ['name', 'contact'] + queryset = ProductionPlan.objects.select_related('order', 'order__contract') + serializer_class = ProductionPlanSerializer + search_fields = ['number'] filterset_fields = [] - ordering_fields = ['create_time'] - ordering = ['-create_time'] + ordering_fields = ['id'] + ordering = ['-id'] def get_serializer_class(self): - if self.action in ['create', 'update']: - return CustomerCreateUpdateSerializer - return CustomerSerializer + if self.action in ['create']: + return ProductionPlanCreateFromOrderSerializer + return ProductionPlanSerializer - -class ContractViewSet(CreateUpdateCustomMixin, ModelViewSet): - """ - 合同-增删改查 - """ - perms_map = {'*': '*'} - queryset = Contract.objects.select_related('customer').all() - serializer_class = ContractSerializer - search_fields = ['name'] - filterset_fields = [] - ordering_fields = ['create_time'] - ordering = ['-create_time'] - - def get_serializer_class(self): - if self.action in ['create', 'update']: - return ContractCreateUpdateSerializer - return ContractSerializer - -class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet): - """ - 订单-增删改查 - """ - perms_map = {'*': '*'} - queryset = Order.objects.select_related('contract', 'customer').all() - serializer_class = OrderSerializer - search_fields = ['number', 'product'] - filterset_fields = [] - ordering_fields = ['create_time'] - ordering = ['-create_time'] - - def get_serializer_class(self): - if self.action in ['create', 'update']: - return OrderCreateUpdateSerializer - return OrderSerializer \ No newline at end of file + def create(self, request, *args, **kwargs): + data = request.data + serializer = self.get_serializer(data=data) + serializer.is_valid(raise_exception=True) + if data.get('order', None): + order = Order.objects.get(pk=data['order']) + if order.planed_count >= data['count'] or data['count'] > 0: + pass + else: + raise APIException('排产数量错误') + instance = serializer.save() + updateOrderPlanedCount(instance.order) + return Response() \ No newline at end of file diff --git a/hb_server/apps/sam/migrations/0004_order_planed_count.py b/hb_server/apps/sam/migrations/0004_order_planed_count.py new file mode 100644 index 0000000..df4b48a --- /dev/null +++ b/hb_server/apps/sam/migrations/0004_order_planed_count.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.6 on 2021-10-08 07:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sam', '0003_contract_invoice'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='planed_count', + field=models.IntegerField(default=0, verbose_name='已排数量'), + ), + ] diff --git a/hb_server/apps/sam/views.py b/hb_server/apps/sam/views.py index d6fc571..f1f4be7 100644 --- a/hb_server/apps/sam/views.py +++ b/hb_server/apps/sam/views.py @@ -61,7 +61,7 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet): @action(methods=['get'], detail=False, perms_map={'get':'*'}) def toplan(self, request, pk=None): - queryset = Order.objects.filter(count__gt=F('planed_count')) + queryset = Order.objects.filter(count__gt=F('planed_count')).order_by('-id') page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) diff --git a/hb_server/server/settings.py b/hb_server/server/settings.py index 652d71e..b2e7755 100644 --- a/hb_server/server/settings.py +++ b/hb_server/server/settings.py @@ -54,7 +54,8 @@ INSTALLED_APPS = [ 'apps.mtm', 'apps.inm', 'apps.sam', - 'apps.qm' + 'apps.qm', + 'apps.pm' ] MIDDLEWARE = [ diff --git a/hb_server/server/urls.py b/hb_server/server/urls.py index e27e660..af315af 100644 --- a/hb_server/server/urls.py +++ b/hb_server/server/urls.py @@ -67,7 +67,7 @@ urlpatterns = [ path('api/inm/', include('apps.inm.urls')), path('api/sam/', include('apps.sam.urls')), path('api/qm/', include('apps.qm.urls')), - + path('api/pm/', include('apps.pm.urls')), # 工具 path('api/utils/signature/', GenSignature.as_view()), From c3cb7e36dc76351ce8825b49176a76ffd89246d8 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 8 Oct 2021 17:00:30 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E7=94=9F=E6=88=90?= =?UTF-8?q?=E8=AE=A1=E5=88=92bug-=E4=BA=A7=E5=93=81=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/pm/serializers.py | 2 ++ hb_server/apps/pm/views.py | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hb_server/apps/pm/serializers.py b/hb_server/apps/pm/serializers.py index 6fc6e31..e3975c1 100644 --- a/hb_server/apps/pm/serializers.py +++ b/hb_server/apps/pm/serializers.py @@ -1,6 +1,7 @@ from apps.pm.models import ProductionPlan from rest_framework import serializers from apps.sam.serializers import OrderSerializer +from apps.mtm.serializers import MaterialSimpleSerializer class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer): @@ -10,6 +11,7 @@ class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer): class ProductionPlanSerializer(serializers.ModelSerializer): order_ = OrderSerializer(source='order', read_only=True) + product_ = MaterialSimpleSerializer(source='product', read_only=True) class Meta: model = ProductionPlan fields ='__all__' diff --git a/hb_server/apps/pm/views.py b/hb_server/apps/pm/views.py index 4745835..25509dc 100644 --- a/hb_server/apps/pm/views.py +++ b/hb_server/apps/pm/views.py @@ -25,7 +25,7 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel 生产计划 """ perms_map = {'*': '*'} - queryset = ProductionPlan.objects.select_related('order', 'order__contract') + queryset = ProductionPlan.objects.select_related('order', 'order__contract', 'product') serializer_class = ProductionPlanSerializer search_fields = ['number'] filterset_fields = [] @@ -47,6 +47,6 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel pass else: raise APIException('排产数量错误') - instance = serializer.save() - updateOrderPlanedCount(instance.order) + instance = serializer.save(create_by=request.user, product=order.product) + updateOrderPlanedCount(instance.order) return Response() \ No newline at end of file From b7a701efe689fec9ffaea3d97a359cfebb8228fd Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 11 Oct 2021 10:04:39 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E6=B5=81=E8=BD=ACbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/sam/models.py | 1 + hb_server/apps/wf/services.py | 2 +- hb_server/apps/wf/views.py | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/hb_server/apps/sam/models.py b/hb_server/apps/sam/models.py index 1f47f5e..583fe87 100644 --- a/hb_server/apps/sam/models.py +++ b/hb_server/apps/sam/models.py @@ -5,6 +5,7 @@ from django.db.models.base import Model import django.utils.timezone as timezone from django.db.models.query import QuerySet + from utils.model import SoftModel, BaseModel from apps.mtm.models import Material diff --git a/hb_server/apps/wf/services.py b/hb_server/apps/wf/services.py index 7fd7026..d78d8f8 100644 --- a/hb_server/apps/wf/services.py +++ b/hb_server/apps/wf/services.py @@ -104,7 +104,7 @@ class WfService(object): expression = i['expression'].format(**ticket_all_value) import datetime, time # 用于支持条件表达式中对时间的操作 if eval(expression): - destination_state = State.objects.get(i['expression'].get('target_state')) + destination_state = State.objects.get(pk=i['target_state']) return destination_state @classmethod diff --git a/hb_server/apps/wf/views.py b/hb_server/apps/wf/views.py index cd33e99..eb2eaab 100644 --- a/hb_server/apps/wf/views.py +++ b/hb_server/apps/wf/views.py @@ -276,6 +276,13 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin return Response() else: raise APIException('无需接单') + + @action(methods=['post'], detail=True, perms_map={'post':'*'}) + def retreat(self, request, pk=None): + """ + 撤回工单,允许创建人在指定状态撤回工单至初始状态,状态设置中开启允许撤回 + """ + pass class TicketFlowViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): """ From e1ddd7f9e7d99771e1da59cbd405ecb593f261e6 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 11 Oct 2021 13:44:33 +0800 Subject: [PATCH 6/7] =?UTF-8?q?flowsteps=E6=8E=A5=E5=8F=A3bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/wf/services.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hb_server/apps/wf/services.py b/hb_server/apps/wf/services.py index d78d8f8..c86fcb7 100644 --- a/hb_server/apps/wf/services.py +++ b/hb_server/apps/wf/services.py @@ -57,10 +57,11 @@ class WfService(object): @classmethod def get_ticket_steps(cls, ticket:Ticket): steps = cls.get_worlflow_states(ticket.workflow) + nsteps_list = [] for i in steps: - if ticket.state.is_hidden and ticket.state != i: - steps.remove(i) - return steps + if ticket.state == i or (not i.is_hidden): + nsteps_list.append(i) + return nsteps_list @classmethod def get_ticket_transitions(cls, ticket:Ticket): From bbba12ed6ca251ce81faee8ec5325a905a68aa9c Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 11 Oct 2021 14:01:47 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E5=B7=A5=E5=8D=95=E6=B5=81=E8=BD=AC?= =?UTF-8?q?=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/wf/serializers.py | 7 +++++++ hb_server/apps/wf/urls.py | 3 ++- hb_server/apps/wf/views.py | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/hb_server/apps/wf/serializers.py b/hb_server/apps/wf/serializers.py index 81512ed..697a96a 100644 --- a/hb_server/apps/wf/serializers.py +++ b/hb_server/apps/wf/serializers.py @@ -115,6 +115,13 @@ class TicketFlowSerializer(serializers.ModelSerializer): model = TicketFlow fields = '__all__' +class TicketFlowSimpleSerializer(serializers.ModelSerializer): + participant_ = UserSimpleSerializer(source='participant', read_only=True) + state_ = StateSimpleSerializer(source='state', read_only=True) + class Meta: + model = TicketFlow + exclude = ['ticket_data'] + class TicketHandleSerializer(serializers.Serializer): transition = serializers.IntegerField(label="流转id") diff --git a/hb_server/apps/wf/urls.py b/hb_server/apps/wf/urls.py index 7d169f9..b03a965 100644 --- a/hb_server/apps/wf/urls.py +++ b/hb_server/apps/wf/urls.py @@ -1,6 +1,6 @@ from django.db.models import base from rest_framework import urlpatterns -from apps.wf.views import CustomFieldViewSet, StateViewSet, TicketViewSet, TransitionViewSet, WorkflowViewSet +from apps.wf.views import CustomFieldViewSet, StateViewSet, TicketFlowViewSet, TicketViewSet, TransitionViewSet, WorkflowViewSet from django.urls import path, include from rest_framework.routers import DefaultRouter @@ -10,6 +10,7 @@ router.register('state', StateViewSet, basename='wf_state') router.register('transition', TransitionViewSet, basename='wf_transitions') router.register('customfield', CustomFieldViewSet, basename='wf_customfield') router.register('ticket', TicketViewSet, basename='wf_ticket') +router.register('ticketflow', TicketFlowViewSet, basename='wf_ticketflow') urlpatterns = [ path('', include(router.urls)), ] diff --git a/hb_server/apps/wf/views.py b/hb_server/apps/wf/views.py index eb2eaab..187d70f 100644 --- a/hb_server/apps/wf/views.py +++ b/hb_server/apps/wf/views.py @@ -3,7 +3,7 @@ from django.core.exceptions import AppRegistryNotReady from rest_framework.response import Response from rest_framework import serializers from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin -from apps.wf.serializers import CustomFieldSerializer, StateSerializer, TicketCreateSerializer, TicketFlowSerializer, TicketHandleSerializer, TicketSerializer, TransitionSerializer, WorkflowSerializer, TicketListSerializer, TicketDetailSerializer +from apps.wf.serializers import CustomFieldSerializer, StateSerializer, TicketCreateSerializer, TicketFlowSerializer, TicketFlowSimpleSerializer, TicketHandleSerializer, TicketSerializer, TransitionSerializer, WorkflowSerializer, TicketListSerializer, TicketDetailSerializer from django.shortcuts import get_object_or_404, render from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.decorators import action, api_view @@ -247,6 +247,16 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin ticket = self.get_object() steps = WfService.get_ticket_steps(ticket) return Response(StateSerializer(instance=steps, many=True).data) + + @action(methods=['get'], detail=True, perms_map={'get':'*'}) + def flowlogs(self, request, pk=None): + """ + 工单流转记录 + """ + ticket = self.get_object() + flowlogs = TicketFlow.objects.filter(ticket=ticket).order_by('-create_time') + serializer = TicketFlowSerializer(instance=flowlogs, many=True) + return Response(serializer.data) @action(methods=['get'], detail=True, perms_map={'get':'*'}) def transitions(self, request, pk=None): @@ -292,5 +302,5 @@ class TicketFlowViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): queryset = TicketFlow.objects.all() serializer_class = TicketFlowSerializer search_fields = ['suggestion'] - filterset_fields = ['paticipant', 'state', 'ticket'] + filterset_fields = ['ticket'] ordering = ['-create_time'] \ No newline at end of file