Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
8f829a1147
|
@ -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': '子生产计划',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -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.
|
|
@ -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']
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
设备状态查看
|
设备状态查看
|
||||||
|
|
Loading…
Reference in New Issue