返工返修执行操作决定
This commit is contained in:
parent
6682d43022
commit
811fe24fc7
|
@ -14,6 +14,8 @@ from rest_framework.decorators import action
|
|||
from django.db.models import F
|
||||
from rest_framework.response import Response
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.wf.models import Workflow
|
||||
# Create your views here.
|
||||
class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
||||
"""
|
||||
|
@ -168,6 +170,10 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C
|
|||
FIFOItemProduct.objects.bulk_create(ipxs)
|
||||
# 更新成品库情况
|
||||
ips.update(is_saled=True)
|
||||
# 更新动态产品表情况
|
||||
from apps.wpm.models import WProduct
|
||||
WProduct.objects.filter(iproduct_wproduct__sale_iproduct__sale=obj).update(
|
||||
act_state=WProduct.WPR_ACT_STATE_SELLED)
|
||||
# 更新库存
|
||||
update_inm(fifo)
|
||||
# 变更审核状态
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-24 06:26
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wf', '0020_auto_20211223_1006'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customfield',
|
||||
name='description',
|
||||
field=models.CharField(blank=True, help_text='字段的描述信息,可用于显示在字段的下方对该字段的详细描述', max_length=100, null=True, verbose_name='描述'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='customfield',
|
||||
name='field_template',
|
||||
field=models.TextField(blank=True, help_text='文本域类型字段前端显示时可以将此内容作为字段的placeholder', null=True, verbose_name='文本域模板'),
|
||||
),
|
||||
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, cascader, cascaders,textarea, file', max_length=50, verbose_name='类型'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='customfield',
|
||||
name='placeholder',
|
||||
field=models.CharField(blank=True, help_text='用户工单详情表单中作为字段的占位符显示', max_length=100, null=True, verbose_name='占位符'),
|
||||
),
|
||||
]
|
|
@ -174,8 +174,8 @@ class CustomField(CommonAModel):
|
|||
help_text='选项值,格式为list, 例["id":1, "name":"张三"]')
|
||||
|
||||
label = models.CharField('标签', max_length=1000, default='', help_text='处理特殊逻辑使用')
|
||||
|
||||
is_hidden = models.BooleanField('是否隐藏', default=False, help_text='可用于携带不需要用户查看的信息')
|
||||
# hook = models.CharField('hook', max_length=1000, default='', help_text='获取下拉选项用于动态选项值')
|
||||
is_hidden = models.BooleanField('是否隐藏', default=False, help_text='可用于携带不需要用户查看的字段信息')
|
||||
|
||||
class Ticket(CommonBModel):
|
||||
"""
|
||||
|
|
|
@ -36,6 +36,7 @@ class WProduct(CommonAModel):
|
|||
WPR_ACT_STATE_NOTOK = 50
|
||||
WPR_ACT_STATE_TOFINALTEST = 60
|
||||
WPR_ACT_STATE_SCRAP = 70
|
||||
WPR_ACT_STATE_SELLED = 80
|
||||
act_state_choices=(
|
||||
(WPR_ACT_STATE_TORETEST, '待复检'),
|
||||
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
||||
|
@ -46,7 +47,8 @@ class WProduct(CommonAModel):
|
|||
(WPR_ACT_STATE_INM, '已入库'),
|
||||
(WPR_ACT_STATE_NOTOK, '不合格'),
|
||||
(WPR_ACT_STATE_TOFINALTEST, '待成品检验'),
|
||||
(WPR_ACT_STATE_SCRAP, '已报废')
|
||||
(WPR_ACT_STATE_SCRAP, '已报废'),
|
||||
(WPR_ACT_STATE_SELLED, '已售出'),
|
||||
)
|
||||
SCRAP_REASON_QIPAO = 10
|
||||
SCRAP_REASON_PODIAN = 20
|
||||
|
@ -58,6 +60,26 @@ class WProduct(CommonAModel):
|
|||
(30, '划伤'),
|
||||
(40, '其他')
|
||||
)
|
||||
|
||||
NG_BACK_WORK = 10
|
||||
NG_BACK_FIX = 20
|
||||
NG_SCRAP = 30
|
||||
NG_ACCEPT = 40
|
||||
NG_PERMIT = 50
|
||||
NG_DOWN = 60
|
||||
NG_BACK_FROM = 70
|
||||
NG_RECALL = 80
|
||||
|
||||
ng_choices = (
|
||||
(NG_BACK_WORK, '返工'),
|
||||
(NG_BACK_FIX, '返修'),
|
||||
(NG_SCRAP, '报废'),
|
||||
(NG_ACCEPT, '让步接收'),
|
||||
(NG_PERMIT, '偏离许可'),
|
||||
(NG_DOWN, '降级使用'),
|
||||
(NG_BACK_FROM, '退回供方'),
|
||||
(NG_RECALL, '召回')
|
||||
)
|
||||
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
|
||||
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
||||
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_step')
|
||||
|
@ -69,6 +91,9 @@ class WProduct(CommonAModel):
|
|||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='wproduct_subplan')
|
||||
|
||||
scrap_reason = models.IntegerField('报废原因', choices=scrap_reason_choices, null=True, blank=True)
|
||||
|
||||
ng_sign = models.PositiveSmallIntegerField('不合格标记', choices=ng_choices, null=True, blank=True)
|
||||
|
||||
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
|
||||
|
@ -89,6 +114,7 @@ class WprouctTicket(CommonAModel):
|
|||
"""
|
||||
玻璃审批工单
|
||||
"""
|
||||
|
||||
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||
wproduct = models.ForeignKey(WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
|
||||
material = models.ForeignKey(Material, verbose_name='所在物料状态', on_delete=models.CASCADE)
|
||||
|
@ -96,7 +122,7 @@ class WprouctTicket(CommonAModel):
|
|||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE)
|
||||
|
||||
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket')
|
||||
decision = models.CharField('最终决定', null=True, blank=True, max_length=100)
|
||||
decision = models.PositiveSmallIntegerField('最终决定', choices=WProduct.ng_choices, null=True, blank=True)
|
||||
|
||||
class Pick(CommonADModel):
|
||||
"""
|
||||
|
|
|
@ -46,17 +46,18 @@ class WpmServies(object):
|
|||
if is_testok:
|
||||
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST: # 复检
|
||||
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
||||
wproduct.ng_sign = None # 把不合格标记去除
|
||||
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.material.type == Material.MA_TYPE_GOOD: # 成品检验
|
||||
wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST
|
||||
else:
|
||||
wproduct.act_state = WProduct.WPR_ACT_STATE_OK
|
||||
if wproduct.number is None: # 产生半成品编号
|
||||
wproduct.number = 'WP'+ranstr(7)
|
||||
# 更新子计划状态
|
||||
# 更新子计划主产品数
|
||||
|
||||
# 更新子计划合格进度
|
||||
instance = 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.count_ok = instance.count_ok + 1
|
||||
instance.save()
|
||||
else:# 如果不合格
|
||||
wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
from django.db.models.signals import post_save
|
||||
from apps.mtm.models import SubprodctionMaterial
|
||||
from apps.pm.models import SubProductionProgress
|
||||
from apps.qm.models import TestRecord
|
||||
from apps.wf.models import Ticket
|
||||
from django.dispatch import receiver
|
||||
|
||||
from rest_framework import exceptions
|
||||
from apps.wpm.models import WProduct, WprouctTicket
|
||||
from apps.wpm.models import OperationWproduct
|
||||
|
||||
|
||||
@receiver(post_save, sender=Ticket)
|
||||
|
@ -43,18 +46,41 @@ def handleTicket(sender, instance, created, **kwargs):
|
|||
ticket_data = instance.ticket_data
|
||||
wt = instance.wt_ticket
|
||||
wp = wt.wproduct
|
||||
decision = WProduct.NG_BACK_WORK
|
||||
|
||||
if 'decision_1' in ticket_data and ticket_data['decision_1']:
|
||||
wt.decision = ticket_data['decision_1']
|
||||
if ticket_data['decision_1'] in ['返工', '返修']:
|
||||
pass
|
||||
elif ticket_data['decision_1'] in ['让步接收']:
|
||||
wp.act_state = WProduct.WPR_ACT_STATE_OK
|
||||
decision = ticket_data['decision_1']
|
||||
elif 'decision_2' in ticket_data and ticket_data['decision_2']:
|
||||
wp.decision = ticket_data['decision_2']
|
||||
if ticket_data['decision_2'] in ['返工', '返修']:
|
||||
pass
|
||||
elif ticket_data['decision_2'] in ['让步接收']:
|
||||
wp.act_state = WProduct.WPR_ACT_STATE_OK
|
||||
wt.save()
|
||||
wp.save()
|
||||
decision = ticket_data['decision_2']
|
||||
|
||||
|
||||
wp.ng_sign = decision
|
||||
if decision in [WProduct.NG_BACK_WORK, WProduct.NG_BACK_FIX]:
|
||||
step = ticket_data['back_step']
|
||||
wp.step = step
|
||||
# 找到当时所属的计划
|
||||
sp = OperationWproduct.objects.filter(operation__is_submited=True, operation__step=step).first()
|
||||
if sp:
|
||||
wp.subproduction_plan = sp
|
||||
wt.save()
|
||||
wp.ticket = None # 解除当前工单
|
||||
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()
|
||||
|
||||
else:
|
||||
raise exceptions.APIException('返回步骤点错误')
|
||||
|
||||
elif decision in [WProduct.NG_ACCEPT, WProduct.NG_PERMIT]:
|
||||
wp.act_state = WProduct.WPR_ACT_STATE_OK
|
||||
wp.ng_sign = decision
|
||||
wt.save()
|
||||
wp.ticket = None # 解除当前工单
|
||||
wp.save()
|
||||
|
||||
|
||||
|
|
@ -370,8 +370,8 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
|||
发起不合格审理单
|
||||
"""
|
||||
obj = self.get_object()
|
||||
if obj.act_state != WProduct.WPR_ACT_STATE_NOTOK:
|
||||
raise exceptions.APIException('非检验不合格产品不可发起不合格审理')
|
||||
if obj.act_state != WProduct.WPR_ACT_STATE_NOTOK or obj.ng_sign is not None:
|
||||
raise exceptions.APIException('该产品不可发起不合格审理')
|
||||
workflow = Workflow.objects.filter(name='不合格品审理单', is_deleted=False).first()
|
||||
if workflow:
|
||||
exist_data = {
|
||||
|
@ -539,11 +539,13 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
else:
|
||||
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
||||
wp.material = wsp.main_product
|
||||
# 更新子计划进度
|
||||
instance = SubProductionProgress.objects.get(subproduction_plan=wsp,
|
||||
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||
instance.count_real = instance.count_real + 1 # 这个地方可能会有问题,不够严谨
|
||||
instance.save()
|
||||
# 更新子计划生产进度
|
||||
# 如果产品有返工标记不做计算
|
||||
if wp.ng_sign not in [WProduct.NG_BACK_FIX, WProduct.NG_BACK_WORK]:
|
||||
instance = SubProductionProgress.objects.get(subproduction_plan=wsp,
|
||||
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
||||
instance.count_real = instance.count_real + 1 # 这个地方可能会有问题,不够严谨
|
||||
instance.save()
|
||||
wp.operation = None
|
||||
wp.update_by = request.user
|
||||
wp.save()
|
||||
|
|
Loading…
Reference in New Issue