Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop

This commit is contained in:
shilixia 2021-10-15 10:14:33 +08:00
commit 8f829a1147
5 changed files with 131 additions and 14 deletions

View File

@ -0,0 +1,45 @@
# Generated by Django 3.2.6 on 2021-10-14 07:03
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 = [
('system', '0003_auto_20210812_0909'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('mtm', '0022_auto_20211014_0944'),
('pm', '0002_alter_productionplan_count'),
]
operations = [
migrations.AddField(
model_name='productionplan',
name='is_planed',
field=models.BooleanField(default=False, verbose_name='是否已排产'),
),
migrations.CreateModel(
name='SubProductionPlan',
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='删除标记')),
('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='subproductionplan_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('process', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.process', verbose_name='关联大工序')),
('production_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.productionplan', verbose_name='关联主生产计划')),
('subproduction', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subproductionplan_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
('workshop', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.organization', verbose_name='生产车间')),
],
options={
'verbose_name': '子生产计划',
'verbose_name_plural': '子生产计划',
},
),
]

View File

@ -1,4 +1,4 @@
from apps.system.models import CommonAModel from apps.system.models import CommonAModel, Organization
from django.db import models from django.db import models
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.db.models.base import Model from django.db.models.base import Model
@ -6,10 +6,9 @@ import django.utils.timezone as timezone
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from utils.model import SoftModel, BaseModel from utils.model import SoftModel, BaseModel
from apps.mtm.models import Material from apps.mtm.models import Material, Process, SubProduction
from apps.sam.models import Order from apps.sam.models import Order
class ProductionPlan(CommonAModel): class ProductionPlan(CommonAModel):
""" """
生产计划 生产计划
@ -20,7 +19,7 @@ class ProductionPlan(CommonAModel):
count = models.IntegerField('生产数量', default=1) count = models.IntegerField('生产数量', default=1)
start_date = models.DateField('计划开工日期') start_date = models.DateField('计划开工日期')
end_date = models.DateField('计划完工日期') end_date = models.DateField('计划完工日期')
is_planed = models.BooleanField('是否已排产', default=False)
class Meta: class Meta:
verbose_name = '生产计划' verbose_name = '生产计划'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
@ -28,3 +27,24 @@ class ProductionPlan(CommonAModel):
def __str__(self): def __str__(self):
return self.number return self.number
class SubProductionPlan(CommonAModel):
"""
子生产计划
"""
production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE)
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
start_date = models.DateField('计划开工日期')
end_date = models.DateField('计划完工日期')
workshop = models.ForeignKey(Organization, verbose_name='生产车间', on_delete=models.CASCADE)
process = models.ForeignKey(Process, verbose_name='关联大工序', on_delete=models.CASCADE)
# steps = models.JSONField('工艺步骤', default=list)
class Meta:
verbose_name = '子生产计划'
verbose_name_plural = verbose_name
# class ProductionProgress(BaseModel):
# """
# 子计划生产进度
# """
# subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE)
# material = models.

View File

@ -1,7 +1,8 @@
from apps.pm.models import ProductionPlan from apps.pm.models import ProductionPlan, SubProductionPlan
from rest_framework import serializers from rest_framework import serializers
from apps.sam.serializers import OrderSerializer from apps.sam.serializers import OrderSerializer
from apps.mtm.serializers import MaterialSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer
from apps.system.serializers import OrganizationSimpleSerializer
class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer): class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer):
@ -22,3 +23,15 @@ class ResourceCalSerializer(serializers.Serializer):
class ResourceCalListSerializer(serializers.ListSerializer): class ResourceCalListSerializer(serializers.ListSerializer):
child = ResourceCalSerializer() child = ResourceCalSerializer()
class SubProductionPlanListSerializer(serializers.ModelSerializer):
workshop_ = OrganizationSimpleSerializer(source='workshop', read_only=True)
process_ = ProcessSimpleSerializer(source='process', read_only=True)
class Meta:
model=SubProductionPlan
fields = '__all__'
class SubProductionPlanUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = SubProductionPlan
fields = ['start_date', 'end_date']

View File

