155 lines
5.6 KiB
Python
155 lines
5.6 KiB
Python
from rest_framework import serializers, status
|
|
|
|
from apps.product.exceptions import QuotaExpiredTimeException
|
|
from apps.product.models import OrganizationQuotaStats
|
|
from apps.warehouse import models as warehouse_models
|
|
from apps.warehouse.exceptions import WareHouseException
|
|
|
|
|
|
class InventoryEntrySerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = warehouse_models.InventoryEntry
|
|
fields = [
|
|
"id",
|
|
"create_date",
|
|
"modify_date",
|
|
"organization",
|
|
"quota",
|
|
'org_quota_stat',
|
|
"weight",
|
|
"balance",
|
|
"lading_number",
|
|
"delivery_address",
|
|
"is_confirmed",
|
|
"notes",
|
|
]
|
|
|
|
def validate(self, attrs):
|
|
"""
|
|
check if inventory entries weight is not more than
|
|
distribution weight & check quota expired time
|
|
"""
|
|
quota = attrs['quota']
|
|
org = attrs['organization']
|
|
|
|
# check for quota expired time
|
|
if not quota.is_in_valid_time():
|
|
raise QuotaExpiredTimeException()
|
|
|
|
# total inventory entries weight
|
|
# total_entered = distribution.inventory_entry.filter(is_confirmed=True).aggregate(
|
|
# total=models.Sum('weight')
|
|
# )['total'] or 0
|
|
|
|
org_quota_stat = OrganizationQuotaStats.objects.get(
|
|
organization=org,
|
|
quota=quota
|
|
)
|
|
|
|
total_entered_weight = org_quota_stat.inventory_received
|
|
remaining_weight_to_enter = org_quota_stat.remaining_amount
|
|
|
|
# if instance exists, for update check weight with distribution weight
|
|
if self.instance:
|
|
if self.instance.weight == 0:
|
|
if total_entered_weight + attrs['weight'] > remaining_weight_to_enter:
|
|
raise WareHouseException(
|
|
"وزن وارد شده برای ورود به انبار نباید از باقیمانده سهمیه بیشتر باشد", # noqa
|
|
status.HTTP_403_FORBIDDEN
|
|
)
|
|
elif self.instance.weight != 0:
|
|
if total_entered_weight - self.instance.weight + attrs['weight'] > remaining_weight_to_enter:
|
|
raise WareHouseException(
|
|
"وزن وارد شده برای ورود به انبار نباید از باقیمانده سهمیه بیشتر باشد", # noqa
|
|
status.HTTP_403_FORBIDDEN
|
|
)
|
|
|
|
# if instance is not exists for create, check entry weight with distribution
|
|
else:
|
|
if total_entered_weight + attrs['weight'] > remaining_weight_to_enter:
|
|
# total_entered + attrs['weight'] > distribution.remaining_weight:
|
|
raise WareHouseException(
|
|
"وزن وارد شده برای ورود به انبار نباید از باقیمانده سهمیه بیشتر باشد", # noqa
|
|
status.HTTP_403_FORBIDDEN
|
|
)
|
|
|
|
return attrs
|
|
|
|
def to_representation(self, instance):
|
|
""" custom output of inventory entry serializer """
|
|
|
|
representation = super().to_representation(instance)
|
|
if instance.document:
|
|
representation['document'] = instance.document
|
|
if instance.distribution:
|
|
# distribution data
|
|
representation['distribution'] = {
|
|
'distribution': instance.distribution.distribution_id,
|
|
'sale_unit': instance.distribution.quota.sale_unit.unit,
|
|
'id': instance.distribution.id
|
|
}
|
|
representation['quota'] = instance.distribution.quota.id
|
|
representation['product'] = {
|
|
'name': instance.distribution.quota.product.name
|
|
}
|
|
|
|
return representation
|
|
|
|
|
|
class InventoryQuotaSaleTransactionSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = warehouse_models.InventoryQuotaSaleTransaction
|
|
fields = '__all__'
|
|
depth = 0
|
|
|
|
def validate(self, attrs):
|
|
"""
|
|
validate total inventory sale should be fewer than
|
|
inventory entry from distribution
|
|
"""
|
|
inventory_entry = attrs['inventory_entry']
|
|
distribution = attrs['quota_distribution']
|
|
|
|
return attrs
|
|
|
|
def to_representation(self, instance: warehouse_models.InventoryQuotaSaleTransaction):
|
|
""" custom output of inventory sale transaction serializer """
|
|
|
|
representation = super().to_representation(instance)
|
|
representation['items'] = InventoryQuotaSaleItemSerializer(
|
|
instance.items.all(),
|
|
many=True
|
|
).data
|
|
|
|
if instance.rancher:
|
|
representation['rancher'] = {
|
|
'id': instance.rancher.id,
|
|
'national_code': instance.rancher.national_code
|
|
}
|
|
if instance.pos_device:
|
|
representation['pos_device'] = {
|
|
'device_identity': instance.pos_device.device_identity,
|
|
'serial': instance.pos_device.serial
|
|
}
|
|
if instance.seller_organization:
|
|
representation['seller_organization'] = {
|
|
'id': instance.seller_organization.id,
|
|
'name': instance.seller_organization.name
|
|
}
|
|
|
|
return representation
|
|
|
|
|
|
class InventoryQuotaSaleItemSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = warehouse_models.InventoryQuotaSaleItem
|
|
fields = '__all__'
|
|
|
|
def to_representation(self, instance):
|
|
representation = super().to_representation(instance)
|
|
|
|
if instance.quota_stat:
|
|
representation['quota_sale_unit'] = instance.quota_stat.quota.sale_unit.unit
|
|
|
|
return representation
|