From 0851e0cc843c1ff4fb7c167fbeec68d60842aab5 Mon Sep 17 00:00:00 2001 From: shijing Date: Tue, 15 Mar 2022 10:29:23 +0800 Subject: [PATCH 1/8] bigScreenData --- hb_client/src/permission.js | 37 +- hb_client/src/utils/request.js | 5 +- hb_client/src/views/bigScreen/center.vue | 107 +++++- .../src/views/bigScreen/centerRight1.vue | 14 +- .../src/views/bigScreen/centerRight2.vue | 10 +- hb_client/src/views/bigScreen/index.vue | 326 ++++++++++++++++-- hb_client/src/views/login/index.vue | 5 +- 7 files changed, 453 insertions(+), 51 deletions(-) diff --git a/hb_client/src/permission.js b/hb_client/src/permission.js index d4a08b6..3414d1b 100644 --- a/hb_client/src/permission.js +++ b/hb_client/src/permission.js @@ -6,68 +6,69 @@ import 'nprogress/nprogress.css' // progress bar style import { getToken } from '@/utils/auth' // get token from cookie import getPageTitle from '@/utils/get-page-title' -NProgress.configure({ showSpinner: false }) // NProgress Configuration +NProgress.configure({ showSpinner: false }) ;// NProgress Configuration -const whiteList = ['/login'] // no redirect whitelist +const whiteList = ['/login']; // no redirect whitelist router.beforeEach(async(to, from, next) => { // start progress bar - NProgress.start() + NProgress.start(); // set page title - document.title = getPageTitle(to.meta.title) + document.title = getPageTitle(to.meta.title); // determine whether the user has logged in - const hasToken = getToken() + const hasToken = getToken(); if (hasToken) { if (to.path === '/login') { // if is logged in, redirect to the home page - next({ path: '/' }) + next({ path: '/' }); NProgress.done() } else { // determine whether the user has obtained his permission perms through getInfo - const hasPerms = store.getters.perms && store.getters.perms.length > 0 + const hasPerms = store.getters.perms && store.getters.perms.length > 0; if (hasPerms) { next() } else { try { // get user info // note: perms must be a object array! such as: ['admin'] or ,['developer','editor'] - const { perms } = await store.dispatch('user/getInfo') + const { perms } = await store.dispatch('user/getInfo'); // generate accessible routes map based on perms - const accessRoutes = await store.dispatch('permission/generateRoutes', perms) + const accessRoutes = await store.dispatch('permission/generateRoutes', perms); // dynamically add accessible routes - router.addRoutes(accessRoutes) + router.addRoutes(accessRoutes); // hack method to ensure that addRoutes is complete // set the replace: true, so the navigation will not leave a history record next({ ...to, replace: true }) } catch (error) { // remove token and go to login page to re-login - await store.dispatch('user/resetToken') - Message.error(error || 'Has Error') - next(`/login?redirect=${to.path}`) + await store.dispatch('user/resetToken'); + Message.error(error || 'Has Error'); + next(`/login?redirect=${to.path}`); NProgress.done() } } } } else { /* has no token*/ - - if (whiteList.indexOf(to.path) !== -1) { + if (to.path === '/index'){ + next() + }else if (whiteList.indexOf(to.path) !== -1) { // in the free login whitelist, go directly next() } else { // other pages that do not have permission to access are redirected to the login page. - next(`/login?redirect=${to.path}`) + next(`/login?redirect=${to.path}`); NProgress.done() } } -}) +}); router.afterEach(() => { // finish progress bar NProgress.done() -}) +}); diff --git a/hb_client/src/utils/request.js b/hb_client/src/utils/request.js index 8db7072..6183457 100644 --- a/hb_client/src/utils/request.js +++ b/hb_client/src/utils/request.js @@ -20,7 +20,7 @@ service.interceptors.request.use( // please modify it according to the actual situation config.headers['Authorization'] = 'Bearer ' + getToken() } - let data = config.data; + let data = config.data?config.data:config.params; /*debugger; console.log(data)*/ if(data){ @@ -28,6 +28,9 @@ service.interceptors.request.use( if(token){ config.headers['Authorization'] = 'Bearer ' + token } + if(data.type==='big_screen'){ + config.headers['Authorization'] = 'big_screen ' + } } /* debugger; console.log(config.headers['Authorization'])*/ diff --git a/hb_client/src/views/bigScreen/center.vue b/hb_client/src/views/bigScreen/center.vue index 14fc87f..ef6c06b 100644 --- a/hb_client/src/views/bigScreen/center.vue +++ b/hb_client/src/views/bigScreen/center.vue @@ -7,7 +7,7 @@ :key="item.title" >

{{ item.title }}

-
+
- 任务完成进度 + 工序生产进度
@@ -49,11 +49,20 @@ diff --git a/hb_client/src/views/bigScreen/centerRight1.vue b/hb_client/src/views/bigScreen/centerRight1.vue index bdb1f85..2b5b409 100644 --- a/hb_client/src/views/bigScreen/centerRight1.vue +++ b/hb_client/src/views/bigScreen/centerRight1.vue @@ -10,7 +10,7 @@
- +
@@ -19,7 +19,7 @@ export default { data() { return { - config: { + /* config: { header: ['姓名', '部门', '到岗情况'], data: [ ['张思', '一车间', "已到岗"], @@ -41,9 +41,17 @@ export default { index: false, // columnWidth: [50], align: ['center'] + }*/ + } + }, + props:{ + userConfig:{ + type:Object, + default:()=>{ + return {} } } - } + }, } diff --git a/hb_client/src/views/bigScreen/centerRight2.vue b/hb_client/src/views/bigScreen/centerRight2.vue index 2d32f13..c54a46e 100644 --- a/hb_client/src/views/bigScreen/centerRight2.vue +++ b/hb_client/src/views/bigScreen/centerRight2.vue @@ -19,7 +19,7 @@ export default { data() { return { - config: { + /*config: { data: [ { name: '冷加工', @@ -50,6 +50,14 @@ export default { value: 100 } ] + }*/ + } + }, + props:{ + config:{ + type:Object, + default:()=>{ + return {} } } }, diff --git a/hb_client/src/views/bigScreen/index.vue b/hb_client/src/views/bigScreen/index.vue index 95cfcbb..ee5698a 100644 --- a/hb_client/src/views/bigScreen/index.vue +++ b/hb_client/src/views/bigScreen/index.vue @@ -4,9 +4,9 @@
- +
- +
航玻生产管理系统 @@ -23,7 +23,7 @@ :color="['#568aea', '#000000']" />
- +
@@ -50,36 +50,45 @@
-
-
+
+
-
- +
+
- +
- +
-
+
- +
- + - +
@@ -90,18 +99,22 @@ diff --git a/hb_client/src/views/login/index.vue b/hb_client/src/views/login/index.vue index 4551caa..392e3ac 100644 --- a/hb_client/src/views/login/index.vue +++ b/hb_client/src/views/login/index.vue @@ -5,7 +5,7 @@
-

航玻生产管理系统

+

航玻生产管理系统

Date: Tue, 15 Mar 2022 10:45:20 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E7=94=9F=E4=BA=A7=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/services.py | 6 +++++- hb_server/apps/srm/serializers.py | 3 +++ hb_server/apps/srm/services.py | 25 +++++++++++++++++++++++++ hb_server/apps/srm/urls.py | 3 ++- hb_server/apps/srm/views.py | 16 +++++++++++++++- hb_server/apps/wpm/services.py | 17 +++++++++++++++++ 6 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 hb_server/apps/srm/services.py diff --git a/hb_server/apps/inm/services.py b/hb_server/apps/inm/services.py index 159f148..0d44820 100644 --- a/hb_server/apps/inm/services.py +++ b/hb_server/apps/inm/services.py @@ -6,6 +6,8 @@ from apps.sam.models import SalePack, SaleProduct from django.db.models import Count from django.db.models.aggregates import Sum import logging + +from apps.wpm.services import WpmService logger = logging.getLogger('log') class InmService: @@ -133,8 +135,10 @@ class InmService: # 更新动态产品表情况 from apps.wpm.models import WProduct - WProduct.objects.filter(id__in=ips.values_list('wproduct', flat=True)).update( + wps = WProduct.objects.filter(id__in=ips.values_list('wproduct', flat=True)) + wps.update( act_state=WProduct.WPR_ACT_STATE_SELLED) + WpmService.add_wproducts_flow_log(instances=wps, change_str='selled') # 变更销售记录实际发货数 sale.count_real = ips.count() diff --git a/hb_server/apps/srm/serializers.py b/hb_server/apps/srm/serializers.py index 2a4e11f..283d360 100644 --- a/hb_server/apps/srm/serializers.py +++ b/hb_server/apps/srm/serializers.py @@ -25,6 +25,9 @@ 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): + datetime_start = serializers.DateField(label='开始时间', required=False, allow_null=True) + datetime_end = serializers.DateField(label='结束时间', required=False, allow_null=True) class AtWorkCountSerializer(serializers.Serializer): year = serializers.IntegerField(label='年') diff --git a/hb_server/apps/srm/services.py b/hb_server/apps/srm/services.py new file mode 100644 index 0000000..de57324 --- /dev/null +++ b/hb_server/apps/srm/services.py @@ -0,0 +1,25 @@ +from apps.mtm.models import Material +from apps.wpm.models import WProduct, WproductFlow + + +class SrmServices: + """ + 数据统计分析 + """ + @classmethod + def get_wp_product_count(cls, datetime_start, datetime_end): + """ + 根据生产情况统计相关数量 + """ + objs = WproductFlow.objects.filter(is_lastlog=True, material__type=Material.MA_TYPE_GOOD) + if datetime_start: + objs = objs.filter(create_time__gte=datetime_start) + if datetime_end: + objs = WproductFlow.objects.filter(create_time__lte=datetime_end) + 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_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) \ No newline at end of file diff --git a/hb_server/apps/srm/urls.py b/hb_server/apps/srm/urls.py index 2b53153..2437fbe 100644 --- a/hb_server/apps/srm/urls.py +++ b/hb_server/apps/srm/urls.py @@ -3,11 +3,12 @@ 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 +from apps.srm.views import AtWorkCountView, GanttPlan, ProcessYieldView, ProductCountView router = DefaultRouter() urlpatterns = [ path('gantt/plan/', GanttPlan.as_view()), + path('product/count/', ProductCountView.as_view()), path('process/yield/', ProcessYieldView.as_view()), path('at_work/', AtWorkCountView.as_view()), path('', include(router.urls)), diff --git a/hb_server/apps/srm/views.py b/hb_server/apps/srm/views.py index ead2e2e..28d0da3 100644 --- a/hb_server/apps/srm/views.py +++ b/hb_server/apps/srm/views.py @@ -9,7 +9,8 @@ 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 +from apps.srm.serializers import AtWorkCountSerializer, PlanGanttSerializer, ProcessYieldSerializer, ProductCountSerializer +from apps.srm.services import SrmServices from apps.wpm.models import WProduct, WproductFlow from django.db.models import Count, F # Create your views here. @@ -23,6 +24,19 @@ class GanttPlan(ListAPIView): queryset = ProductionPlan.objects.filter(is_deleted=False, is_planed=True).prefetch_related('subplan_plan', 'subplan_plan__process') ordering = ['-id'] +class ProductCountView(CreateAPIView): + """ + 产品数量统计 + """ + perms_map = {'post':'*'} + serializer_class = ProductCountSerializer + 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_wp_product_count(datetime_start= vdata.get('datetime_start', None), datetime_end= vdata.get('datetime_end', None)) + return Response(res) + class ProcessYieldView(CreateAPIView): """ 工序成品率统计 diff --git a/hb_server/apps/wpm/services.py b/hb_server/apps/wpm/services.py index 36db321..74af318 100644 --- a/hb_server/apps/wpm/services.py +++ b/hb_server/apps/wpm/services.py @@ -167,6 +167,23 @@ class WpmService(object): ins.change_str = change_str ins.save() + @classmethod + def add_wproducts_flow_log(cls, instances, change_str=''): + """ + 批量创建产品变动日志 + """ + WproductFlow.objects.filter(wproduct__in=instances).update(is_lastlog=False) + wfw = [] + for i in instances: + ins = WproductFlow() + ins.wproduct = i + for f in WproductFlow.__meta.fields: + if f.name not in ['id', 'wproduct', 'is_lastlog']: + setattr(ins, f.name, getattr(i, f.name, None)) + ins.change_str = change_str + wfw.append(ins) + WproductFlow.objects.bulk_create(wfw) + @classmethod def update_cutting_list_with_operation(cls, op:Operation): """ From 80956f41c223a03ca1bbe18e5bc63afedce0a998 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 15 Mar 2022 11:13:17 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E6=95=B0=E9=87=8Fbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/srm/services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hb_server/apps/srm/services.py b/hb_server/apps/srm/services.py index de57324..2c3400b 100644 --- a/hb_server/apps/srm/services.py +++ b/hb_server/apps/srm/services.py @@ -15,7 +15,7 @@ class SrmServices: if datetime_start: objs = objs.filter(create_time__gte=datetime_start) if datetime_end: - objs = WproductFlow.objects.filter(create_time__lte=datetime_end) + objs = objs.filter(create_time__lte=datetime_end) 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() From 1d0de666b8409de164cfdebcdccb0bb90a41e88f Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 15 Mar 2022 15:03:24 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=EF=BC=8C=E7=94=9F=E4=BA=A7=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/develop/views.py | 4 ++ .../migrations/0013_alter_equipment_state.py | 18 +++++++ .../inm/migrations/0034_alter_fifo_sale.py | 20 +++++++ hb_server/apps/srm/serializers.py | 14 ++++- hb_server/apps/srm/services.py | 53 +++++++++++++++++-- hb_server/apps/srm/urls.py | 5 +- hb_server/apps/srm/views.py | 50 +++++++++++++++-- .../wpm/migrations/0054_auto_20220315_1500.py | 28 ++++++++++ hb_server/apps/wpm/models.py | 2 + hb_server/apps/wpm/views.py | 3 +- 10 files changed, 186 insertions(+), 11 deletions(-) create mode 100644 hb_server/apps/em/migrations/0013_alter_equipment_state.py create mode 100644 hb_server/apps/inm/migrations/0034_alter_fifo_sale.py create mode 100644 hb_server/apps/wpm/migrations/0054_auto_20220315_1500.py diff --git a/hb_server/apps/develop/views.py b/hb_server/apps/develop/views.py index ec43e41..f46227b 100644 --- a/hb_server/apps/develop/views.py +++ b/hb_server/apps/develop/views.py @@ -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): diff --git a/hb_server/apps/em/migrations/0013_alter_equipment_state.py b/hb_server/apps/em/migrations/0013_alter_equipment_state.py new file mode 100644 index 0000000..da0e59b --- /dev/null +++ b/hb_server/apps/em/migrations/0013_alter_equipment_state.py @@ -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='设备状态'), + ), + ] diff --git a/hb_server/apps/inm/migrations/0034_alter_fifo_sale.py b/hb_server/apps/inm/migrations/0034_alter_fifo_sale.py new file mode 100644 index 0000000..4bd942d --- /dev/null +++ b/hb_server/apps/inm/migrations/0034_alter_fifo_sale.py @@ -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='关联销售记录'), + ), + ] diff --git a/hb_server/apps/srm/serializers.py b/hb_server/apps/srm/serializers.py index 283d360..ab5e1a4 100644 --- a/hb_server/apps/srm/serializers.py +++ b/hb_server/apps/srm/serializers.py @@ -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='月') \ No newline at end of file diff --git a/hb_server/apps/srm/services.py b/hb_server/apps/srm/services.py index 2c3400b..e6edf02 100644 --- a/hb_server/apps/srm/services.py +++ b/hb_server/apps/srm/services.py @@ -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) \ No newline at end of file + 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) + \ No newline at end of file diff --git a/hb_server/apps/srm/urls.py b/hb_server/apps/srm/urls.py index 2437fbe..2829723 100644 --- a/hb_server/apps/srm/urls.py +++ b/hb_server/apps/srm/urls.py @@ -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)), ] diff --git a/hb_server/apps/srm/views.py b/hb_server/apps/srm/views.py index 28d0da3..158489f 100644 --- a/hb_server/apps/srm/views.py +++ b/hb_server/apps/srm/views.py @@ -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): """ 工序成品率统计 diff --git a/hb_server/apps/wpm/migrations/0054_auto_20220315_1500.py b/hb_server/apps/wpm/migrations/0054_auto_20220315_1500.py new file mode 100644 index 0000000..3b4a060 --- /dev/null +++ b/hb_server/apps/wpm/migrations/0054_auto_20220315_1500.py @@ -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='进行状态'), + ), + ] diff --git a/hb_server/apps/wpm/models.py b/hb_server/apps/wpm/models.py index f75908f..b408f18 100644 --- a/hb_server/apps/wpm/models.py +++ b/hb_server/apps/wpm/models.py @@ -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 diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index 430dc78..b8234d0 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -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 From e7fdc7984a7ad994df0534cda6ec525e08c5bb96 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 15 Mar 2022 16:50:37 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E5=A2=9E=E5=8A=A0count=5Fdoing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/cms/__init__.py | 0 hb_server/apps/cms/admin.py | 3 +++ hb_server/apps/cms/apps.py | 5 +++++ hb_server/apps/cms/migrations/__init__.py | 0 hb_server/apps/cms/models.py | 3 +++ hb_server/apps/cms/tests.py | 3 +++ hb_server/apps/cms/views.py | 3 +++ hb_server/apps/develop/views.py | 6 ++++-- hb_server/apps/srm/services.py | 10 ++++++++-- 9 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 hb_server/apps/cms/__init__.py create mode 100644 hb_server/apps/cms/admin.py create mode 100644 hb_server/apps/cms/apps.py create mode 100644 hb_server/apps/cms/migrations/__init__.py create mode 100644 hb_server/apps/cms/models.py create mode 100644 hb_server/apps/cms/tests.py create mode 100644 hb_server/apps/cms/views.py diff --git a/hb_server/apps/cms/__init__.py b/hb_server/apps/cms/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hb_server/apps/cms/admin.py b/hb_server/apps/cms/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/hb_server/apps/cms/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/hb_server/apps/cms/apps.py b/hb_server/apps/cms/apps.py new file mode 100644 index 0000000..7ef3fea --- /dev/null +++ b/hb_server/apps/cms/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CmsConfig(AppConfig): + name = 'cms' diff --git a/hb_server/apps/cms/migrations/__init__.py b/hb_server/apps/cms/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hb_server/apps/cms/models.py b/hb_server/apps/cms/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/hb_server/apps/cms/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/hb_server/apps/cms/tests.py b/hb_server/apps/cms/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/hb_server/apps/cms/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/hb_server/apps/cms/views.py b/hb_server/apps/cms/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/hb_server/apps/cms/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/hb_server/apps/develop/views.py b/hb_server/apps/develop/views.py index f46227b..4013959 100644 --- a/hb_server/apps/develop/views.py +++ b/hb_server/apps/develop/views.py @@ -121,10 +121,12 @@ class UpdateFIFONumber(APIView): i.save() return Response() -class CorrectWproductState(APIView): +class CorrectWproduct(APIView): permission_classes = [IsAdminUser] def post(self, request): - pass + """ + """ + # WProduct.objects.filter(is_hidden=True).update(act_state=WProduct.WPR_ACT_STATE_USED) class ReloadServer(APIView): diff --git a/hb_server/apps/srm/services.py b/hb_server/apps/srm/services.py index e6edf02..d9ae057 100644 --- a/hb_server/apps/srm/services.py +++ b/hb_server/apps/srm/services.py @@ -3,7 +3,7 @@ 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 - +from apps.wpm.serializers import WProductDetailSerializer class SrmServices: """ 数据统计分析 @@ -34,7 +34,13 @@ class SrmServices: ).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) + count_mtestnotok = objs.filter(is_mtestok=False).count() + count_doing = objs.filter(act_state__in=[ + WProduct.WPR_ACT_STATE_TOTEST, WProduct.WPR_ACT_STATE_TOCOMBTEST, WProduct.WPR_ACT_STATE_TOFINALTEST, + WProduct.WPR_ACT_STATE_TORETEST, WProduct.WPR_ACT_STATE_DOWAIT, WProduct.WPR_ACT_STATE_DOING + ], subproduction_plan__product=F('material')).count() + return dict(count=count,count_ok=count_ok, count_notok=count_notok, + count_selled=count_selled, count_mtestok=count_mtestok, count_mtestnotok=count_mtestnotok, count_doing=count_doing) @classmethod def get_plan_count(cls, datetime_start=None, datetime_end=None): From b4795ab9f263eed98581a7b80262db917f27a60b Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 16 Mar 2022 10:28:39 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E5=A2=9E=E5=8A=A0cms=20article?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/cms/apps.py | 3 +- hb_server/apps/cms/migrations/0001_initial.py | 37 +++++++++++++++++++ hb_server/apps/cms/models.py | 11 +++++- hb_server/apps/cms/serializers.py | 21 +++++++++++ hb_server/apps/cms/urls.py | 10 +++++ hb_server/apps/cms/views.py | 23 ++++++++++++ hb_server/apps/hrm/urls.py | 2 +- hb_server/apps/srm/views.py | 2 +- hb_server/server/settings.py | 3 +- hb_server/server/urls.py | 1 + 10 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 hb_server/apps/cms/migrations/0001_initial.py create mode 100644 hb_server/apps/cms/serializers.py create mode 100644 hb_server/apps/cms/urls.py diff --git a/hb_server/apps/cms/apps.py b/hb_server/apps/cms/apps.py index 7ef3fea..d20462e 100644 --- a/hb_server/apps/cms/apps.py +++ b/hb_server/apps/cms/apps.py @@ -2,4 +2,5 @@ from django.apps import AppConfig class CmsConfig(AppConfig): - name = 'cms' + name = 'apps.cms' + verbose_name = '内容管理' diff --git a/hb_server/apps/cms/migrations/0001_initial.py b/hb_server/apps/cms/migrations/0001_initial.py new file mode 100644 index 0000000..bbfa1ac --- /dev/null +++ b/hb_server/apps/cms/migrations/0001_initial.py @@ -0,0 +1,37 @@ +# Generated by Django 3.2.9 on 2022-03-16 02:25 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Article', + 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='删除标记')), + ('title', models.CharField(max_length=100, verbose_name='标题')), + ('content', models.TextField(verbose_name='内容')), + ('author', models.CharField(blank=True, max_length=100, null=True, verbose_name='作者')), + ('is_top', models.BooleanField(default=False, verbose_name='是否置顶')), + ('is_published', models.BooleanField(default=False, verbose_name='是否发布')), + ('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='article_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='article_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/hb_server/apps/cms/models.py b/hb_server/apps/cms/models.py index 71a8362..86964fe 100644 --- a/hb_server/apps/cms/models.py +++ b/hb_server/apps/cms/models.py @@ -1,3 +1,12 @@ from django.db import models - +from apps.system.models import CommonAModel # Create your models here. +class Article(CommonAModel): + """ + 文章 + """ + title = models.CharField('标题', max_length=100) + content = models.TextField('内容') + author = models.CharField('作者', max_length=100, null=True, blank=True) + is_top = models.BooleanField('是否置顶', default=False) + is_published = models.BooleanField('是否发布', default=False) diff --git a/hb_server/apps/cms/serializers.py b/hb_server/apps/cms/serializers.py new file mode 100644 index 0000000..f8a6b8e --- /dev/null +++ b/hb_server/apps/cms/serializers.py @@ -0,0 +1,21 @@ +from rest_framework import serializers +from apps.cms.models import Article +from apps.system.serializers import UserSimpleSerializer + +class ArticleListSerializer(serializers.ModelSerializer): + create_by_ = UserSimpleSerializer(source='create_by', read_only=True) + class Meta: + model = Article + exclude = ['content'] + +class ArticleCreateUpdateSerializer(serializers.ModelSerializer): + class Meta: + model = Article + fields = ['title', 'content', 'author', 'is_published', 'is_top'] + + +class ArticleDetailSerializer(serializers.ModelSerializer): + create_by_ = UserSimpleSerializer(source='create_by', read_only=True) + class Meta: + model = Article + fields = '__all__' \ No newline at end of file diff --git a/hb_server/apps/cms/urls.py b/hb_server/apps/cms/urls.py new file mode 100644 index 0000000..df95a52 --- /dev/null +++ b/hb_server/apps/cms/urls.py @@ -0,0 +1,10 @@ +from rest_framework.routers import DefaultRouter +from django.urls import path, include +from apps.cms.views import ArticleViewSet + +router = DefaultRouter() +router.register('article', ArticleViewSet, basename='article') + +urlpatterns = [ + path('', include(router.urls)), +] \ No newline at end of file diff --git a/hb_server/apps/cms/views.py b/hb_server/apps/cms/views.py index 91ea44a..0d918e9 100644 --- a/hb_server/apps/cms/views.py +++ b/hb_server/apps/cms/views.py @@ -1,3 +1,26 @@ from django.shortcuts import render +from rest_framework.viewsets import ModelViewSet +from apps.cms.models import Article +from apps.cms.serializers import ArticleCreateUpdateSerializer, ArticleDetailSerializer, ArticleListSerializer +from apps.system.mixins import CreateUpdateModelAMixin # Create your views here. + +class ArticleViewSet(CreateUpdateModelAMixin, ModelViewSet): + """ + 文章增删改查 + """ + perms_map = {'get': '*', 'post': 'article_create' + , 'put':'article_update', 'delete':'article_delete'} + queryset = Article.objects.select_related('create_by') + filterset_fields = ['is_top', 'is_published'] + serializer_class = ArticleListSerializer + search_fields = ['title', 'author'] + ordering = ['is_published', 'is_top', 'update_time'] + + def get_serializer_class(self): + if self.action in ['create', 'update']: + return ArticleCreateUpdateSerializer + elif self.action in ['retrieve']: + return ArticleDetailSerializer + return super().get_serializer_class() \ No newline at end of file diff --git a/hb_server/apps/hrm/urls.py b/hb_server/apps/hrm/urls.py index 9db9637..b0ced0c 100644 --- a/hb_server/apps/hrm/urls.py +++ b/hb_server/apps/hrm/urls.py @@ -1,4 +1,4 @@ -from django.db.models import base + from rest_framework import urlpatterns from apps.hrm.views import ClockRecordViewSet, EmployeeViewSet, FaceLogin, NotWorkRemarkViewSet from django.urls import path, include diff --git a/hb_server/apps/srm/views.py b/hb_server/apps/srm/views.py index 158489f..631380b 100644 --- a/hb_server/apps/srm/views.py +++ b/hb_server/apps/srm/views.py @@ -72,7 +72,7 @@ class ProcessNowView(CreateAPIView): 工序当前进度 """ perms_map = {'post':'*'} - serializers_class = serializers.Serializer + serializer_class = serializers.Serializer def create(self, request, *args, **kwargs): objs = SubProductionPlan.objects.filter(production_plan__state__in =[ProductionPlan.PLAN_STATE_WORKING, diff --git a/hb_server/server/settings.py b/hb_server/server/settings.py index d0fdffa..32a09e1 100644 --- a/hb_server/server/settings.py +++ b/hb_server/server/settings.py @@ -60,7 +60,8 @@ INSTALLED_APPS = [ 'apps.pm', 'apps.wpm', 'apps.srm', - 'apps.develop' + 'apps.develop', + 'apps.cms' ] X_FRAME_OPTIONS = 'SAMEORIGIN' diff --git a/hb_server/server/urls.py b/hb_server/server/urls.py index 50bc49f..2e95b54 100644 --- a/hb_server/server/urls.py +++ b/hb_server/server/urls.py @@ -72,6 +72,7 @@ urlpatterns = [ path('api/wpm/', include('apps.wpm.urls')), path('api/srm/', include('apps.srm.urls')), path('api/develop/', include('apps.develop.urls')), + path('api/cms/', include('apps.cms.urls')), # 工具 path('api/utils/signature/', GenSignature.as_view()), From d3f999d2c8b8929c9c84af7fc58079f943ece5ac Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 16 Mar 2022 16:11:45 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E5=85=B6=E4=BB=96=E5=87=BA=E5=BA=93?= =?UTF-8?q?=E4=B8=8D=E5=8F=AF=E6=93=8D=E4=BD=9C=E6=88=90=E5=93=81=E6=88=96?= =?UTF-8?q?=E5=8D=8A=E6=88=90=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/serializers.py | 3 +++ hb_server/apps/inm/views.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/hb_server/apps/inm/serializers.py b/hb_server/apps/inm/serializers.py index 357084d..c5df25b 100644 --- a/hb_server/apps/inm/serializers.py +++ b/hb_server/apps/inm/serializers.py @@ -2,6 +2,7 @@ from rest_framework import exceptions from rest_framework import serializers from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse, Inventory +from apps.mtm.models import Material from apps.pum.models import PuOrder, Vendor from apps.qm.models import TestRecord, TestRecordItem from apps.sam.serializers import OrderSimpleSerializer @@ -173,6 +174,8 @@ class FIFOOutOtherSerializer(serializers.ModelSerializer): obj.save() for i in details: mb = i.pop('material_batch') + if mb.material.type in [Material.MA_TYPE_GOOD, Material.MA_TYPE_HALFGOOD]: + raise ValidationError('不可直接出成品或半成品') i['material'] = mb.material i['batch'] = mb.batch i['warehouse'] = mb.warehouse diff --git a/hb_server/apps/inm/views.py b/hb_server/apps/inm/views.py index fcc454f..c528834 100644 --- a/hb_server/apps/inm/views.py +++ b/hb_server/apps/inm/views.py @@ -163,6 +163,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): return super().destroy(request, *args, **kwargs) @action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_pur'}, serializer_class=FIFOInPurSerializer) + @transaction.atomic() def in_pur(self, request, pk=None): """ 采购入库 @@ -174,6 +175,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): @action(methods=['post'], detail=False, perms_map={'post': 'fifo_in_other'}, serializer_class=FIFOInOtherSerializer) + @transaction.atomic() def in_other(self, request, pk=None): """ 其他入库 @@ -185,6 +187,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet): @action(methods=['post'], detail=False, perms_map={'post': 'fifo_out_other'}, serializer_class=FIFOOutOtherSerializer) + @transaction.atomic() def out_other(self, request, pk=None): """ 其他出库 From 8859c13edf5ce29d979eb3d498b5f1772ca7bbd3 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 16 Mar 2022 16:34:59 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E5=A2=9E=E5=8A=A0to=5Forder=5Fneed=5Fmtest?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/inm/filters.py | 3 ++- hb_server/apps/wpm/filters.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hb_server/apps/inm/filters.py b/hb_server/apps/inm/filters.py index 377cb4d..1c44ab5 100644 --- a/hb_server/apps/inm/filters.py +++ b/hb_server/apps/inm/filters.py @@ -23,10 +23,11 @@ class MbFilterSet(DynamicFieldsFilterMixin, filters.FilterSet): class IProductFilterSet(DynamicFieldsFilterMixin, filters.FilterSet): order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order") to_order = filters.NumberFilter(field_name="wproduct__to_order") + to_order_need_mtest = filters.BooleanFilter(field_name="wproduct__to_order__need_mtest") need_to_order = filters.BooleanFilter(field_name="wproduct__need_to_order") update_time_start = filters.DateFilter(field_name="update_time", lookup_expr='gte') update_time_end = filters.DateFilter(field_name="update_time", lookup_expr='lte') class Meta: model = IProduct fields = ['material', 'warehouse', 'batch', 'order', 'material__type', 'update_time_start', 'update_time_end', - 'to_order', 'need_to_order', 'state'] + 'to_order', 'need_to_order', 'state', 'to_order_need_mtest'] diff --git a/hb_server/apps/wpm/filters.py b/hb_server/apps/wpm/filters.py index 2798e98..2ef5b25 100644 --- a/hb_server/apps/wpm/filters.py +++ b/hb_server/apps/wpm/filters.py @@ -33,6 +33,7 @@ class WProductFilterSet(DynamicFieldsFilterMixin, filters.FilterSet): tag = filters.CharFilter(method='filter_tag') production_plan = filters.NumberFilter( field_name='subproduction_plan__production_plan') + to_order_need_mtest = filters.BooleanFilter(field_name="to_order__need_mtest") def filter_fields(self, queryset, name, value): return queryset @@ -41,7 +42,7 @@ class WProductFilterSet(DynamicFieldsFilterMixin, filters.FilterSet): class Meta: model = WProduct fields = ['step', 'subproduction_plan', 'material', - 'step__process', 'act_state', 'material__type', 'need_to_order'] + 'step__process', 'act_state', 'material__type', 'need_to_order', 'to_order_need_mtest'] def filter_tag(self, queryset, name, value): if value == 'no_scrap':