订单数量统计,生产进度统计
This commit is contained in:
parent
80956f41c2
commit
1d0de666b8
|
@ -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):
|
||||
|
|
|
@ -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='设备状态'),
|
||||
),
|
||||
]
|
|
@ -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='关联销售记录'),
|
||||
),
|
||||
]
|
|
@ -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='月')
|
|
@ -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)
|
||||
|
||||
@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)
|
||||
|
|
@ -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)),
|
||||
]
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
工序成品率统计
|
||||
|
|
|
@ -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='进行状态'),
|
||||
),
|
||||
]
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue