from apps.herd.services.services import get_rancher_statistics, rancher_quota_weight from apps.product.services.services import ( quota_live_stock_allocation_info, quota_incentive_plans_info, quota_brokers_value, quota_attribute_value ) from apps.pos_device.services.services import pos_organizations_sharing_information from apps.pos_device.pos.api.v1.serializers.device import DeviceSerializer from apps.herd.pos.api.v1.serializers import RancherSerializer from apps.warehouse.exceptions import ( TotalInventorySaleException ) from apps.warehouse import models as warehouse_models from rest_framework import serializers from django.db import models class InventoryEntrySerializer(serializers.ModelSerializer): class Meta: model = warehouse_models.InventoryEntry fields = [ "id", "entry_identity", "create_date", "modify_date", "organization", "distribution", "weight", "balance", "lading_number", "delivery_address", "is_confirmed", "notes", ] 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_identity': instance.distribution.distribution_id, 'sale_unit': instance.distribution.quota.sale_unit.unit, 'id': instance.distribution.id } representation['quota'] = { 'quota_identity': instance.distribution.quota.quota_id, 'quota_weight': instance.distribution.quota.quota_weight, 'quota_livestock_allocations': quota_live_stock_allocation_info( instance.distribution.quota ), 'quota_incentive_plans': quota_incentive_plans_info(instance.distribution.quota) } representation['product'] = { 'name': instance.distribution.quota.product.name, 'id': instance.distribution.quota.product.id, } representation['pricing'] = { 'brokers_info': quota_brokers_value(instance.distribution.quota), 'pricing_attributes': quota_attribute_value(instance.distribution.quota), 'sharing': pos_organizations_sharing_information(self.context['device']) } if 'rancher' in self.context.keys(): # rancher herd & live stock statistics representation['rancher_statistics'] = get_rancher_statistics(self.context['rancher']) # rancher live stock statistics by inventory entry representation['rancher_quota_weight_statistics'] = rancher_quota_weight( self.context['rancher'], instance ) return representation class InventoryQuotaSaleTransactionSerializer(serializers.ModelSerializer): class Meta: # noqa 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 to_representation(self, instance): """ customize output of transactions serializer """ representation = super().to_representation(instance) representation['rancher'] = RancherSerializer(instance.rancher).data representation['pos_device'] = DeviceSerializer(instance.pos_device).data representation['seller_organization'] = instance.seller_organization.name representation['inventory_entry'] = InventoryEntrySerializer(instance.inventory_entry).data return representation