mirror of
https://github.com/himool/HimoolERP.git
synced 2024-09-20 14:56:00 +08:00
feat: 调整
This commit is contained in:
parent
2efdd5c038
commit
88007169df
|
@ -79,9 +79,9 @@
|
||||||
* 仓库
|
* 仓库
|
||||||
* 结算账户
|
* 结算账户
|
||||||
* 收支项目
|
* 收支项目
|
||||||
* 商品管理
|
* 产品管理
|
||||||
* 商品分类
|
* 产品分类
|
||||||
* 商品信息
|
* 产品信息
|
||||||
* 采购管理
|
* 采购管理
|
||||||
* 采购开单
|
* 采购开单
|
||||||
* 采购退货
|
* 采购退货
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
### 界面截图
|
### 界面截图
|
||||||
![首页](https://gitee.com/haioucloud/erp/raw/master/raw/%E9%A6%96%E9%A1%B5.png)
|
![首页](https://gitee.com/haioucloud/erp/raw/master/raw/%E9%A6%96%E9%A1%B5.png)
|
||||||
![报表](https://gitee.com/haioucloud/erp/raw/master/raw/%E6%8A%A5%E8%A1%A8.png)
|
![报表](https://gitee.com/haioucloud/erp/raw/master/raw/%E6%8A%A5%E8%A1%A8.png)
|
||||||
![商品](https://gitee.com/haioucloud/erp/raw/master/raw/%E5%95%86%E5%93%81.png)
|
![产品](https://gitee.com/haioucloud/erp/raw/master/raw/%E5%95%86%E5%93%81.png)
|
||||||
![采购](https://gitee.com/haioucloud/erp/raw/master/raw/%E9%87%87%E8%B4%AD.png)
|
![采购](https://gitee.com/haioucloud/erp/raw/master/raw/%E9%87%87%E8%B4%AD.png)
|
||||||
![库存](https://gitee.com/haioucloud/erp/raw/master/raw/%E5%BA%93%E5%AD%98.png)
|
![库存](https://gitee.com/haioucloud/erp/raw/master/raw/%E5%BA%93%E5%AD%98.png)
|
||||||
![财务](https://gitee.com/haioucloud/erp/raw/master/raw/%E8%B4%A2%E5%8A%A1.png)
|
![财务](https://gitee.com/haioucloud/erp/raw/master/raw/%E8%B4%A2%E5%8A%A1.png)
|
||||||
|
|
|
@ -27,7 +27,7 @@ class InventoryFlow(Model):
|
||||||
VOID_STOCK_TRANSFER_IN = ('void_stock_transfer_in', '作废调拨转入')
|
VOID_STOCK_TRANSFER_IN = ('void_stock_transfer_in', '作废调拨转入')
|
||||||
|
|
||||||
warehouse = ForeignKey('data.Warehouse', on_delete=PROTECT, related_name='inventory_flows', verbose_name='仓库')
|
warehouse = ForeignKey('data.Warehouse', on_delete=PROTECT, related_name='inventory_flows', verbose_name='仓库')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT, related_name='inventory_flows', verbose_name='商品')
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT, related_name='inventory_flows', verbose_name='产品')
|
||||||
type = CharField(max_length=32, choices=Type.choices, verbose_name='流水类型')
|
type = CharField(max_length=32, choices=Type.choices, verbose_name='流水类型')
|
||||||
quantity_before = FloatField(verbose_name='变化之前数量')
|
quantity_before = FloatField(verbose_name='变化之前数量')
|
||||||
quantity_change = FloatField(verbose_name='变化数量')
|
quantity_change = FloatField(verbose_name='变化数量')
|
||||||
|
|
|
@ -7,9 +7,9 @@ from apps.flow.models import *
|
||||||
class InventoryFlowSerializer(BaseSerializer):
|
class InventoryFlowSerializer(BaseSerializer):
|
||||||
warehouse_number = CharField(source='warehouse.number', read_only=True, label='仓库编号')
|
warehouse_number = CharField(source='warehouse.number', read_only=True, label='仓库编号')
|
||||||
warehouse_name = CharField(source='warehouse.name', read_only=True, label='仓库名称')
|
warehouse_name = CharField(source='warehouse.name', read_only=True, label='仓库名称')
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
type_display = CharField(source='get_type_display', read_only=True, label='流水类型')
|
type_display = CharField(source='get_type_display', read_only=True, label='流水类型')
|
||||||
purchase_order_number = CharField(source='purchase_order.number', read_only=True, label='采购单号')
|
purchase_order_number = CharField(source='purchase_order.number', read_only=True, label='采购单号')
|
||||||
|
|
|
@ -3,7 +3,7 @@ from extensions.models import *
|
||||||
|
|
||||||
|
|
||||||
class GoodsCategory(Model):
|
class GoodsCategory(Model):
|
||||||
"""商品分类"""
|
"""产品分类"""
|
||||||
|
|
||||||
name = CharField(max_length=64, verbose_name='名称')
|
name = CharField(max_length=64, verbose_name='名称')
|
||||||
remark = CharField(max_length=256, null=True, blank=True, verbose_name='备注')
|
remark = CharField(max_length=256, null=True, blank=True, verbose_name='备注')
|
||||||
|
@ -14,7 +14,7 @@ class GoodsCategory(Model):
|
||||||
|
|
||||||
|
|
||||||
class GoodsUnit(Model):
|
class GoodsUnit(Model):
|
||||||
"""商品单位"""
|
"""产品单位"""
|
||||||
|
|
||||||
name = CharField(max_length=64, verbose_name='名称')
|
name = CharField(max_length=64, verbose_name='名称')
|
||||||
remark = CharField(max_length=256, null=True, blank=True, verbose_name='备注')
|
remark = CharField(max_length=256, null=True, blank=True, verbose_name='备注')
|
||||||
|
@ -25,15 +25,15 @@ class GoodsUnit(Model):
|
||||||
|
|
||||||
|
|
||||||
class Goods(Model):
|
class Goods(Model):
|
||||||
"""商品"""
|
"""产品"""
|
||||||
|
|
||||||
number = CharField(max_length=32, verbose_name='编号')
|
number = CharField(max_length=32, verbose_name='编号')
|
||||||
name = CharField(max_length=64, verbose_name='名称')
|
name = CharField(max_length=64, verbose_name='名称')
|
||||||
barcode = CharField(max_length=32, null=True, blank=True, verbose_name='条码')
|
barcode = CharField(max_length=32, null=True, blank=True, verbose_name='条码')
|
||||||
category = ForeignKey('goods.GoodsCategory', on_delete=SET_NULL, null=True,
|
category = ForeignKey('goods.GoodsCategory', on_delete=SET_NULL, null=True,
|
||||||
related_name='goods_set', verbose_name='商品分类')
|
related_name='goods_set', verbose_name='产品分类')
|
||||||
unit = ForeignKey('goods.GoodsUnit', on_delete=SET_NULL, null=True,
|
unit = ForeignKey('goods.GoodsUnit', on_delete=SET_NULL, null=True,
|
||||||
related_name='goods_set', verbose_name='商品单位')
|
related_name='goods_set', verbose_name='产品单位')
|
||||||
spec = CharField(max_length=64, null=True, blank=True, verbose_name='规格')
|
spec = CharField(max_length=64, null=True, blank=True, verbose_name='规格')
|
||||||
enable_batch_control = BooleanField(default=False, verbose_name='启用批次控制')
|
enable_batch_control = BooleanField(default=False, verbose_name='启用批次控制')
|
||||||
shelf_life_days = IntegerField(null=True, verbose_name='保质期天数')
|
shelf_life_days = IntegerField(null=True, verbose_name='保质期天数')
|
||||||
|
@ -76,10 +76,10 @@ class Goods(Model):
|
||||||
|
|
||||||
|
|
||||||
class GoodsImage(Model):
|
class GoodsImage(Model):
|
||||||
"""商品图片"""
|
"""产品图片"""
|
||||||
|
|
||||||
goods = ForeignKey('goods.Goods', on_delete=SET_NULL, null=True,
|
goods = ForeignKey('goods.Goods', on_delete=SET_NULL, null=True,
|
||||||
related_name='goods_images', verbose_name='商品')
|
related_name='goods_images', verbose_name='产品')
|
||||||
file = ImageField(verbose_name='文件')
|
file = ImageField(verbose_name='文件')
|
||||||
name = CharField(max_length=256, verbose_name='文件名称')
|
name = CharField(max_length=256, verbose_name='文件名称')
|
||||||
team = ForeignKey('system.Team', on_delete=CASCADE, related_name='goods_images')
|
team = ForeignKey('system.Team', on_delete=CASCADE, related_name='goods_images')
|
||||||
|
@ -91,7 +91,7 @@ class Batch(Model):
|
||||||
number = CharField(max_length=32, verbose_name='编号')
|
number = CharField(max_length=32, verbose_name='编号')
|
||||||
inventory = ForeignKey('goods.Inventory', on_delete=CASCADE, related_name='batchs', verbose_name='库存')
|
inventory = ForeignKey('goods.Inventory', on_delete=CASCADE, related_name='batchs', verbose_name='库存')
|
||||||
warehouse = ForeignKey('data.Warehouse', on_delete=CASCADE, related_name='batchs', verbose_name='仓库')
|
warehouse = ForeignKey('data.Warehouse', on_delete=CASCADE, related_name='batchs', verbose_name='仓库')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=CASCADE, related_name='batchs', verbose_name='商品')
|
goods = ForeignKey('goods.Goods', on_delete=CASCADE, related_name='batchs', verbose_name='产品')
|
||||||
initial_quantity = FloatField(default=0, verbose_name='初始库存')
|
initial_quantity = FloatField(default=0, verbose_name='初始库存')
|
||||||
total_quantity = FloatField(verbose_name='批次数量')
|
total_quantity = FloatField(verbose_name='批次数量')
|
||||||
remain_quantity = FloatField(verbose_name='批次剩余数量')
|
remain_quantity = FloatField(verbose_name='批次剩余数量')
|
||||||
|
@ -110,7 +110,7 @@ class Inventory(Model):
|
||||||
"""库存"""
|
"""库存"""
|
||||||
|
|
||||||
warehouse = ForeignKey('data.Warehouse', on_delete=CASCADE, related_name='inventories', verbose_name='仓库')
|
warehouse = ForeignKey('data.Warehouse', on_delete=CASCADE, related_name='inventories', verbose_name='仓库')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=CASCADE, related_name='inventories', verbose_name='商品')
|
goods = ForeignKey('goods.Goods', on_delete=CASCADE, related_name='inventories', verbose_name='产品')
|
||||||
initial_quantity = FloatField(default=0, verbose_name='初始库存')
|
initial_quantity = FloatField(default=0, verbose_name='初始库存')
|
||||||
total_quantity = FloatField(default=0, verbose_name='库存总数')
|
total_quantity = FloatField(default=0, verbose_name='库存总数')
|
||||||
has_stock = BooleanField(default=False, verbose_name='库存状态')
|
has_stock = BooleanField(default=False, verbose_name='库存状态')
|
||||||
|
|
|
@ -93,7 +93,7 @@ class GoodsSerializer(BaseSerializer):
|
||||||
inventory_items = InventoryItemSerializer(
|
inventory_items = InventoryItemSerializer(
|
||||||
source='inventories', required=False, many=True, label='库存Item')
|
source='inventories', required=False, many=True, label='库存Item')
|
||||||
goods_image_items = GoodsImageItemSerializer(
|
goods_image_items = GoodsImageItemSerializer(
|
||||||
source='goods_images', many=True, read_only=True, label='商品图片Item')
|
source='goods_images', many=True, read_only=True, label='产品图片Item')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Goods
|
model = Goods
|
||||||
|
@ -110,20 +110,20 @@ class GoodsSerializer(BaseSerializer):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def validate_category(self, instance):
|
def validate_category(self, instance):
|
||||||
instance = self.validate_foreign_key(GoodsCategory, instance, message='商品分类不存在')
|
instance = self.validate_foreign_key(GoodsCategory, instance, message='产品分类不存在')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_unit(self, instance):
|
def validate_unit(self, instance):
|
||||||
instance = self.validate_foreign_key(GoodsUnit, instance, message='商品单位不存在')
|
instance = self.validate_foreign_key(GoodsUnit, instance, message='产品单位不存在')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_enable_batch_control(self, value):
|
def validate_enable_batch_control(self, value):
|
||||||
if value and (self.team.enable_auto_stock_in or self.team.enable_auto_stock_out):
|
if value and (self.team.enable_auto_stock_in or self.team.enable_auto_stock_out):
|
||||||
raise ValidationError('只有同时关闭自动入库、自动出库, 才可以开启商品的批次控制')
|
raise ValidationError('只有同时关闭自动入库、自动出库, 才可以开启产品的批次控制')
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def validate_goods_images(self, instances):
|
def validate_goods_images(self, instances):
|
||||||
instances = self.validate_foreign_key_set(GoodsImage, instances, message='商品图片不存在')
|
instances = self.validate_foreign_key_set(GoodsImage, instances, message='产品图片不存在')
|
||||||
return instances
|
return instances
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
|
@ -145,7 +145,7 @@ class GoodsSerializer(BaseSerializer):
|
||||||
|
|
||||||
total_initial_quantity = 0
|
total_initial_quantity = 0
|
||||||
|
|
||||||
# 商品开启批次控制, 创建批次
|
# 产品开启批次控制, 创建批次
|
||||||
batch_items = inventory_item.get('batchs')
|
batch_items = inventory_item.get('batchs')
|
||||||
if goods.enable_batch_control and batch_items:
|
if goods.enable_batch_control and batch_items:
|
||||||
for batch_item in batch_items:
|
for batch_item in batch_items:
|
||||||
|
@ -171,7 +171,7 @@ class GoodsSerializer(BaseSerializer):
|
||||||
inventory.initial_quantity = total_initial_quantity
|
inventory.initial_quantity = total_initial_quantity
|
||||||
inventory.total_quantity = total_initial_quantity
|
inventory.total_quantity = total_initial_quantity
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['initial_quantity', 'total_quantity', 'has_stock'])
|
inventory.save(update_fields=['initial_quantity', 'total_quantity', 'has_stock'])
|
||||||
break
|
break
|
||||||
|
@ -265,7 +265,7 @@ class GoodsSerializer(BaseSerializer):
|
||||||
inventory.initial_quantity = total_initial_quantity
|
inventory.initial_quantity = total_initial_quantity
|
||||||
inventory.total_quantity = NP.plus(inventory.total_quantity, inventory.initial_quantity)
|
inventory.total_quantity = NP.plus(inventory.total_quantity, inventory.initial_quantity)
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['initial_quantity', 'total_quantity', 'has_stock'])
|
inventory.save(update_fields=['initial_quantity', 'total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
|
@ -273,7 +273,7 @@ class GoodsSerializer(BaseSerializer):
|
||||||
inventory.initial_quantity = inventory_initial_quantity
|
inventory.initial_quantity = inventory_initial_quantity
|
||||||
inventory.total_quantity = NP.plus(inventory.total_quantity, inventory.initial_quantity)
|
inventory.total_quantity = NP.plus(inventory.total_quantity, inventory.initial_quantity)
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['initial_quantity', 'total_quantity', 'has_stock'])
|
inventory.save(update_fields=['initial_quantity', 'total_quantity', 'has_stock'])
|
||||||
|
|
||||||
|
@ -290,8 +290,8 @@ class GoodsSerializer(BaseSerializer):
|
||||||
|
|
||||||
|
|
||||||
class GoodsImportExportSerializer(BaseSerializer):
|
class GoodsImportExportSerializer(BaseSerializer):
|
||||||
number = CharField(label='商品编号(唯一必填)')
|
number = CharField(label='产品编号(唯一必填)')
|
||||||
name = CharField(label='商品名称(必填)')
|
name = CharField(label='产品名称(必填)')
|
||||||
barcode = CharField(required=False, label='条码')
|
barcode = CharField(required=False, label='条码')
|
||||||
category = CharField(source='category.name', required=False, label='分类')
|
category = CharField(source='category.name', required=False, label='分类')
|
||||||
unit = CharField(source='unit.name', required=False, label='单位')
|
unit = CharField(source='unit.name', required=False, label='单位')
|
||||||
|
@ -334,9 +334,9 @@ class GoodsImageSerializer(BaseSerializer):
|
||||||
class BatchSerializer(BaseSerializer):
|
class BatchSerializer(BaseSerializer):
|
||||||
warehouse_number = CharField(source='warehouse.number', read_only=True, label='仓库编号')
|
warehouse_number = CharField(source='warehouse.number', read_only=True, label='仓库编号')
|
||||||
warehouse_name = CharField(source='warehouse.name', read_only=True, label='仓库名称')
|
warehouse_name = CharField(source='warehouse.name', read_only=True, label='仓库名称')
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -349,9 +349,9 @@ class BatchSerializer(BaseSerializer):
|
||||||
class InventorySerializer(BaseSerializer):
|
class InventorySerializer(BaseSerializer):
|
||||||
warehouse_number = CharField(source='warehouse.number', read_only=True, label='仓库编号')
|
warehouse_number = CharField(source='warehouse.number', read_only=True, label='仓库编号')
|
||||||
warehouse_name = CharField(source='warehouse.name', read_only=True, label='仓库名称')
|
warehouse_name = CharField(source='warehouse.name', read_only=True, label='仓库名称')
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -12,7 +12,7 @@ from apps.data.models import *
|
||||||
|
|
||||||
|
|
||||||
class GoodsCategoryViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
class GoodsCategoryViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
||||||
"""商品分类"""
|
"""产品分类"""
|
||||||
|
|
||||||
serializer_class = GoodsCategorySerializer
|
serializer_class = GoodsCategorySerializer
|
||||||
permission_classes = [IsAuthenticated, GoodsCategoryPermission]
|
permission_classes = [IsAuthenticated, GoodsCategoryPermission]
|
||||||
|
@ -77,7 +77,7 @@ class GoodsCategoryViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
||||||
|
|
||||||
|
|
||||||
class GoodsUnitViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
class GoodsUnitViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
||||||
"""商品单位"""
|
"""产品单位"""
|
||||||
|
|
||||||
serializer_class = GoodsUnitSerializer
|
serializer_class = GoodsUnitSerializer
|
||||||
permission_classes = [IsAuthenticated, GoodsUnitPermission]
|
permission_classes = [IsAuthenticated, GoodsUnitPermission]
|
||||||
|
@ -142,7 +142,7 @@ class GoodsUnitViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
||||||
|
|
||||||
|
|
||||||
class GoodsViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
class GoodsViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
||||||
"""商品"""
|
"""产品"""
|
||||||
|
|
||||||
serializer_class = GoodsSerializer
|
serializer_class = GoodsSerializer
|
||||||
permission_classes = [IsAuthenticated, GoodsPermission]
|
permission_classes = [IsAuthenticated, GoodsPermission]
|
||||||
|
@ -250,7 +250,7 @@ class GoodsViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
||||||
|
|
||||||
|
|
||||||
class GoodsImageViewSet(ModelViewSet):
|
class GoodsImageViewSet(ModelViewSet):
|
||||||
"""商品图片"""
|
"""产品图片"""
|
||||||
|
|
||||||
serializer_class = GoodsImageSerializer
|
serializer_class = GoodsImageSerializer
|
||||||
permission_classes = [IsAuthenticated, GoodsPermission]
|
permission_classes = [IsAuthenticated, GoodsPermission]
|
||||||
|
|
|
@ -2,10 +2,10 @@ from extensions.serializers import *
|
||||||
|
|
||||||
|
|
||||||
class InventoryWarningResponse(Serializer):
|
class InventoryWarningResponse(Serializer):
|
||||||
goods = IntegerField(label='商品ID')
|
goods = IntegerField(label='产品ID')
|
||||||
goods_number = CharField(label='商品编号')
|
goods_number = CharField(label='产品编号')
|
||||||
goods_name = CharField(label='商品名称')
|
goods_name = CharField(label='产品名称')
|
||||||
goods_barcode = CharField(label='商品条码')
|
goods_barcode = CharField(label='产品条码')
|
||||||
unit_name = CharField(label='单位名称')
|
unit_name = CharField(label='单位名称')
|
||||||
inventory_upper = FloatField(label='库存上限')
|
inventory_upper = FloatField(label='库存上限')
|
||||||
inventory_lower = FloatField(label='库存下限')
|
inventory_lower = FloatField(label='库存下限')
|
||||||
|
|
|
@ -8,7 +8,7 @@ from apps.sales.models import *
|
||||||
# Goods
|
# Goods
|
||||||
class BatchOptionFilter(FilterSet):
|
class BatchOptionFilter(FilterSet):
|
||||||
warehouse = NumberFilter(field_name='warehouse', required=True, label='仓库')
|
warehouse = NumberFilter(field_name='warehouse', required=True, label='仓库')
|
||||||
goods = NumberFilter(field_name='goods', required=True, label='商品')
|
goods = NumberFilter(field_name='goods', required=True, label='产品')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Batch
|
model = Batch
|
||||||
|
@ -17,8 +17,8 @@ class BatchOptionFilter(FilterSet):
|
||||||
|
|
||||||
class InventoryOptionFilter(FilterSet):
|
class InventoryOptionFilter(FilterSet):
|
||||||
warehouse = NumberFilter(field_name='warehouse', required=True, label='仓库')
|
warehouse = NumberFilter(field_name='warehouse', required=True, label='仓库')
|
||||||
category = NumberFilter(field_name='goods__category', label='商品分类')
|
category = NumberFilter(field_name='goods__category', label='产品分类')
|
||||||
is_active = BooleanFilter(field_name='goods__is_active', label='商品激活状态')
|
is_active = BooleanFilter(field_name='goods__is_active', label='产品激活状态')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Inventory
|
model = Inventory
|
||||||
|
|
|
@ -92,10 +92,10 @@ class BatchOptionSerializer(ModelSerializer):
|
||||||
|
|
||||||
|
|
||||||
class InventoryOptionSerializer(ModelSerializer):
|
class InventoryOptionSerializer(ModelSerializer):
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
goods_spec = CharField(source='goods.spec', read_only=True, label='商品规格')
|
goods_spec = CharField(source='goods.spec', read_only=True, label='产品规格')
|
||||||
purchase_price = FloatField(source='goods.purchase_price', read_only=True, label='采购价')
|
purchase_price = FloatField(source='goods.purchase_price', read_only=True, label='采购价')
|
||||||
retail_price = FloatField(source='goods.retail_price', read_only=True, label='零售价')
|
retail_price = FloatField(source='goods.retail_price', read_only=True, label='零售价')
|
||||||
level_price1 = FloatField(source='goods.level_price1', read_only=True, label='等级价一')
|
level_price1 = FloatField(source='goods.level_price1', read_only=True, label='等级价一')
|
||||||
|
@ -116,9 +116,9 @@ class InventoryOptionSerializer(ModelSerializer):
|
||||||
class PurchaseOrderOptionSerializer(ModelSerializer):
|
class PurchaseOrderOptionSerializer(ModelSerializer):
|
||||||
|
|
||||||
class PurchaseGoodsItemSerializer(ModelSerializer):
|
class PurchaseGoodsItemSerializer(ModelSerializer):
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -141,7 +141,7 @@ class PurchaseOrderOptionSerializer(ModelSerializer):
|
||||||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
purchase_goods_items = PurchaseGoodsItemSerializer(
|
purchase_goods_items = PurchaseGoodsItemSerializer(
|
||||||
source='purchase_goods_set', many=True, label='采购商品Item')
|
source='purchase_goods_set', many=True, label='采购产品Item')
|
||||||
purchase_account_items = PurchaseAccountItemSerializer(
|
purchase_account_items = PurchaseAccountItemSerializer(
|
||||||
source='purchase_accounts', required=False, many=True, label='采购结算账户Item')
|
source='purchase_accounts', required=False, many=True, label='采购结算账户Item')
|
||||||
|
|
||||||
|
@ -158,9 +158,9 @@ class PurchaseOrderOptionSerializer(ModelSerializer):
|
||||||
class SalesOrderOptionSerializer(ModelSerializer):
|
class SalesOrderOptionSerializer(ModelSerializer):
|
||||||
|
|
||||||
class SalesGoodsItemSerializer(ModelSerializer):
|
class SalesGoodsItemSerializer(ModelSerializer):
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -183,7 +183,7 @@ class SalesOrderOptionSerializer(ModelSerializer):
|
||||||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
sales_goods_items = SalesGoodsItemSerializer(
|
sales_goods_items = SalesGoodsItemSerializer(
|
||||||
source='sales_goods_set', many=True, label='采购商品Item')
|
source='sales_goods_set', many=True, label='采购产品Item')
|
||||||
sales_account_items = SalesAccountItemSerializer(
|
sales_account_items = SalesAccountItemSerializer(
|
||||||
source='sales_accounts', required=False, many=True, label='采购结算账户Item')
|
source='sales_accounts', required=False, many=True, label='采购结算账户Item')
|
||||||
|
|
||||||
|
|
0
apps/production/__init__.py
Normal file
0
apps/production/__init__.py
Normal file
3
apps/production/admin.py
Normal file
3
apps/production/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
6
apps/production/apps.py
Normal file
6
apps/production/apps.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class ProductionConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'apps.production'
|
7
apps/production/filters.py
Normal file
7
apps/production/filters.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
from django_filters.rest_framework import FilterSet
|
||||||
|
from django_filters.filters import *
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
|
||||||
|
]
|
0
apps/production/migrations/__init__.py
Normal file
0
apps/production/migrations/__init__.py
Normal file
36
apps/production/models.py
Normal file
36
apps/production/models.py
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
from extensions.models import *
|
||||||
|
|
||||||
|
|
||||||
|
class ProductionOrder(Model):
|
||||||
|
"""生产单据"""
|
||||||
|
|
||||||
|
number = CharField(max_length=32, verbose_name='编号')
|
||||||
|
is_related = BooleanField()
|
||||||
|
sales_order = ForeignKey()
|
||||||
|
warehouse = ForeignKey('data.Warehouse', on_delete=PROTECT, related_name='sales_orders', verbose_name='仓库')
|
||||||
|
goods = ForeignKey()
|
||||||
|
total_quantity = FloatField()
|
||||||
|
start_time = DateTimeField()
|
||||||
|
end_time = DateTimeField()
|
||||||
|
creator = ForeignKey('system.User', on_delete=PROTECT,
|
||||||
|
related_name='created_sales_orders', verbose_name='创建人')
|
||||||
|
create_time = DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||||
|
team = ForeignKey('system.Team', on_delete=CASCADE, related_name='sales_orders')
|
||||||
|
|
||||||
|
|
||||||
|
class ProductionRecord(Model):
|
||||||
|
"""生产记录"""
|
||||||
|
|
||||||
|
production_order = ForeignKey()
|
||||||
|
warehouse = ForeignKey('data.Warehouse', on_delete=PROTECT, related_name='sales_orders', verbose_name='仓库')
|
||||||
|
goods = ForeignKey()
|
||||||
|
production_quantity = FloatField()
|
||||||
|
creator = ForeignKey('system.User', on_delete=PROTECT,
|
||||||
|
related_name='created_sales_orders', verbose_name='创建人')
|
||||||
|
create_time = DateTimeField(auto_now_add=True, verbose_name='创建时间')
|
||||||
|
team = ForeignKey('system.Team', on_delete=CASCADE, related_name='sales_orders')
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'ProductionPlan', 'ProductionRecord',
|
||||||
|
]
|
6
apps/production/permissions.py
Normal file
6
apps/production/permissions.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from extensions.permissions import ModelPermission
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
|
||||||
|
]
|
6
apps/production/schemas.py
Normal file
6
apps/production/schemas.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from extensions.serializers import *
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
|
||||||
|
]
|
8
apps/production/serializers.py
Normal file
8
apps/production/serializers.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from extensions.common.base import *
|
||||||
|
from extensions.serializers import *
|
||||||
|
from extensions.exceptions import *
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
|
||||||
|
]
|
3
apps/production/tests.py
Normal file
3
apps/production/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
5
apps/production/urls.py
Normal file
5
apps/production/urls.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from extensions.routers import *
|
||||||
|
|
||||||
|
|
||||||
|
router = BaseRouter()
|
||||||
|
urlpatterns = router.urls
|
10
apps/production/views.py
Normal file
10
apps/production/views.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from extensions.common.schema import *
|
||||||
|
from extensions.common.base import *
|
||||||
|
from extensions.permissions import *
|
||||||
|
from extensions.exceptions import *
|
||||||
|
from extensions.viewsets import *
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
|
||||||
|
]
|
|
@ -41,11 +41,11 @@ class PurchaseOrder(Model):
|
||||||
|
|
||||||
|
|
||||||
class PurchaseGoods(Model):
|
class PurchaseGoods(Model):
|
||||||
"""采购商品"""
|
"""采购产品"""
|
||||||
|
|
||||||
purchase_order = ForeignKey('purchase.PurchaseOrder', on_delete=CASCADE,
|
purchase_order = ForeignKey('purchase.PurchaseOrder', on_delete=CASCADE,
|
||||||
related_name='purchase_goods_set', verbose_name='采购单据')
|
related_name='purchase_goods_set', verbose_name='采购单据')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT, related_name='purchase_goods_set', verbose_name='商品')
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT, related_name='purchase_goods_set', verbose_name='产品')
|
||||||
purchase_quantity = FloatField(verbose_name='采购数量')
|
purchase_quantity = FloatField(verbose_name='采购数量')
|
||||||
purchase_price = FloatField(verbose_name='采购单价')
|
purchase_price = FloatField(verbose_name='采购单价')
|
||||||
total_amount = AmountField(verbose_name='总金额')
|
total_amount = AmountField(verbose_name='总金额')
|
||||||
|
@ -110,14 +110,14 @@ class PurchaseReturnOrder(Model):
|
||||||
|
|
||||||
|
|
||||||
class PurchaseReturnGoods(Model):
|
class PurchaseReturnGoods(Model):
|
||||||
"""采购退货商品"""
|
"""采购退货产品"""
|
||||||
|
|
||||||
purchase_return_order = ForeignKey('purchase.PurchaseReturnOrder', on_delete=CASCADE,
|
purchase_return_order = ForeignKey('purchase.PurchaseReturnOrder', on_delete=CASCADE,
|
||||||
related_name='purchase_return_goods_set', verbose_name='采购退货单据')
|
related_name='purchase_return_goods_set', verbose_name='采购退货单据')
|
||||||
purchase_goods = ForeignKey('purchase.PurchaseGoods', on_delete=CASCADE, null=True,
|
purchase_goods = ForeignKey('purchase.PurchaseGoods', on_delete=CASCADE, null=True,
|
||||||
related_name='purchase_return_goods_set', verbose_name='采购商品')
|
related_name='purchase_return_goods_set', verbose_name='采购产品')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
||||||
related_name='purchase_return_goods_set', verbose_name='商品')
|
related_name='purchase_return_goods_set', verbose_name='产品')
|
||||||
return_quantity = FloatField(verbose_name='退货数量')
|
return_quantity = FloatField(verbose_name='退货数量')
|
||||||
return_price = FloatField(verbose_name='退货单价')
|
return_price = FloatField(verbose_name='退货单价')
|
||||||
total_amount = AmountField(verbose_name='总金额')
|
total_amount = AmountField(verbose_name='总金额')
|
||||||
|
|
|
@ -12,11 +12,11 @@ class PurchaseOrderSerializer(BaseSerializer):
|
||||||
"""采购单据"""
|
"""采购单据"""
|
||||||
|
|
||||||
class PurchaseGoodsItemSerializer(BaseSerializer):
|
class PurchaseGoodsItemSerializer(BaseSerializer):
|
||||||
"""采购商品"""
|
"""采购产品"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -26,9 +26,9 @@ class PurchaseOrderSerializer(BaseSerializer):
|
||||||
fields = ['goods', 'purchase_quantity', 'purchase_price', *read_only_fields]
|
fields = ['goods', 'purchase_quantity', 'purchase_price', *read_only_fields]
|
||||||
|
|
||||||
def validate_goods(self, instance):
|
def validate_goods(self, instance):
|
||||||
instance = self.validate_foreign_key(Goods, instance, message='商品不存在')
|
instance = self.validate_foreign_key(Goods, instance, message='产品不存在')
|
||||||
if not instance.is_active:
|
if not instance.is_active:
|
||||||
raise ValidationError(f'商品[{instance.name}]未激活')
|
raise ValidationError(f'产品[{instance.name}]未激活')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_purchase_quantity(self, value):
|
def validate_purchase_quantity(self, value):
|
||||||
|
@ -70,7 +70,7 @@ class PurchaseOrderSerializer(BaseSerializer):
|
||||||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
purchase_goods_items = PurchaseGoodsItemSerializer(
|
purchase_goods_items = PurchaseGoodsItemSerializer(
|
||||||
source='purchase_goods_set', many=True, label='采购商品Item')
|
source='purchase_goods_set', many=True, label='采购产品Item')
|
||||||
purchase_account_items = PurchaseAccountItemSerializer(
|
purchase_account_items = PurchaseAccountItemSerializer(
|
||||||
source='purchase_accounts', required=False, many=True, label='采购结算账户Item')
|
source='purchase_accounts', required=False, many=True, label='采购结算账户Item')
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ class PurchaseOrderSerializer(BaseSerializer):
|
||||||
total_purchase_quantity = 0
|
total_purchase_quantity = 0
|
||||||
total_purchase_amount = 0
|
total_purchase_amount = 0
|
||||||
|
|
||||||
# 创建采购商品
|
# 创建采购产品
|
||||||
purchase_goods_set = []
|
purchase_goods_set = []
|
||||||
for purchase_goods_item in purchase_goods_items:
|
for purchase_goods_item in purchase_goods_items:
|
||||||
purchase_quantity = purchase_goods_item['purchase_quantity']
|
purchase_quantity = purchase_goods_item['purchase_quantity']
|
||||||
|
@ -171,11 +171,11 @@ class PurchaseReturnOrderSerializer(BaseSerializer):
|
||||||
"""采购退货单据"""
|
"""采购退货单据"""
|
||||||
|
|
||||||
class PurchaseReturnGoodsItemSerializer(BaseSerializer):
|
class PurchaseReturnGoodsItemSerializer(BaseSerializer):
|
||||||
"""采购退货商品"""
|
"""采购退货产品"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -185,13 +185,13 @@ class PurchaseReturnOrderSerializer(BaseSerializer):
|
||||||
fields = ['purchase_goods', 'goods', 'return_quantity', 'return_price', *read_only_fields]
|
fields = ['purchase_goods', 'goods', 'return_quantity', 'return_price', *read_only_fields]
|
||||||
|
|
||||||
def validate_purchase_goods(self, instance):
|
def validate_purchase_goods(self, instance):
|
||||||
instance = self.validate_foreign_key(PurchaseGoods, instance, message='采购商品不存在')
|
instance = self.validate_foreign_key(PurchaseGoods, instance, message='采购产品不存在')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_goods(self, instance):
|
def validate_goods(self, instance):
|
||||||
instance = self.validate_foreign_key(Goods, instance, message='商品不存在')
|
instance = self.validate_foreign_key(Goods, instance, message='产品不存在')
|
||||||
if not instance.is_active:
|
if not instance.is_active:
|
||||||
raise ValidationError(f'商品[{instance.name}]未激活')
|
raise ValidationError(f'产品[{instance.name}]未激活')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_return_quantity(self, value):
|
def validate_return_quantity(self, value):
|
||||||
|
@ -234,7 +234,7 @@ class PurchaseReturnOrderSerializer(BaseSerializer):
|
||||||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
purchase_return_goods_items = PurchaseReturnGoodsItemSerializer(
|
purchase_return_goods_items = PurchaseReturnGoodsItemSerializer(
|
||||||
source='purchase_return_goods_set', many=True, label='采购退货商品Item')
|
source='purchase_return_goods_set', many=True, label='采购退货产品Item')
|
||||||
purchase_return_account_items = PurchaseReturnAccountItemSerializer(
|
purchase_return_account_items = PurchaseReturnAccountItemSerializer(
|
||||||
source='purchase_return_accounts', required=False, many=True, label='采购退货结算账户Item')
|
source='purchase_return_accounts', required=False, many=True, label='采购退货结算账户Item')
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ class PurchaseReturnOrderSerializer(BaseSerializer):
|
||||||
total_return_quantity = 0
|
total_return_quantity = 0
|
||||||
total_return_amount = 0
|
total_return_amount = 0
|
||||||
|
|
||||||
# 创建采购退货商品
|
# 创建采购退货产品
|
||||||
purchase_return_goods_set = []
|
purchase_return_goods_set = []
|
||||||
for purchase_return_goods_item in purchase_return_goods_items:
|
for purchase_return_goods_item in purchase_return_goods_items:
|
||||||
goods = purchase_return_goods_item['goods']
|
goods = purchase_return_goods_item['goods']
|
||||||
|
@ -308,13 +308,13 @@ class PurchaseReturnOrderSerializer(BaseSerializer):
|
||||||
purchase_goods = None
|
purchase_goods = None
|
||||||
if purchase_order := purchase_return_order.purchase_order:
|
if purchase_order := purchase_return_order.purchase_order:
|
||||||
if not (purchase_goods := purchase_return_goods_item.get('purchase_goods')):
|
if not (purchase_goods := purchase_return_goods_item.get('purchase_goods')):
|
||||||
raise ValidationError(f'采购单据[{purchase_order.number}]不存在商品[{goods.name}]')
|
raise ValidationError(f'采购单据[{purchase_order.number}]不存在产品[{goods.name}]')
|
||||||
|
|
||||||
purchase_goods.return_quantity = NP.plus(purchase_goods.return_quantity, return_quantity)
|
purchase_goods.return_quantity = NP.plus(purchase_goods.return_quantity, return_quantity)
|
||||||
if purchase_goods.return_quantity > purchase_goods.purchase_quantity:
|
if purchase_goods.return_quantity > purchase_goods.purchase_quantity:
|
||||||
raise ValidationError(f'退货商品[{goods.name}]退货数量错误')
|
raise ValidationError(f'退货产品[{goods.name}]退货数量错误')
|
||||||
|
|
||||||
# 同步采购商品退货数量
|
# 同步采购产品退货数量
|
||||||
purchase_goods.save(update_fields=['return_quantity'])
|
purchase_goods.save(update_fields=['return_quantity'])
|
||||||
|
|
||||||
return_price = purchase_return_goods_item['return_price']
|
return_price = purchase_return_goods_item['return_price']
|
||||||
|
|
|
@ -51,7 +51,7 @@ class PurchaseOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
|
@ -67,7 +67,7 @@ class PurchaseOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
||||||
creator=self.user, team=self.team
|
creator=self.user, team=self.team
|
||||||
)
|
)
|
||||||
|
|
||||||
# 创建入库商品
|
# 创建入库产品
|
||||||
stock_in_goods_set = []
|
stock_in_goods_set = []
|
||||||
for purchase_goods in purchase_order.purchase_goods_set.all():
|
for purchase_goods in purchase_order.purchase_goods_set.all():
|
||||||
stock_in_goods_set.append(StockInGoods(
|
stock_in_goods_set.append(StockInGoods(
|
||||||
|
@ -125,7 +125,7 @@ class PurchaseOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
||||||
if purchase_order.is_void:
|
if purchase_order.is_void:
|
||||||
raise ValidationError(f'采购单据[{purchase_order.number}]已作废, 无法再次作废')
|
raise ValidationError(f'采购单据[{purchase_order.number}]已作废, 无法再次作废')
|
||||||
|
|
||||||
# 同步采购单据, 采购商品
|
# 同步采购单据, 采购产品
|
||||||
purchase_order.is_void = True
|
purchase_order.is_void = True
|
||||||
purchase_order.save(update_fields=['is_void'])
|
purchase_order.save(update_fields=['is_void'])
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ class PurchaseOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
|
@ -232,7 +232,7 @@ class PurchaseReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
|
@ -248,7 +248,7 @@ class PurchaseReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin
|
||||||
creator=self.user, team=self.team
|
creator=self.user, team=self.team
|
||||||
)
|
)
|
||||||
|
|
||||||
# 创建出库商品
|
# 创建出库产品
|
||||||
stock_out_goods_set = []
|
stock_out_goods_set = []
|
||||||
for purchase_return_goods in purchase_return_order.purchase_return_goods_set.all():
|
for purchase_return_goods in purchase_return_order.purchase_return_goods_set.all():
|
||||||
stock_out_goods_set.append(StockOutGoods(
|
stock_out_goods_set.append(StockOutGoods(
|
||||||
|
@ -305,7 +305,7 @@ class PurchaseReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin
|
||||||
if purchase_return_order.is_void:
|
if purchase_return_order.is_void:
|
||||||
raise ValidationError(f'采购退货单据[{purchase_return_order.number}]已作废, 无法再次作废')
|
raise ValidationError(f'采购退货单据[{purchase_return_order.number}]已作废, 无法再次作废')
|
||||||
|
|
||||||
# 同步采购退货单据, 采购退货商品
|
# 同步采购退货单据, 采购退货产品
|
||||||
purchase_return_order.is_void = True
|
purchase_return_order.is_void = True
|
||||||
purchase_return_order.save(update_fields=['is_void'])
|
purchase_return_order.save(update_fields=['is_void'])
|
||||||
|
|
||||||
|
@ -328,11 +328,11 @@ class PurchaseReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
|
|
||||||
# 同步采购商品退货数量
|
# 同步采购产品退货数量
|
||||||
if purchase_goods := purchase_return_goods.purchase_goods:
|
if purchase_goods := purchase_return_goods.purchase_goods:
|
||||||
purchase_goods.return_quantity = NP.minus(purchase_goods.return_quantity,
|
purchase_goods.return_quantity = NP.minus(purchase_goods.return_quantity,
|
||||||
purchase_return_goods.return_quantity)
|
purchase_return_goods.return_quantity)
|
||||||
|
|
|
@ -42,11 +42,11 @@ class SalesOrder(Model):
|
||||||
|
|
||||||
|
|
||||||
class SalesGoods(Model):
|
class SalesGoods(Model):
|
||||||
"""销售商品"""
|
"""销售产品"""
|
||||||
|
|
||||||
sales_order = ForeignKey('sales.SalesOrder', on_delete=CASCADE,
|
sales_order = ForeignKey('sales.SalesOrder', on_delete=CASCADE,
|
||||||
related_name='sales_goods_set', verbose_name='销售单据')
|
related_name='sales_goods_set', verbose_name='销售单据')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT, related_name='sales_goods_set', verbose_name='商品')
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT, related_name='sales_goods_set', verbose_name='产品')
|
||||||
sales_quantity = FloatField(verbose_name='销售数量')
|
sales_quantity = FloatField(verbose_name='销售数量')
|
||||||
sales_price = FloatField(verbose_name='销售单价')
|
sales_price = FloatField(verbose_name='销售单价')
|
||||||
total_amount = AmountField(verbose_name='总金额')
|
total_amount = AmountField(verbose_name='总金额')
|
||||||
|
@ -111,13 +111,13 @@ class SalesReturnOrder(Model):
|
||||||
|
|
||||||
|
|
||||||
class SalesReturnGoods(Model):
|
class SalesReturnGoods(Model):
|
||||||
"""销售退货商品"""
|
"""销售退货产品"""
|
||||||
|
|
||||||
sales_return_order = ForeignKey('sales.SalesReturnOrder', on_delete=CASCADE,
|
sales_return_order = ForeignKey('sales.SalesReturnOrder', on_delete=CASCADE,
|
||||||
related_name='sales_return_goods_set', verbose_name='销售退货单据')
|
related_name='sales_return_goods_set', verbose_name='销售退货单据')
|
||||||
sales_goods = ForeignKey('sales.SalesGoods', on_delete=CASCADE, null=True,
|
sales_goods = ForeignKey('sales.SalesGoods', on_delete=CASCADE, null=True,
|
||||||
related_name='sales_return_goods_set', verbose_name='销售商品')
|
related_name='sales_return_goods_set', verbose_name='销售产品')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT, related_name='sales_return_goods_set', verbose_name='商品')
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT, related_name='sales_return_goods_set', verbose_name='产品')
|
||||||
return_quantity = FloatField(verbose_name='退货数量')
|
return_quantity = FloatField(verbose_name='退货数量')
|
||||||
return_price = FloatField(verbose_name='退货单价')
|
return_price = FloatField(verbose_name='退货单价')
|
||||||
total_amount = AmountField(verbose_name='总金额')
|
total_amount = AmountField(verbose_name='总金额')
|
||||||
|
|
|
@ -12,11 +12,11 @@ class SalesOrderSerializer(BaseSerializer):
|
||||||
"""销售单据"""
|
"""销售单据"""
|
||||||
|
|
||||||
class SalesGoodsItemSerializer(BaseSerializer):
|
class SalesGoodsItemSerializer(BaseSerializer):
|
||||||
"""销售商品"""
|
"""销售产品"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -26,9 +26,9 @@ class SalesOrderSerializer(BaseSerializer):
|
||||||
fields = ['goods', 'sales_quantity', 'sales_price', *read_only_fields]
|
fields = ['goods', 'sales_quantity', 'sales_price', *read_only_fields]
|
||||||
|
|
||||||
def validate_goods(self, instance):
|
def validate_goods(self, instance):
|
||||||
instance = self.validate_foreign_key(Goods, instance, message='商品不存在')
|
instance = self.validate_foreign_key(Goods, instance, message='产品不存在')
|
||||||
if not instance.is_active:
|
if not instance.is_active:
|
||||||
raise ValidationError(f'商品[{instance.name}]未激活')
|
raise ValidationError(f'产品[{instance.name}]未激活')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_sales_quantity(self, value):
|
def validate_sales_quantity(self, value):
|
||||||
|
@ -70,7 +70,7 @@ class SalesOrderSerializer(BaseSerializer):
|
||||||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
sales_goods_items = SalesGoodsItemSerializer(
|
sales_goods_items = SalesGoodsItemSerializer(
|
||||||
source='sales_goods_set', many=True, label='销售商品Item')
|
source='sales_goods_set', many=True, label='销售产品Item')
|
||||||
sales_account_items = SalesAccountItemSerializer(
|
sales_account_items = SalesAccountItemSerializer(
|
||||||
source='sales_accounts', required=False, many=True, label='销售结算账户Item')
|
source='sales_accounts', required=False, many=True, label='销售结算账户Item')
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ class SalesOrderSerializer(BaseSerializer):
|
||||||
total_sales_quantity = 0
|
total_sales_quantity = 0
|
||||||
total_sales_amount = 0
|
total_sales_amount = 0
|
||||||
|
|
||||||
# 创建销售商品
|
# 创建销售产品
|
||||||
sales_goods_set = []
|
sales_goods_set = []
|
||||||
for sales_goods_item in sales_goods_items:
|
for sales_goods_item in sales_goods_items:
|
||||||
sales_quantity = sales_goods_item['sales_quantity']
|
sales_quantity = sales_goods_item['sales_quantity']
|
||||||
|
@ -175,11 +175,11 @@ class SalesReturnOrderSerializer(BaseSerializer):
|
||||||
"""销售退货单据"""
|
"""销售退货单据"""
|
||||||
|
|
||||||
class SalesReturnGoodsItemSerializer(BaseSerializer):
|
class SalesReturnGoodsItemSerializer(BaseSerializer):
|
||||||
"""销售退货商品"""
|
"""销售退货产品"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -189,13 +189,13 @@ class SalesReturnOrderSerializer(BaseSerializer):
|
||||||
fields = ['sales_goods', 'goods', 'return_quantity', 'return_price', *read_only_fields]
|
fields = ['sales_goods', 'goods', 'return_quantity', 'return_price', *read_only_fields]
|
||||||
|
|
||||||
def validate_sales_goods(self, instance):
|
def validate_sales_goods(self, instance):
|
||||||
instance = self.validate_foreign_key(SalesGoods, instance, message='销售商品不存在')
|
instance = self.validate_foreign_key(SalesGoods, instance, message='销售产品不存在')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_goods(self, instance):
|
def validate_goods(self, instance):
|
||||||
instance = self.validate_foreign_key(Goods, instance, message='商品不存在')
|
instance = self.validate_foreign_key(Goods, instance, message='产品不存在')
|
||||||
if not instance.is_active:
|
if not instance.is_active:
|
||||||
raise ValidationError(f'商品[{instance.name}]未激活')
|
raise ValidationError(f'产品[{instance.name}]未激活')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_return_quantity(self, value):
|
def validate_return_quantity(self, value):
|
||||||
|
@ -238,7 +238,7 @@ class SalesReturnOrderSerializer(BaseSerializer):
|
||||||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
sales_return_goods_items = SalesReturnGoodsItemSerializer(
|
sales_return_goods_items = SalesReturnGoodsItemSerializer(
|
||||||
source='sales_return_goods_set', many=True, label='销售退货商品')
|
source='sales_return_goods_set', many=True, label='销售退货产品')
|
||||||
sales_return_account_items = SalesReturnAccountItemSerializer(
|
sales_return_account_items = SalesReturnAccountItemSerializer(
|
||||||
source='sales_return_accounts', required=False, many=True, label='销售退货结算账户')
|
source='sales_return_accounts', required=False, many=True, label='销售退货结算账户')
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ class SalesReturnOrderSerializer(BaseSerializer):
|
||||||
total_return_quantity = 0
|
total_return_quantity = 0
|
||||||
total_return_amount = 0
|
total_return_amount = 0
|
||||||
|
|
||||||
# 创建销售退货商品
|
# 创建销售退货产品
|
||||||
sales_return_goods_set = []
|
sales_return_goods_set = []
|
||||||
for sales_return_goods_item in sales_return_goods_items:
|
for sales_return_goods_item in sales_return_goods_items:
|
||||||
goods = sales_return_goods_item['goods']
|
goods = sales_return_goods_item['goods']
|
||||||
|
@ -317,13 +317,13 @@ class SalesReturnOrderSerializer(BaseSerializer):
|
||||||
sales_goods = None
|
sales_goods = None
|
||||||
if sales_order := sales_return_order.sales_order:
|
if sales_order := sales_return_order.sales_order:
|
||||||
if not (sales_goods := sales_return_goods_item.get('sales_goods')):
|
if not (sales_goods := sales_return_goods_item.get('sales_goods')):
|
||||||
raise ValidationError(f'销售单据[{sales_order.number}]不存在商品[{goods.name}]')
|
raise ValidationError(f'销售单据[{sales_order.number}]不存在产品[{goods.name}]')
|
||||||
|
|
||||||
sales_goods.return_quantity = NP.plus(sales_goods.return_quantity, return_quantity)
|
sales_goods.return_quantity = NP.plus(sales_goods.return_quantity, return_quantity)
|
||||||
if sales_goods.return_quantity > sales_goods.sales_quantity:
|
if sales_goods.return_quantity > sales_goods.sales_quantity:
|
||||||
raise ValidationError(f'退货商品[{goods.name}]退货数量错误')
|
raise ValidationError(f'退货产品[{goods.name}]退货数量错误')
|
||||||
|
|
||||||
# 同步销售商品退货数量
|
# 同步销售产品退货数量
|
||||||
sales_goods.save(update_fields=['return_quantity'])
|
sales_goods.save(update_fields=['return_quantity'])
|
||||||
|
|
||||||
return_price = sales_return_goods_item['return_price']
|
return_price = sales_return_goods_item['return_price']
|
||||||
|
|
|
@ -51,7 +51,7 @@ class SalesOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, CreateM
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
|
@ -67,7 +67,7 @@ class SalesOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, CreateM
|
||||||
creator=self.user, team=self.team
|
creator=self.user, team=self.team
|
||||||
)
|
)
|
||||||
|
|
||||||
# 创建出库商品
|
# 创建出库产品
|
||||||
stock_out_goods_set = []
|
stock_out_goods_set = []
|
||||||
for sales_goods in sales_order.sales_goods_set.all():
|
for sales_goods in sales_order.sales_goods_set.all():
|
||||||
stock_out_goods_set.append(StockOutGoods(
|
stock_out_goods_set.append(StockOutGoods(
|
||||||
|
@ -125,7 +125,7 @@ class SalesOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, CreateM
|
||||||
if sales_order.is_void:
|
if sales_order.is_void:
|
||||||
raise ValidationError(f'销售单据[{sales_order.number}]已作废, 无法再次作废')
|
raise ValidationError(f'销售单据[{sales_order.number}]已作废, 无法再次作废')
|
||||||
|
|
||||||
# 同步销售单据, 销售商品
|
# 同步销售单据, 销售产品
|
||||||
sales_order.is_void = True
|
sales_order.is_void = True
|
||||||
sales_order.save(update_fields=['is_void'])
|
sales_order.save(update_fields=['is_void'])
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ class SalesOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, CreateM
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
|
@ -232,7 +232,7 @@ class SalesReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, C
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
|
@ -248,7 +248,7 @@ class SalesReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, C
|
||||||
creator=self.user, team=self.team
|
creator=self.user, team=self.team
|
||||||
)
|
)
|
||||||
|
|
||||||
# 创建入库商品
|
# 创建入库产品
|
||||||
stock_in_goods_set = []
|
stock_in_goods_set = []
|
||||||
for sales_return_goods in sales_return_order.sales_return_goods_set.all():
|
for sales_return_goods in sales_return_order.sales_return_goods_set.all():
|
||||||
stock_in_goods_set.append(StockInGoods(
|
stock_in_goods_set.append(StockInGoods(
|
||||||
|
@ -306,7 +306,7 @@ class SalesReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, C
|
||||||
if sales_return_order.is_void:
|
if sales_return_order.is_void:
|
||||||
raise ValidationError(f'销售退货单据[{sales_return_order.number}]已作废, 无法再次作废')
|
raise ValidationError(f'销售退货单据[{sales_return_order.number}]已作废, 无法再次作废')
|
||||||
|
|
||||||
# 同步销售退货单据, 采购退货商品
|
# 同步销售退货单据, 采购退货产品
|
||||||
sales_return_order.is_void = True
|
sales_return_order.is_void = True
|
||||||
sales_return_order.save(update_fields=['is_void'])
|
sales_return_order.save(update_fields=['is_void'])
|
||||||
|
|
||||||
|
@ -329,11 +329,11 @@ class SalesReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, C
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
|
|
||||||
# 同步采购商品退货数量
|
# 同步采购产品退货数量
|
||||||
if sales_goods := sales_return_goods.sales_goods:
|
if sales_goods := sales_return_goods.sales_goods:
|
||||||
sales_goods.return_quantity = NP.minus(sales_goods.return_quantity,
|
sales_goods.return_quantity = NP.minus(sales_goods.return_quantity,
|
||||||
sales_return_goods.return_quantity)
|
sales_return_goods.return_quantity)
|
||||||
|
|
|
@ -6,7 +6,7 @@ from apps.finance.models import *
|
||||||
|
|
||||||
|
|
||||||
class PurchaseReportFilter(FilterSet):
|
class PurchaseReportFilter(FilterSet):
|
||||||
category = NumberFilter(field_name='goods__category', label='商品分类')
|
category = NumberFilter(field_name='goods__category', label='产品分类')
|
||||||
creator = NumberFilter(field_name='sales_order__creator', label='创建人')
|
creator = NumberFilter(field_name='sales_order__creator', label='创建人')
|
||||||
start_date = DateFilter(field_name='purchase_order__create_time', required=True, lookup_expr='gte', label='开始日期')
|
start_date = DateFilter(field_name='purchase_order__create_time', required=True, lookup_expr='gte', label='开始日期')
|
||||||
end_date = DateFilter(field_name='purchase_order__create_time', required=True, lookup_expr='lt', label='结束日期')
|
end_date = DateFilter(field_name='purchase_order__create_time', required=True, lookup_expr='lt', label='结束日期')
|
||||||
|
@ -17,7 +17,7 @@ class PurchaseReportFilter(FilterSet):
|
||||||
|
|
||||||
|
|
||||||
class SalesReportFilter(FilterSet):
|
class SalesReportFilter(FilterSet):
|
||||||
category = NumberFilter(field_name='goods__category', label='商品分类')
|
category = NumberFilter(field_name='goods__category', label='产品分类')
|
||||||
creator = NumberFilter(field_name='sales_order__creator', label='创建人')
|
creator = NumberFilter(field_name='sales_order__creator', label='创建人')
|
||||||
start_date = DateFilter(field_name='sales_order__create_time', required=True, lookup_expr='gte', label='开始日期')
|
start_date = DateFilter(field_name='sales_order__create_time', required=True, lookup_expr='gte', label='开始日期')
|
||||||
end_date = DateFilter(field_name='sales_order__create_time', required=True, lookup_expr='lt', label='结束日期')
|
end_date = DateFilter(field_name='sales_order__create_time', required=True, lookup_expr='lt', label='结束日期')
|
||||||
|
|
|
@ -5,7 +5,7 @@ from extensions.serializers import *
|
||||||
class PurchaseReportParameter(Serializer):
|
class PurchaseReportParameter(Serializer):
|
||||||
start_date = DateField(required=True, label='开始日期')
|
start_date = DateField(required=True, label='开始日期')
|
||||||
end_date = DateField(required=True, label='结束日期')
|
end_date = DateField(required=True, label='结束日期')
|
||||||
category = IntegerField(required=False, label='商品分类')
|
category = IntegerField(required=False, label='产品分类')
|
||||||
|
|
||||||
|
|
||||||
class PurchaseReportStatisticResponse(Serializer):
|
class PurchaseReportStatisticResponse(Serializer):
|
||||||
|
@ -15,11 +15,11 @@ class PurchaseReportStatisticResponse(Serializer):
|
||||||
|
|
||||||
|
|
||||||
class PurchaseReportGroupByGoodsResponse(Serializer):
|
class PurchaseReportGroupByGoodsResponse(Serializer):
|
||||||
goods = IntegerField(label='商品ID')
|
goods = IntegerField(label='产品ID')
|
||||||
goods_number = CharField(label='商品编号')
|
goods_number = CharField(label='产品编号')
|
||||||
goods_name = CharField(label='商品名称')
|
goods_name = CharField(label='产品名称')
|
||||||
goods_barcode = CharField(label='商品条码')
|
goods_barcode = CharField(label='产品条码')
|
||||||
goods_spec = CharField(label='商品规格')
|
goods_spec = CharField(label='产品规格')
|
||||||
category_name = CharField(label='分类名称')
|
category_name = CharField(label='分类名称')
|
||||||
unit_name = CharField(label='单位名称')
|
unit_name = CharField(label='单位名称')
|
||||||
total_purchase_quantity = FloatField(label='采购总数量')
|
total_purchase_quantity = FloatField(label='采购总数量')
|
||||||
|
@ -32,7 +32,7 @@ class PurchaseReportGroupByGoodsResponse(Serializer):
|
||||||
class SalesReportParameter(Serializer):
|
class SalesReportParameter(Serializer):
|
||||||
start_date = DateField(required=True, label='开始日期')
|
start_date = DateField(required=True, label='开始日期')
|
||||||
end_date = DateField(required=True, label='结束日期')
|
end_date = DateField(required=True, label='结束日期')
|
||||||
category = IntegerField(required=False, label='商品分类')
|
category = IntegerField(required=False, label='产品分类')
|
||||||
|
|
||||||
|
|
||||||
class SalesReportStatisticResponse(Serializer):
|
class SalesReportStatisticResponse(Serializer):
|
||||||
|
@ -42,11 +42,11 @@ class SalesReportStatisticResponse(Serializer):
|
||||||
|
|
||||||
|
|
||||||
class SalesReportGroupByGoodsResponse(Serializer):
|
class SalesReportGroupByGoodsResponse(Serializer):
|
||||||
goods = IntegerField(label='商品ID')
|
goods = IntegerField(label='产品ID')
|
||||||
goods_number = CharField(label='商品编号')
|
goods_number = CharField(label='产品编号')
|
||||||
goods_name = CharField(label='商品名称')
|
goods_name = CharField(label='产品名称')
|
||||||
goods_barcode = CharField(label='商品条码')
|
goods_barcode = CharField(label='产品条码')
|
||||||
goods_spec = CharField(label='商品规格')
|
goods_spec = CharField(label='产品规格')
|
||||||
category_name = CharField(label='分类名称')
|
category_name = CharField(label='分类名称')
|
||||||
unit_name = CharField(label='单位名称')
|
unit_name = CharField(label='单位名称')
|
||||||
total_sales_quantity = FloatField(label='销售总数量')
|
total_sales_quantity = FloatField(label='销售总数量')
|
||||||
|
@ -62,11 +62,11 @@ class SalesHotGoodsParameter(Serializer):
|
||||||
|
|
||||||
|
|
||||||
class SalesHotGoodsResponse(Serializer):
|
class SalesHotGoodsResponse(Serializer):
|
||||||
goods = IntegerField(label='商品ID')
|
goods = IntegerField(label='产品ID')
|
||||||
goods_number = CharField(label='商品编号')
|
goods_number = CharField(label='产品编号')
|
||||||
goods_name = CharField(label='商品名称')
|
goods_name = CharField(label='产品名称')
|
||||||
goods_barcode = CharField(label='商品条码')
|
goods_barcode = CharField(label='产品条码')
|
||||||
goods_spec = CharField(label='商品规格')
|
goods_spec = CharField(label='产品规格')
|
||||||
category_name = CharField(label='分类名称')
|
category_name = CharField(label='分类名称')
|
||||||
unit_name = CharField(label='单位名称')
|
unit_name = CharField(label='单位名称')
|
||||||
total_sales_quantity = FloatField(label='销售总数量')
|
total_sales_quantity = FloatField(label='销售总数量')
|
||||||
|
@ -79,8 +79,8 @@ class SalesTrendParameter(Serializer):
|
||||||
|
|
||||||
class SalesTrendResponse(Serializer):
|
class SalesTrendResponse(Serializer):
|
||||||
warehouse = IntegerField(label='仓库ID')
|
warehouse = IntegerField(label='仓库ID')
|
||||||
warehouse_number = CharField(label='商品编号')
|
warehouse_number = CharField(label='产品编号')
|
||||||
warehouse_name = CharField(label='商品名称')
|
warehouse_name = CharField(label='产品名称')
|
||||||
total_sales_amount = AmountField(label='销售总金额')
|
total_sales_amount = AmountField(label='销售总金额')
|
||||||
date = DateField(label='日期')
|
date = DateField(label='日期')
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,10 @@ from apps.finance.models import *
|
||||||
class PurchaseReportDetialSerializer(BaseSerializer):
|
class PurchaseReportDetialSerializer(BaseSerializer):
|
||||||
"""采购明细"""
|
"""采购明细"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
goods_spec = CharField(source='goods.spec', read_only=True, label='商品规格')
|
goods_spec = CharField(source='goods.spec', read_only=True, label='产品规格')
|
||||||
category_name = CharField(source='goods.category.name', read_only=True, label='分类名称')
|
category_name = CharField(source='goods.category.name', read_only=True, label='分类名称')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
purchase_order_number = CharField(source='purchase_order.number', read_only=True, label='采购单号')
|
purchase_order_number = CharField(source='purchase_order.number', read_only=True, label='采购单号')
|
||||||
|
@ -34,10 +34,10 @@ class PurchaseReportDetialSerializer(BaseSerializer):
|
||||||
class SalesReportDetialSerializer(BaseSerializer):
|
class SalesReportDetialSerializer(BaseSerializer):
|
||||||
"""销售明细"""
|
"""销售明细"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
goods_spec = CharField(source='goods.spec', read_only=True, label='商品规格')
|
goods_spec = CharField(source='goods.spec', read_only=True, label='产品规格')
|
||||||
category_name = CharField(source='goods.category.name', read_only=True, label='分类名称')
|
category_name = CharField(source='goods.category.name', read_only=True, label='分类名称')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
sales_order_number = CharField(source='sales_order.number', read_only=True, label='采购单号')
|
sales_order_number = CharField(source='sales_order.number', read_only=True, label='采购单号')
|
||||||
|
|
|
@ -60,7 +60,7 @@ class PurchaseReportViewSet(BaseViewSet):
|
||||||
responses={200: PurchaseReportGroupByGoodsResponse})
|
responses={200: PurchaseReportGroupByGoodsResponse})
|
||||||
@action(detail=False, methods=['get'])
|
@action(detail=False, methods=['get'])
|
||||||
def group_by_goods(self, request, *args, **kwargs):
|
def group_by_goods(self, request, *args, **kwargs):
|
||||||
"""商品汇总"""
|
"""产品汇总"""
|
||||||
|
|
||||||
queryset = self.filter_queryset(self.get_queryset())
|
queryset = self.filter_queryset(self.get_queryset())
|
||||||
queryset = queryset.select_related('goods', 'goods__category', 'goods__unit')
|
queryset = queryset.select_related('goods', 'goods__category', 'goods__unit')
|
||||||
|
@ -124,7 +124,7 @@ class SalesReportViewSet(BaseViewSet):
|
||||||
responses={200: SalesReportGroupByGoodsResponse})
|
responses={200: SalesReportGroupByGoodsResponse})
|
||||||
@action(detail=False, methods=['get'])
|
@action(detail=False, methods=['get'])
|
||||||
def group_by_goods(self, request, *args, **kwargs):
|
def group_by_goods(self, request, *args, **kwargs):
|
||||||
"""商品汇总"""
|
"""产品汇总"""
|
||||||
|
|
||||||
queryset = self.filter_queryset(self.get_queryset())
|
queryset = self.filter_queryset(self.get_queryset())
|
||||||
queryset = queryset.select_related('goods', 'goods__category', 'goods__unit')
|
queryset = queryset.select_related('goods', 'goods__category', 'goods__unit')
|
||||||
|
@ -143,7 +143,7 @@ class SalesReportViewSet(BaseViewSet):
|
||||||
|
|
||||||
|
|
||||||
class SalesHotGoodsViewSet(BaseViewSet, ListModelMixin):
|
class SalesHotGoodsViewSet(BaseViewSet, ListModelMixin):
|
||||||
"""销售前十商品"""
|
"""销售前十产品"""
|
||||||
|
|
||||||
permission_classes = [IsAuthenticated, SalesHotGoodsPermission]
|
permission_classes = [IsAuthenticated, SalesHotGoodsPermission]
|
||||||
pagination_class = None
|
pagination_class = None
|
||||||
|
|
|
@ -48,7 +48,7 @@ class StockCheckOrder(Model):
|
||||||
|
|
||||||
|
|
||||||
class StockCheckGoods(Model):
|
class StockCheckGoods(Model):
|
||||||
"""盘点商品"""
|
"""盘点产品"""
|
||||||
|
|
||||||
class Status(TextChoices):
|
class Status(TextChoices):
|
||||||
"""盘点状态"""
|
"""盘点状态"""
|
||||||
|
@ -60,7 +60,7 @@ class StockCheckGoods(Model):
|
||||||
stock_check_order = ForeignKey('stock_check.StockCheckOrder', on_delete=CASCADE,
|
stock_check_order = ForeignKey('stock_check.StockCheckOrder', on_delete=CASCADE,
|
||||||
related_name='stock_check_goods_set', verbose_name='盘点单据')
|
related_name='stock_check_goods_set', verbose_name='盘点单据')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
||||||
related_name='stock_check_goods_set', verbose_name='商品')
|
related_name='stock_check_goods_set', verbose_name='产品')
|
||||||
book_quantity = FloatField(verbose_name='账面数量')
|
book_quantity = FloatField(verbose_name='账面数量')
|
||||||
actual_quantity = FloatField(verbose_name='实际数量')
|
actual_quantity = FloatField(verbose_name='实际数量')
|
||||||
surplus_quantity = FloatField(verbose_name='盘盈数量')
|
surplus_quantity = FloatField(verbose_name='盘盈数量')
|
||||||
|
@ -86,11 +86,11 @@ class StockCheckBatch(Model):
|
||||||
stock_check_order = ForeignKey('stock_check.StockCheckOrder', on_delete=CASCADE,
|
stock_check_order = ForeignKey('stock_check.StockCheckOrder', on_delete=CASCADE,
|
||||||
related_name='stock_check_batchs', verbose_name='盘点单据')
|
related_name='stock_check_batchs', verbose_name='盘点单据')
|
||||||
stock_check_goods = ForeignKey('stock_check.StockCheckGoods', on_delete=CASCADE,
|
stock_check_goods = ForeignKey('stock_check.StockCheckGoods', on_delete=CASCADE,
|
||||||
related_name='stock_check_batchs', verbose_name='盘点商品')
|
related_name='stock_check_batchs', verbose_name='盘点产品')
|
||||||
batch_number = CharField(max_length=32, verbose_name='批次编号')
|
batch_number = CharField(max_length=32, verbose_name='批次编号')
|
||||||
production_date = DateField(null=True, verbose_name='生产日期')
|
production_date = DateField(null=True, verbose_name='生产日期')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
||||||
related_name='stock_check_batchs', verbose_name='商品')
|
related_name='stock_check_batchs', verbose_name='产品')
|
||||||
book_quantity = FloatField(verbose_name='账面数量')
|
book_quantity = FloatField(verbose_name='账面数量')
|
||||||
actual_quantity = FloatField(verbose_name='实际数量')
|
actual_quantity = FloatField(verbose_name='实际数量')
|
||||||
surplus_quantity = FloatField(verbose_name='盘盈数量')
|
surplus_quantity = FloatField(verbose_name='盘盈数量')
|
||||||
|
|
|
@ -11,7 +11,7 @@ class StockCheckOrderSerializer(BaseSerializer):
|
||||||
"""盘点单据"""
|
"""盘点单据"""
|
||||||
|
|
||||||
class StockCheckGoodsItemSerializer(BaseSerializer):
|
class StockCheckGoodsItemSerializer(BaseSerializer):
|
||||||
"""盘点商品"""
|
"""盘点产品"""
|
||||||
|
|
||||||
class StockCheckBatchItemSerializer(BaseSerializer):
|
class StockCheckBatchItemSerializer(BaseSerializer):
|
||||||
"""盘点批次"""
|
"""盘点批次"""
|
||||||
|
@ -28,9 +28,9 @@ class StockCheckOrderSerializer(BaseSerializer):
|
||||||
raise ValidationError('盘点数量小于零')
|
raise ValidationError('盘点数量小于零')
|
||||||
return value
|
return value
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
||||||
read_only=True, label='启用批次控制')
|
read_only=True, label='启用批次控制')
|
||||||
|
@ -46,9 +46,9 @@ class StockCheckOrderSerializer(BaseSerializer):
|
||||||
fields = ['goods', 'actual_quantity', 'stock_check_batch_items', *read_only_fields]
|
fields = ['goods', 'actual_quantity', 'stock_check_batch_items', *read_only_fields]
|
||||||
|
|
||||||
def validate_goods(self, instance):
|
def validate_goods(self, instance):
|
||||||
instance = self.validate_foreign_key(Goods, instance, message='商品不存在')
|
instance = self.validate_foreign_key(Goods, instance, message='产品不存在')
|
||||||
if not instance.is_active:
|
if not instance.is_active:
|
||||||
raise ValidationError(f'商品[{instance.name}]未激活')
|
raise ValidationError(f'产品[{instance.name}]未激活')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_actual_quantity(self, value):
|
def validate_actual_quantity(self, value):
|
||||||
|
@ -60,13 +60,13 @@ class StockCheckOrderSerializer(BaseSerializer):
|
||||||
goods = attrs['goods']
|
goods = attrs['goods']
|
||||||
if goods.enable_batch_control:
|
if goods.enable_batch_control:
|
||||||
if not (stock_check_batch_items := attrs.get('stock_check_batchs')):
|
if not (stock_check_batch_items := attrs.get('stock_check_batchs')):
|
||||||
raise ValidationError(f'商品[{goods.name}]批次为空')
|
raise ValidationError(f'产品[{goods.name}]批次为空')
|
||||||
|
|
||||||
total_actual_quantity = reduce(lambda total, item: NP.plus(total, item['actual_quantity']),
|
total_actual_quantity = reduce(lambda total, item: NP.plus(total, item['actual_quantity']),
|
||||||
stock_check_batch_items, 0)
|
stock_check_batch_items, 0)
|
||||||
|
|
||||||
if total_actual_quantity != attrs['actual_quantity']:
|
if total_actual_quantity != attrs['actual_quantity']:
|
||||||
raise ValidationError(f'商品[{goods.name}]盘点数量错误')
|
raise ValidationError(f'产品[{goods.name}]盘点数量错误')
|
||||||
|
|
||||||
return super().validate(attrs)
|
return super().validate(attrs)
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ class StockCheckOrderSerializer(BaseSerializer):
|
||||||
status_display = CharField(source='get_status_display', read_only=True, label='盘点状态')
|
status_display = CharField(source='get_status_display', read_only=True, label='盘点状态')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
stock_check_goods_Items = StockCheckGoodsItemSerializer(
|
stock_check_goods_Items = StockCheckGoodsItemSerializer(
|
||||||
source='stock_check_goods_set', many=True, label='盘点商品')
|
source='stock_check_goods_set', many=True, label='盘点产品')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = StockCheckOrder
|
model = StockCheckOrder
|
||||||
|
@ -116,7 +116,7 @@ class StockCheckOrderSerializer(BaseSerializer):
|
||||||
total_actual_quantity = 0
|
total_actual_quantity = 0
|
||||||
total_surplus_amount = 0
|
total_surplus_amount = 0
|
||||||
|
|
||||||
# 创建盘点商品
|
# 创建盘点产品
|
||||||
stock_check_batchs = []
|
stock_check_batchs = []
|
||||||
for stock_check_goods_item in stock_check_goods_items:
|
for stock_check_goods_item in stock_check_goods_items:
|
||||||
goods = stock_check_goods_item['goods']
|
goods = stock_check_goods_item['goods']
|
||||||
|
|
|
@ -53,7 +53,7 @@ class StockCheckOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cr
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
update_inventories.append(inventory)
|
update_inventories.append(inventory)
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ class StockCheckOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cr
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
update_inventories.append(inventory)
|
update_inventories.append(inventory)
|
||||||
|
|
||||||
|
|
|
@ -53,12 +53,12 @@ class StockInOrder(Model):
|
||||||
|
|
||||||
|
|
||||||
class StockInGoods(Model):
|
class StockInGoods(Model):
|
||||||
"""入库商品"""
|
"""入库产品"""
|
||||||
|
|
||||||
stock_in_order = ForeignKey('stock_in.StockInOrder', on_delete=CASCADE,
|
stock_in_order = ForeignKey('stock_in.StockInOrder', on_delete=CASCADE,
|
||||||
related_name='stock_in_goods_set', verbose_name='入库单据')
|
related_name='stock_in_goods_set', verbose_name='入库单据')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
||||||
related_name='stock_in_goods_set', verbose_name='商品')
|
related_name='stock_in_goods_set', verbose_name='产品')
|
||||||
stock_in_quantity = FloatField(verbose_name='入库总数')
|
stock_in_quantity = FloatField(verbose_name='入库总数')
|
||||||
remain_quantity = FloatField(default=0, verbose_name='入库剩余数量')
|
remain_quantity = FloatField(default=0, verbose_name='入库剩余数量')
|
||||||
is_completed = BooleanField(default=False, verbose_name='完成状态')
|
is_completed = BooleanField(default=False, verbose_name='完成状态')
|
||||||
|
@ -88,14 +88,14 @@ class StockInRecord(Model):
|
||||||
|
|
||||||
|
|
||||||
class StockInRecordGoods(Model):
|
class StockInRecordGoods(Model):
|
||||||
"""入库记录商品"""
|
"""入库记录产品"""
|
||||||
|
|
||||||
stock_in_record = ForeignKey('stock_in.StockInRecord', on_delete=CASCADE,
|
stock_in_record = ForeignKey('stock_in.StockInRecord', on_delete=CASCADE,
|
||||||
related_name='stock_in_record_goods_set', verbose_name='入库记录')
|
related_name='stock_in_record_goods_set', verbose_name='入库记录')
|
||||||
stock_in_goods = ForeignKey('stock_in.StockInGoods', on_delete=CASCADE,
|
stock_in_goods = ForeignKey('stock_in.StockInGoods', on_delete=CASCADE,
|
||||||
related_name='stock_in_record_goods_set', verbose_name='入库商品')
|
related_name='stock_in_record_goods_set', verbose_name='入库产品')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
||||||
related_name='stock_in_record_goods_set', verbose_name='商品')
|
related_name='stock_in_record_goods_set', verbose_name='产品')
|
||||||
stock_in_quantity = FloatField(verbose_name='入库数量')
|
stock_in_quantity = FloatField(verbose_name='入库数量')
|
||||||
batch = ForeignKey('goods.Batch', on_delete=CASCADE, null=True,
|
batch = ForeignKey('goods.Batch', on_delete=CASCADE, null=True,
|
||||||
related_name='stock_in_record_goods_set', verbose_name='批次')
|
related_name='stock_in_record_goods_set', verbose_name='批次')
|
||||||
|
|
|
@ -10,11 +10,11 @@ class StockInOrderSerializer(BaseSerializer):
|
||||||
"""入库单据"""
|
"""入库单据"""
|
||||||
|
|
||||||
class StockInGoodsItemSerializer(BaseSerializer):
|
class StockInGoodsItemSerializer(BaseSerializer):
|
||||||
"""入库商品"""
|
"""入库产品"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
||||||
read_only=True, label='启用批次控制')
|
read_only=True, label='启用批次控制')
|
||||||
|
@ -36,7 +36,7 @@ class StockInOrderSerializer(BaseSerializer):
|
||||||
read_only=True, label='调拨单据编号')
|
read_only=True, label='调拨单据编号')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
stock_in_goods_items = StockInGoodsItemSerializer(
|
stock_in_goods_items = StockInGoodsItemSerializer(
|
||||||
source='stock_in_goods_set', many=True, label='入库商品Item')
|
source='stock_in_goods_set', many=True, label='入库产品Item')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = StockInOrder
|
model = StockInOrder
|
||||||
|
@ -51,11 +51,11 @@ class StockInRecordSerializer(BaseSerializer):
|
||||||
"""入库记录"""
|
"""入库记录"""
|
||||||
|
|
||||||
class StockInRecordGoodsItemSerializer(BaseSerializer):
|
class StockInRecordGoodsItemSerializer(BaseSerializer):
|
||||||
"""入库记录商品"""
|
"""入库记录产品"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
||||||
read_only=True, label='启用批次控制')
|
read_only=True, label='启用批次控制')
|
||||||
|
@ -72,9 +72,9 @@ class StockInRecordSerializer(BaseSerializer):
|
||||||
*read_only_fields]
|
*read_only_fields]
|
||||||
|
|
||||||
def validate_stock_in_goods(self, instance):
|
def validate_stock_in_goods(self, instance):
|
||||||
instance = self.validate_foreign_key(StockInGoods, instance, message='入库商品不存在')
|
instance = self.validate_foreign_key(StockInGoods, instance, message='入库产品不存在')
|
||||||
if instance.is_completed:
|
if instance.is_completed:
|
||||||
raise ValidationError(f'入库商品[{instance.goods.name}]已完成')
|
raise ValidationError(f'入库产品[{instance.goods.name}]已完成')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_stock_in_quantity(self, value):
|
def validate_stock_in_quantity(self, value):
|
||||||
|
@ -87,11 +87,11 @@ class StockInRecordSerializer(BaseSerializer):
|
||||||
goods = stock_in_goods.goods
|
goods = stock_in_goods.goods
|
||||||
|
|
||||||
if stock_in_goods.remain_quantity < attrs['stock_in_quantity']:
|
if stock_in_goods.remain_quantity < attrs['stock_in_quantity']:
|
||||||
raise ValidationError(f'商品[{goods.name}]入库数量错误')
|
raise ValidationError(f'产品[{goods.name}]入库数量错误')
|
||||||
|
|
||||||
if goods.enable_batch_control:
|
if goods.enable_batch_control:
|
||||||
if not (attrs.get('batch') or attrs['batch'].get('number')):
|
if not (attrs.get('batch') or attrs['batch'].get('number')):
|
||||||
raise ValidationError(f'商品[{goods.name}]批次编号为空')
|
raise ValidationError(f'产品[{goods.name}]批次编号为空')
|
||||||
return super().validate(attrs)
|
return super().validate(attrs)
|
||||||
|
|
||||||
stock_in_order_number = CharField(source='stock_in_order.number', read_only=True, label='入库单据编号')
|
stock_in_order_number = CharField(source='stock_in_order.number', read_only=True, label='入库单据编号')
|
||||||
|
@ -100,7 +100,7 @@ class StockInRecordSerializer(BaseSerializer):
|
||||||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
stock_in_record_goods_items = StockInRecordGoodsItemSerializer(
|
stock_in_record_goods_items = StockInRecordGoodsItemSerializer(
|
||||||
source='stock_in_record_goods_set', many=True, label='入库记录商品')
|
source='stock_in_record_goods_set', many=True, label='入库记录产品')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = StockInRecord
|
model = StockInRecord
|
||||||
|
@ -136,12 +136,12 @@ class StockInRecordSerializer(BaseSerializer):
|
||||||
|
|
||||||
total_stock_in_quantity = 0
|
total_stock_in_quantity = 0
|
||||||
|
|
||||||
# 创建入库记录商品
|
# 创建入库记录产品
|
||||||
stock_in_record_goods_set = []
|
stock_in_record_goods_set = []
|
||||||
for stock_in_record_goods_item in stock_in_record_goods_items:
|
for stock_in_record_goods_item in stock_in_record_goods_items:
|
||||||
stock_in_goods = stock_in_record_goods_item['stock_in_goods']
|
stock_in_goods = stock_in_record_goods_item['stock_in_goods']
|
||||||
if stock_in_goods.stock_in_order != stock_in_order:
|
if stock_in_goods.stock_in_order != stock_in_order:
|
||||||
raise ValidationError('入库商品错误')
|
raise ValidationError('入库产品错误')
|
||||||
|
|
||||||
stock_in_quantity = stock_in_record_goods_item['stock_in_quantity']
|
stock_in_quantity = stock_in_record_goods_item['stock_in_quantity']
|
||||||
goods = stock_in_goods.goods
|
goods = stock_in_goods.goods
|
||||||
|
|
|
@ -63,11 +63,11 @@ class StockInRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
|
|
||||||
# 同步入库商品
|
# 同步入库产品
|
||||||
stock_in_goods = stock_in_record_goods.stock_in_goods
|
stock_in_goods = stock_in_record_goods.stock_in_goods
|
||||||
stock_in_goods.remain_quantity = NP.minus(stock_in_goods.remain_quantity, quantity_change)
|
stock_in_goods.remain_quantity = NP.minus(stock_in_goods.remain_quantity, quantity_change)
|
||||||
stock_in_goods.save(update_fields=['remain_quantity'])
|
stock_in_goods.save(update_fields=['remain_quantity'])
|
||||||
|
@ -89,7 +89,7 @@ class StockInRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
||||||
if stock_in_record.is_void:
|
if stock_in_record.is_void:
|
||||||
raise ValidationError(f'入库记录已作废, 无法再次作废')
|
raise ValidationError(f'入库记录已作废, 无法再次作废')
|
||||||
|
|
||||||
# 同步入库记录, 入库记录商品
|
# 同步入库记录, 入库记录产品
|
||||||
stock_in_record.is_void = True
|
stock_in_record.is_void = True
|
||||||
stock_in_record.save(update_fields=['is_void'])
|
stock_in_record.save(update_fields=['is_void'])
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ class StockInRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ class StockInRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
||||||
batch.has_stock = batch.remain_quantity > 0
|
batch.has_stock = batch.remain_quantity > 0
|
||||||
batch.save(update_fields=['total_quantity', 'remain_quantity', 'has_stock'])
|
batch.save(update_fields=['total_quantity', 'remain_quantity', 'has_stock'])
|
||||||
|
|
||||||
# 同步入库商品
|
# 同步入库产品
|
||||||
stock_in_goods = stock_in_record_goods.stock_in_goods
|
stock_in_goods = stock_in_record_goods.stock_in_goods
|
||||||
stock_in_goods.remain_quantity = NP.plus(stock_in_goods.remain_quantity, quantity_change)
|
stock_in_goods.remain_quantity = NP.plus(stock_in_goods.remain_quantity, quantity_change)
|
||||||
stock_in_goods.save(update_fields=['remain_quantity'])
|
stock_in_goods.save(update_fields=['remain_quantity'])
|
||||||
|
|
|
@ -49,12 +49,12 @@ class StockOutOrder(Model):
|
||||||
|
|
||||||
|
|
||||||
class StockOutGoods(Model):
|
class StockOutGoods(Model):
|
||||||
"""出库商品"""
|
"""出库产品"""
|
||||||
|
|
||||||
stock_out_order = ForeignKey('stock_out.StockOutOrder', on_delete=CASCADE,
|
stock_out_order = ForeignKey('stock_out.StockOutOrder', on_delete=CASCADE,
|
||||||
related_name='stock_out_goods_set', verbose_name='出库单据')
|
related_name='stock_out_goods_set', verbose_name='出库单据')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
||||||
related_name='stock_out_goods_set', verbose_name='商品')
|
related_name='stock_out_goods_set', verbose_name='产品')
|
||||||
stock_out_quantity = FloatField(verbose_name='出库总数')
|
stock_out_quantity = FloatField(verbose_name='出库总数')
|
||||||
remain_quantity = FloatField(default=0, verbose_name='出库剩余数量')
|
remain_quantity = FloatField(default=0, verbose_name='出库剩余数量')
|
||||||
is_completed = BooleanField(default=False, verbose_name='完成状态')
|
is_completed = BooleanField(default=False, verbose_name='完成状态')
|
||||||
|
@ -84,14 +84,14 @@ class StockOutRecord(Model):
|
||||||
|
|
||||||
|
|
||||||
class StockOutRecordGoods(Model):
|
class StockOutRecordGoods(Model):
|
||||||
"""出库记录商品"""
|
"""出库记录产品"""
|
||||||
|
|
||||||
stock_out_record = ForeignKey('stock_out.StockOutRecord', on_delete=CASCADE,
|
stock_out_record = ForeignKey('stock_out.StockOutRecord', on_delete=CASCADE,
|
||||||
related_name='stock_out_record_goods_set', verbose_name='出库记录')
|
related_name='stock_out_record_goods_set', verbose_name='出库记录')
|
||||||
stock_out_goods = ForeignKey('stock_out.StockOutGoods', on_delete=CASCADE,
|
stock_out_goods = ForeignKey('stock_out.StockOutGoods', on_delete=CASCADE,
|
||||||
related_name='stock_out_record_goods_set', verbose_name='出库商品')
|
related_name='stock_out_record_goods_set', verbose_name='出库产品')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
||||||
related_name='stock_out_record_goods_set', verbose_name='商品')
|
related_name='stock_out_record_goods_set', verbose_name='产品')
|
||||||
stock_out_quantity = FloatField(verbose_name='出库数量')
|
stock_out_quantity = FloatField(verbose_name='出库数量')
|
||||||
batch = ForeignKey('goods.Batch', on_delete=CASCADE, null=True,
|
batch = ForeignKey('goods.Batch', on_delete=CASCADE, null=True,
|
||||||
related_name='stock_out_record_goods_set', verbose_name='批次')
|
related_name='stock_out_record_goods_set', verbose_name='批次')
|
||||||
|
|
|
@ -10,11 +10,11 @@ class StockOutOrderSerializer(BaseSerializer):
|
||||||
"""出库单据"""
|
"""出库单据"""
|
||||||
|
|
||||||
class StockOutGoodsItemSerializer(BaseSerializer):
|
class StockOutGoodsItemSerializer(BaseSerializer):
|
||||||
"""出库商品"""
|
"""出库产品"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
||||||
read_only=True, label='启用批次控制')
|
read_only=True, label='启用批次控制')
|
||||||
|
@ -34,7 +34,7 @@ class StockOutOrderSerializer(BaseSerializer):
|
||||||
read_only=True, label='调拨单据编号')
|
read_only=True, label='调拨单据编号')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
stock_out_goods_items = StockOutGoodsItemSerializer(
|
stock_out_goods_items = StockOutGoodsItemSerializer(
|
||||||
source='stock_out_goods_set', many=True, label='出库商品')
|
source='stock_out_goods_set', many=True, label='出库产品')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = StockOutOrder
|
model = StockOutOrder
|
||||||
|
@ -49,11 +49,11 @@ class StockOutRecordSerializer(BaseSerializer):
|
||||||
"""出库记录"""
|
"""出库记录"""
|
||||||
|
|
||||||
class StockOutRecordGoodsSerializer(BaseSerializer):
|
class StockOutRecordGoodsSerializer(BaseSerializer):
|
||||||
"""出库记录商品"""
|
"""出库记录产品"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
||||||
read_only=True, label='启用批次控制')
|
read_only=True, label='启用批次控制')
|
||||||
|
@ -66,9 +66,9 @@ class StockOutRecordSerializer(BaseSerializer):
|
||||||
fields = ['stock_out_goods', 'stock_out_quantity', 'batch', *read_only_fields]
|
fields = ['stock_out_goods', 'stock_out_quantity', 'batch', *read_only_fields]
|
||||||
|
|
||||||
def validate_stock_out_goods(self, instance):
|
def validate_stock_out_goods(self, instance):
|
||||||
instance = self.validate_foreign_key(StockOutGoods, instance, message='出库商品不存在')
|
instance = self.validate_foreign_key(StockOutGoods, instance, message='出库产品不存在')
|
||||||
if instance.is_completed:
|
if instance.is_completed:
|
||||||
raise ValidationError(f'出库商品[{instance.goods.name}]已完成')
|
raise ValidationError(f'出库产品[{instance.goods.name}]已完成')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_stock_out_quantity(self, value):
|
def validate_stock_out_quantity(self, value):
|
||||||
|
@ -87,11 +87,11 @@ class StockOutRecordSerializer(BaseSerializer):
|
||||||
goods = stock_out_goods.goods
|
goods = stock_out_goods.goods
|
||||||
|
|
||||||
if stock_out_goods.remain_quantity < attrs['stock_out_quantity']:
|
if stock_out_goods.remain_quantity < attrs['stock_out_quantity']:
|
||||||
raise ValidationError(f'商品[{goods.name}]出库数量错误')
|
raise ValidationError(f'产品[{goods.name}]出库数量错误')
|
||||||
|
|
||||||
if goods.enable_batch_control:
|
if goods.enable_batch_control:
|
||||||
if not (batch := attrs.get('batch')):
|
if not (batch := attrs.get('batch')):
|
||||||
raise ValidationError(f'商品[{goods.name}]未选择批次')
|
raise ValidationError(f'产品[{goods.name}]未选择批次')
|
||||||
|
|
||||||
if batch.goods != attrs['stock_out_goods'].goods:
|
if batch.goods != attrs['stock_out_goods'].goods:
|
||||||
raise ValidationError(f'批次[{batch.number}]选择错误')
|
raise ValidationError(f'批次[{batch.number}]选择错误')
|
||||||
|
@ -107,7 +107,7 @@ class StockOutRecordSerializer(BaseSerializer):
|
||||||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
stock_out_record_goods_items = StockOutRecordGoodsSerializer(source='stock_out_record_goods_set',
|
stock_out_record_goods_items = StockOutRecordGoodsSerializer(source='stock_out_record_goods_set',
|
||||||
many=True, label='出库记录商品')
|
many=True, label='出库记录产品')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = StockOutRecord
|
model = StockOutRecord
|
||||||
|
@ -143,12 +143,12 @@ class StockOutRecordSerializer(BaseSerializer):
|
||||||
|
|
||||||
total_stock_out_quantity = 0
|
total_stock_out_quantity = 0
|
||||||
|
|
||||||
# 创建出库记录商品
|
# 创建出库记录产品
|
||||||
stock_out_record_goods_set = []
|
stock_out_record_goods_set = []
|
||||||
for stock_out_record_goods_item in stock_out_record_goods_items:
|
for stock_out_record_goods_item in stock_out_record_goods_items:
|
||||||
stock_out_goods = stock_out_record_goods_item['stock_out_goods']
|
stock_out_goods = stock_out_record_goods_item['stock_out_goods']
|
||||||
if stock_out_goods.stock_out_order != stock_out_order:
|
if stock_out_goods.stock_out_order != stock_out_order:
|
||||||
raise ValidationError('出库商品错误')
|
raise ValidationError('出库产品错误')
|
||||||
|
|
||||||
stock_out_quantity = stock_out_record_goods_item['stock_out_quantity']
|
stock_out_quantity = stock_out_record_goods_item['stock_out_quantity']
|
||||||
batch = stock_out_record_goods_item.get('batch')
|
batch = stock_out_record_goods_item.get('batch')
|
||||||
|
|
|
@ -63,7 +63,7 @@ class StockOutRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cre
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class StockOutRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cre
|
||||||
batch.has_stock = batch.remain_quantity > 0
|
batch.has_stock = batch.remain_quantity > 0
|
||||||
batch.save(update_fields=['remain_quantity', 'has_stock'])
|
batch.save(update_fields=['remain_quantity', 'has_stock'])
|
||||||
|
|
||||||
# 同步出库商品
|
# 同步出库产品
|
||||||
stock_out_goods = stock_out_record_goods.stock_out_goods
|
stock_out_goods = stock_out_record_goods.stock_out_goods
|
||||||
stock_out_goods.remain_quantity = NP.minus(stock_out_goods.remain_quantity, quantity_change)
|
stock_out_goods.remain_quantity = NP.minus(stock_out_goods.remain_quantity, quantity_change)
|
||||||
stock_out_goods.save(update_fields=['remain_quantity'])
|
stock_out_goods.save(update_fields=['remain_quantity'])
|
||||||
|
@ -95,7 +95,7 @@ class StockOutRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cre
|
||||||
if stock_out_record.is_void:
|
if stock_out_record.is_void:
|
||||||
raise ValidationError(f'出库记录已作废, 无法再次作废')
|
raise ValidationError(f'出库记录已作废, 无法再次作废')
|
||||||
|
|
||||||
# 同步出库记录, 出库记录商品
|
# 同步出库记录, 出库记录产品
|
||||||
stock_out_record.is_void = True
|
stock_out_record.is_void = True
|
||||||
stock_out_record.save(update_fields=['is_void'])
|
stock_out_record.save(update_fields=['is_void'])
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ class StockOutRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cre
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ class StockOutRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cre
|
||||||
batch.has_stock = batch.remain_quantity > 0
|
batch.has_stock = batch.remain_quantity > 0
|
||||||
batch.save(update_fields=['total_quantity', 'remain_quantity', 'has_stock'])
|
batch.save(update_fields=['total_quantity', 'remain_quantity', 'has_stock'])
|
||||||
|
|
||||||
# 同步出库商品
|
# 同步出库产品
|
||||||
stock_out_goods = stock_out_record_goods.stock_out_goods
|
stock_out_goods = stock_out_record_goods.stock_out_goods
|
||||||
stock_out_goods.remain_quantity = NP.plus(stock_out_goods.remain_quantity, quantity_change)
|
stock_out_goods.remain_quantity = NP.plus(stock_out_goods.remain_quantity, quantity_change)
|
||||||
stock_out_goods.save(update_fields=['remain_quantity'])
|
stock_out_goods.save(update_fields=['remain_quantity'])
|
||||||
|
|
|
@ -41,12 +41,12 @@ class StockTransferOrder(Model):
|
||||||
|
|
||||||
|
|
||||||
class StockTransferGoods(Model):
|
class StockTransferGoods(Model):
|
||||||
"""调拨商品"""
|
"""调拨产品"""
|
||||||
|
|
||||||
stock_transfer_order = ForeignKey('stock_transfer.StockTransferOrder', on_delete=CASCADE,
|
stock_transfer_order = ForeignKey('stock_transfer.StockTransferOrder', on_delete=CASCADE,
|
||||||
related_name='stock_transfer_goods_set', verbose_name='采购单据')
|
related_name='stock_transfer_goods_set', verbose_name='采购单据')
|
||||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
goods = ForeignKey('goods.Goods', on_delete=PROTECT,
|
||||||
related_name='stock_transfer_goods_set', verbose_name='商品')
|
related_name='stock_transfer_goods_set', verbose_name='产品')
|
||||||
stock_transfer_quantity = FloatField(verbose_name='调拨数量')
|
stock_transfer_quantity = FloatField(verbose_name='调拨数量')
|
||||||
team = ForeignKey('system.Team', on_delete=CASCADE, related_name='stock_transfer_goods_set')
|
team = ForeignKey('system.Team', on_delete=CASCADE, related_name='stock_transfer_goods_set')
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,11 @@ class StockTransferOrderSerializer(BaseSerializer):
|
||||||
"""调拨单据"""
|
"""调拨单据"""
|
||||||
|
|
||||||
class StockTransferGoodsItemSerializer(BaseSerializer):
|
class StockTransferGoodsItemSerializer(BaseSerializer):
|
||||||
"""调拨商品"""
|
"""调拨产品"""
|
||||||
|
|
||||||
goods_number = CharField(source='goods.number', read_only=True, label='商品编号')
|
goods_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||||
goods_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
goods_name = CharField(source='goods.name', read_only=True, label='产品名称')
|
||||||
goods_barcode = CharField(source='goods.barcode', read_only=True, label='商品条码')
|
goods_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -24,9 +24,9 @@ class StockTransferOrderSerializer(BaseSerializer):
|
||||||
fields = ['goods', 'stock_transfer_quantity', *read_only_fields]
|
fields = ['goods', 'stock_transfer_quantity', *read_only_fields]
|
||||||
|
|
||||||
def validate_goods(self, instance):
|
def validate_goods(self, instance):
|
||||||
instance = self.validate_foreign_key(Goods, instance, message='商品不存在')
|
instance = self.validate_foreign_key(Goods, instance, message='产品不存在')
|
||||||
if not instance.is_active:
|
if not instance.is_active:
|
||||||
raise ValidationError(f'入库商品[{instance.goods.name}]已作废')
|
raise ValidationError(f'入库产品[{instance.goods.name}]已作废')
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def validate_stock_transfer_quantity(self, value):
|
def validate_stock_transfer_quantity(self, value):
|
||||||
|
@ -41,7 +41,7 @@ class StockTransferOrderSerializer(BaseSerializer):
|
||||||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||||
stock_transfer_goods_items = StockTransferGoodsItemSerializer(
|
stock_transfer_goods_items = StockTransferGoodsItemSerializer(
|
||||||
source='stock_transfer_goods_set', many=True, label='调拨商品')
|
source='stock_transfer_goods_set', many=True, label='调拨产品')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = StockTransferOrder
|
model = StockTransferOrder
|
||||||
|
@ -92,7 +92,7 @@ class StockTransferOrderSerializer(BaseSerializer):
|
||||||
|
|
||||||
total_stock_transfer_quantity = 0
|
total_stock_transfer_quantity = 0
|
||||||
|
|
||||||
# 创建调拨商品
|
# 创建调拨产品
|
||||||
stock_transfer_goods_set = []
|
stock_transfer_goods_set = []
|
||||||
for stock_transfer_goods_item in stock_transfer_goods_items:
|
for stock_transfer_goods_item in stock_transfer_goods_items:
|
||||||
goods = stock_transfer_goods_item['goods']
|
goods = stock_transfer_goods_item['goods']
|
||||||
|
|
|
@ -75,11 +75,11 @@ class StockTransferOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin,
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
# 创建出库商品
|
# 创建出库产品
|
||||||
stock_out_goods_set.append(StockOutGoods(
|
stock_out_goods_set.append(StockOutGoods(
|
||||||
stock_out_order=stock_out_order, goods=stock_transfer_goods.goods,
|
stock_out_order=stock_out_order, goods=stock_transfer_goods.goods,
|
||||||
stock_out_quantity=stock_transfer_goods.stock_transfer_quantity,
|
stock_out_quantity=stock_transfer_goods.stock_transfer_quantity,
|
||||||
|
@ -103,11 +103,11 @@ class StockTransferOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin,
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
# 创建入库商品
|
# 创建入库产品
|
||||||
stock_in_goods_set.append(StockInGoods(
|
stock_in_goods_set.append(StockInGoods(
|
||||||
stock_in_order=stock_in_order, goods=stock_transfer_goods.goods,
|
stock_in_order=stock_in_order, goods=stock_transfer_goods.goods,
|
||||||
stock_in_quantity=stock_transfer_goods.stock_transfer_quantity,
|
stock_in_quantity=stock_transfer_goods.stock_transfer_quantity,
|
||||||
|
@ -136,7 +136,7 @@ class StockTransferOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin,
|
||||||
if stock_transfer_order.is_void:
|
if stock_transfer_order.is_void:
|
||||||
raise ValidationError(f'调拨单据[{stock_transfer_order.number}]已作废, 无法再次作废')
|
raise ValidationError(f'调拨单据[{stock_transfer_order.number}]已作废, 无法再次作废')
|
||||||
|
|
||||||
# 同步调拨单据, 调拨商品
|
# 同步调拨单据, 调拨产品
|
||||||
stock_transfer_order.is_void = True
|
stock_transfer_order.is_void = True
|
||||||
stock_transfer_order.save(update_fields=['is_void'])
|
stock_transfer_order.save(update_fields=['is_void'])
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ class StockTransferOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin,
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
|
@ -190,7 +190,7 @@ class StockTransferOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin,
|
||||||
|
|
||||||
inventory.total_quantity = quantity_after
|
inventory.total_quantity = quantity_after
|
||||||
if inventory.total_quantity < 0:
|
if inventory.total_quantity < 0:
|
||||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||||
inventory.has_stock = inventory.total_quantity > 0
|
inventory.has_stock = inventory.total_quantity > 0
|
||||||
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
inventory.save(update_fields=['total_quantity', 'has_stock'])
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -29,13 +29,13 @@ class SystemConfigSerializer(BaseSerializer):
|
||||||
|
|
||||||
def validate_enable_batch_control(self, value):
|
def validate_enable_batch_control(self, value):
|
||||||
if value and (self.team.enable_auto_stock_in or self.team.enable_auto_stock_out):
|
if value and (self.team.enable_auto_stock_in or self.team.enable_auto_stock_out):
|
||||||
raise ValidationError('只有同时关闭自动入库、自动出库, 才可以开启商品的批次控制')
|
raise ValidationError('只有同时关闭自动入库、自动出库, 才可以开启产品的批次控制')
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def validate(self, attrs):
|
def validate(self, attrs):
|
||||||
if attrs['enable_auto_stock_in'] or attrs['enable_auto_stock_out']:
|
if attrs['enable_auto_stock_in'] or attrs['enable_auto_stock_out']:
|
||||||
if goods := Goods.objects.filter(enable_batch_control=True, team=self.team).first():
|
if goods := Goods.objects.filter(enable_batch_control=True, team=self.team).first():
|
||||||
raise ValidationError(f'商品[{goods.name}]已开启批次控制, 无法开启自动出/入库')
|
raise ValidationError(f'产品[{goods.name}]已开启批次控制, 无法开启自动出/入库')
|
||||||
return super().validate(attrs)
|
return super().validate(attrs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
# 商品信息
|
# 产品信息
|
||||||
|
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
- 查询/创建商品:
|
- 查询/创建产品:
|
||||||
[/api/goods/]
|
[/api/goods/]
|
||||||
|
|
||||||
- 编辑/删除商品:
|
- 编辑/删除产品:
|
||||||
[/api/goods/{id}/]
|
[/api/goods/{id}/]
|
||||||
|
|
||||||
- 获取商品编号:
|
- 获取产品编号:
|
||||||
[/api/goods/number/]
|
[/api/goods/number/]
|
||||||
|
|
||||||
- 导出
|
- 导出
|
||||||
|
@ -24,13 +24,13 @@
|
||||||
|
|
||||||
## 其他接口
|
## 其他接口
|
||||||
|
|
||||||
- 商品分类选项:
|
- 产品分类选项:
|
||||||
[/api/goods_categories/options/]
|
[/api/goods_categories/options/]
|
||||||
|
|
||||||
- 商品单位选项:
|
- 产品单位选项:
|
||||||
[/api/goods_units/options/]
|
[/api/goods_units/options/]
|
||||||
|
|
||||||
- 上传商品图片:
|
- 上传产品图片:
|
||||||
[/api/goods_images/]
|
[/api/goods_images/]
|
||||||
|
|
||||||
- 仓库选项:
|
- 仓库选项:
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# 商品分类
|
# 产品分类
|
||||||
|
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
- 查询/创建商品分类:
|
- 查询/创建产品分类:
|
||||||
[/api/goods_categories/]
|
[/api/goods_categories/]
|
||||||
|
|
||||||
- 编辑/删除商品分类:
|
- 编辑/删除产品分类:
|
||||||
[/api/goods_categories/{id}/]
|
[/api/goods_categories/{id}/]
|
||||||
|
|
||||||
- 导出
|
- 导出
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# 商品单位
|
# 产品单位
|
||||||
|
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
- 查询/创建商品单位:
|
- 查询/创建产品单位:
|
||||||
[/api/goods_units/]
|
[/api/goods_units/]
|
||||||
|
|
||||||
- 编辑/删除商品单位:
|
- 编辑/删除产品单位:
|
||||||
[/api/goods_units/{id}/]
|
[/api/goods_units/{id}/]
|
||||||
|
|
||||||
- 导出
|
- 导出
|
||||||
|
|
|
@ -24,4 +24,4 @@
|
||||||
|
|
||||||
## 补充说明
|
## 补充说明
|
||||||
|
|
||||||
- 如果入库商品开启批次控制, 则需要额外输入批次编号
|
- 如果入库产品开启批次控制, 则需要额外输入批次编号
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
- 经手人选项:
|
- 经手人选项:
|
||||||
[/api/users/options/]{is_active: true}
|
[/api/users/options/]{is_active: true}
|
||||||
|
|
||||||
- 商品选项:
|
- 产品选项:
|
||||||
[/api/inventories/options/]{page, warehouse, is_active: true}
|
[/api/inventories/options/]{page, warehouse, is_active: true}
|
||||||
|
|
||||||
- 批次选项:
|
- 批次选项:
|
||||||
|
@ -30,4 +30,4 @@
|
||||||
|
|
||||||
## 补充说明
|
## 补充说明
|
||||||
|
|
||||||
- 如果盘点商品开启批次控制, 则需要额外输入该商品的批次信息
|
- 如果盘点产品开启批次控制, 则需要额外输入该产品的批次信息
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
- 经手人选项:
|
- 经手人选项:
|
||||||
[/api/users/options/]{is_active: true}
|
[/api/users/options/]{is_active: true}
|
||||||
|
|
||||||
- 商品选项:
|
- 产品选项:
|
||||||
[/api/inventories/options/]{page, warehouse, is_active: true}
|
[/api/inventories/options/]{page, warehouse, is_active: true}
|
||||||
|
|
||||||
- 批次选项:
|
- 批次选项:
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
- 采购报表明细:
|
- 采购报表明细:
|
||||||
[/api/purchase_reports/detials/]
|
[/api/purchase_reports/detials/]
|
||||||
|
|
||||||
- 采购报表按商品汇总:
|
- 采购报表按产品汇总:
|
||||||
[/api/purchase_reports/group_by_goods/]
|
[/api/purchase_reports/group_by_goods/]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
- 销售报表明细:
|
- 销售报表明细:
|
||||||
[/api/sales_reports/detials/]
|
[/api/sales_reports/detials/]
|
||||||
|
|
||||||
- 销售报表按商品汇总:
|
- 销售报表按产品汇总:
|
||||||
[/api/sales_reports/group_by_goods/]
|
[/api/sales_reports/group_by_goods/]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
- 仓库
|
- 仓库
|
||||||
- 结算账户
|
- 结算账户
|
||||||
- 收支项目
|
- 收支项目
|
||||||
- 商品管理
|
- 产品管理
|
||||||
- 商品分类
|
- 产品分类
|
||||||
- 商品单位
|
- 产品单位
|
||||||
- 商品信息
|
- 产品信息
|
||||||
- 采购管理
|
- 采购管理
|
||||||
- 采购开单
|
- 采购开单
|
||||||
- 采购记录
|
- 采购记录
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
- 经手人选项:
|
- 经手人选项:
|
||||||
[/api/users/options/]{is_active: true}
|
[/api/users/options/]{is_active: true}
|
||||||
|
|
||||||
- 商品选项:
|
- 产品选项:
|
||||||
[/api/inventories/options/]{page, warehouse, is_active: true}
|
[/api/inventories/options/]{page, warehouse, is_active: true}
|
||||||
|
|
||||||
- 结算账户选项:
|
- 结算账户选项:
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
- 经手人选项:
|
- 经手人选项:
|
||||||
[/api/users/options/]{is_active: true}
|
[/api/users/options/]{is_active: true}
|
||||||
|
|
||||||
- 商品选项:
|
- 产品选项:
|
||||||
[/api/inventories/options/]{page, warehouse, is_active: true}
|
[/api/inventories/options/]{page, warehouse, is_active: true}
|
||||||
|
|
||||||
- 结算账户选项:
|
- 结算账户选项:
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
- 仓库选项:
|
- 仓库选项:
|
||||||
[/api/warehouses/options/]{is_active: true}
|
[/api/warehouses/options/]{is_active: true}
|
||||||
|
|
||||||
- 商品选项:
|
- 产品选项:
|
||||||
[/api/goods/options/]{page, is_active: true}
|
[/api/goods/options/]{page, is_active: true}
|
||||||
|
|
||||||
- 销售员选项:
|
- 销售员选项:
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
- 经手人选项:
|
- 经手人选项:
|
||||||
[/api/users/options/]{is_active: true}
|
[/api/users/options/]{is_active: true}
|
||||||
|
|
||||||
- 商品选项:
|
- 产品选项:
|
||||||
[/api/inventories/options/]{page, warehouse, is_active: true}
|
[/api/inventories/options/]{page, warehouse, is_active: true}
|
||||||
|
|
||||||
- 结算账户选项:
|
- 结算账户选项:
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
- 经手人选项:
|
- 经手人选项:
|
||||||
[/api/users/options/]{is_active: true}
|
[/api/users/options/]{is_active: true}
|
||||||
|
|
||||||
- 商品选项:
|
- 产品选项:
|
||||||
[/api/inventories/options/]{page, warehouse, is_active: true}
|
[/api/inventories/options/]{page, warehouse, is_active: true}
|
||||||
|
|
||||||
- 结算账户选项:
|
- 结算账户选项:
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
- 出库任务提醒
|
- 出库任务提醒
|
||||||
[/api/stock_out_order_reminders/]
|
[/api/stock_out_order_reminders/]
|
||||||
|
|
||||||
- 销售前十商品
|
- 销售前十产品
|
||||||
[/api/sales_hot_goods/]{start_date, end_date}
|
[/api/sales_hot_goods/]{start_date, end_date}
|
||||||
|
|
||||||
- 销售走势
|
- 销售走势
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<a-modal v-model="visible" :confirmLoading="loading" :maskClosable="false" @cancel="cancel" @ok="confirm">
|
<a-modal v-model="visible" :width="560" :confirmLoading="loading" :maskClosable="false" @cancel="cancel" @ok="confirm">
|
||||||
<div slot="title">{{form.id ? '编辑角色' : '新增角色' }}</div>
|
<div slot="title">{{form.id ? '编辑角色' : '新增角色' }}</div>
|
||||||
<div>
|
<div>
|
||||||
<a-form-model ref="form" :model="form" :rules="rules" :label-col="{ span: 4 }" :wrapper-col="{ span: 16 }">
|
<a-form-model ref="form" :model="form" :rules="rules" :label-col="{ span: 4 }" :wrapper-col="{ span: 16 }">
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
<a-input v-model="form.remark" allowClear />
|
<a-input v-model="form.remark" allowClear />
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
|
|
||||||
<a-checkbox-group v-model="form.permissions">
|
<!-- <a-checkbox-group v-model="form.permissions">
|
||||||
<a-descriptions size="small" title="权限" bordered>
|
<a-descriptions size="small" title="权限" bordered>
|
||||||
<a-descriptions-item v-for="permissionTypeItem in $parent.permissionItems" :key="permissionTypeItem.id" :label="permissionTypeItem.name" :span="3">
|
<a-descriptions-item v-for="permissionTypeItem in $parent.permissionItems" :key="permissionTypeItem.id" :label="permissionTypeItem.name" :span="3">
|
||||||
<a-row>
|
<a-row>
|
||||||
|
@ -21,6 +21,28 @@
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
|
</a-checkbox-group> -->
|
||||||
|
|
||||||
|
|
||||||
|
<a-checkbox-group v-model="form.permissions">
|
||||||
|
<a-descriptions size="small" title="权限" bordered>
|
||||||
|
<a-descriptions-item
|
||||||
|
v-for="permissionTypeItem in $parent.permissionItems"
|
||||||
|
:key="permissionTypeItem.id"
|
||||||
|
:span="3"
|
||||||
|
>
|
||||||
|
<div slot="label" style="width: 90px">
|
||||||
|
<a-checkbox :value="permissionTypeItem.name" @change="checkAll">{{
|
||||||
|
permissionTypeItem.name
|
||||||
|
}}</a-checkbox>
|
||||||
|
</div>
|
||||||
|
<a-row>
|
||||||
|
<a-col v-for="item in permissionTypeItem.permission_items" :key="item.id" :span="8">
|
||||||
|
<a-checkbox :value="item.id">{{ item.name }}</a-checkbox>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
</a-checkbox-group>
|
</a-checkbox-group>
|
||||||
|
|
||||||
<!-- <a-form-model-item prop="permissions" label="角色权限">
|
<!-- <a-form-model-item prop="permissions" label="角色权限">
|
||||||
|
@ -70,6 +92,22 @@
|
||||||
this.$emit('cancel', false);
|
this.$emit('cancel', false);
|
||||||
this.$refs.form.resetFields();
|
this.$refs.form.resetFields();
|
||||||
},
|
},
|
||||||
|
checkAll(event) {
|
||||||
|
for (let item of this.$parent.permissionItems) {
|
||||||
|
if (item.name == event.target.value) {
|
||||||
|
for (let permissionItem of item.permission_items) {
|
||||||
|
let index = this.form.permissions.indexOf(permissionItem.id);
|
||||||
|
|
||||||
|
if (event.target.checked && index == -1) {
|
||||||
|
this.form.permissions.push(permissionItem.id);
|
||||||
|
} else if (!event.target.checked && index != -1) {
|
||||||
|
this.form.permissions.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -12,6 +12,6 @@ def run(*args):
|
||||||
Supplier.objects.create(number='S001', name='默认供应商', team=team)
|
Supplier.objects.create(number='S001', name='默认供应商', team=team)
|
||||||
|
|
||||||
warehouse = Warehouse.objects.create(number='W001', name='默认仓库', team=team)
|
warehouse = Warehouse.objects.create(number='W001', name='默认仓库', team=team)
|
||||||
goods = Goods.objects.create(number='G001', name='商品A', purchase_price=10, retail_price=20,
|
goods = Goods.objects.create(number='G001', name='产品A', purchase_price=10, retail_price=20,
|
||||||
level_price1=20, level_price2=20, level_price3=20, team=team)
|
level_price1=20, level_price2=20, level_price3=20, team=team)
|
||||||
Inventory.objects.create(warehouse=warehouse, goods=goods, team=team)
|
Inventory.objects.create(warehouse=warehouse, goods=goods, team=team)
|
||||||
|
|
|
@ -6,7 +6,7 @@ PERMISSIONS = [
|
||||||
'name': '首页',
|
'name': '首页',
|
||||||
'permissions': [
|
'permissions': [
|
||||||
{'name': '销售走势', 'code': 'sales_trend'},
|
{'name': '销售走势', 'code': 'sales_trend'},
|
||||||
{'name': '销售前十商品', 'code': 'sales_hot_goods'},
|
{'name': '销售前十产品', 'code': 'sales_hot_goods'},
|
||||||
{'name': '入库任务提醒', 'code': 'stock_in_reminder'},
|
{'name': '入库任务提醒', 'code': 'stock_in_reminder'},
|
||||||
{'name': '出库任务提醒', 'code': 'stock_out_reminder'},
|
{'name': '出库任务提醒', 'code': 'stock_out_reminder'},
|
||||||
{'name': '库存预警', 'code': 'inventory_warning'},
|
{'name': '库存预警', 'code': 'inventory_warning'},
|
||||||
|
@ -33,11 +33,11 @@ PERMISSIONS = [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': '商品管理',
|
'name': '产品管理',
|
||||||
'permissions': [
|
'permissions': [
|
||||||
{'name': '商品分类', 'code': 'goods_category'},
|
{'name': '产品分类', 'code': 'goods_category'},
|
||||||
{'name': '商品单位', 'code': 'goods_unit'},
|
{'name': '产品单位', 'code': 'goods_unit'},
|
||||||
{'name': '商品信息', 'code': 'goods'},
|
{'name': '产品信息', 'code': 'goods'},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue