Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
04f1521939
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-27 05:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pm', '0017_auto_20211213_1401'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='productionplan',
|
||||
name='process_json',
|
||||
field=models.JSONField(blank=True, default=list, null=True, verbose_name='按工序的统计数'),
|
||||
),
|
||||
]
|
|
@ -29,6 +29,7 @@ class ProductionPlan(CommonAModel):
|
|||
count_ok = models.PositiveIntegerField('合格数', default=0)
|
||||
start_date = models.DateField('计划开工日期')
|
||||
end_date = models.DateField('计划完工日期')
|
||||
process_json = models.JSONField('按工序的统计数', default=dict, null=True, blank=True)
|
||||
is_planed = models.BooleanField('是否已排产', default=False)
|
||||
class Meta:
|
||||
verbose_name = '生产计划'
|
||||
|
|
|
@ -48,11 +48,7 @@ class SubProductionPlanUpdateSerializer(serializers.ModelSerializer):
|
|||
class GenSubPlanSerializer(serializers.Serializer):
|
||||
pass
|
||||
|
||||
class SubProductionProgressSerializer(serializers.ModelSerializer):
|
||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||
class Meta:
|
||||
model = SubProductionProgress
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class PickNeedSerializer(serializers.Serializer):
|
||||
warehouse = serializers.IntegerField(label="仓库ID")
|
||||
|
@ -64,3 +60,10 @@ class SubproductionPlanSimpleSerializer(serializers.ModelSerializer):
|
|||
class Meta:
|
||||
model = SubProductionPlan
|
||||
fields = ['id', 'number']
|
||||
|
||||
class SubProductionProgressSerializer(serializers.ModelSerializer):
|
||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||
subproduction_plan_ = SubproductionPlanSimpleSerializer(source='subproduction_plan', read_only=True)
|
||||
class Meta:
|
||||
model = SubProductionProgress
|
||||
fields = '__all__'
|
|
@ -0,0 +1,27 @@
|
|||
from django.db.models.aggregates import Sum
|
||||
from apps.pm.models import ProductionPlan, SubProductionPlan
|
||||
|
||||
class PmService:
|
||||
|
||||
@classmethod
|
||||
def update_plan_process_json(cls, plan:ProductionPlan):
|
||||
"""
|
||||
更新计划按工序统计字段
|
||||
"""
|
||||
ret = {}
|
||||
subplans = SubProductionPlan.objects.filter(production_plan=plan, is_deleted=False)
|
||||
qs = subplans.values('process', 'process__name', 'process__number').annotate(count=Sum('main_count'),
|
||||
count_real=Sum('main_count_real'), count_ok=Sum('main_count_ok'))
|
||||
qs_list = list(qs)
|
||||
for i in qs_list:
|
||||
ret[i['process__number']] = {
|
||||
'count':i['count'],
|
||||
'count_real':i['count_real'],
|
||||
'count_ok':i['count_ok'],
|
||||
'rate': round((i['count_ok']/i['count_real'])*100,2) if i['count_real'] > 0 else 0
|
||||
}
|
||||
plan.process_json = ret
|
||||
plan.save()
|
||||
|
||||
|
||||
|
|
@ -2,6 +2,7 @@ from django.db.models.signals import post_save
|
|||
from django.dispatch import receiver
|
||||
from apps.mtm.models import Material
|
||||
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||
from apps.pm.services import PmService
|
||||
|
||||
@receiver(post_save, sender=SubProductionProgress)
|
||||
def update_subplan_main(sender, instance, created, **kwargs):
|
||||
|
@ -13,6 +14,7 @@ def update_subplan_main(sender, instance, created, **kwargs):
|
|||
if created:
|
||||
subplan.main_product = instance.material
|
||||
subplan.main_count = instance.count
|
||||
|
||||
subplan.main_count_real = instance.count_real
|
||||
subplan.main_count_ok = instance.count_ok
|
||||
if instance.count_ok >= instance.count and instance.count_ok > 0:
|
||||
|
@ -26,6 +28,10 @@ def update_subplan_main(sender, instance, created, **kwargs):
|
|||
plan.count_real = subplan.main_count_real
|
||||
plan.count_ok = subplan.main_count_ok
|
||||
plan.save()
|
||||
# 更新计划工序统计字段
|
||||
PmService.update_plan_process_json(subplan.production_plan)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-27 05:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wf', '0022_alter_customfield_is_hidden'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customfield',
|
||||
name='field_type',
|
||||
field=models.CharField(choices=[('string', '字符串'), ('int', '整型'), ('float', '浮点'), ('boolean', '布尔'), ('date', '日期'), ('datetime', '日期时间'), ('radio', '单选'), ('checkbox', '多选'), ('select', '单选下拉'), ('selects', '多选下拉'), ('cascader', '单选级联'), ('cascaders', '多选级联'), ('select_dg', '弹框单选'), ('select_dgs', '弹框多选'), ('textarea', '文本域'), ('file', '附件')], help_text='string, int, float, date, datetime, radio, checkbox, select, selects, cascader, cascaders, select_dg, select_dgs,textarea, file', max_length=50, verbose_name='类型'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='customfield',
|
||||
name='label',
|
||||
field=models.CharField(default='', help_text='处理特殊逻辑使用,比如sys_user用于获取用户作为选项', max_length=1000, verbose_name='标签'),
|
||||
),
|
||||
]
|
|
@ -159,7 +159,7 @@ class CustomField(CommonAModel):
|
|||
)
|
||||
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流')
|
||||
field_type = models.CharField('类型', max_length=50, choices=field_type_choices,
|
||||
help_text='string, int, float, date, datetime, radio, checkbox, select, selects, cascader, cascaders, cascader, cascaders,textarea, file')
|
||||
help_text='string, int, float, date, datetime, radio, checkbox, select, selects, cascader, cascaders, select_dg, select_dgs,textarea, file')
|
||||
field_key = models.CharField('字段标识', max_length=50, help_text='字段类型请尽量特殊,避免与系统中关键字冲突')
|
||||
field_name = models.CharField('字段名称', max_length=50)
|
||||
sort = models.IntegerField('排序', default=0, help_text='工单基础字段在表单中排序为:流水号0,标题20,状态id40,状态名41,创建人80,创建时间100,更新时间120.前端展示工单信息的表单可以根据这个id顺序排列')
|
||||
|
@ -173,7 +173,7 @@ class CustomField(CommonAModel):
|
|||
field_choice = models.JSONField('选项值', default=list, blank=True,
|
||||
help_text='选项值,格式为list, 例["id":1, "name":"张三"]')
|
||||
|
||||
label = models.CharField('标签', max_length=1000, default='', help_text='处理特殊逻辑使用')
|
||||
label = models.CharField('标签', max_length=1000, default='', help_text='处理特殊逻辑使用,比如sys_user用于获取用户作为选项')
|
||||
# hook = models.CharField('hook', max_length=1000, default='', help_text='获取下拉选项用于动态选项值')
|
||||
is_hidden = models.BooleanField('是否隐藏', default=False, help_text='可用于携带不需要用户查看的字段信息')
|
||||
|
||||
|
|
|
@ -129,21 +129,22 @@ class TicketDetailSerializer(serializers.ModelSerializer):
|
|||
i['field_state'] = state_fields.get(key, 1)
|
||||
i['field_value'] = ticket_data.get(key, None)
|
||||
i['field_display'] = i['field_value'] # 该字段是用于查看详情直接展示
|
||||
if 'sys_user' in i['label']:
|
||||
if isinstance(i['field_value'], list):
|
||||
i['field_display'] = ','.join(list(User.objects.filter(id__in=i['field_value']).values_list('name', flat=True)))
|
||||
else:
|
||||
i['field_display'] = User.objects.get(id=i['field_value']).name
|
||||
elif i['field_type'] in ['radio', 'select']:
|
||||
for m in i['field_choice']:
|
||||
if m['id'] == i['field_value']:
|
||||
i['field_display'] = m['name']
|
||||
elif i['field_type'] in ['checkbox', 'selects']:
|
||||
d_list = []
|
||||
for m in i['field_choice']:
|
||||
if m['id'] in i['field_value']:
|
||||
d_list.append(m['name'])
|
||||
i['field_display'] = ','.join(d_list)
|
||||
if i['field_value']:
|
||||
if 'sys_user' in i['label']:
|
||||
if isinstance(i['field_value'], list):
|
||||
i['field_display'] = ','.join(list(User.objects.filter(id__in=i['field_value']).values_list('name', flat=True)))
|
||||
else:
|
||||
i['field_display'] = User.objects.get(id=i['field_value']).name
|
||||
elif i['field_type'] in ['radio', 'select']:
|
||||
for m in i['field_choice']:
|
||||
if m['id'] == i['field_value']:
|
||||
i['field_display'] = m['name']
|
||||
elif i['field_type'] in ['checkbox', 'selects']:
|
||||
d_list = []
|
||||
for m in i['field_choice']:
|
||||
if m['id'] in i['field_value']:
|
||||
d_list.append(m['name'])
|
||||
i['field_display'] = ','.join(d_list)
|
||||
return all_fields_l
|
||||
|
||||
def filter_display(self, item, field_value):
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
from typing import List
|
||||
|
||||
from django.db.models.expressions import F
|
||||
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||
from apps.mtm.models import Material, Step, SubprodctionMaterial
|
||||
from apps.qm.models import TestRecord
|
||||
|
@ -55,10 +57,10 @@ class WpmServies(object):
|
|||
wproduct.number = 'WP'+ranstr(7)
|
||||
|
||||
# 更新子计划合格进度
|
||||
instance = SubProductionProgress.objects.get(subproduction_plan=wproduct.subproduction_plan,
|
||||
ins = SubProductionProgress.objects.get(subproduction_plan=wproduct.subproduction_plan,
|
||||
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||
instance.count_ok = instance.count_ok + 1
|
||||
instance.save()
|
||||
ins.count_ok = ins.count_ok + 1
|
||||
ins.save()
|
||||
else:# 如果不合格
|
||||
wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK
|
||||
# 需要走不合格品审理的工单
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from django.db.models.expressions import F
|
||||
from django.db.models.signals import post_save
|
||||
from apps.mtm.models import SubprodctionMaterial
|
||||
from apps.pm.models import SubProductionProgress
|
||||
from apps.mtm.models import Step, SubprodctionMaterial
|
||||
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||
from apps.qm.models import TestRecord
|
||||
from apps.wf.models import Ticket
|
||||
from django.dispatch import receiver
|
||||
|
@ -56,10 +57,11 @@ def handleTicket(sender, instance, created, **kwargs):
|
|||
|
||||
wp.ng_sign = decision
|
||||
if decision in [WProduct.NG_BACK_WORK, WProduct.NG_BACK_FIX]:
|
||||
step = ticket_data['back_step']
|
||||
step = Step.objects.get(id=ticket_data['back_step'])
|
||||
wp.step = step
|
||||
# 找到当时所属的计划
|
||||
sp = OperationWproduct.objects.filter(operation__is_submited=True, operation__step=step).first()
|
||||
sp = SubProductionPlan.objects.filter(ow_subplan__wproduct=wp,
|
||||
ow_subplan__operation__is_submited=True, ow_subplan__step=step).first()
|
||||
if sp:
|
||||
wp.subproduction_plan = sp
|
||||
wt.save()
|
||||
|
@ -67,10 +69,11 @@ def handleTicket(sender, instance, created, **kwargs):
|
|||
wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
||||
wp.save()
|
||||
# 更新子计划合格进度
|
||||
instance = SubProductionProgress.objects.get(subproduction_plan=sp,
|
||||
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||
instance.count_ok = instance.count_ok - 1 #进度计算这里该怎么处理呢
|
||||
instance.save()
|
||||
if sp != wt.subproduction_plan:
|
||||
ins = SubProductionProgress.objects.filter(subproduction_plan=sp,
|
||||
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||
ins.count_ok = ins.count_ok - 1
|
||||
ins.save()
|
||||
|
||||
else:
|
||||
raise exceptions.APIException('返回步骤点错误')
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from django.db.models.expressions import F
|
||||
from django.shortcuts import render
|
||||
from rest_framework.generics import CreateAPIView, GenericAPIView
|
||||
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||
|
@ -370,7 +371,8 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
|||
发起不合格审理单
|
||||
"""
|
||||
obj = self.get_object()
|
||||
if obj.act_state != WProduct.WPR_ACT_STATE_NOTOK or obj.ng_sign is not None:
|
||||
if obj.act_state != WProduct.WPR_ACT_STATE_NOTOK or obj.ng_sign is not None\
|
||||
or obj.ticket is not None:
|
||||
raise exceptions.APIException('该产品不可发起不合格审理')
|
||||
workflow = Workflow.objects.filter(name='不合格品审理单', is_deleted=False).first()
|
||||
if workflow:
|
||||
|
@ -542,10 +544,10 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
# 更新子计划生产进度
|
||||
# 如果产品有返工标记不做计算
|
||||
if wp.ng_sign not in [WProduct.NG_BACK_FIX, WProduct.NG_BACK_WORK]:
|
||||
instance = SubProductionProgress.objects.get(subproduction_plan=wsp,
|
||||
ins = SubProductionProgress.objects.get(subproduction_plan=wsp,
|
||||
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||
instance.count_real = instance.count_real + 1 # 这个地方可能会有问题,不够严谨
|
||||
instance.save()
|
||||
ins.count_real = ins.count_real + 1
|
||||
ins.save()
|
||||
wp.operation = None
|
||||
wp.update_by = request.user
|
||||
wp.save()
|
||||
|
|
Loading…
Reference in New Issue