订单数量统计,生产进度统计

This commit is contained in:
caoqianming 2022-03-15 15:03:24 +08:00
parent 80956f41c2
commit 1d0de666b8
10 changed files with 186 additions and 11 deletions

View File

@ -121,6 +121,10 @@ class UpdateFIFONumber(APIView):
i.save()
return Response()
class CorrectWproductState(APIView):
permission_classes = [IsAdminUser]
def post(self, request):
pass
class ReloadServer(APIView):

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2022-03-15 07:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('em', '0012_auto_20220120_1048'),
]
operations = [
migrations.AlterField(
model_name='equipment',
name='state',
field=models.PositiveIntegerField(choices=[(10, '完好'), (20, '限用'), (30, '在修'), (40, '禁用'), (50, '报废')], default=0, verbose_name='设备状态'),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.9 on 2022-03-15 07:00
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('sam', '0016_sale_iproducts'),
('inm', '0033_fifoitem_expiration_date'),
]
operations = [
migrations.AlterField(
model_name='fifo',
name='sale',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='fifo_sale', to='sam.sale', verbose_name='关联销售记录'),
),
]

View File

@ -1,6 +1,8 @@
from email.policy import default
from rest_framework import serializers
from apps.pm.models import ProductionPlan, SubProductionPlan
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer
from apps.system.models import Organization
class SubplanGanttSerializer(serializers.ModelSerializer):
process_ = ProcessSimpleSerializer(source='process', read_only=True)
@ -25,10 +27,20 @@ class ProcessYieldSerializer(serializers.Serializer):
datetime_start = serializers.DateField(label='开始时间', required=False, allow_null=True)
datetime_end = serializers.DateField(label='结束时间', required=False, allow_null=True)
class ProductCountSerializer(serializers.Serializer):
class SrmCountSerializer(serializers.Serializer):
datetime_start = serializers.DateField(label='开始时间', required=False, allow_null=True)
datetime_end = serializers.DateField(label='结束时间', required=False, allow_null=True)
class ProductCountSerializer(serializers.Serializer):
tag_choices=(
(1, '统计成品'),
(2, '统计全部')
)
datetime_start = serializers.DateField(label='开始时间', required=False, allow_null=True)
datetime_end = serializers.DateField(label='结束时间', required=False, allow_null=True)
tag = serializers.ChoiceField(choices=tag_choices, label='统计范围1成品2全部', default=1)
dept = serializers.PrimaryKeyRelatedField(queryset=Organization.objects.all(), label="车间", required=False)
class AtWorkCountSerializer(serializers.Serializer):
year = serializers.IntegerField(label='')
month = serializers.IntegerField(label='')

View File

@ -1,25 +1,68 @@
from apps.mtm.models import Material
from apps.pm.models import ProductionPlan
from apps.sam.models import Order
from apps.wpm.models import WProduct, WproductFlow
from django.db.models import F
class SrmServices:
"""
数据统计分析
"""
@classmethod
def get_wp_product_count(cls, datetime_start, datetime_end):
def get_product_count(cls, datetime_start=None, datetime_end=None, tag=1, dept=None):
"""
根据生产情况统计相关数量
"""
objs = WproductFlow.objects.filter(is_lastlog=True, material__type=Material.MA_TYPE_GOOD)
if tag == 1:
objs = WproductFlow.objects.filter(is_lastlog=True, material__type=Material.MA_TYPE_GOOD)
else:
objs = WproductFlow.objects.filter(is_lastlog=True)
if datetime_start:
objs = objs.filter(create_time__gte=datetime_start)
if datetime_end:
objs = objs.filter(create_time__lte=datetime_end)
if dept:
objs = objs.filter(subproduction_plan__workshop=dept)
count = objs.count()
count_ok = objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_INM,
WProduct.WPR_ACT_STATE_OK, WProduct.WPR_ACT_STATE_SELLED]).count()
count_notok = objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_NOTOK, WProduct.WPR_ACT_STATE_SCRAP]).count()
# count_notok = objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_NOTOK, WProduct.WPR_ACT_STATE_SCRAP]).count()
count_notok = (
objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_NOTOK, WProduct.WPR_ACT_STATE_SCRAP]).exclude(step__process__id=1)
| objs.filter(act_state__in=[WProduct.WPR_ACT_STATE_NOTOK, WProduct.WPR_ACT_STATE_SCRAP],
step__process__id=1).exclude(number=None)
).count()
count_selled = objs.filter(act_state=WProduct.WPR_ACT_STATE_SELLED).count()
count_mtestok = objs.filter(is_mtestok=True).count()
return dict(count=count,count_ok=count_ok, count_notok=count_notok, count_selled=count_selled, count_mtestok=count_mtestok)
return dict(count=count,count_ok=count_ok, count_notok=count_notok, count_selled=count_selled, count_mtestok=count_mtestok)
@classmethod
def get_plan_count(cls, datetime_start=None, datetime_end=None):
"""
任务数量
"""
objs = ProductionPlan.objects.all()
if datetime_start:
objs = objs.filter(end_date__gte=datetime_start)
if datetime_end:
objs = objs.filter(end_date__lte=datetime_end)
count = objs.count()
count_use = objs.exclude(state__in=[ProductionPlan.PLAN_STATE_PAUSE, ProductionPlan.PLAN_STATE_STOP]).count()
count_completed = objs.filter(state__in=[ProductionPlan.PLAN_STATE_DONE, ProductionPlan.PLAN_MTEST_DONE]).count()
return dict(count=count, count_use=count_use, count_completed=count_completed)
@classmethod
def get_order_count(cls, datetime_start=None, datetime_end=None):
"""
订单数量
"""
objs = Order.objects.all()
if datetime_start:
objs = objs.filter(delivery_date__gte=datetime_start)
if datetime_end:
objs = objs.filter(delivery_date__lte=datetime_end)
count = objs.count()
count_delivered = objs.filter(delivered_count__gte=F('count')).count()
return dict(count=count, count_delivered=count_delivered)

View File

@ -3,13 +3,16 @@ from rest_framework import urlpatterns
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from apps.srm.views import AtWorkCountView, GanttPlan, ProcessYieldView, ProductCountView
from apps.srm.views import AtWorkCountView, GanttPlan, OrderCountView, PlanCountView, ProcessNowView, ProcessYieldView, ProductCountView
router = DefaultRouter()
urlpatterns = [
path('gantt/plan/', GanttPlan.as_view()),
path('product/count/', ProductCountView.as_view()),
path('plan/count/', PlanCountView.as_view()),
path('order/count/', OrderCountView.as_view()),
path('process/yield/', ProcessYieldView.as_view()),
path('process/now/', ProcessNowView.as_view()),
path('at_work/', AtWorkCountView.as_view()),
path('', include(router.urls)),
]

View File

