From 0c7c1e4f17612980ae73bac83d0645976163370f Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 24 Jul 2025 10:50:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E9=87=87=E8=B4=AD?= =?UTF-8?q?=E9=80=80=E8=B4=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inm/migrations/0032_auto_20250723_1639.py | 23 +++++++++++++++ apps/inm/models.py | 16 +++++++---- apps/inm/services.py | 7 +++++ apps/inm/views.py | 2 +- apps/pum/services.py | 28 +++++++++++++++---- 5 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 apps/inm/migrations/0032_auto_20250723_1639.py diff --git a/apps/inm/migrations/0032_auto_20250723_1639.py b/apps/inm/migrations/0032_auto_20250723_1639.py new file mode 100644 index 00000000..5a7450fb --- /dev/null +++ b/apps/inm/migrations/0032_auto_20250723_1639.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.12 on 2025-07-23 08:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('inm', '0031_mioitem_unit_price'), + ] + + operations = [ + migrations.AddField( + model_name='mioitem', + name='note', + field=models.TextField(blank=True, null=True, verbose_name='备注'), + ), + migrations.AlterField( + model_name='mio', + name='type', + field=models.CharField(choices=[('do_out', '生产领料'), ('sale_out', '销售发货'), ('pur_in', '采购入库'), ('pur_out', '采购退货'), ('do_in', '生产入库'), ('other_in', '其他入库'), ('other_out', '其他出库')], default='do_out', help_text="(('do_out', '生产领料'), ('sale_out', '销售发货'), ('pur_in', '采购入库'), ('pur_out', '采购退货'), ('do_in', '生产入库'), ('other_in', '其他入库'), ('other_out', '其他出库'))", max_length=10, verbose_name='出入库类型'), + ), + ] diff --git a/apps/inm/models.py b/apps/inm/models.py index a0c931b9..70bc36a7 100644 --- a/apps/inm/models.py +++ b/apps/inm/models.py @@ -52,12 +52,13 @@ class MaterialBatchA(BaseModel): MIO_TYPE_PREFIX = { - 'do_out': 'SCLL', # 生产领料 (Shēngchǎn Lǐngliào) - 'sale_out': 'XSFH', # 销售发货 (Xiāoshòu Fāhuò) - 'pur_in': 'CGRK', # 采购入库 (Cǎigòu Rùkù) - 'do_in': 'SCRK', # 生产入库 (Shēngchǎn Rùkù) - 'other_in': 'QTRK', # 其他入库 (Qítā Rùkù) - 'other_out': 'QTCK' # 其他出库 (Qítā Chūkù) + 'do_out': 'SCLL', # 生产领料 + 'sale_out': 'XSFH', # 销售发货 + 'pur_in': 'CGRK', # 采购入库 + 'pur_out': 'CGTH', # 采购退货 + 'do_in': 'SCRK', # 生产入库 + 'other_in': 'QTRK', # 其他入库 + 'other_out': 'QTCK' # 其他出库 } class MIO(CommonBDModel): @@ -67,6 +68,7 @@ class MIO(CommonBDModel): MIO_TYPE_DO_OUT = 'do_out' MIO_TYPE_SALE_OUT = 'sale_out' MIO_TYPE_PUR_IN = 'pur_in' + MIO_TYPE_PUR_OUT = 'pur_out' MIO_TYPE_DO_IN = 'do_in' MIO_TYPE_OTHER_IN = 'other_in' MIO_TYPE_OTHER_OUT = 'other_out' @@ -75,6 +77,7 @@ class MIO(CommonBDModel): (MIO_TYPE_DO_OUT, '生产领料'), (MIO_TYPE_SALE_OUT, '销售发货'), (MIO_TYPE_PUR_IN, '采购入库'), + (MIO_TYPE_PUR_OUT, '采购退货'), (MIO_TYPE_DO_IN, '生产入库'), (MIO_TYPE_OTHER_IN, '其他入库'), (MIO_TYPE_OTHER_OUT, '其他出库') @@ -168,6 +171,7 @@ class MIOItem(BaseModel): count_n_qt = models.PositiveIntegerField('其他', default=0) is_testok = models.BooleanField('检验是否合格', null=True, blank=True) + note = models.TextField('备注', null=True, blank=True) @classmethod def count_fields(cls): diff --git a/apps/inm/services.py b/apps/inm/services.py index a4ac8fee..70e057a0 100644 --- a/apps/inm/services.py +++ b/apps/inm/services.py @@ -288,6 +288,13 @@ class InmService: else: cls.update_mb(instance, 1) PumService.mio_purin(instance, is_reverse) + elif instance.type == MIO.MIO_TYPE_PUR_OUT: + from apps.pum.services import PumService + if is_reverse: + cls.update_mb(instance, 1) + else: + cls.update_mb(instance, -1) + PumService.mio_purout(instance, is_reverse) elif instance.type == MIO.MIO_TYPE_OTHER_IN: if is_reverse: BatchLog.clear(mio=instance) diff --git a/apps/inm/views.py b/apps/inm/views.py index 99385e82..a8e37112 100644 --- a/apps/inm/views.py +++ b/apps/inm/views.py @@ -182,7 +182,7 @@ class MIOViewSet(CustomModelViewSet): if not has_perm(user, ['mio.sale']): raise PermissionDenied return MIOSaleSerializer - elif type == MIO.MIO_TYPE_PUR_IN: + elif type in [MIO.MIO_TYPE_PUR_IN, MIO.MIO_TYPE_PUR_OUT]: if not has_perm(user, ['mio.pur']): raise PermissionDenied return MIOPurSerializer diff --git a/apps/pum/services.py b/apps/pum/services.py index b6233d2e..156f40f3 100644 --- a/apps/pum/services.py +++ b/apps/pum/services.py @@ -2,6 +2,7 @@ from rest_framework.exceptions import ValidationError from apps.pum.models import PuOrderItem, PuPlan, PuPlanItem, PuOrder from django.db.models import F, Sum from apps.inm.models import MIO, MIOItem +from rest_framework.exceptions import ParseError class PumService: @@ -44,17 +45,33 @@ class PumService: 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 mio.type == MIO.MIO_TYPE_PUR_IN: if is_reverse: + xtype = "out" + else: + xtype = "in" + elif mio.type == MIO.MIO_TYPE_PUR_OUT: + if is_reverse: + xtype = "in" + else: + xtype = "out" + + for i in qs: + try: + pu_orderitem = PuOrderItem.objects.get( + material=i.material, pu_order=pu_order) + except PuOrderItem.DoesNotExist: + raise ParseError(f'{str(i.material)}-采购订单中不存在该物料') + if xtype == "out": 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}-超出采购订单所需数量') + raise ValidationError(f'{str(i.material)}-超出采购订单所需数量') elif delivered_count < 0: - raise ValidationError(f'{i.material.name}-数量小于0') + raise ValidationError(f'{str(i.material)}-数量小于0') pu_orderitem.delivered_count = delivered_count pu_orderitem.save() pu_order_state = PuOrder.PUORDER_SHIP @@ -77,3 +94,4 @@ class PumService: if len(states) == 1 and list(states)[0] == PuOrder.PUORDER_DONE: puplan.state = PuPlan.PUPLAN_DONE puplan.save() +