feat: 支持采购退货
This commit is contained in:
parent
2fbe1620fb
commit
0c7c1e4f17
|
@ -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='出入库类型'),
|
||||
),
|
||||
]
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in New Issue