@ -1,6 +1,7 @@
from datetime import date, timedelta
from django.shortcuts import render
from idna import valid_contextj
from numpy import number
from rest_framework import serializers
from rest_framework.generics import ListAPIView, CreateAPIView
@ -9,10 +10,10 @@ from rest_framework.response import Response
from apps.hrm.models import ClockRecord
from apps.mtm.models import Process, Step
from apps.pm.models import ProductionPlan, SubProductionPlan
from apps.srm.serializers import AtWorkCountSerializer, PlanGanttSerializer, ProcessYieldSerializer, ProductCountSerializer
from apps.srm.serializers import AtWorkCountSerializer, PlanGanttSerializer, ProcessYieldSerializer, ProductCountSerializer, SrmCountSerializer
from apps.srm.services import SrmServices
from apps.wpm.models import WProduct, WproductFlow
from django.db.models import Count, F
from django.db.models import Count, F, Sum
# Create your views here.
class GanttPlan(ListAPIView):
@ -34,9 +35,52 @@ class ProductCountView(CreateAPIView):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
res = SrmServices.get_wp_product_count(datetime_start= vdata.get('datetime_start', None), datetime_end= vdata.get('datetime_end', None))
res = SrmServices.get_product_count(**vdata)
return Response(res)
class PlanCountView(CreateAPIView):
"""
计划数量统计
"""
perms_map = {'post':'*'}
serializer_class = SrmCountSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
res = SrmServices.get_plan_count(**vdata)
return Response(res)
class OrderCountView(CreateAPIView):
"""
订单数量统计
"""
perms_map = {'post':'*'}
serializer_class = SrmCountSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
res = SrmServices.get_order_count(**vdata)
return Response(res)
class ProcessNowView(CreateAPIView):
"""
工序当前进度
"""
perms_map = {'post':'*'}
serializers_class = serializers.Serializer
def create(self, request, *args, **kwargs):
objs = SubProductionPlan.objects.filter(production_plan__state__in =[ProductionPlan.PLAN_STATE_WORKING,
ProductionPlan.PLAN_STATE_ASSGINED]).order_by('process__number').values('process',
'process__name').annotate(count_ok=Sum('count_ok'),
count=Sum('count'), count_real=Sum('count_real'), count_notok=Sum('count_notok'))
return Response(objs)
class ProcessYieldView(CreateAPIView):
"""
工序成品率统计

View File

@ -0,0 +1,28 @@
# Generated by Django 3.2.9 on 2022-03-15 07:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wpm', '0053_auto_20220129_1512'),
]
operations = [
migrations.AlterField(
model_name='operationequip',
name='state',
field=models.PositiveSmallIntegerField(choices=[(10, '完好'), (20, '限用'), (30, '在修'), (40, '禁用'), (50, '报废')], default=10, verbose_name='当前设备状态'),
),
migrations.AlterField(
model_name='wproduct',
name='act_state',
field=models.IntegerField(choices=[(6, '待复检'), (8, '操作准备中'), (10, '操作进行中'), (20, '待检验'), (26, '待夹层检验'), (30, '已合格'), (40, '已入库'), (50, '不合格'), (60, '待成品检验'), (70, '已报废'), (80, '已售出'), (90, '已使用')], default=0, verbose_name='进行状态'),
),
migrations.AlterField(
model_name='wproductflow',
name='act_state',
field=models.IntegerField(choices=[(6, '待复检'), (8, '操作准备中'), (10, '操作进行中'), (20, '待检验'), (26, '待夹层检验'), (30, '已合格'), (40, '已入库'), (50, '不合格'), (60, '待成品检验'), (70, '已报废'), (80, '已售出'), (90, '已使用')], default=0, verbose_name='进行状态'),
),
]

View File

@ -43,6 +43,7 @@ class WProduct(CommonAModel):
WPR_ACT_STATE_TOFINALTEST = 60
WPR_ACT_STATE_SCRAP = 70
WPR_ACT_STATE_SELLED = 80
WPR_ACT_STATE_USED = 90
act_state_choices = (
(WPR_ACT_STATE_TORETEST, '待复检'),
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
@ -55,6 +56,7 @@ class WProduct(CommonAModel):
(WPR_ACT_STATE_TOFINALTEST, '待成品检验'),
(WPR_ACT_STATE_SCRAP, '已报废'),
(WPR_ACT_STATE_SELLED, '已售出'),
(WPR_ACT_STATE_USED, '已使用'),
)
SCRAP_REASON_QIPAO = 10
SCRAP_REASON_PODIAN = 20

View File

@ -781,8 +781,9 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
WpmService.add_wproduct_flow_log(wproduct, 'wproduct_create')
# 隐藏原半成品
wps = WProduct.objects.filter(ow_wproduct__operation=op)
wps.update(is_hidden=True, child=wproduct,
wps.update(act_state=WProduct.WPR_ACT_STATE_USED, child=wproduct, is_hidden=True,
update_by=request.user, update_time=timezone.now())
WpmService.add_wproducts_flow_log(wps, change_str='wproduct_create')
else:
raise exceptions.APIException('产出物料未填写或填写错误')
op.is_submited = True