change list of rancher inventory entries to rancher distributions for one item be as sale in pos device

This commit is contained in:
2025-09-06 12:04:41 +03:30
parent 272e9ed2c8
commit 18a7955e3a
5 changed files with 151 additions and 50 deletions

View File

@@ -1,14 +1,17 @@
from rest_framework import serializers
from apps.product import models as product_models
from apps.product.services.services import quota_live_stock_allocation_info, quota_incentive_plans_info, \
quota_attribute_value
from apps.herd.services.services import get_rancher_statistics, rancher_quota_weight
from apps.pos_device.services.services import pos_organizations_sharing_information
from rest_framework.exceptions import APIException
from apps.product.web.api.v1.serializers.quota_serializers import QuotaSerializer
from django.db import models
from apps.product import models as product_models
from rest_framework import serializers
from apps.product.exceptions import (
QuotaWeightException,
QuotaClosedException,
QuotaExpiredTimeException,
QuotaLimitByOrganizationException
)
from django.db import models
class QuotaDistributionSerializer(serializers.ModelSerializer):
@@ -77,7 +80,46 @@ class QuotaDistributionSerializer(serializers.ModelSerializer):
representation = super().to_representation(instance)
if instance.quota:
representation['quota'] = QuotaSerializer(instance.quota).data
representation['quota'] = {
'quota_identity': instance.quota.quota_id,
'quota_weight': instance.quota.quota_weight,
'quota_livestock_allocations': quota_live_stock_allocation_info(
instance.quota
),
'quota_incentive_plans': quota_incentive_plans_info(instance.quota)
}
representation['product'] = {
'image': instance.quota.product.img,
'name': instance.quota.product.name,
'id': instance.quota.product.id,
}
representation['pricing'] = { # noqa
'pricing_attributes': quota_attribute_value(instance.quota),
'sharing': pos_organizations_sharing_information(self.context['device']),
'base_prices': [
{
"text": "قیمت درب کارخانه", # noqa
"name": "base_price_factory",
"value": instance.quota.base_price_factory
},
{
"text": "قیمت درب اتحادیه", # noqa
"name": "base_price_cooperative",
"value": instance.quota.base_price_cooperative
}
]
}
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 quota distributions
representation['rancher_quota_weight_statistics'] = rancher_quota_weight(
self.context['rancher'], distribution=instance
)
if instance.assigned_organization:
representation['assigned_organization'] = {

View File

@@ -1,10 +1,11 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .viewsets import product_api
from .viewsets import product_api, quota_distribution_api
router = DefaultRouter()
router.register(r'product', product_api.ProductViewSet, basename='product')
router.register(r'pos_free_products', product_api.POSFreeProductsViewSet, basename='pos_free_products')
router.register(r'distributions', quota_distribution_api.QuotaDistributionViewSet, basename='distributions')
urlpatterns = [
path('v1/', include(router.urls))

View File

@@ -1,12 +1,16 @@
from apps.product.pos.api.v1.serializers import quota_distribution_serializers as distribution_serializers
from apps.pos_device.mixins.pos_device_mixin import POSDeviceMixin
from apps.core.mixins.search_mixin import DynamicSearchMixin
from apps.core.pagination import CustomPageNumberPagination
from apps.warehouse.services.services import can_buy_from_inventory
from common.helpers import get_organization_by_user
from rest_framework.exceptions import APIException
from apps.product import models as product_models
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework import viewsets, filters
from apps.herd.models import Rancher
from rest_framework import status
from django.db import transaction
from django.db.models import Q
@@ -25,12 +29,12 @@ def delete(queryset, pk):
obj.delete()
class QuotaDistributionViewSet(viewsets.ModelViewSet, DynamicSearchMixin):
class QuotaDistributionViewSet(viewsets.ModelViewSet, DynamicSearchMixin, POSDeviceMixin):
""" quota distribution apis """
queryset = product_models.QuotaDistribution.objects.all()
serializer_class = distribution_serializers.QuotaDistributionSerializer
filter_backends = [filters.SearchFilter]
permission_classes = [AllowAny]
CustomPageNumberPagination.page_size = 5
search_fields = [
"assigner_organization__name",
@@ -53,37 +57,61 @@ class QuotaDistributionViewSet(viewsets.ModelViewSet, DynamicSearchMixin):
def my_distributions(self, request):
""" list of my distributions """
queryset = self.filter_query(self.queryset) # return by search param or all objects
organization = get_organization_by_user(request.user)
organization = self.get_device_organization()
device = self.get_pos_device()
query = self.request.query_params
if query.get('param') == 'assigned':
# paginate queryset
page = self.paginate_queryset(
queryset.filter(
Q(assigned_organization=organization)
).order_by('-modify_date')
# get distributions with open quota
distributions = self.queryset.filter(
assigned_organization=organization,
quota__is_closed=False,
warehouse_entry__gt=0
).order_by('-create_date')
queryset = self.filter_query(distributions) # return by search param or all objects
# paginate & response
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True, context={'device': device})
return self.get_paginated_response(serializer.data)
@action(
methods=['get'],
detail=False,
url_name='rancher_distributions',
url_path='rancher_distributions',
name='rancher_distributions'
)
def rancher_distributions(self, request):
""" list of quota distributions for rancher """
organization = self.get_device_organization()
device = self.get_pos_device()
rancher = Rancher.objects.filter(national_code=request.GET['national_code'])
# get distributions with open quota
distributions = self.queryset.filter(
assigned_organization=organization,
quota__is_closed=False,
warehouse_entry__gt=0
).order_by('-create_date')
# check quota distributions for rancher
available_distributions = [
distribution for distribution in distributions if (
can_buy_from_inventory(rancher.first(), distribution=distribution) & rancher.exists()
)
]
elif query.get('param') == 'assigner':
# paginate queryset
page = self.paginate_queryset(
queryset.filter(
Q(assigner_organization=organization)
).order_by('-modify_date')
)
elif query.get('param') == 'all':
# paginate queryset
page = self.paginate_queryset(
queryset.filter(
Q(assigner_organization=organization) |
Q(assigned_organization=organization)
).order_by('-modify_date')
)
if page is not None: # noqa
serializer = self.get_serializer(page, many=True) # noqa
# paginate & response
page = self.paginate_queryset(available_distributions) # noqa
if page is not None:
serializer = self.get_serializer(page, many=True, context={'rancher': rancher.first(), 'device': device})
# set custom message for paginator
if not rancher:
self.paginator.set_message("دامدار با کد ملی مد نظر یافت نشد") # noqa
elif not available_distributions:
self.paginator.set_message("دامدار با کد ملی مد نظر سهمیه ایی ندارد") # noqa
return self.get_paginated_response(serializer.data)
@action(