diff --git a/apps/asm/serializers.py b/apps/asm/serializers.py index f6fa70b1..66080407 100644 --- a/apps/asm/serializers.py +++ b/apps/asm/serializers.py @@ -12,6 +12,9 @@ class AssetCateSerializer(CustomModelSerializer): read_only_fields = EXCLUDE_FIELDS class AssetSerializer(CustomModelSerializer): + keep_dept_name = serializers.CharField(source="keep_dept.name", read_only=True) + keeper_name = serializers.CharField(source="keeper.name", read_only=True) + cate_name = serializers.CharField(source="cate.name", read_only=True) class Meta: model = Asset fields = '__all__' diff --git a/apps/asm/views.py b/apps/asm/views.py index 75ff3454..785140c1 100644 --- a/apps/asm/views.py +++ b/apps/asm/views.py @@ -60,5 +60,12 @@ class AssetLogViewSet(TicketMixin, CustomModelViewSet): def gen_other_ticket_data(self, instance:AssetLog): return {"keep_dept_name": instance.keep_dept.name} - + + @staticmethod + def apply(ticket: Ticket, transition, new_ticket_data: dict): + assetlog:AssetLog = ticket.assetlog_ticket + items = assetlog.items + sr = AssetSerializer(data=items, many=True) + sr.is_valid(raise_exception=True) + sr.save(create_by=ticket.create_by) diff --git a/apps/hrm/views.py b/apps/hrm/views.py index 8098a9bc..51324568 100755 --- a/apps/hrm/views.py +++ b/apps/hrm/views.py @@ -401,6 +401,9 @@ class ResignationViewSet(TicketMixin, EuModelViewSet): search_fields = ["employee__name"] workflow_key = "wf_resignation" + def gen_other_ticket_data(self, instance): + return {"employee_name": instance.employee.name} + @staticmethod def update_handle_date(ticket: Ticket, transition, new_ticket_data: dict): handle_date = new_ticket_data.get("handle_date", None) diff --git a/apps/inm/serializers.py b/apps/inm/serializers.py index a1a6a6e6..3f8fdce5 100644 --- a/apps/inm/serializers.py +++ b/apps/inm/serializers.py @@ -247,6 +247,15 @@ class MIOItemAListSerializer(CustomModelSerializer): read_only_fields = EXCLUDE_FIELDS_BASE +class MIOItemListSimpleSerializer(CustomModelSerializer): + warehouse_name = serializers.CharField(source='warehouse.name', read_only=True) + material_name = serializers.StringRelatedField( + source='material', read_only=True) + + class Meta: + model = MIOItem + fields = ["id", "mio", "material", "warehouse", "material_name", "warehouse_name", "batch", "count", "test_date", "count_notok"] + class MIOItemSerializer(CustomModelSerializer): warehouse_name = serializers.CharField(source='warehouse.name', read_only=True) material_ = MaterialSerializer(source='material', read_only=True) diff --git a/apps/inm/views.py b/apps/inm/views.py index e1a3c988..a5d35267 100644 --- a/apps/inm/views.py +++ b/apps/inm/views.py @@ -14,7 +14,7 @@ from apps.inm.serializers import ( MaterialBatchSerializer, WareHourseSerializer, MIOListSerializer, MIOItemSerializer, MioItemAnaSerializer, MIODoSerializer, MIOSaleSerializer, MIOPurSerializer, MIOOtherSerializer, MIOItemCreateSerializer, MaterialBatchDetailSerializer, MIODetailSerializer, MIOItemTestSerializer, MIOItemPurInTestSerializer, - MIOItemwSerializer, MioItemDetailSerializer, PackSerializer, PackMioSerializer) + MIOItemwSerializer, MioItemDetailSerializer, PackSerializer, PackMioSerializer, MIOItemListSimpleSerializer) from apps.inm.serializers2 import MIOItemwCreateUpdateSerializer from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet from apps.inm.services import InmService @@ -163,20 +163,39 @@ class MIOViewSet(CustomModelViewSet): return mio def add_info_for_list(self, data): - # 获取检验状态 - mio_dict = {} + # 1. 收集所有mio的ID + mio_ids = [item['id'] for item in data] + + # 2. 预初始化mio字典和items列表 + mio_dict = {item['id']: { + **item, + 'is_tested': False, # 默认值设为False + 'mioitems': [] + } for item in data} + + # 3. 批量查询MIOItem数据 + if mio_ids: # 避免空查询 + mioitems = MIOItemListSimpleSerializer( + instance=MIOItem.objects.filter( + mio__id__in=mio_ids + ).select_related("warehouse", "material"), + many=True + ).data + + # 4. 单次循环处理所有item + for item in mioitems: + mio_id = item['mio'] + if mio_id in mio_dict: + mio_dict[mio_id]['mioitems'].append(item) + # 更新is_tested状态(只要有一个item有test_date就为True) + if item.get('test_date'): + mio_dict[mio_id]['is_tested'] = True + + # 5. 直接返回原始data列表,避免额外转换 for item in data: - item['is_tested'] = None - mio_dict[item['id']] = item - mioitems = list(MIOItem.objects.filter(mio__id__in=mio_dict.keys()).values_list("mio__id", "test_date")) - for item in mioitems: - mioId, test_date = item - is_tested = False - if test_date: - is_tested = True - mio_dict[mioId]['is_tested'] = is_tested - datax = [mio_dict[key] for key in mio_dict.keys()] - return datax + item.update(mio_dict[item['id']]) + + return data def get_serializer_class(self): if self.action in ['create', 'update', 'partial_update']: diff --git a/apps/qm/services.py b/apps/qm/services.py index a6bb0577..8de5259e 100644 --- a/apps/qm/services.py +++ b/apps/qm/services.py @@ -157,6 +157,43 @@ def ftestwork_submit(ins:FtestWork, user: User): # 触发批次统计分析 ana_batch_thread(xbatchs=[ins.batch]) + +def ftestwork_revert(ins: FtestWork): + wm:WMaterial = ins.wm + if wm and ins.need_update_wm: + fwd_qs = FtestworkDefect.objects.filter(ftestwork=ins) + for item in fwd_qs: + item:FtestworkDefect = item + if item.count > 0: + wm.count = wm.count + item.count + wm.save() + wmstate = WMaterial.WM_OK + if item.defect.okcate == Defect.DEFECT_NOTOK: + wmstate = WMaterial.WM_NOTOK + try: + wmx = WMaterial.objects.get( + material=wm.material, + batch=wm.batch, + mgroup=wm.mgroup, + belong_dept=wm.belong_dept, + state=wmstate, + notok_sign=None, + defect=item.defect, + ) + except Exception as e: + raise ParseError(f'找不到{item.defect.name}的车间库存: {str(e)}') + wmx.count = wmx.count - item.count + if wmx.count < 0: + raise ParseError("数量不足,撤回失败") + wmx.save() + else: + raise ParseError("该检验工作不支持撤回") + ins.submit_user = None + ins.submit_time = None + ins.save() + # 触发批次统计分析 + ana_batch_thread(xbatchs=[ins.batch]) + def bind_ftestwork(ticket: Ticket, transition, new_ticket_data: dict): ins = FtestWork.objects.get(id=new_ticket_data['t_id']) if ins.submit_time is not None: diff --git a/apps/qm/views.py b/apps/qm/views.py index 927fe158..e60d3db2 100644 --- a/apps/qm/views.py +++ b/apps/qm/views.py @@ -17,7 +17,7 @@ from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet from apps.wpm.models import SfLog from apps.qm.filters import QuaStatFilter, TestItemFilter, FtestWorkFilter, QctFilter, FtestFilter from django.db import transaction -from apps.qm.services import ftestwork_submit +from apps.qm.services import ftestwork_submit, ftestwork_revert from apps.wpm.services_2 import ana_batch_thread from apps.wf.models import State # Create your views here. @@ -327,4 +327,20 @@ class FtestWorkViewSet(CustomModelViewSet): ftestwork_submit(ins, request.user) else: raise ParseError('该检验工作已提交') + return Response() + + @action(methods=['post'], detail=True, perms_map={'post': 'ftestwork.submit'}, serializer_class=Serializer) + @transaction.atomic + def revert(self, request, *args, **kwargs): + """撤回检验工作 + + 撤回检验工作 + """ + ins:FtestWork = self.get_object() + if ins.submit_time: + if self.request.user != ins.submit_user: + raise ParseError('只能由提交人撤回') + ftestwork_revert(ins) + else: + raise ParseError('该检验工作未提交') return Response() \ No newline at end of file diff --git a/apps/system/filters.py b/apps/system/filters.py index d3f10c99..481b6398 100755 --- a/apps/system/filters.py +++ b/apps/system/filters.py @@ -45,5 +45,6 @@ class DeptFilterSet(filters.FilterSet): model = Dept fields = { 'type': ['exact', 'in'], - 'name': ['exact', 'in', 'contains'] + 'name': ['exact', 'in', 'contains'], + "parent": ['exact', 'isnull'], } diff --git a/apps/wpm/serializers.py b/apps/wpm/serializers.py index 968ae690..f306bccc 100644 --- a/apps/wpm/serializers.py +++ b/apps/wpm/serializers.py @@ -1049,6 +1049,11 @@ class MlogbwStartTestSerializer(serializers.Serializer): test_equip=test_equip ) +class MlogbOutPatchUpdateSerializer(CustomModelSerializer): + class Meta: + model = Mlogb + fields = ["batch"] + class MlogbOutUpdateSerializer(CustomModelSerializer): mlogbdefect = MlogbDefectSerializer(many=True, required=False) count_json = CountJsonSerializer(required=False, many=True) diff --git a/apps/wpm/services.py b/apps/wpm/services.py index b9dea08d..7b265863 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -172,13 +172,15 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): mgroup = mlog.mgroup process = mgroup.process - into_wm_mgroup = process.into_wm_mgroup - need_store_notok = process.store_notok + stored_mgroup = process.into_wm_mgroup + stored_notok = process.store_notok belong_dept = mgroup.belong_dept material_out: Material = mlog.material_out material_in: Material = mlog.material_in supplier = mlog.supplier # 外协 is_fix = mlog.is_fix + if is_fix: # 如果是返工,直接放到工段下 + stored_mgroup = True m_ins_list = [] m_ins_bl_list = [] @@ -252,7 +254,7 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): Wpr.change_or_new(wpr=item.wpr, old_wm=wm, ftest=item.ftest) # 针对加工前不良的暂时额外处理 - if need_store_notok: + if stored_notok: for item in m_ins_bl_list: material, batch, count, defect, mi_ = item if count <= 0: @@ -275,12 +277,10 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): mlogb_out_qs = Mlogb.objects.filter(mlog=mlog, material_out__isnull=False) - stored_mgroup = into_wm_mgroup - stored_notok = need_store_notok if mlogb_out_qs.exists(): mlogb_out_qs = mlogb_out_qs.filter(need_inout=True) m_outs_list = [(mo.material_out, mo.batch if mo.batch else mlog.batch, mo.count_ok_full if mo.count_ok_full is not None else mo.count_ok, mlog.count_real_eweight, None, mo) for mo in mlogb_out_qs.all()] - if need_store_notok: + if stored_notok: for item in mlogb_out_qs: mbd_qs = MlogbDefect.get_defect_qs_from_mlogb(item) if item.qct is not None or mbd_qs.exists(): @@ -309,7 +309,6 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): if 'count_n_' in f.name and getattr(item, f.name) > 0: notok_sign = f.name.replace('count_n_', '') m_outs_list.append( (item.material_out, item.batch if item.batch else mlog.batch, getattr(item, f.name), mlog.count_real_eweight, notok_sign, item)) - stored_notok = True # 这里有一个漏洞,在产出物为兄弟件的情况下,不合格品的数量是记录在mlog上的, # 而不是mlogb上,以上的额外处理就没有效果了, 不过光子不记录不合格品 else: @@ -339,7 +338,7 @@ def mlog_submit(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): lookup['defect'] = notok_sign_or_defect elif notok_sign_or_defect is not None: lookup['notok_sign'] = notok_sign_or_defect - if into_wm_mgroup: + if stored_mgroup: lookup['mgroup'] = mgroup else: lookup['belong_dept'] = belong_dept @@ -529,7 +528,6 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): # 再生成消耗 m_ins_list = [] m_ins_bl_list = [] - into_wm_mgroup = process.into_wm_mgroup m_ins = Mlogb.objects.filter(mlog=mlog, material_in__isnull=False) if m_ins.exists(): m_ins = m_ins.filter(need_inout=True) @@ -553,7 +551,7 @@ def mlog_revert(mlog: Mlog, user: User, now: Union[datetime.datetime, None]): else: # 针对光子的情况,实际上必须需要wm_in lookup = {'batch': mi_batch, 'material': mi_ma, 'mgroup': None, 'state': WMaterial.WM_OK} - if into_wm_mgroup: + if stored_mgroup: # 退回到本工段 lookup['mgroup'] = mgroup else: @@ -785,7 +783,7 @@ def handover_submit(handover:Handover, user: User, now: Union[datetime.datetime, if handover.type == Handover.H_NORMAL: if mtype == Handover.H_MERGE and handover.new_wm: wm_to = handover.new_wm - if wm_to.state != WMaterial.WM_OK or wm_to.material != wm_from.material or wm_to.defect != wm_from.defect: + if wm_to.state != wm_from.state or wm_to.material != wm_from.material or wm_to.defect != wm_from.defect: raise ParseError("正常合并到的车间库存状态或物料异常") else: wm_to, _ = WMaterial.objects.get_or_create( @@ -952,7 +950,7 @@ def handover_revert(handover:Handover, handler:User=None): ticket:Ticket = handover.ticket if ticket: # 首先把ticket改回开始状态 - WfService.retreat(ticket=ticket, suggestion="撤销交接单", handler=handler, next_handler=handover.create_by) + WfService.retreat(ticket=ticket, suggestion="撤回交接单", handler=handler, next_handler=handover.create_by) mids = [] # handover_type = handover.type # handover_mtype = handover.mtype @@ -973,7 +971,7 @@ def handover_revert(handover:Handover, handler:User=None): wm = item.wm wm_to = item.wm_to if wm is None or wm_to is None: - raise ParseError('该交接单不支持撤销2!') + raise ParseError('该交接单不支持撤回2!') if wm == wm_to: # 此时是自己交给自己,不需要做任何操作 pass @@ -1064,6 +1062,7 @@ def get_batch_dag(batch_number: str, method="full"): } if method == "full": + raise ParseError("不支持获取全局关系链条") # 完整DAG模式 - 收集所有相关批次和边(原逻辑) nodes_set = {batch_ins.id} edges = [] @@ -1120,33 +1119,33 @@ def get_batch_dag(batch_number: str, method="full"): }) # 查询作为source的其他关系 - leftLogs = BatchLog.objects.filter(source_id__in=left_source_ids).exclude(id__in=exist_log_ids) - for log in leftLogs: - source = log.source.id - target = log.target.id - nodes_set.add(log.target.id) - edges.append({ - 'id': log.id, - 'source': source, - 'target': target, - "handover": log.handover.id if log.handover else None, - "mlog": log.mlog.id if log.mlog else None, - 'label': r_dict.get(log.relation_type, ""), - }) + # leftLogs = BatchLog.objects.filter(source_id__in=left_source_ids).exclude(id__in=exist_log_ids) + # for log in leftLogs: + # source = log.source.id + # target = log.target.id + # nodes_set.add(log.target.id) + # edges.append({ + # 'id': log.id, + # 'source': source, + # 'target': target, + # "handover": log.handover.id if log.handover else None, + # "mlog": log.mlog.id if log.mlog else None, + # 'label': r_dict.get(log.relation_type, ""), + # }) - rightLogs = BatchLog.objects.filter(target_id__in=right_target_ids).exclude(id__in=exist_log_ids) - for log in rightLogs: - source = log.source.id - target = log.target.id - nodes_set.add(log.source.id) - edges.append({ - 'id': log.id, - 'source': source, - 'target': target, - "handover": log.handover.id if log.handover else None, - "mlog": log.mlog.id if log.mlog else None, - 'label': r_dict.get(log.relation_type, ""), - }) + # rightLogs = BatchLog.objects.filter(target_id__in=right_target_ids).exclude(id__in=exist_log_ids) + # for log in rightLogs: + # source = log.source.id + # target = log.target.id + # nodes_set.add(log.source.id) + # edges.append({ + # 'id': log.id, + # 'source': source, + # 'target': target, + # "handover": log.handover.id if log.handover else None, + # "mlog": log.mlog.id if log.mlog else None, + # 'label': r_dict.get(log.relation_type, ""), + # }) else: raise ParseError("不支持的查询方法,请使用'full'或'direct'") diff --git a/apps/wpm/views.py b/apps/wpm/views.py index 41f88666..1a0fc458 100644 --- a/apps/wpm/views.py +++ b/apps/wpm/views.py @@ -50,7 +50,8 @@ from .serializers import ( MlogQuickSerializer, MlogbwStartTestSerializer, HandoverListSerializer, - BatchChangeSerializer + BatchChangeSerializer, + MlogbOutPatchUpdateSerializer ) from .services import mlog_submit, handover_submit, mlog_revert, get_batch_dag, handover_revert from apps.wpm.services import mlog_submit_validate, generate_new_batch @@ -446,9 +447,9 @@ class MlogViewSet(CustomModelViewSet): raise ParseError("该日志存在审批!") user = request.user if ins.submit_time is None: - raise ParseError("日志未提交不可撤销") + raise ParseError("日志未提交不可撤回") if user != ins.submit_user: - raise ParseError("非提交人不可撤销!") + raise ParseError("非提交人不可撤回!") now = timezone.now() mlog_revert(ins, user, now) return Response(MlogSerializer(instance=ins).data) @@ -836,7 +837,7 @@ class MlogbInViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, BulkDestroyMode "batch": mlogbin.batch, "batch_ofrom": wm_in.batch_ofrom, "material_ofrom": wm_in.material_ofrom, - "qct": Qct.get(material_out, "process", "out"), + "qct": Qct.get(material_out, "fix" if mlog.is_fix else "process", "out"), } if mtype == Process.PRO_DIV and material_in.tracking == Material.MA_TRACKING_SINGLE: pass @@ -1020,18 +1021,22 @@ class MlogbInViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, BulkDestroyMode class MlogbOutViewSet(BulkUpdateModelMixin, CustomGenericViewSet): - perms_map = {"put": "mlog.update"} + perms_map = {"put": "mlog.update", "patch": "mlog.update"} queryset = Mlogb.objects.filter(material_out__isnull=False) serializer_class = MlogbOutUpdateSerializer + partial_update_serializer_class = MlogbOutPatchUpdateSerializer def perform_update(self, serializer): - ins: Mlogb = serializer.instance - mlog = MlogViewSet.lock_and_check_can_update(ins.mlog) - material_out = serializer.validated_data.get("material_out") - if material_out and material_out.tracking == Material.MA_TRACKING_SINGLE: - raise ParseError("单件产品不支持直接修改") - ins: Mlogb = serializer.save() - mlog.cal_mlog_count_from_mlogb() + if self.request.method == "PATCH": + serializer.save() + else: + ins: Mlogb = serializer.instance + mlog = MlogViewSet.lock_and_check_can_update(ins.mlog) + material_out = serializer.validated_data.get("material_out") + if material_out and material_out.tracking == Material.MA_TRACKING_SINGLE: + raise ParseError("单件产品不支持直接修改") + ins: Mlogb = serializer.save() + mlog.cal_mlog_count_from_mlogb() class FmlogViewSet(CustomModelViewSet): @@ -1074,7 +1079,7 @@ class BatchStViewSet(CustomListModelMixin, ComplexQueryMixin, CustomGenericViewS class MlogbwViewSet(CustomModelViewSet): - perms_map = {"get": "*", "post": "mlog.update", "put": "mlog.update", "delete": "mlog.update"} + perms_map = {"get": "*", "post": "mlog.update", "put": "mlog.update", "delete": "mlog.update", "patch": "mlog.update"} queryset = Mlogbw.objects.all() serializer_class = MlogbwCreateUpdateSerializer list_serializer_class = MlogbwListSerializer diff --git a/apps/wpmw/filters.py b/apps/wpmw/filters.py index fae8b731..36d89328 100644 --- a/apps/wpmw/filters.py +++ b/apps/wpmw/filters.py @@ -17,6 +17,7 @@ class WprFilter(filters.FilterSet): "mb": ["exact", "isnull"], "wm": ["exact", "isnull"], "material__process": ["exact"], + "material__name": ["exact", "contains"], "state": ["exact"], "defects": ["exact"], "number": ["exact"] diff --git a/changelog.md b/changelog.md index 536b772e..00e7c0f9 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,148 @@ +## 3.0.2025122514 +- feat: 新增功能 + - mlogbw patch权限 [caoqianming] + - 固定资产入库流程apply [caoqianming] + - resignation ticket存入employee_name [caoqianming] + - 新增人员交接单及其修改 人员交接时候反存校验 [TianyangZhang] + - asm assetlogcreate [caoqianming] + - base 提交时可变动工单title [caoqianming] + - 车间库存支持传入count_all [caoqianming] + - wmaterial search时去除material__number [caoqianming] + - base ticketmixin 修改 ”perform_update“ bug [TianyangZhang] + - wmaterial添加mlog_date_start筛选条件 [caoqianming] + - 新增hrm --人员交接表 [TianyangZhang] + - asm初步接口 [caoqianming] + - base userfilter获取归属于该部门及以下部门的人 [caoqianming] + - 玻纤添加mioitemw检验导入表 [caoqianming] + - 修改mioitemw test的导入逻辑 [caoqianming] + - 光子六车间批次生产合格率修改 [caoqianming] + - 取消handover_submit无用校验 [caoqianming] + - 合批时校验批次是否已存在 [caoqianming] + - routepack删除时做一下校验 [caoqianming] + - 维修记录初步完成 [caoqianming] + - base ticketmixin传入other_data [caoqianming] + - base 模板字段改为textfield [caoqianming] + - 删除asm同步文件 [caoqianming] + - 修改hrm/urls --EMPneed [TianyangZhang] + - 新增模块固定资产 asm [TianyangZhang] + - 添加员工需求表 [caoqianming] + - route接口增加按product获取总图 [caoqianming] + - base wf增加ticket_count接口添加分类 [caoqianming] + - validate_dag检查检查未到达的物料 [caoqianming] + - 自动生成物料的逻辑优化 [caoqianming] + - cal_x_task_count默认使用target_quantity [caoqianming] + - base wf 捕获expr is None的错误 [caoqianming] + - validate_dag增加传入参数 [caoqianming] + - 改版交接支持拆合批 [caoqianming] + - translate_eval_formula 打印报错信息 [caoqianming] + - base 优化safe_get_or_create [caoqianming] + - base 增加statedetailserializer可返回节点操作人员 [caoqianming] + - 获取batchlog dag数据支持临近节点返回 [caoqianming] + - base ticket create支持transition非必传 [caoqianming] + - 供应商审核通过后即可添加供应商 [caoqianming] + - 校验SupplierAudit供应商名称已存在 [caoqianming] + - material list filter low_inm优化 [caoqianming] + - material list 如需获取库存数据需指定传参 [caoqianming] + - 添加部分索引 [caoqianming] + - base ticket create支持transition非必传 [caoqianming] + - 供应商审核通过后即可添加供应商 [caoqianming] + - 校验SupplierAudit供应商名称已存在 [caoqianming] + - material list filter low_inm优化 [caoqianming] + - material list 如需获取库存数据需指定传参 [caoqianming] + - 添加部分索引 [caoqianming] + - srm -model-Papersecret 增加 organization 申请部门字段 [TianyangZhang] + - 优化mlogbw list接口速度 [caoqianming] + - srm-patent修改字段类型 [TianyangZhang] + - resignation添加ticketrelate_name [caoqianming] + - base get_object加锁时注意is_deleted过滤采用base_manager [caoqianming] + - base wf 调用方法支持静态方法 [caoqianming] + - mlogbw关于wpr的校验修改以支持手动新增 [caoqianming] + - resignatioin提交时调用的方法 [caoqianming] + - ResignationSerializer create bug [caoqianming] + - base ticketmixin添加ticket_auto_submit_on_create [caoqianming] + - resignation添加ticketMixin [caoqianming] + - base wfmixin 修改时校验 [caoqianming] + - base ticketDetail添加create_by_name [caoqianming] + - 短信发送功能未开启 [caoqianming] + - 批次号格式错误的校验 [caoqianming] + - mioitemcreate时接收count_send [caoqianming] + - mioitemw增加筛选条件 [caoqianming] + - wpr_bxerp优化mlogbw的获取 [caoqianming] + - do_out报错更明确 [caoqianming] + - 优化ana batchwork [caoqianming] + - 改版交接支持new_wm [caoqianming] + - ofm-models borrowRecord 增加借阅数量 [TianyangZhang] + - ofm-models fix bug [TianyangZhang] + - feat : ofm -vehicle fix bug [TianyangZhang] + - ofm 修改车辆model 字段 [TianyangZhang] + - ofm-service fix bug [TianyangZhang] + - feat:ofm-service 修改 bug [TianyangZhang] + - ofm -修改 view 字段 [TianyangZhang] + - ofm 修改 ofm 字段 并重新生成迁移文件 [TianyangZhang] + - base workflow添加分类字段 [caoqianming] + - ofm-views 修改 车辆字段 [TianyangZhang] + - ofm-vehicle 修改车辆审批申请 改完按时间段进行选择 [TianyangZhang] + - mioitem添加count_send字段 [caoqianming] + - 校验改版时选择的改版物料 [caoqianming] + - 导入物料明细支持直接从名称等匹配 [caoqianming] + - 增强新批次号校验 [caoqianming] + - 提供修改编号的接口 [caoqianming] + - supplieraudit采用新工作流挂载方式 [caoqianming] + - base 添加ticketmixin可集成到viewset下以支持工作流 [caoqianming] + - base 可跳过短信发送 [caoqianming] + - 反向操作时忽略明细校验 [caoqianming] + - 拦截new_batch的错误 [caoqianming] + - fix 修改 srm 的 views [TianyangZhang] + - base wfservice创建出工单时处理人为提交人 [caoqianming] + - feat:srm fix serializer [TianyangZhang] + - base handle_ticket 完善transition校验 [caoqianming] + - DatasetRecord添加filter [caoqianming] + - handover添加selectfield [caoqianming] + - 交接记录返回material_changed_fname [caoqianming] + - 改版交接必须为合批操作 [caoqianming] + - base 创建数据时检验不包含id2 [caoqianming] + - fix srm serializer [TianyangZhang] + - srm-service 去掉 platform belong_dept [TianyangZhang] + - add new model platform '平台审批' [TianyangZhang] + - base 创建数据时检验不包含id [caoqianming] + - 添加供应商审核 [caoqianming] + - base 开始编写ticketMixin可自动挂载 [caoqianming] + - ResignationSerializer返回employee_id_number [caoqianming] + - base 添加EuModelViewSet [caoqianming] + - 离职申请支持删除 [caoqianming] + - Resignationserializer返回employee_name [caoqianming] + - base handle_ticket 默认参数 [caoqianming] + - 优化bind_resignation [caoqianming] + - base 优化wf create [caoqianming] + - ResignationViewSet添加RetrieveModelMixin [caoqianming] + - bind_resignation bug [caoqianming] + - 返回TicketSimpleSerializer [caoqianming] +- fix: 问题修复 + - repair swaggger显示问题 [caoqianming] + - 修改 ofm - vehicle 中的出发里程 [TianyangZhang] + - handoverserializer 关于new_wm的处理 [caoqianming] + - handovermerge时new_state未定义 [caoqianming] + - 修改印章申请binging_seal [TianyangZhang] + - update_mb_item时考虑检验的存在 [caoqianming] + - hrm-用人需求修改标题模板 [TianyangZhang] + - 先调整asm以启动服务 [caoqianming] + - do_in bug [caoqianming] + - base ticketmixin先创建再handle [caoqianming] + - fix :修改提交审批报错 RelatedManager' object has no attribute 'belong_dept [TianyangZhang] + - fix : srm 修改 paperrecord 字段 cor_author 字段类型 [TianyangZhang] + - fix:srm 修改论文审批 反存 论文台账 主要修改model 字段类型 [TianyangZhang] + - srm 修改专利台账 [TianyangZhang] + - base wfmixin gen_ticket_data保存t_id转为str [caoqianming] + - fix : 修改ofm -views -vehicle && services [TianyangZhang] + - format_json_with_placeholders 处理decimal [caoqianming] + - base wf工作流分类接口detail错误 [caoqianming] + - do_in 可直接取用wm [caoqianming] + - material get_queryset忘记return qs [caoqianming] + - material增加count__gt等查询条件 [caoqianming] + - mioitem create时校验是否混批的bug [caoqianming] + - base handle_ticket处理ticket_title [caoqianming] + - bind_resignation bug [caoqianming] + - clean_data关于material的处理 [caoqianming] ## 3.0.2025120109 - feat: 新增功能 - 供应商审核通过后即可添加供应商 [caoqianming] diff --git a/server/settings.py b/server/settings.py index 4b37f2eb..b6b8b02e 100755 --- a/server/settings.py +++ b/server/settings.py @@ -35,7 +35,7 @@ sys.path.insert(0, os.path.join(BASE_DIR, 'apps')) ALLOWED_HOSTS = ['*'] SYS_NAME = '星途工厂综合管理系统' -SYS_VERSION = '3.0.2025120109' +SYS_VERSION = '3.0.2025122514' X_FRAME_OPTIONS = 'SAMEORIGIN' # Application definition