mirror of
https://github.com/himool/HimoolERP.git
synced 2024-11-16 04:15:51 +08:00
136 lines
6.6 KiB
Python
136 lines
6.6 KiB
Python
from extensions.serializers import *
|
|
from extensions.exceptions import *
|
|
from apps.goods.models import *
|
|
from apps.data.models import *
|
|
|
|
|
|
class GoodsSerializer(BaseSerializer):
|
|
|
|
class InventorySerializer(BaseSerializer):
|
|
warehouse_number = CharField(source='warehouse.number', read_only=True, label='仓库编号')
|
|
warehouse_name = CharField(source='warehouse.name', read_only=True, label='仓库名称')
|
|
|
|
class Meta:
|
|
model = Inventory
|
|
read_only_fields = ['id', 'warehouse_number', 'warehouse_name']
|
|
fields = ['warehouse', 'initial_quantity', *read_only_fields]
|
|
|
|
category_name = CharField(source='category.name', read_only=True, label='分类名称')
|
|
unit_name = CharField(source='unit.name', read_only=True, label='单位名称')
|
|
inventory_items = InventorySerializer(source='inventories', required=False, many=True, label='库存')
|
|
|
|
class Meta:
|
|
model = Goods
|
|
read_only_fields = ['id', 'category_name', 'unit_name']
|
|
fields = ['number', 'name', 'barcode', 'category', 'unit', 'spec', 'enable_batch_control',
|
|
'shelf_life_days', 'shelf_life_warning_days', 'enable_inventory_warning',
|
|
'inventory_upper', 'inventory_lower', 'purchase_price', 'retail_price',
|
|
'level_price1', 'level_price2', 'level_price3', 'remark', 'order',
|
|
'is_active', 'inventory_items', *read_only_fields]
|
|
|
|
def validate_number(self, value):
|
|
self.validate_unique({'number': value}, message=f'编号[{value}]已存在')
|
|
return value
|
|
|
|
def validate_name(self, value):
|
|
self.validate_unique({'name': value}, message=f'名称[{value}]已存在')
|
|
return value
|
|
|
|
def validate_category(self, instance):
|
|
instance = self.validate_foreign_key(GoodsCategory, instance, message='商品分类不存在')
|
|
return instance
|
|
|
|
def validate_unit(self, instance):
|
|
instance = self.validate_foreign_key(GoodsUnit, instance, message='商品单位不存在')
|
|
return instance
|
|
|
|
@transaction.atomic
|
|
def create(self, validated_data):
|
|
inventory_items = validated_data.pop('inventories', [])
|
|
goods = super().create(validated_data)
|
|
|
|
# 同步库存
|
|
inventories = []
|
|
for warehouse in Warehouse.objects.filter(team=self.team):
|
|
for inventory_item in inventory_items:
|
|
if warehouse == inventory_item['warehouse']:
|
|
inventories.append(Inventory(
|
|
warehouse=warehouse, goods=goods,
|
|
initial_quantity=inventory_item['initial_quantity'],
|
|
total_quantity=inventory_item['initial_quantity'], team=self.team
|
|
))
|
|
break
|
|
else:
|
|
inventories.append(Inventory(warehouse=warehouse, goods=goods, team=self.team))
|
|
else:
|
|
Inventory.objects.bulk_create(inventories)
|
|
|
|
return goods
|
|
|
|
@transaction.atomic
|
|
def update(self, instance, validated_data):
|
|
inventory_items = validated_data.pop('inventories', [])
|
|
goods = super().update(instance, validated_data)
|
|
|
|
# 同步批次
|
|
if enable_batch_control := validated_data.get('enable_batch_control'):
|
|
if enable_batch_control != instance.enable_batch_control:
|
|
if enable_batch_control:
|
|
batch_number = 'B' + pendulum.today().format('YYYYMMDD')
|
|
batchs = []
|
|
for inventory in Inventory.objects.filter(goods=goods, has_stock=True, team=self.team):
|
|
batchs.append(Batch(
|
|
number=batch_number, warehouse=inventory.warehouse, goods=inventory.goods,
|
|
total_quantity=inventory.total_quantity, remain_quantity=inventory.total_quantity,
|
|
shelf_life_days=goods.shelf_life_days, team=self.team
|
|
))
|
|
else:
|
|
Batch.objects.bulk_create(batchs)
|
|
else:
|
|
instance.batchs.all().delete()
|
|
|
|
# 同步库存
|
|
for inventory in Inventory.objects.filter(goods=goods, team=self.team):
|
|
for inventory_item in inventory_items:
|
|
if (inventory.warehouse == inventory_item['warehouse'] and
|
|
inventory.initial_quantity != inventory_item['initial_quantity']):
|
|
inventory.total_quantity = NP.minus(inventory.total_quantity, inventory.initial_quantity)
|
|
inventory.initial_quantity = inventory_item['initial_quantity']
|
|
inventory.total_quantity = NP.plus(inventory.total_quantity, inventory.initial_quantity)
|
|
inventory.save(update_fields=['initial_quantity', 'total_quantity'])
|
|
|
|
return goods
|
|
|
|
|
|
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='商品条码')
|
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
|
|
|
class Meta:
|
|
model = Batch
|
|
fields = ['id', 'number', 'warehouse', 'warehouse_number', 'warehouse_name', 'goods', 'goods_number',
|
|
'goods_name', 'goods_barcode', 'total_quantity', 'remain_quantity', 'unit_name',
|
|
'production_date', 'shelf_life_days', 'expiration_date', 'has_stock', 'create_time']
|
|
|
|
|
|
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='商品条码')
|
|
unit_name = CharField(source='goods.unit.name', read_only=True, label='单位名称')
|
|
|
|
class Meta:
|
|
model = Inventory
|
|
fields = ['id', 'warehouse', 'warehouse_number', 'warehouse_name', 'goods', 'goods_number',
|
|
'goods_name', 'goods_barcode', 'total_quantity', 'unit_name', 'has_stock']
|
|
|
|
|
|
__all__ = [
|
|
'GoodsSerializer', 'BatchSerializer', 'InventorySerializer',
|
|
]
|