diff --git a/apps/inm/services.py b/apps/inm/services.py index 8316013f..51faed2f 100644 --- a/apps/inm/services.py +++ b/apps/inm/services.py @@ -438,3 +438,23 @@ class InmService: ana_batch_thread(xbatchs) + + def revert_and_del(cls, mioitem: MIOItem): + mio:MIO = MIOItem.mio + if mio.submit_time is None: + raise ParseError("未提交的出入库明细不允许撤销") + if mioitem.test_date is not None: + raise ParseError("已检验的出入库明细不允许撤销") + if mio.type == MIO.MIO_TYPE_PUR_IN: + from apps.pum.services import PumService + cls.update_mb_item(mioitem, -1) + PumService.mio_purin(mio=mio, is_reverse=True, mioitem=mioitem) + mioitem.delete() + elif mio.type == MIO.MIO_TYPE_OTHER_IN: + cls.update_mb_item(mioitem, -1) + mioitem.delete() + elif mio.type == MIO.MIO_TYPE_DO_OUT: + do_in(mioitem) + mioitem.delete() + else: + raise ParseError("不支持该出入库单明细撤销") \ No newline at end of file diff --git a/apps/inm/views.py b/apps/inm/views.py index 5be1edfb..6fec5a4a 100644 --- a/apps/inm/views.py +++ b/apps/inm/views.py @@ -291,6 +291,17 @@ class MIOItemViewSet(CustomListModelMixin, BulkCreateModelMixin, BulkDestroyMode raise PermissionDenied('无权限删除') return super().perform_destroy(instance) + @action(methods=['post'], detail=True, perms_map={'post': 'mio.update'}) + def revert_and_del(self, request, *args, **kwargs): + """撤回并删除 + + 撤回并删除 + """ + ins:MIOItem = self.get_object() + InmService.revert_and_del(ins) + return Response() + + @action(methods=['post'], detail=True, perms_map={'post': 'mioitem.test'}, serializer_class=MIOItemTestSerializer) @transaction.atomic def test(self, request, *args, **kwargs): diff --git a/apps/pum/services.py b/apps/pum/services.py index ac7aaa92..b6233d2e 100644 --- a/apps/pum/services.py +++ b/apps/pum/services.py @@ -6,16 +6,19 @@ from apps.inm.models import MIO, MIOItem class PumService: + @staticmethod def cal_pu_order_total_price(puorder: PuOrder): total_price = PuOrderItem.objects.filter(pu_order=puorder).aggregate(total=Sum("total_price"))["total"] or 0 puorder.total_price = total_price puorder.save() + @staticmethod def cal_pu_plan_total_price(puplan: PuPlan): total_price = PuPlanItem.objects.filter(pu_plan=puplan).aggregate(total=Sum("total_price"))["total"] or 0 puplan.total_price = total_price puplan.save() + @staticmethod def change_puplan_state_when_puorder_sumbit(puorder: PuOrder): puplanIds = PuPlanItem.objects.filter( pu_order=puorder).values_list('pu_plan', flat=True) @@ -29,14 +32,19 @@ class PumService: puplan.state = state puplan.save() - def mio_purin(mio: MIO, is_reverse: bool = False): + @staticmethod + def mio_purin(mio: MIO, is_reverse: bool = False, mioitem: MIOItem = None): """ 采购入库成功后的操作 """ pu_order = mio.pu_order if pu_order is None: return - for i in MIOItem.objects.filter(mio=mio): + if mioitem is None: + qs = MIOItem.objects.filter(mio=mio) + else: + qs = MIOItem.objects.filter(id=mioitem.id) + for i in qs: pu_orderitem = PuOrderItem.objects.get( material=i.material, pu_order=pu_order) if is_reverse: diff --git a/apps/wpm/migrations/0118_batchst_mioitem.py b/apps/wpm/migrations/0118_batchst_mioitem.py new file mode 100644 index 00000000..60b076c1 --- /dev/null +++ b/apps/wpm/migrations/0118_batchst_mioitem.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.12 on 2025-06-27 05:25 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('inm', '0031_mioitem_unit_price'), + ('wpm', '0117_alter_handoverbw_handoverb'), + ] + + operations = [ + migrations.AddField( + model_name='batchst', + name='mioitem', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='inm.mioitem', verbose_name='由何出入库记录明细创建'), + ), + ] diff --git a/apps/wpm/models.py b/apps/wpm/models.py index 051a27ae..86344831 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -647,6 +647,7 @@ class BatchSt(BaseModel): data = models.JSONField("数据", default=list, blank=True) material_start = models.ForeignKey(Material, verbose_name="起始物料", on_delete=models.SET_NULL, null=True, blank=True) mio = models.ForeignKey("inm.mio", verbose_name="由何出入库记录创建", on_delete=models.CASCADE, null=True, blank=True) + mioitem = models.ForeignKey("inm.mioitem", verbose_name="由何出入库记录明细创建", on_delete=models.CASCADE, null=True, blank=True) handover = models.ForeignKey(Handover, verbose_name='由何交接记录创建', on_delete=models.CASCADE, null=True, blank=True) mlog = models.ForeignKey(Mlog, verbose_name='由何日志创建', on_delete=models.CASCADE, null=True, blank=True) @@ -654,10 +655,12 @@ class BatchSt(BaseModel): unique_together = [("batch", "version")] @classmethod - def g_create(cls, batch:str, mio=None, handover=None, mlog=None, material_start=None, reuse_node=False, exclude_batchst_ids=[]): + def g_create(cls, batch:str, mio=None, mioitem=None, handover=None, mlog=None, material_start=None, reuse_node=False, exclude_batchst_ids=[]): """ 创建新的批次 """ + if mioitem: + mio = mioitem.mio if mio is None and handover is None and mlog is None: try: node = cls.objects.exclude(id__in=exclude_batchst_ids).get(batch=batch) @@ -689,7 +692,7 @@ class BatchSt(BaseModel): else: latest_version = BatchSt.objects.filter(batch=batch).aggregate(Max("version"))["version__max"] version = latest_version + 1 - ins = cls.objects.create(batch=batch, mio=mio, handover=handover, mlog=mlog, material_start=material_start, version=version) + ins = cls.objects.create(batch=batch, mio=mio, mioitem=mioitem, handover=handover, mlog=mlog, material_start=material_start, version=version) return ins, True @classmethod @@ -733,7 +736,7 @@ class BatchLog(BaseModel): defaults={"relation_type": relation_type}) @classmethod - def clear(cls, handover=None, mlog=None, mio=None): + def clear(cls, handover=None, mlog=None, mio=None, mioitem=None): if handover: cls.objects.filter(handover=handover).delete() BatchSt.objects.filter(handover=handover).delete() @@ -742,6 +745,8 @@ class BatchLog(BaseModel): BatchSt.objects.filter(mlog=mlog).delete() if mio: BatchSt.objects.filter(mio=mio).delete() + if mioitem: + BatchSt.objects.filter(mioitem=mioitem).delete() @classmethod def batches_to(cls, batch:str):