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.contrib.auth.models import AbstractUser
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 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
class ProductionPlan(CommonAModel):
"""
生产计划
@ -20,7 +19,7 @@ class ProductionPlan(CommonAModel):
count = models.IntegerField('生产数量', default=1)
start_date = models.DateField('计划开工日期')
end_date = models.DateField('计划完工日期')
is_planed = models.BooleanField('是否已排产', default=False)
class Meta:
verbose_name = '生产计划'
verbose_name_plural = verbose_name
@ -28,3 +27,24 @@ class ProductionPlan(CommonAModel):
def __str__(self):
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 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):
@ -22,3 +23,15 @@ class ResourceCalSerializer(serializers.Serializer):
class ResourceCalListSerializer(serializers.ListSerializer):
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 rest_framework import urlpatterns
from django.urls import path, include
from rest_framework.routers import 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')
urlpatterns = [
path('', include(router.urls)),

View File

@ -1,11 +1,12 @@
from rest_framework import serializers
from rest_framework.views import APIView
from apps.em.models import Equipment
from apps.em.serializers import EquipmentSerializer
from apps.mtm.models import InputMaterial, Step, SubProduction, UsedStep
from apps.system.mixins import CreateUpdateModelAMixin
from apps.pm.serializers import ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer
from rest_framework.mixins import CreateModelMixin, ListModelMixin
from apps.pm.models import ProductionPlan
from apps.pm.serializers import ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin
from apps.pm.models import ProductionPlan, SubProductionPlan
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from django.shortcuts import render
from apps.sam.models import Order
@ -40,7 +41,9 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
def get_serializer_class(self):
if self.action in ['create']:
return ProductionPlanCreateFromOrderSerializer
return ProductionPlanSerializer
elif self.action == 'list':
return ProductionPlanSerializer
return super().get_serializer_class()
def create(self, request, *args, **kwargs):
data = request.data
@ -55,11 +58,46 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
instance = serializer.save(create_by=request.user, product=order.product)
updateOrderPlanedCount(instance.order)
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):
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):
"""
物料消耗计算
@ -85,7 +123,7 @@ class ResourceViewSet(GenericViewSet):
'count':m['count']*i['count'], 'inv_count':m['material__count']})
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):
"""
设备状态查看