@ -1,11 +1,12 @@
from apps.pm.views import ProductionPlanViewSet, ResourceViewSet from apps.pm.views import ProductionPlanViewSet, ResourceViewSet, SubProductionPlanViewSet
from django.db.models import base from django.db.models import base
from rest_framework import urlpatterns from rest_framework import urlpatterns
from django.urls import path, include from django.urls import path, include
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
router = DefaultRouter() router = DefaultRouter()
router.register('productionplan', ProductionPlanViewSet, basename='productionplan') router.register('production_plan', ProductionPlanViewSet, basename='production_plan')
router.register('subproduction_plan', SubProductionPlanViewSet, basename='subproduction_plan')
router.register('resource', ResourceViewSet, basename='resource') router.register('resource', ResourceViewSet, basename='resource')
urlpatterns = [ urlpatterns = [
path('', include(router.urls)), path('', include(router.urls)),

View File

@ -1,11 +1,12 @@
from rest_framework import serializers
from rest_framework.views import APIView from rest_framework.views import APIView
from apps.em.models import Equipment from apps.em.models import Equipment
from apps.em.serializers import EquipmentSerializer from apps.em.serializers import EquipmentSerializer
from apps.mtm.models import InputMaterial, Step, SubProduction, UsedStep from apps.mtm.models import InputMaterial, Step, SubProduction, UsedStep
from apps.system.mixins import CreateUpdateModelAMixin from apps.system.mixins import CreateUpdateModelAMixin
from apps.pm.serializers import ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer from apps.pm.serializers import ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer
from rest_framework.mixins import CreateModelMixin, ListModelMixin from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin
from apps.pm.models import ProductionPlan from apps.pm.models import ProductionPlan, SubProductionPlan
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet
from django.shortcuts import render from django.shortcuts import render
from apps.sam.models import Order from apps.sam.models import Order
@ -40,7 +41,9 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
def get_serializer_class(self): def get_serializer_class(self):
if self.action in ['create']: if self.action in ['create']:
return ProductionPlanCreateFromOrderSerializer return ProductionPlanCreateFromOrderSerializer
return ProductionPlanSerializer elif self.action == 'list':
return ProductionPlanSerializer
return super().get_serializer_class()
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
data = request.data data = request.data
@ -55,11 +58,46 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
instance = serializer.save(create_by=request.user, product=order.product) instance = serializer.save(create_by=request.user, product=order.product)
updateOrderPlanedCount(instance.order) updateOrderPlanedCount(instance.order)
return Response() return Response()
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
def gen_subplan(self, request, pk=None):
"""
生成子计划
"""
production_plan=self.get_object()
if production_plan.is_planed:
raise APIException('已生成子计划')
subps = SubProduction.objects.filter(product=production_plan.product).order_by('process__number')
for i in subps:
SubProductionPlan.objects.create(production_plan=production_plan, subproduction=i,
start_date=production_plan.start_date, end_date=production_plan.end_date,
workshop=i.process.workshop, process=i.process, create_by=request.user)
production_plan.is_planed=True
production_plan.save()
return Response()
class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
"""
子生产计划-列表/修改
"""
perms_map = {'*': '*'}
queryset = SubProductionPlan.objects.select_related('process', 'workshop')
search_fields = []
filterset_fields = ['production_plan']
ordering_fields = ['process__number']
ordering = ['process__number']
def get_serializer_class(self):
if self.action == 'list':
return SubProductionPlanListSerializer
elif self.action == 'update':
return SubProductionPlanUpdateSerializer
class ResourceViewSet(GenericViewSet): class ResourceViewSet(GenericViewSet):
perms_map = {'*': '*'} perms_map = {'*': '*'}
@action(methods=['post'], detail=False, perms_map={'get':'*'}, serializer_class=ResourceCalListSerializer) @action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=ResourceCalListSerializer)
def cal(self, request, pk=None): def cal(self, request, pk=None):
""" """
物料消耗计算 物料消耗计算
@ -85,7 +123,7 @@ class ResourceViewSet(GenericViewSet):
'count':m['count']*i['count'], 'inv_count':m['material__count']}) 'count':m['count']*i['count'], 'inv_count':m['material__count']})
return Response(res) return Response(res)
@action(methods=['post'], detail=False, perms_map={'get':'*'}, serializer_class=ResourceCalListSerializer) @action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=ResourceCalListSerializer)
def cal_equip(self, request, pk=None): def cal_equip(self, request, pk=None):
""" """
设备状态查看 设备状态查看