diff --git a/apps/inm/services.py b/apps/inm/services.py index dc31926e..ee656d10 100644 --- a/apps/inm/services.py +++ b/apps/inm/services.py @@ -10,29 +10,43 @@ from apps.utils.tools import ranstr class InmService: @classmethod - def update_inm(cls, instance: MIO): + def update_inm(cls, instance: MIO, is_reverse: bool = False): """ - 更新库存, 暂不支持反向操作 + 更新库存, 支持反向操作 """ if instance.type in [MIO.MIO_TYPE_PUR_IN, MIO.MIO_TYPE_DO_IN, MIO.MIO_TYPE_OTHER_IN]: # 采购入库, 生产入库, 其他入库 - cls.update_mb(instance) + in_or_out = 1 + if is_reverse: + in_or_out = -1 + cls.update_mb(instance, in_or_out) if instance.type == MIO.MIO_TYPE_PUR_IN: # 需要更新订单 from apps.pum.services import PumService - PumService.mio_purin(instance) + PumService.mio_purin(instance, is_reverse) elif instance.type == MIO.MIO_TYPE_DO_IN: - do_in(instance) + if is_reverse: + do_out(instance) + else: + do_in(instance) elif instance.type in [MIO.MIO_TYPE_DO_OUT, MIO.MIO_TYPE_SALE_OUT, MIO.MIO_TYPE_OTHER_OUT]: # 生产领料 销售出库 - cls.update_mb(instance, -1) + in_or_out = -1 + if is_reverse: + in_or_out = 1 + cls.update_mb(instance, 1) if instance.type == MIO.MIO_TYPE_SALE_OUT: from apps.sam.services import SamService - SamService.mio_saleout(instance) + SamService.mio_saleout(instance, is_reverse) elif instance.type == MIO.MIO_TYPE_DO_OUT: - do_out(instance) + if is_reverse: + do_in(instance) + else: + do_out(instance) @classmethod def update_mb(cls, instance: MIO, in_or_out: int = 1): """ 更新物料批次 + in = 1 + out = -1 """ mioitems = MIOItem.objects.filter(mio=instance) if not mioitems.exists(): diff --git a/apps/inm/views.py b/apps/inm/views.py index b3b9b982..a82db2d8 100644 --- a/apps/inm/views.py +++ b/apps/inm/views.py @@ -186,6 +186,25 @@ class MIOViewSet(CustomModelViewSet): InmService.update_inm(ins) return Response(MIOListSerializer(instance=ins).data) + @action(methods=['post'], detail=True, perms_map={'post': 'mio.submit'}, serializer_class=serializers.Serializer) + @transaction.atomic + def revert(self, request, *args, **kwargs): + """撤回 + + 撤回 + """ + ins = self.get_object() + user = self.request.user + if ins.state != MIO.MIO_SUBMITED: + raise ParseError('记录状态异常') + if ins.submit_user != user: + raise ParseError('非提交人不可撤回') + ins.submit_time = None + ins.state = MIO.MIO_CREATE + ins.save() + InmService.update_inm(ins, is_reverse=True) + return Response() + class MIOItemViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomGenericViewSet): """ diff --git a/apps/pum/services.py b/apps/pum/services.py index b6bc7de5..cd54e4a9 100644 --- a/apps/pum/services.py +++ b/apps/pum/services.py @@ -19,17 +19,24 @@ class PumService: puplan.state = state puplan.save() - def mio_purin(mio: MIO): + def mio_purin(mio: MIO, is_reverse: bool = False): """ 采购入库成功后的操作 """ pu_order = mio.pu_order + if pu_order is None: + return for i in MIOItem.objects.filter(mio=mio): pu_orderitem = PuOrderItem.objects.get( material=i.material, pu_order=pu_order) - delivered_count = pu_orderitem.delivered_count + i.count + if is_reverse: + delivered_count = pu_orderitem.delivered_count - i.count + else: + delivered_count = pu_orderitem.delivered_count + i.count if delivered_count > pu_orderitem.count: raise ValidationError(f'{i.material.name}-超出采购订单所需数量') + elif delivered_count < 0: + raise ValidationError(f'{i.material.name}-数量小于0') pu_orderitem.delivered_count = delivered_count pu_orderitem.save() pu_order_state = PuOrder.PUORDER_SHIP diff --git a/apps/sam/services.py b/apps/sam/services.py index 38a843b2..833cb227 100644 --- a/apps/sam/services.py +++ b/apps/sam/services.py @@ -6,23 +6,32 @@ from apps.inm.models import MIO, MIOItem class SamService: - def mio_saleout(mio: MIO): + def mio_saleout(mio: MIO, is_reverse: bool = False): """ 销售出库成功后的操作 """ order = mio.order + if order is None: + return for i in MIOItem.objects.filter(mio=mio): orderitem = OrderItem.objects.get(order=order, material=i.material) - delivered_count = orderitem.delivered_count + i.count + if is_reverse: + delivered_count = orderitem.delivered_count - i.count + else: + delivered_count = orderitem.delivered_count + i.count if delivered_count > orderitem.count: raise ValidationError((f'{i.material.name}-超出订单所需数量')) + elif delivered_count < 0: + raise ValidationError((f'{i.material.name}-数量小于0')) orderitem.delivered_count = delivered_count orderitem.save() # 更新order的状态 qs = OrderItem.objects.filter( order=order, count__lte=F('delivered_count')) + order_state = Order.ORDER_DOING if qs.exists(): pass else: - order.state = Order.ORDER_DELIVERED - order.save() + order_state = Order.ORDER_DELIVERED + order.state = order_state + order.save() diff --git a/apps/wpm/services.py b/apps/wpm/services.py index ca9e4e67..022a1a9e 100644 --- a/apps/wpm/services.py +++ b/apps/wpm/services.py @@ -84,18 +84,30 @@ def do_out(mio: MIO): do_user = mio.do_user mioitems = MIOItem.objects.filter(mio=mio) for item in mioitems: - wm, new_create = WMaterial.objects.get_or_create(batch=item.batch, material=item.material, - belong_dept=belong_dept, defaults={ - "batch": item.batch, - "material": item.material, - "count": item.count, - "create_by": do_user, - "belong_dept": belong_dept - }) - if not new_create: - wm.count = wm.count + item.count - wm.update_by = do_user - wm.save() + action_list = [] + mias = MIOItemA.objects.filter(mioitem=item) + if mias.exists(): # 组合件入库 + mias_list = list(mias.values_list('material', 'batch', 'rate')) + for i in range(len(mias_list)): + material, batch, rate = mias_list[i] + new_count = rate * item.count # 假设 item.count 存在 + action_list.append([material, batch, new_count]) + else: + action_list = [[item.material, item.batch, item.count]] + for al in action_list: + xmaterial, xbatch, xcount = al + wm, new_create = WMaterial.objects.get_or_create(batch=xbatch, material=xmaterial, + belong_dept=belong_dept, defaults={ + "batch": xbatch, + "material": xmaterial, + "count": xcount, + "create_by": do_user, + "belong_dept": belong_dept + }) + if not new_create: + wm.count = wm.count + item.count + wm.update_by = do_user + wm.save() def do_in(mio: MIO):