mirror of
https://github.com/himool/HimoolERP.git
synced 2024-09-20 06:46: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/%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/%E5%BA%93%E5%AD%98.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', '作废调拨转入')
|
||||
|
||||
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='流水类型')
|
||||
quantity_before = FloatField(verbose_name='变化之前数量')
|
||||
quantity_change = FloatField(verbose_name='变化数量')
|
||||
|
|
|
@ -7,9 +7,9 @@ from apps.flow.models import *
|
|||
class InventoryFlowSerializer(BaseSerializer):
|
||||
warehouse_number = CharField(source='warehouse.number', 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_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
||||
goods_barcode = CharField(source='goods.barcode', 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_barcode = CharField(source='goods.barcode', 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='流水类型')
|
||||
purchase_order_number = CharField(source='purchase_order.number', read_only=True, label='采购单号')
|
||||
|
|
|
@ -3,7 +3,7 @@ from extensions.models import *
|
|||
|
||||
|
||||
class GoodsCategory(Model):
|
||||
"""商品分类"""
|
||||
"""产品分类"""
|
||||
|
||||
name = CharField(max_length=64, verbose_name='名称')
|
||||
remark = CharField(max_length=256, null=True, blank=True, verbose_name='备注')
|
||||
|
@ -14,7 +14,7 @@ class GoodsCategory(Model):
|
|||
|
||||
|
||||
class GoodsUnit(Model):
|
||||
"""商品单位"""
|
||||
"""产品单位"""
|
||||
|
||||
name = CharField(max_length=64, verbose_name='名称')
|
||||
remark = CharField(max_length=256, null=True, blank=True, verbose_name='备注')
|
||||
|
@ -25,15 +25,15 @@ class GoodsUnit(Model):
|
|||
|
||||
|
||||
class Goods(Model):
|
||||
"""商品"""
|
||||
"""产品"""
|
||||
|
||||
number = CharField(max_length=32, verbose_name='编号')
|
||||
name = CharField(max_length=64, verbose_name='名称')
|
||||
barcode = CharField(max_length=32, null=True, blank=True, verbose_name='条码')
|
||||
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,
|
||||
related_name='goods_set', verbose_name='商品单位')
|
||||
related_name='goods_set', verbose_name='产品单位')
|
||||
spec = CharField(max_length=64, null=True, blank=True, verbose_name='规格')
|
||||
enable_batch_control = BooleanField(default=False, verbose_name='启用批次控制')
|
||||
shelf_life_days = IntegerField(null=True, verbose_name='保质期天数')
|
||||
|
@ -76,10 +76,10 @@ class Goods(Model):
|
|||
|
||||
|
||||
class GoodsImage(Model):
|
||||
"""商品图片"""
|
||||
"""产品图片"""
|
||||
|
||||
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='文件')
|
||||
name = CharField(max_length=256, verbose_name='文件名称')
|
||||
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='编号')
|
||||
inventory = ForeignKey('goods.Inventory', 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='初始库存')
|
||||
total_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='仓库')
|
||||
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='初始库存')
|
||||
total_quantity = FloatField(default=0, verbose_name='库存总数')
|
||||
has_stock = BooleanField(default=False, verbose_name='库存状态')
|
||||
|
|
|
@ -93,7 +93,7 @@ class GoodsSerializer(BaseSerializer):
|
|||
inventory_items = InventoryItemSerializer(
|
||||
source='inventories', required=False, many=True, label='库存Item')
|
||||
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:
|
||||
model = Goods
|
||||
|
@ -110,20 +110,20 @@ class GoodsSerializer(BaseSerializer):
|
|||
return value
|
||||
|
||||
def validate_category(self, instance):
|
||||
instance = self.validate_foreign_key(GoodsCategory, instance, message='商品分类不存在')
|
||||
instance = self.validate_foreign_key(GoodsCategory, instance, message='产品分类不存在')
|
||||
return instance
|
||||
|
||||
def validate_unit(self, instance):
|
||||
instance = self.validate_foreign_key(GoodsUnit, instance, message='商品单位不存在')
|
||||
instance = self.validate_foreign_key(GoodsUnit, instance, message='产品单位不存在')
|
||||
return instance
|
||||
|
||||
def validate_enable_batch_control(self, value):
|
||||
if value and (self.team.enable_auto_stock_in or self.team.enable_auto_stock_out):
|
||||
raise ValidationError('只有同时关闭自动入库、自动出库, 才可以开启商品的批次控制')
|
||||
raise ValidationError('只有同时关闭自动入库、自动出库, 才可以开启产品的批次控制')
|
||||
return value
|
||||
|
||||
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
|
||||
|
||||
@transaction.atomic
|
||||
|
@ -145,7 +145,7 @@ class GoodsSerializer(BaseSerializer):
|
|||
|
||||
total_initial_quantity = 0
|
||||
|
||||
# 商品开启批次控制, 创建批次
|
||||
# 产品开启批次控制, 创建批次
|
||||
batch_items = inventory_item.get('batchs')
|
||||
if goods.enable_batch_control and batch_items:
|
||||
for batch_item in batch_items:
|
||||
|
@ -171,7 +171,7 @@ class GoodsSerializer(BaseSerializer):
|
|||
inventory.initial_quantity = total_initial_quantity
|
||||
inventory.total_quantity = total_initial_quantity
|
||||
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.save(update_fields=['initial_quantity', 'total_quantity', 'has_stock'])
|
||||
break
|
||||
|
@ -265,7 +265,7 @@ class GoodsSerializer(BaseSerializer):
|
|||
inventory.initial_quantity = total_initial_quantity
|
||||
inventory.total_quantity = NP.plus(inventory.total_quantity, inventory.initial_quantity)
|
||||
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.save(update_fields=['initial_quantity', 'total_quantity', 'has_stock'])
|
||||
else:
|
||||
|
@ -273,7 +273,7 @@ class GoodsSerializer(BaseSerializer):
|
|||
inventory.initial_quantity = inventory_initial_quantity
|
||||
inventory.total_quantity = NP.plus(inventory.total_quantity, inventory.initial_quantity)
|
||||
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.save(update_fields=['initial_quantity', 'total_quantity', 'has_stock'])
|
||||
|
||||
|
@ -290,8 +290,8 @@ class GoodsSerializer(BaseSerializer):
|
|||
|
||||
|
||||
class GoodsImportExportSerializer(BaseSerializer):
|
||||
number = CharField(label='商品编号(唯一必填)')
|
||||
name = CharField(label='商品名称(必填)')
|
||||
number = CharField(label='产品编号(唯一必填)')
|
||||
name = CharField(label='产品名称(必填)')
|
||||
barcode = CharField(required=False, label='条码')
|
||||
category = CharField(source='category.name', required=False, label='分类')
|
||||
unit = CharField(source='unit.name', required=False, label='单位')
|
||||
|
@ -334,9 +334,9 @@ class GoodsImageSerializer(BaseSerializer):
|
|||
class BatchSerializer(BaseSerializer):
|
||||
warehouse_number = CharField(source='warehouse.number', 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_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
||||
goods_barcode = CharField(source='goods.barcode', 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_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||
|
||||
class Meta:
|
||||
|
@ -349,9 +349,9 @@ class BatchSerializer(BaseSerializer):
|
|||
class InventorySerializer(BaseSerializer):
|
||||
warehouse_number = CharField(source='warehouse.number', 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_name = CharField(source='goods.name', read_only=True, label='商品名称')
|
||||
goods_barcode = CharField(source='goods.barcode', 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_barcode = CharField(source='goods.barcode', read_only=True, label='产品条码')
|
||||
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -12,7 +12,7 @@ from apps.data.models import *
|
|||
|
||||
|
||||
class GoodsCategoryViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
||||
"""商品分类"""
|
||||
"""产品分类"""
|
||||
|
||||
serializer_class = GoodsCategorySerializer
|
||||
permission_classes = [IsAuthenticated, GoodsCategoryPermission]
|
||||
|
@ -77,7 +77,7 @@ class GoodsCategoryViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
|||
|
||||
|
||||
class GoodsUnitViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
||||
"""商品单位"""
|
||||
"""产品单位"""
|
||||
|
||||
serializer_class = GoodsUnitSerializer
|
||||
permission_classes = [IsAuthenticated, GoodsUnitPermission]
|
||||
|
@ -142,7 +142,7 @@ class GoodsUnitViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
|||
|
||||
|
||||
class GoodsViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
||||
"""商品"""
|
||||
"""产品"""
|
||||
|
||||
serializer_class = GoodsSerializer
|
||||
permission_classes = [IsAuthenticated, GoodsPermission]
|
||||
|
@ -250,7 +250,7 @@ class GoodsViewSet(ModelViewSet, ExportMixin, ImportMixin):
|
|||
|
||||
|
||||
class GoodsImageViewSet(ModelViewSet):
|
||||
"""商品图片"""
|
||||
"""产品图片"""
|
||||
|
||||
serializer_class = GoodsImageSerializer
|
||||
permission_classes = [IsAuthenticated, GoodsPermission]
|
||||
|
|
|
@ -2,10 +2,10 @@ from extensions.serializers import *
|
|||
|
||||
|
||||
class InventoryWarningResponse(Serializer):
|
||||
goods = IntegerField(label='商品ID')
|
||||
goods_number = CharField(label='商品编号')
|
||||
goods_name = CharField(label='商品名称')
|
||||
goods_barcode = CharField(label='商品条码')
|
||||
goods = IntegerField(label='产品ID')
|
||||
goods_number = CharField(label='产品编号')
|
||||
goods_name = CharField(label='产品名称')
|
||||
goods_barcode = CharField(label='产品条码')
|
||||
unit_name = CharField(label='单位名称')
|
||||
inventory_upper = FloatField(label='库存上限')
|
||||
inventory_lower = FloatField(label='库存下限')
|
||||
|
|
|
@ -8,7 +8,7 @@ from apps.sales.models import *
|
|||
# Goods
|
||||
class BatchOptionFilter(FilterSet):
|
||||
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:
|
||||
model = Batch
|
||||
|
@ -17,8 +17,8 @@ class BatchOptionFilter(FilterSet):
|
|||
|
||||
class InventoryOptionFilter(FilterSet):
|
||||
warehouse = NumberFilter(field_name='warehouse', required=True, label='仓库')
|
||||
category = NumberFilter(field_name='goods__category', label='商品分类')
|
||||
is_active = BooleanFilter(field_name='goods__is_active', label='商品激活状态')
|
||||
category = NumberFilter(field_name='goods__category', label='产品分类')
|
||||
is_active = BooleanFilter(field_name='goods__is_active', label='产品激活状态')
|
||||
|
||||
class Meta:
|
||||
model = Inventory
|
||||
|
|
|
@ -92,10 +92,10 @@ class BatchOptionSerializer(ModelSerializer):
|
|||
|
||||
|
||||
class InventoryOptionSerializer(ModelSerializer):
|
||||
goods_number = CharField(source='goods.number', 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_spec = CharField(source='goods.spec', 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_barcode = CharField(source='goods.barcode', 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='采购价')
|
||||
retail_price = FloatField(source='goods.retail_price', 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 PurchaseGoodsItemSerializer(ModelSerializer):
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
|
||||
class Meta:
|
||||
|
@ -141,7 +141,7 @@ class PurchaseOrderOptionSerializer(ModelSerializer):
|
|||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
purchase_goods_items = PurchaseGoodsItemSerializer(
|
||||
source='purchase_goods_set', many=True, label='采购商品Item')
|
||||
source='purchase_goods_set', many=True, label='采购产品Item')
|
||||
purchase_account_items = PurchaseAccountItemSerializer(
|
||||
source='purchase_accounts', required=False, many=True, label='采购结算账户Item')
|
||||
|
||||
|
@ -158,9 +158,9 @@ class PurchaseOrderOptionSerializer(ModelSerializer):
|
|||
class SalesOrderOptionSerializer(ModelSerializer):
|
||||
|
||||
class SalesGoodsItemSerializer(ModelSerializer):
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
|
||||
class Meta:
|
||||
|
@ -183,7 +183,7 @@ class SalesOrderOptionSerializer(ModelSerializer):
|
|||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
sales_goods_items = SalesGoodsItemSerializer(
|
||||
source='sales_goods_set', many=True, label='采购商品Item')
|
||||
source='sales_goods_set', many=True, label='采购产品Item')
|
||||
sales_account_items = SalesAccountItemSerializer(
|
||||
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):
|
||||
"""采购商品"""
|
||||
"""采购产品"""
|
||||
|
||||
purchase_order = ForeignKey('purchase.PurchaseOrder', on_delete=CASCADE,
|
||||
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_price = FloatField(verbose_name='采购单价')
|
||||
total_amount = AmountField(verbose_name='总金额')
|
||||
|
@ -110,14 +110,14 @@ class PurchaseReturnOrder(Model):
|
|||
|
||||
|
||||
class PurchaseReturnGoods(Model):
|
||||
"""采购退货商品"""
|
||||
"""采购退货产品"""
|
||||
|
||||
purchase_return_order = ForeignKey('purchase.PurchaseReturnOrder', on_delete=CASCADE,
|
||||
related_name='purchase_return_goods_set', verbose_name='采购退货单据')
|
||||
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,
|
||||
related_name='purchase_return_goods_set', verbose_name='商品')
|
||||
related_name='purchase_return_goods_set', verbose_name='产品')
|
||||
return_quantity = FloatField(verbose_name='退货数量')
|
||||
return_price = FloatField(verbose_name='退货单价')
|
||||
total_amount = AmountField(verbose_name='总金额')
|
||||
|
|
|
@ -12,11 +12,11 @@ class PurchaseOrderSerializer(BaseSerializer):
|
|||
"""采购单据"""
|
||||
|
||||
class PurchaseGoodsItemSerializer(BaseSerializer):
|
||||
"""采购商品"""
|
||||
"""采购产品"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
|
||||
class Meta:
|
||||
|
@ -26,9 +26,9 @@ class PurchaseOrderSerializer(BaseSerializer):
|
|||
fields = ['goods', 'purchase_quantity', 'purchase_price', *read_only_fields]
|
||||
|
||||
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:
|
||||
raise ValidationError(f'商品[{instance.name}]未激活')
|
||||
raise ValidationError(f'产品[{instance.name}]未激活')
|
||||
return instance
|
||||
|
||||
def validate_purchase_quantity(self, value):
|
||||
|
@ -70,7 +70,7 @@ class PurchaseOrderSerializer(BaseSerializer):
|
|||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
purchase_goods_items = PurchaseGoodsItemSerializer(
|
||||
source='purchase_goods_set', many=True, label='采购商品Item')
|
||||
source='purchase_goods_set', many=True, label='采购产品Item')
|
||||
purchase_account_items = PurchaseAccountItemSerializer(
|
||||
source='purchase_accounts', required=False, many=True, label='采购结算账户Item')
|
||||
|
||||
|
@ -123,7 +123,7 @@ class PurchaseOrderSerializer(BaseSerializer):
|
|||
total_purchase_quantity = 0
|
||||
total_purchase_amount = 0
|
||||
|
||||
# 创建采购商品
|
||||
# 创建采购产品
|
||||
purchase_goods_set = []
|
||||
for purchase_goods_item in purchase_goods_items:
|
||||
purchase_quantity = purchase_goods_item['purchase_quantity']
|
||||
|
@ -171,11 +171,11 @@ class PurchaseReturnOrderSerializer(BaseSerializer):
|
|||
"""采购退货单据"""
|
||||
|
||||
class PurchaseReturnGoodsItemSerializer(BaseSerializer):
|
||||
"""采购退货商品"""
|
||||
"""采购退货产品"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
|
||||
class Meta:
|
||||
|
@ -185,13 +185,13 @@ class PurchaseReturnOrderSerializer(BaseSerializer):
|
|||
fields = ['purchase_goods', 'goods', 'return_quantity', 'return_price', *read_only_fields]
|
||||
|
||||
def validate_purchase_goods(self, instance):
|
||||
instance = self.validate_foreign_key(PurchaseGoods, instance, message='采购商品不存在')
|
||||
instance = self.validate_foreign_key(PurchaseGoods, instance, message='采购产品不存在')
|
||||
return 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:
|
||||
raise ValidationError(f'商品[{instance.name}]未激活')
|
||||
raise ValidationError(f'产品[{instance.name}]未激活')
|
||||
return instance
|
||||
|
||||
def validate_return_quantity(self, value):
|
||||
|
@ -234,7 +234,7 @@ class PurchaseReturnOrderSerializer(BaseSerializer):
|
|||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
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(
|
||||
source='purchase_return_accounts', required=False, many=True, label='采购退货结算账户Item')
|
||||
|
||||
|
@ -299,7 +299,7 @@ class PurchaseReturnOrderSerializer(BaseSerializer):
|
|||
total_return_quantity = 0
|
||||
total_return_amount = 0
|
||||
|
||||
# 创建采购退货商品
|
||||
# 创建采购退货产品
|
||||
purchase_return_goods_set = []
|
||||
for purchase_return_goods_item in purchase_return_goods_items:
|
||||
goods = purchase_return_goods_item['goods']
|
||||
|
@ -308,13 +308,13 @@ class PurchaseReturnOrderSerializer(BaseSerializer):
|
|||
purchase_goods = None
|
||||
if purchase_order := purchase_return_order.purchase_order:
|
||||
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)
|
||||
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'])
|
||||
|
||||
return_price = purchase_return_goods_item['return_price']
|
||||
|
|
|
@ -51,7 +51,7 @@ class PurchaseOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
else:
|
||||
|
@ -67,7 +67,7 @@ class PurchaseOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
|||
creator=self.user, team=self.team
|
||||
)
|
||||
|
||||
# 创建入库商品
|
||||
# 创建入库产品
|
||||
stock_in_goods_set = []
|
||||
for purchase_goods in purchase_order.purchase_goods_set.all():
|
||||
stock_in_goods_set.append(StockInGoods(
|
||||
|
@ -125,7 +125,7 @@ class PurchaseOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
|||
if purchase_order.is_void:
|
||||
raise ValidationError(f'采购单据[{purchase_order.number}]已作废, 无法再次作废')
|
||||
|
||||
# 同步采购单据, 采购商品
|
||||
# 同步采购单据, 采购产品
|
||||
purchase_order.is_void = True
|
||||
purchase_order.save(update_fields=['is_void'])
|
||||
|
||||
|
@ -148,7 +148,7 @@ class PurchaseOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
else:
|
||||
|
@ -232,7 +232,7 @@ class PurchaseReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
else:
|
||||
|
@ -248,7 +248,7 @@ class PurchaseReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin
|
|||
creator=self.user, team=self.team
|
||||
)
|
||||
|
||||
# 创建出库商品
|
||||
# 创建出库产品
|
||||
stock_out_goods_set = []
|
||||
for purchase_return_goods in purchase_return_order.purchase_return_goods_set.all():
|
||||
stock_out_goods_set.append(StockOutGoods(
|
||||
|
@ -305,7 +305,7 @@ class PurchaseReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin
|
|||
if purchase_return_order.is_void:
|
||||
raise ValidationError(f'采购退货单据[{purchase_return_order.number}]已作废, 无法再次作废')
|
||||
|
||||
# 同步采购退货单据, 采购退货商品
|
||||
# 同步采购退货单据, 采购退货产品
|
||||
purchase_return_order.is_void = True
|
||||
purchase_return_order.save(update_fields=['is_void'])
|
||||
|
||||
|
@ -328,11 +328,11 @@ class PurchaseReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
|
||||
# 同步采购商品退货数量
|
||||
# 同步采购产品退货数量
|
||||
if purchase_goods := purchase_return_goods.purchase_goods:
|
||||
purchase_goods.return_quantity = NP.minus(purchase_goods.return_quantity,
|
||||
purchase_return_goods.return_quantity)
|
||||
|
|
|
@ -42,11 +42,11 @@ class SalesOrder(Model):
|
|||
|
||||
|
||||
class SalesGoods(Model):
|
||||
"""销售商品"""
|
||||
"""销售产品"""
|
||||
|
||||
sales_order = ForeignKey('sales.SalesOrder', on_delete=CASCADE,
|
||||
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_price = FloatField(verbose_name='销售单价')
|
||||
total_amount = AmountField(verbose_name='总金额')
|
||||
|
@ -111,13 +111,13 @@ class SalesReturnOrder(Model):
|
|||
|
||||
|
||||
class SalesReturnGoods(Model):
|
||||
"""销售退货商品"""
|
||||
"""销售退货产品"""
|
||||
|
||||
sales_return_order = ForeignKey('sales.SalesReturnOrder', on_delete=CASCADE,
|
||||
related_name='sales_return_goods_set', verbose_name='销售退货单据')
|
||||
sales_goods = ForeignKey('sales.SalesGoods', on_delete=CASCADE, null=True,
|
||||
related_name='sales_return_goods_set', verbose_name='销售商品')
|
||||
goods = ForeignKey('goods.Goods', on_delete=PROTECT, 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='产品')
|
||||
return_quantity = FloatField(verbose_name='退货数量')
|
||||
return_price = FloatField(verbose_name='退货单价')
|
||||
total_amount = AmountField(verbose_name='总金额')
|
||||
|
|
|
@ -12,11 +12,11 @@ class SalesOrderSerializer(BaseSerializer):
|
|||
"""销售单据"""
|
||||
|
||||
class SalesGoodsItemSerializer(BaseSerializer):
|
||||
"""销售商品"""
|
||||
"""销售产品"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
|
||||
class Meta:
|
||||
|
@ -26,9 +26,9 @@ class SalesOrderSerializer(BaseSerializer):
|
|||
fields = ['goods', 'sales_quantity', 'sales_price', *read_only_fields]
|
||||
|
||||
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:
|
||||
raise ValidationError(f'商品[{instance.name}]未激活')
|
||||
raise ValidationError(f'产品[{instance.name}]未激活')
|
||||
return instance
|
||||
|
||||
def validate_sales_quantity(self, value):
|
||||
|
@ -70,7 +70,7 @@ class SalesOrderSerializer(BaseSerializer):
|
|||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
sales_goods_items = SalesGoodsItemSerializer(
|
||||
source='sales_goods_set', many=True, label='销售商品Item')
|
||||
source='sales_goods_set', many=True, label='销售产品Item')
|
||||
sales_account_items = SalesAccountItemSerializer(
|
||||
source='sales_accounts', required=False, many=True, label='销售结算账户Item')
|
||||
|
||||
|
@ -128,7 +128,7 @@ class SalesOrderSerializer(BaseSerializer):
|
|||
total_sales_quantity = 0
|
||||
total_sales_amount = 0
|
||||
|
||||
# 创建销售商品
|
||||
# 创建销售产品
|
||||
sales_goods_set = []
|
||||
for sales_goods_item in sales_goods_items:
|
||||
sales_quantity = sales_goods_item['sales_quantity']
|
||||
|
@ -175,11 +175,11 @@ class SalesReturnOrderSerializer(BaseSerializer):
|
|||
"""销售退货单据"""
|
||||
|
||||
class SalesReturnGoodsItemSerializer(BaseSerializer):
|
||||
"""销售退货商品"""
|
||||
"""销售退货产品"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
|
||||
class Meta:
|
||||
|
@ -189,13 +189,13 @@ class SalesReturnOrderSerializer(BaseSerializer):
|
|||
fields = ['sales_goods', 'goods', 'return_quantity', 'return_price', *read_only_fields]
|
||||
|
||||
def validate_sales_goods(self, instance):
|
||||
instance = self.validate_foreign_key(SalesGoods, instance, message='销售商品不存在')
|
||||
instance = self.validate_foreign_key(SalesGoods, instance, message='销售产品不存在')
|
||||
return 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:
|
||||
raise ValidationError(f'商品[{instance.name}]未激活')
|
||||
raise ValidationError(f'产品[{instance.name}]未激活')
|
||||
return instance
|
||||
|
||||
def validate_return_quantity(self, value):
|
||||
|
@ -238,7 +238,7 @@ class SalesReturnOrderSerializer(BaseSerializer):
|
|||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
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(
|
||||
source='sales_return_accounts', required=False, many=True, label='销售退货结算账户')
|
||||
|
||||
|
@ -308,7 +308,7 @@ class SalesReturnOrderSerializer(BaseSerializer):
|
|||
total_return_quantity = 0
|
||||
total_return_amount = 0
|
||||
|
||||
# 创建销售退货商品
|
||||
# 创建销售退货产品
|
||||
sales_return_goods_set = []
|
||||
for sales_return_goods_item in sales_return_goods_items:
|
||||
goods = sales_return_goods_item['goods']
|
||||
|
@ -317,13 +317,13 @@ class SalesReturnOrderSerializer(BaseSerializer):
|
|||
sales_goods = None
|
||||
if sales_order := sales_return_order.sales_order:
|
||||
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)
|
||||
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'])
|
||||
|
||||
return_price = sales_return_goods_item['return_price']
|
||||
|
|
|
@ -51,7 +51,7 @@ class SalesOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, CreateM
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
else:
|
||||
|
@ -67,7 +67,7 @@ class SalesOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, CreateM
|
|||
creator=self.user, team=self.team
|
||||
)
|
||||
|
||||
# 创建出库商品
|
||||
# 创建出库产品
|
||||
stock_out_goods_set = []
|
||||
for sales_goods in sales_order.sales_goods_set.all():
|
||||
stock_out_goods_set.append(StockOutGoods(
|
||||
|
@ -125,7 +125,7 @@ class SalesOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, CreateM
|
|||
if sales_order.is_void:
|
||||
raise ValidationError(f'销售单据[{sales_order.number}]已作废, 无法再次作废')
|
||||
|
||||
# 同步销售单据, 销售商品
|
||||
# 同步销售单据, 销售产品
|
||||
sales_order.is_void = True
|
||||
sales_order.save(update_fields=['is_void'])
|
||||
|
||||
|
@ -148,7 +148,7 @@ class SalesOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, CreateM
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
else:
|
||||
|
@ -232,7 +232,7 @@ class SalesReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, C
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
else:
|
||||
|
@ -248,7 +248,7 @@ class SalesReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, C
|
|||
creator=self.user, team=self.team
|
||||
)
|
||||
|
||||
# 创建入库商品
|
||||
# 创建入库产品
|
||||
stock_in_goods_set = []
|
||||
for sales_return_goods in sales_return_order.sales_return_goods_set.all():
|
||||
stock_in_goods_set.append(StockInGoods(
|
||||
|
@ -306,7 +306,7 @@ class SalesReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, C
|
|||
if sales_return_order.is_void:
|
||||
raise ValidationError(f'销售退货单据[{sales_return_order.number}]已作废, 无法再次作废')
|
||||
|
||||
# 同步销售退货单据, 采购退货商品
|
||||
# 同步销售退货单据, 采购退货产品
|
||||
sales_return_order.is_void = True
|
||||
sales_return_order.save(update_fields=['is_void'])
|
||||
|
||||
|
@ -329,11 +329,11 @@ class SalesReturnOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, C
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
|
||||
# 同步采购商品退货数量
|
||||
# 同步采购产品退货数量
|
||||
if sales_goods := sales_return_goods.sales_goods:
|
||||
sales_goods.return_quantity = NP.minus(sales_goods.return_quantity,
|
||||
sales_return_goods.return_quantity)
|
||||
|
|
|
@ -6,7 +6,7 @@ from apps.finance.models import *
|
|||
|
||||
|
||||
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='创建人')
|
||||
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='结束日期')
|
||||
|
@ -17,7 +17,7 @@ class PurchaseReportFilter(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='创建人')
|
||||
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='结束日期')
|
||||
|
|
|
@ -5,7 +5,7 @@ from extensions.serializers import *
|
|||
class PurchaseReportParameter(Serializer):
|
||||
start_date = DateField(required=True, label='开始日期')
|
||||
end_date = DateField(required=True, label='结束日期')
|
||||
category = IntegerField(required=False, label='商品分类')
|
||||
category = IntegerField(required=False, label='产品分类')
|
||||
|
||||
|
||||
class PurchaseReportStatisticResponse(Serializer):
|
||||
|
@ -15,11 +15,11 @@ class PurchaseReportStatisticResponse(Serializer):
|
|||
|
||||
|
||||
class PurchaseReportGroupByGoodsResponse(Serializer):
|
||||
goods = IntegerField(label='商品ID')
|
||||
goods_number = CharField(label='商品编号')
|
||||
goods_name = CharField(label='商品名称')
|
||||
goods_barcode = CharField(label='商品条码')
|
||||
goods_spec = CharField(label='商品规格')
|
||||
goods = IntegerField(label='产品ID')
|
||||
goods_number = CharField(label='产品编号')
|
||||
goods_name = CharField(label='产品名称')
|
||||
goods_barcode = CharField(label='产品条码')
|
||||
goods_spec = CharField(label='产品规格')
|
||||
category_name = CharField(label='分类名称')
|
||||
unit_name = CharField(label='单位名称')
|
||||
total_purchase_quantity = FloatField(label='采购总数量')
|
||||
|
@ -32,7 +32,7 @@ class PurchaseReportGroupByGoodsResponse(Serializer):
|
|||
class SalesReportParameter(Serializer):
|
||||
start_date = DateField(required=True, label='开始日期')
|
||||
end_date = DateField(required=True, label='结束日期')
|
||||
category = IntegerField(required=False, label='商品分类')
|
||||
category = IntegerField(required=False, label='产品分类')
|
||||
|
||||
|
||||
class SalesReportStatisticResponse(Serializer):
|
||||
|
@ -42,11 +42,11 @@ class SalesReportStatisticResponse(Serializer):
|
|||
|
||||
|
||||
class SalesReportGroupByGoodsResponse(Serializer):
|
||||
goods = IntegerField(label='商品ID')
|
||||
goods_number = CharField(label='商品编号')
|
||||
goods_name = CharField(label='商品名称')
|
||||
goods_barcode = CharField(label='商品条码')
|
||||
goods_spec = CharField(label='商品规格')
|
||||
goods = IntegerField(label='产品ID')
|
||||
goods_number = CharField(label='产品编号')
|
||||
goods_name = CharField(label='产品名称')
|
||||
goods_barcode = CharField(label='产品条码')
|
||||
goods_spec = CharField(label='产品规格')
|
||||
category_name = CharField(label='分类名称')
|
||||
unit_name = CharField(label='单位名称')
|
||||
total_sales_quantity = FloatField(label='销售总数量')
|
||||
|
@ -62,11 +62,11 @@ class SalesHotGoodsParameter(Serializer):
|
|||
|
||||
|
||||
class SalesHotGoodsResponse(Serializer):
|
||||
goods = IntegerField(label='商品ID')
|
||||
goods_number = CharField(label='商品编号')
|
||||
goods_name = CharField(label='商品名称')
|
||||
goods_barcode = CharField(label='商品条码')
|
||||
goods_spec = CharField(label='商品规格')
|
||||
goods = IntegerField(label='产品ID')
|
||||
goods_number = CharField(label='产品编号')
|
||||
goods_name = CharField(label='产品名称')
|
||||
goods_barcode = CharField(label='产品条码')
|
||||
goods_spec = CharField(label='产品规格')
|
||||
category_name = CharField(label='分类名称')
|
||||
unit_name = CharField(label='单位名称')
|
||||
total_sales_quantity = FloatField(label='销售总数量')
|
||||
|
@ -79,8 +79,8 @@ class SalesTrendParameter(Serializer):
|
|||
|
||||
class SalesTrendResponse(Serializer):
|
||||
warehouse = IntegerField(label='仓库ID')
|
||||
warehouse_number = CharField(label='商品编号')
|
||||
warehouse_name = CharField(label='商品名称')
|
||||
warehouse_number = CharField(label='产品编号')
|
||||
warehouse_name = CharField(label='产品名称')
|
||||
total_sales_amount = AmountField(label='销售总金额')
|
||||
date = DateField(label='日期')
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ from apps.finance.models import *
|
|||
class PurchaseReportDetialSerializer(BaseSerializer):
|
||||
"""采购明细"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_spec = CharField(source='goods.spec', 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_barcode = CharField(source='goods.barcode', 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='分类名称')
|
||||
unit_name = CharField(source='goods.unit.name', 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):
|
||||
"""销售明细"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_spec = CharField(source='goods.spec', 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_barcode = CharField(source='goods.barcode', 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='分类名称')
|
||||
unit_name = CharField(source='goods.unit.name', 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})
|
||||
@action(detail=False, methods=['get'])
|
||||
def group_by_goods(self, request, *args, **kwargs):
|
||||
"""商品汇总"""
|
||||
"""产品汇总"""
|
||||
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
queryset = queryset.select_related('goods', 'goods__category', 'goods__unit')
|
||||
|
@ -124,7 +124,7 @@ class SalesReportViewSet(BaseViewSet):
|
|||
responses={200: SalesReportGroupByGoodsResponse})
|
||||
@action(detail=False, methods=['get'])
|
||||
def group_by_goods(self, request, *args, **kwargs):
|
||||
"""商品汇总"""
|
||||
"""产品汇总"""
|
||||
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
queryset = queryset.select_related('goods', 'goods__category', 'goods__unit')
|
||||
|
@ -143,7 +143,7 @@ class SalesReportViewSet(BaseViewSet):
|
|||
|
||||
|
||||
class SalesHotGoodsViewSet(BaseViewSet, ListModelMixin):
|
||||
"""销售前十商品"""
|
||||
"""销售前十产品"""
|
||||
|
||||
permission_classes = [IsAuthenticated, SalesHotGoodsPermission]
|
||||
pagination_class = None
|
||||
|
|
|
@ -48,7 +48,7 @@ class StockCheckOrder(Model):
|
|||
|
||||
|
||||
class StockCheckGoods(Model):
|
||||
"""盘点商品"""
|
||||
"""盘点产品"""
|
||||
|
||||
class Status(TextChoices):
|
||||
"""盘点状态"""
|
||||
|
@ -60,7 +60,7 @@ class StockCheckGoods(Model):
|
|||
stock_check_order = ForeignKey('stock_check.StockCheckOrder', on_delete=CASCADE,
|
||||
related_name='stock_check_goods_set', verbose_name='盘点单据')
|
||||
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='账面数量')
|
||||
actual_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,
|
||||
related_name='stock_check_batchs', verbose_name='盘点单据')
|
||||
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='批次编号')
|
||||
production_date = DateField(null=True, verbose_name='生产日期')
|
||||
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='账面数量')
|
||||
actual_quantity = FloatField(verbose_name='实际数量')
|
||||
surplus_quantity = FloatField(verbose_name='盘盈数量')
|
||||
|
|
|
@ -11,7 +11,7 @@ class StockCheckOrderSerializer(BaseSerializer):
|
|||
"""盘点单据"""
|
||||
|
||||
class StockCheckGoodsItemSerializer(BaseSerializer):
|
||||
"""盘点商品"""
|
||||
"""盘点产品"""
|
||||
|
||||
class StockCheckBatchItemSerializer(BaseSerializer):
|
||||
"""盘点批次"""
|
||||
|
@ -28,9 +28,9 @@ class StockCheckOrderSerializer(BaseSerializer):
|
|||
raise ValidationError('盘点数量小于零')
|
||||
return value
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
||||
read_only=True, label='启用批次控制')
|
||||
|
@ -46,9 +46,9 @@ class StockCheckOrderSerializer(BaseSerializer):
|
|||
fields = ['goods', 'actual_quantity', 'stock_check_batch_items', *read_only_fields]
|
||||
|
||||
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:
|
||||
raise ValidationError(f'商品[{instance.name}]未激活')
|
||||
raise ValidationError(f'产品[{instance.name}]未激活')
|
||||
return instance
|
||||
|
||||
def validate_actual_quantity(self, value):
|
||||
|
@ -60,13 +60,13 @@ class StockCheckOrderSerializer(BaseSerializer):
|
|||
goods = attrs['goods']
|
||||
if goods.enable_batch_control:
|
||||
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']),
|
||||
stock_check_batch_items, 0)
|
||||
|
||||
if total_actual_quantity != attrs['actual_quantity']:
|
||||
raise ValidationError(f'商品[{goods.name}]盘点数量错误')
|
||||
raise ValidationError(f'产品[{goods.name}]盘点数量错误')
|
||||
|
||||
return super().validate(attrs)
|
||||
|
||||
|
@ -76,7 +76,7 @@ class StockCheckOrderSerializer(BaseSerializer):
|
|||
status_display = CharField(source='get_status_display', read_only=True, label='盘点状态')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
stock_check_goods_Items = StockCheckGoodsItemSerializer(
|
||||
source='stock_check_goods_set', many=True, label='盘点商品')
|
||||
source='stock_check_goods_set', many=True, label='盘点产品')
|
||||
|
||||
class Meta:
|
||||
model = StockCheckOrder
|
||||
|
@ -116,7 +116,7 @@ class StockCheckOrderSerializer(BaseSerializer):
|
|||
total_actual_quantity = 0
|
||||
total_surplus_amount = 0
|
||||
|
||||
# 创建盘点商品
|
||||
# 创建盘点产品
|
||||
stock_check_batchs = []
|
||||
for stock_check_goods_item in stock_check_goods_items:
|
||||
goods = stock_check_goods_item['goods']
|
||||
|
|
|
@ -53,7 +53,7 @@ class StockCheckOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cr
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
if inventory.total_quantity < 0:
|
||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
||||
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||
inventory.has_stock = inventory.total_quantity > 0
|
||||
update_inventories.append(inventory)
|
||||
|
||||
|
@ -113,7 +113,7 @@ class StockCheckOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cr
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
if inventory.total_quantity < 0:
|
||||
raise ValidationError(f'商品[{inventory.goods.name}]库存不足')
|
||||
raise ValidationError(f'产品[{inventory.goods.name}]库存不足')
|
||||
inventory.has_stock = inventory.total_quantity > 0
|
||||
update_inventories.append(inventory)
|
||||
|
||||
|
|
|
@ -53,12 +53,12 @@ class StockInOrder(Model):
|
|||
|
||||
|
||||
class StockInGoods(Model):
|
||||
"""入库商品"""
|
||||
"""入库产品"""
|
||||
|
||||
stock_in_order = ForeignKey('stock_in.StockInOrder', on_delete=CASCADE,
|
||||
related_name='stock_in_goods_set', verbose_name='入库单据')
|
||||
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='入库总数')
|
||||
remain_quantity = FloatField(default=0, verbose_name='入库剩余数量')
|
||||
is_completed = BooleanField(default=False, verbose_name='完成状态')
|
||||
|
@ -88,14 +88,14 @@ class StockInRecord(Model):
|
|||
|
||||
|
||||
class StockInRecordGoods(Model):
|
||||
"""入库记录商品"""
|
||||
"""入库记录产品"""
|
||||
|
||||
stock_in_record = ForeignKey('stock_in.StockInRecord', on_delete=CASCADE,
|
||||
related_name='stock_in_record_goods_set', verbose_name='入库记录')
|
||||
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,
|
||||
related_name='stock_in_record_goods_set', verbose_name='商品')
|
||||
related_name='stock_in_record_goods_set', verbose_name='产品')
|
||||
stock_in_quantity = FloatField(verbose_name='入库数量')
|
||||
batch = ForeignKey('goods.Batch', on_delete=CASCADE, null=True,
|
||||
related_name='stock_in_record_goods_set', verbose_name='批次')
|
||||
|
|
|
@ -10,11 +10,11 @@ class StockInOrderSerializer(BaseSerializer):
|
|||
"""入库单据"""
|
||||
|
||||
class StockInGoodsItemSerializer(BaseSerializer):
|
||||
"""入库商品"""
|
||||
"""入库产品"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
||||
read_only=True, label='启用批次控制')
|
||||
|
@ -36,7 +36,7 @@ class StockInOrderSerializer(BaseSerializer):
|
|||
read_only=True, label='调拨单据编号')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
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:
|
||||
model = StockInOrder
|
||||
|
@ -51,11 +51,11 @@ class StockInRecordSerializer(BaseSerializer):
|
|||
"""入库记录"""
|
||||
|
||||
class StockInRecordGoodsItemSerializer(BaseSerializer):
|
||||
"""入库记录商品"""
|
||||
"""入库记录产品"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
||||
read_only=True, label='启用批次控制')
|
||||
|
@ -72,9 +72,9 @@ class StockInRecordSerializer(BaseSerializer):
|
|||
*read_only_fields]
|
||||
|
||||
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:
|
||||
raise ValidationError(f'入库商品[{instance.goods.name}]已完成')
|
||||
raise ValidationError(f'入库产品[{instance.goods.name}]已完成')
|
||||
return instance
|
||||
|
||||
def validate_stock_in_quantity(self, value):
|
||||
|
@ -87,11 +87,11 @@ class StockInRecordSerializer(BaseSerializer):
|
|||
goods = stock_in_goods.goods
|
||||
|
||||
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 not (attrs.get('batch') or attrs['batch'].get('number')):
|
||||
raise ValidationError(f'商品[{goods.name}]批次编号为空')
|
||||
raise ValidationError(f'产品[{goods.name}]批次编号为空')
|
||||
return super().validate(attrs)
|
||||
|
||||
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='经手人名称')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
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:
|
||||
model = StockInRecord
|
||||
|
@ -136,12 +136,12 @@ class StockInRecordSerializer(BaseSerializer):
|
|||
|
||||
total_stock_in_quantity = 0
|
||||
|
||||
# 创建入库记录商品
|
||||
# 创建入库记录产品
|
||||
stock_in_record_goods_set = []
|
||||
for stock_in_record_goods_item in stock_in_record_goods_items:
|
||||
stock_in_goods = stock_in_record_goods_item['stock_in_goods']
|
||||
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']
|
||||
goods = stock_in_goods.goods
|
||||
|
|
|
@ -63,11 +63,11 @@ class StockInRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
|
||||
# 同步入库商品
|
||||
# 同步入库产品
|
||||
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.save(update_fields=['remain_quantity'])
|
||||
|
@ -89,7 +89,7 @@ class StockInRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
|||
if stock_in_record.is_void:
|
||||
raise ValidationError(f'入库记录已作废, 无法再次作废')
|
||||
|
||||
# 同步入库记录, 入库记录商品
|
||||
# 同步入库记录, 入库记录产品
|
||||
stock_in_record.is_void = True
|
||||
stock_in_record.save(update_fields=['is_void'])
|
||||
|
||||
|
@ -111,7 +111,7 @@ class StockInRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Crea
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.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.save(update_fields=['total_quantity', 'remain_quantity', 'has_stock'])
|
||||
|
||||
# 同步入库商品
|
||||
# 同步入库产品
|
||||
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.save(update_fields=['remain_quantity'])
|
||||
|
|
|
@ -49,12 +49,12 @@ class StockOutOrder(Model):
|
|||
|
||||
|
||||
class StockOutGoods(Model):
|
||||
"""出库商品"""
|
||||
"""出库产品"""
|
||||
|
||||
stock_out_order = ForeignKey('stock_out.StockOutOrder', on_delete=CASCADE,
|
||||
related_name='stock_out_goods_set', verbose_name='出库单据')
|
||||
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='出库总数')
|
||||
remain_quantity = FloatField(default=0, verbose_name='出库剩余数量')
|
||||
is_completed = BooleanField(default=False, verbose_name='完成状态')
|
||||
|
@ -84,14 +84,14 @@ class StockOutRecord(Model):
|
|||
|
||||
|
||||
class StockOutRecordGoods(Model):
|
||||
"""出库记录商品"""
|
||||
"""出库记录产品"""
|
||||
|
||||
stock_out_record = ForeignKey('stock_out.StockOutRecord', on_delete=CASCADE,
|
||||
related_name='stock_out_record_goods_set', verbose_name='出库记录')
|
||||
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,
|
||||
related_name='stock_out_record_goods_set', verbose_name='商品')
|
||||
related_name='stock_out_record_goods_set', verbose_name='产品')
|
||||
stock_out_quantity = FloatField(verbose_name='出库数量')
|
||||
batch = ForeignKey('goods.Batch', on_delete=CASCADE, null=True,
|
||||
related_name='stock_out_record_goods_set', verbose_name='批次')
|
||||
|
|
|
@ -10,11 +10,11 @@ class StockOutOrderSerializer(BaseSerializer):
|
|||
"""出库单据"""
|
||||
|
||||
class StockOutGoodsItemSerializer(BaseSerializer):
|
||||
"""出库商品"""
|
||||
"""出库产品"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
||||
read_only=True, label='启用批次控制')
|
||||
|
@ -34,7 +34,7 @@ class StockOutOrderSerializer(BaseSerializer):
|
|||
read_only=True, label='调拨单据编号')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
stock_out_goods_items = StockOutGoodsItemSerializer(
|
||||
source='stock_out_goods_set', many=True, label='出库商品')
|
||||
source='stock_out_goods_set', many=True, label='出库产品')
|
||||
|
||||
class Meta:
|
||||
model = StockOutOrder
|
||||
|
@ -49,11 +49,11 @@ class StockOutRecordSerializer(BaseSerializer):
|
|||
"""出库记录"""
|
||||
|
||||
class StockOutRecordGoodsSerializer(BaseSerializer):
|
||||
"""出库记录商品"""
|
||||
"""出库记录产品"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
enable_batch_control = BooleanField(source='goods.enable_batch_control',
|
||||
read_only=True, label='启用批次控制')
|
||||
|
@ -66,9 +66,9 @@ class StockOutRecordSerializer(BaseSerializer):
|
|||
fields = ['stock_out_goods', 'stock_out_quantity', 'batch', *read_only_fields]
|
||||
|
||||
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:
|
||||
raise ValidationError(f'出库商品[{instance.goods.name}]已完成')
|
||||
raise ValidationError(f'出库产品[{instance.goods.name}]已完成')
|
||||
return instance
|
||||
|
||||
def validate_stock_out_quantity(self, value):
|
||||
|
@ -87,11 +87,11 @@ class StockOutRecordSerializer(BaseSerializer):
|
|||
goods = stock_out_goods.goods
|
||||
|
||||
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 not (batch := attrs.get('batch')):
|
||||
raise ValidationError(f'商品[{goods.name}]未选择批次')
|
||||
raise ValidationError(f'产品[{goods.name}]未选择批次')
|
||||
|
||||
if batch.goods != attrs['stock_out_goods'].goods:
|
||||
raise ValidationError(f'批次[{batch.number}]选择错误')
|
||||
|
@ -107,7 +107,7 @@ class StockOutRecordSerializer(BaseSerializer):
|
|||
handler_name = CharField(source='handler.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',
|
||||
many=True, label='出库记录商品')
|
||||
many=True, label='出库记录产品')
|
||||
|
||||
class Meta:
|
||||
model = StockOutRecord
|
||||
|
@ -143,12 +143,12 @@ class StockOutRecordSerializer(BaseSerializer):
|
|||
|
||||
total_stock_out_quantity = 0
|
||||
|
||||
# 创建出库记录商品
|
||||
# 创建出库记录产品
|
||||
stock_out_record_goods_set = []
|
||||
for stock_out_record_goods_item in stock_out_record_goods_items:
|
||||
stock_out_goods = stock_out_record_goods_item['stock_out_goods']
|
||||
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']
|
||||
batch = stock_out_record_goods_item.get('batch')
|
||||
|
|
|
@ -63,7 +63,7 @@ class StockOutRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cre
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.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.save(update_fields=['remain_quantity', 'has_stock'])
|
||||
|
||||
# 同步出库商品
|
||||
# 同步出库产品
|
||||
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.save(update_fields=['remain_quantity'])
|
||||
|
@ -95,7 +95,7 @@ class StockOutRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cre
|
|||
if stock_out_record.is_void:
|
||||
raise ValidationError(f'出库记录已作废, 无法再次作废')
|
||||
|
||||
# 同步出库记录, 出库记录商品
|
||||
# 同步出库记录, 出库记录产品
|
||||
stock_out_record.is_void = True
|
||||
stock_out_record.save(update_fields=['is_void'])
|
||||
|
||||
|
@ -117,7 +117,7 @@ class StockOutRecordViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin, Cre
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.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.save(update_fields=['total_quantity', 'remain_quantity', 'has_stock'])
|
||||
|
||||
# 同步出库商品
|
||||
# 同步出库产品
|
||||
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.save(update_fields=['remain_quantity'])
|
||||
|
|
|
@ -41,12 +41,12 @@ class StockTransferOrder(Model):
|
|||
|
||||
|
||||
class StockTransferGoods(Model):
|
||||
"""调拨商品"""
|
||||
"""调拨产品"""
|
||||
|
||||
stock_transfer_order = ForeignKey('stock_transfer.StockTransferOrder', on_delete=CASCADE,
|
||||
related_name='stock_transfer_goods_set', verbose_name='采购单据')
|
||||
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='调拨数量')
|
||||
team = ForeignKey('system.Team', on_delete=CASCADE, related_name='stock_transfer_goods_set')
|
||||
|
||||
|
|
|
@ -11,11 +11,11 @@ class StockTransferOrderSerializer(BaseSerializer):
|
|||
"""调拨单据"""
|
||||
|
||||
class StockTransferGoodsItemSerializer(BaseSerializer):
|
||||
"""调拨商品"""
|
||||
"""调拨产品"""
|
||||
|
||||
goods_number = CharField(source='goods.number', 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_number = CharField(source='goods.number', read_only=True, label='产品编号')
|
||||
goods_name = CharField(source='goods.name', 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='单位名称')
|
||||
|
||||
class Meta:
|
||||
|
@ -24,9 +24,9 @@ class StockTransferOrderSerializer(BaseSerializer):
|
|||
fields = ['goods', 'stock_transfer_quantity', *read_only_fields]
|
||||
|
||||
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:
|
||||
raise ValidationError(f'入库商品[{instance.goods.name}]已作废')
|
||||
raise ValidationError(f'入库产品[{instance.goods.name}]已作废')
|
||||
return instance
|
||||
|
||||
def validate_stock_transfer_quantity(self, value):
|
||||
|
@ -41,7 +41,7 @@ class StockTransferOrderSerializer(BaseSerializer):
|
|||
handler_name = CharField(source='handler.name', read_only=True, label='经手人名称')
|
||||
creator_name = CharField(source='creator.name', read_only=True, label='创建人名称')
|
||||
stock_transfer_goods_items = StockTransferGoodsItemSerializer(
|
||||
source='stock_transfer_goods_set', many=True, label='调拨商品')
|
||||
source='stock_transfer_goods_set', many=True, label='调拨产品')
|
||||
|
||||
class Meta:
|
||||
model = StockTransferOrder
|
||||
|
@ -92,7 +92,7 @@ class StockTransferOrderSerializer(BaseSerializer):
|
|||
|
||||
total_stock_transfer_quantity = 0
|
||||
|
||||
# 创建调拨商品
|
||||
# 创建调拨产品
|
||||
stock_transfer_goods_set = []
|
||||
for stock_transfer_goods_item in stock_transfer_goods_items:
|
||||
goods = stock_transfer_goods_item['goods']
|
||||
|
|
|
@ -75,11 +75,11 @@ class StockTransferOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin,
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
else:
|
||||
# 创建出库商品
|
||||
# 创建出库产品
|
||||
stock_out_goods_set.append(StockOutGoods(
|
||||
stock_out_order=stock_out_order, goods=stock_transfer_goods.goods,
|
||||
stock_out_quantity=stock_transfer_goods.stock_transfer_quantity,
|
||||
|
@ -103,11 +103,11 @@ class StockTransferOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin,
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
else:
|
||||
# 创建入库商品
|
||||
# 创建入库产品
|
||||
stock_in_goods_set.append(StockInGoods(
|
||||
stock_in_order=stock_in_order, goods=stock_transfer_goods.goods,
|
||||
stock_in_quantity=stock_transfer_goods.stock_transfer_quantity,
|
||||
|
@ -136,7 +136,7 @@ class StockTransferOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin,
|
|||
if stock_transfer_order.is_void:
|
||||
raise ValidationError(f'调拨单据[{stock_transfer_order.number}]已作废, 无法再次作废')
|
||||
|
||||
# 同步调拨单据, 调拨商品
|
||||
# 同步调拨单据, 调拨产品
|
||||
stock_transfer_order.is_void = True
|
||||
stock_transfer_order.save(update_fields=['is_void'])
|
||||
|
||||
|
@ -159,7 +159,7 @@ class StockTransferOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin,
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
else:
|
||||
|
@ -190,7 +190,7 @@ class StockTransferOrderViewSet(BaseViewSet, ListModelMixin, RetrieveModelMixin,
|
|||
|
||||
inventory.total_quantity = quantity_after
|
||||
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.save(update_fields=['total_quantity', 'has_stock'])
|
||||
else:
|
||||
|
|
|
@ -29,13 +29,13 @@ class SystemConfigSerializer(BaseSerializer):
|
|||
|
||||
def validate_enable_batch_control(self, value):
|
||||
if value and (self.team.enable_auto_stock_in or self.team.enable_auto_stock_out):
|
||||
raise ValidationError('只有同时关闭自动入库、自动出库, 才可以开启商品的批次控制')
|
||||
raise ValidationError('只有同时关闭自动入库、自动出库, 才可以开启产品的批次控制')
|
||||
return value
|
||||
|
||||
def validate(self, attrs):
|
||||
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():
|
||||
raise ValidationError(f'商品[{goods.name}]已开启批次控制, 无法开启自动出/入库')
|
||||
raise ValidationError(f'产品[{goods.name}]已开启批次控制, 无法开启自动出/入库')
|
||||
return super().validate(attrs)
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
# 商品信息
|
||||
# 产品信息
|
||||
|
||||
|
||||
## 功能
|
||||
|
||||
- 查询/创建商品:
|
||||
- 查询/创建产品:
|
||||
[/api/goods/]
|
||||
|
||||
- 编辑/删除商品:
|
||||
- 编辑/删除产品:
|
||||
[/api/goods/{id}/]
|
||||
|
||||
- 获取商品编号:
|
||||
- 获取产品编号:
|
||||
[/api/goods/number/]
|
||||
|
||||
- 导出
|
||||
|
@ -24,13 +24,13 @@
|
|||
|
||||
## 其他接口
|
||||
|
||||
- 商品分类选项:
|
||||
- 产品分类选项:
|
||||
[/api/goods_categories/options/]
|
||||
|
||||
- 商品单位选项:
|
||||
- 产品单位选项:
|
||||
[/api/goods_units/options/]
|
||||
|
||||
- 上传商品图片:
|
||||
- 上传产品图片:
|
||||
[/api/goods_images/]
|
||||
|
||||
- 仓库选项:
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# 商品分类
|
||||
# 产品分类
|
||||
|
||||
|
||||
## 功能
|
||||
|
||||
- 查询/创建商品分类:
|
||||
- 查询/创建产品分类:
|
||||
[/api/goods_categories/]
|
||||
|
||||
- 编辑/删除商品分类:
|
||||
- 编辑/删除产品分类:
|
||||
[/api/goods_categories/{id}/]
|
||||
|
||||
- 导出
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# 商品单位
|
||||
# 产品单位
|
||||
|
||||
|
||||
## 功能
|
||||
|
||||
- 查询/创建商品单位:
|
||||
- 查询/创建产品单位:
|
||||
[/api/goods_units/]
|
||||
|
||||
- 编辑/删除商品单位:
|
||||
- 编辑/删除产品单位:
|
||||
[/api/goods_units/{id}/]
|
||||
|
||||
- 导出
|
||||
|
|
|
@ -24,4 +24,4 @@
|
|||
|
||||
## 补充说明
|
||||
|
||||
- 如果入库商品开启批次控制, 则需要额外输入批次编号
|
||||
- 如果入库产品开启批次控制, 则需要额外输入批次编号
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
- 经手人选项:
|
||||
[/api/users/options/]{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/inventories/options/]{page, warehouse, is_active: true}
|
||||
|
||||
- 批次选项:
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
- 采购报表明细:
|
||||
[/api/purchase_reports/detials/]
|
||||
|
||||
- 采购报表按商品汇总:
|
||||
- 采购报表按产品汇总:
|
||||
[/api/purchase_reports/group_by_goods/]
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
- 销售报表明细:
|
||||
[/api/sales_reports/detials/]
|
||||
|
||||
- 销售报表按商品汇总:
|
||||
- 销售报表按产品汇总:
|
||||
[/api/sales_reports/group_by_goods/]
|
||||
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
- 仓库
|
||||
- 结算账户
|
||||
- 收支项目
|
||||
- 商品管理
|
||||
- 商品分类
|
||||
- 商品单位
|
||||
- 商品信息
|
||||
- 产品管理
|
||||
- 产品分类
|
||||
- 产品单位
|
||||
- 产品信息
|
||||
- 采购管理
|
||||
- 采购开单
|
||||
- 采购记录
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
- 经手人选项:
|
||||
[/api/users/options/]{is_active: true}
|
||||
|
||||
- 商品选项:
|
||||
- 产品选项:
|
||||
[/api/inventories/options/]{page, warehouse, is_active: true}
|
||||
|
||||
- 结算账户选项:
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
- 经手人选项:
|
||||
[/api/users/options/]{is_active: true}
|
||||
|
||||
- 商品选项:
|
||||
- 产品选项:
|
||||
[/api/inventories/options/]{page, warehouse, is_active: true}
|
||||
|
||||
- 结算账户选项:
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
- 仓库选项:
|
||||
[/api/warehouses/options/]{is_active: true}
|
||||
|
||||
- 商品选项:
|
||||
- 产品选项:
|
||||
[/api/goods/options/]{page, is_active: true}
|
||||
|
||||
- 销售员选项:
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
- 经手人选项:
|
||||
[/api/users/options/]{is_active: true}
|
||||
|
||||
- 商品选项:
|
||||
- 产品选项:
|
||||
[/api/inventories/options/]{page, warehouse, is_active: true}
|
||||
|
||||
- 结算账户选项:
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
- 经手人选项:
|
||||
[/api/users/options/]{is_active: true}
|
||||
|
||||
- 商品选项:
|
||||
- 产品选项:
|
||||
[/api/inventories/options/]{page, warehouse, is_active: true}
|
||||
|
||||
- 结算账户选项:
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
- 出库任务提醒
|
||||
[/api/stock_out_order_reminders/]
|
||||
|
||||
- 销售前十商品
|
||||
- 销售前十产品
|
||||
[/api/sales_hot_goods/]{start_date, end_date}
|
||||
|
||||
- 销售走势
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<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>
|
||||
<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-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-item v-for="permissionTypeItem in $parent.permissionItems" :key="permissionTypeItem.id" :label="permissionTypeItem.name" :span="3">
|
||||
<a-row>
|
||||
|
@ -21,6 +21,28 @@
|
|||
</a-row>
|
||||
</a-descriptions-item>
|
||||
</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-form-model-item prop="permissions" label="角色权限">
|
||||
|
@ -70,6 +92,22 @@
|
|||
this.$emit('cancel', false);
|
||||
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>
|
||||
|
|
|
@ -12,6 +12,6 @@ def run(*args):
|
|||
Supplier.objects.create(number='S001', 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)
|
||||
Inventory.objects.create(warehouse=warehouse, goods=goods, team=team)
|
||||
|
|
|
@ -6,7 +6,7 @@ PERMISSIONS = [
|
|||
'name': '首页',
|
||||
'permissions': [
|
||||
{'name': '销售走势', 'code': 'sales_trend'},
|
||||
{'name': '销售前十商品', 'code': 'sales_hot_goods'},
|
||||
{'name': '销售前十产品', 'code': 'sales_hot_goods'},
|
||||
{'name': '入库任务提醒', 'code': 'stock_in_reminder'},
|
||||
{'name': '出库任务提醒', 'code': 'stock_out_reminder'},
|
||||
{'name': '库存预警', 'code': 'inventory_warning'},
|
||||
|
@ -33,11 +33,11 @@ PERMISSIONS = [
|
|||
],
|
||||
},
|
||||
{
|
||||
'name': '商品管理',
|
||||
'name': '产品管理',
|
||||
'permissions': [
|
||||
{'name': '商品分类', 'code': 'goods_category'},
|
||||
{'name': '商品单位', 'code': 'goods_unit'},
|
||||
{'name': '商品信息', 'code': 'goods'},
|
||||
{'name': '产品分类', 'code': 'goods_category'},
|
||||
{'name': '产品单位', 'code': 'goods_unit'},
|
||||
{'name': '产品信息', 'code': 'goods'},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue