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): """ 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.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__'