from apps.warehouse.exceptions import ( InventoryEntryWeightException, TotalInventorySaleException ) from apps.product.exceptions import QuotaExpiredTimeException from apps.warehouse import models as warehouse_models from apps.authorization.models import UserRelations from rest_framework import serializers from django.db import models class InventoryEntrySerializer(serializers.ModelSerializer): class Meta: model = warehouse_models.InventoryEntry fields = [ "id", "create_date", "modify_date", "organization", "distribution", "weight", "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 """ distribution = attrs['distribution'] # check for quota expired time if not distribution.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 # if instance exists, for update check weight with distribution weight if self.instance: if self.instance.weight is 0: if total_entered + attrs['weight'] > distribution.weight: raise InventoryEntryWeightException() elif self.instance.weight is not 0: if total_entered - self.instance.weight + attrs['weight'] > distribution.weight: raise InventoryEntryWeightException() # if instance is not exists for create, check entry weight with distribution elif not self.instance: if total_entered + attrs['weight'] > distribution.weight: raise InventoryEntryWeightException() 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 } 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'] total_sale_weight = inventory_entry.inventory_sales.aggregate( total=models.Sum('weight') )['total'] or 0 if total_sale_weight + attrs['weight'] > distribution.warehouse_balance: raise TotalInventorySaleException() return attrs def create(self, validated_data): """ Custom create & set some parameters like seller & buyer """ distribution = validated_data['quota_distribution'] seller_organization = distribution.assigned_organization user = self.context['request'].user buyer_user = user seller_user = validated_data['inventory_entry'].created_by return warehouse_models.InventoryQuotaSaleTransaction.objects.create( seller_organization=seller_organization, seller_user=seller_user, buyer_user=buyer_user, **validated_data )