fix agencie share on pos device - fix validation bug of free product pos
This commit is contained in:
@@ -1,4 +1,10 @@
|
|||||||
from apps.product.models import Quota, QuotaDistribution
|
from apps.product.models import (
|
||||||
|
Quota,
|
||||||
|
QuotaDistribution,
|
||||||
|
Organization,
|
||||||
|
QuotaPriceCalculationItems,
|
||||||
|
QuotaFinalPriceTypes
|
||||||
|
)
|
||||||
from apps.pos_device.models import Device, StakeHolderShareAmount
|
from apps.pos_device.models import Device, StakeHolderShareAmount
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
@@ -6,7 +12,8 @@ import typing
|
|||||||
def pos_organizations_sharing_information(
|
def pos_organizations_sharing_information(
|
||||||
device: Device,
|
device: Device,
|
||||||
quota: Quota = None,
|
quota: Quota = None,
|
||||||
distribution: QuotaDistribution = None
|
distribution: QuotaDistribution = None,
|
||||||
|
owner_org: Organization = None
|
||||||
) -> typing.Any:
|
) -> typing.Any:
|
||||||
"""
|
"""
|
||||||
pos sharing organizations' information,
|
pos sharing organizations' information,
|
||||||
@@ -14,21 +21,54 @@ def pos_organizations_sharing_information(
|
|||||||
"""
|
"""
|
||||||
stake_holders = device.stake_holders.select_related('broker', 'organization').filter(default=False)
|
stake_holders = device.stake_holders.select_related('broker', 'organization').filter(default=False)
|
||||||
|
|
||||||
sharing_information_list = [{
|
sharing_information_list = []
|
||||||
"organization_name": item.organization.name,
|
for item in stake_holders:
|
||||||
"bank_account": {
|
if item.broker and not owner_org.type.name == 'AGC': # if stakeholder is not an agency, it is a broker
|
||||||
"credit_card": item.organization.bank_information.first().card,
|
sharing_information_list.append({
|
||||||
"sheba": item.organization.bank_information.first().sheba,
|
"organization_name": item.organization.name,
|
||||||
"account": item.organization.bank_information.first().account,
|
"bank_account": {
|
||||||
} if item.organization.bank_information.exists() else {},
|
"credit_card": item.organization.bank_information.first().card,
|
||||||
"broker": item.broker.name if item.broker else None,
|
"sheba": item.organization.bank_information.first().sheba,
|
||||||
"amount": quota.broker_values.filter(
|
"account": item.organization.bank_information.first().account,
|
||||||
broker=item.broker
|
} if item.organization.bank_information.exists() else {},
|
||||||
).first().value if quota and item.broker else (
|
"broker": item.broker.name if item.broker else None,
|
||||||
item.holders_share_amount.filter(quota_distribution=distribution).first().share_amount
|
"amount": quota.broker_values.filter(
|
||||||
if item.holders_share_amount.filter(quota_distribution=distribution).exists() else None
|
broker=item.broker
|
||||||
),
|
).first().value if quota and item.broker else None,
|
||||||
"default_account": item.default
|
|
||||||
} for item in stake_holders]
|
# """
|
||||||
|
# if we will need to get agencies share amount, we can use this bellow code
|
||||||
|
#
|
||||||
|
# # item.holders_share_amount.filter(quota_distribution=distribution).first().share_amount
|
||||||
|
# # if item.holders_share_amount.filter(quota_distribution=distribution).exists() else None
|
||||||
|
# """
|
||||||
|
|
||||||
|
"default_account": item.default
|
||||||
|
})
|
||||||
|
|
||||||
|
# if device owner is an agency organization
|
||||||
|
if owner_org.type.name == 'AGC':
|
||||||
|
sharing_information_list.append({
|
||||||
|
"organization_name": owner_org.parent_organization.name,
|
||||||
|
"bank_account": {
|
||||||
|
"credit_card": owner_org.parent_organization.bank_information.first().card,
|
||||||
|
"sheba": owner_org.parent_organization.bank_information.first().sheba,
|
||||||
|
"account": owner_org.parent_organization.bank_information.first().account,
|
||||||
|
} if owner_org.parent_organization.bank_information.exists() else {},
|
||||||
|
"amount": quota.pricing_items.get(
|
||||||
|
name='base_price'
|
||||||
|
) if quota.pricing_items.filter(
|
||||||
|
name='base_price'
|
||||||
|
) else None,
|
||||||
|
|
||||||
|
# """
|
||||||
|
# if we will need to get agencies share amount, we can use this bellow code
|
||||||
|
#
|
||||||
|
# # item.holders_share_amount.filter(quota_distribution=distribution).first().share_amount
|
||||||
|
# # if item.holders_share_amount.filter(quota_distribution=distribution).exists() else None
|
||||||
|
# """
|
||||||
|
|
||||||
|
"default_account": item.default
|
||||||
|
})
|
||||||
|
|
||||||
return sharing_information_list
|
return sharing_information_list
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Generated by Django 5.0 on 2025-10-05 08:04
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('product', '0079_quotausage_distribution_quotausage_usage_type_and_more'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='QuotaFinalPriceTypes',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('create_date', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('modify_date', models.DateTimeField(auto_now=True)),
|
||||||
|
('creator_info', models.CharField(max_length=100, null=True)),
|
||||||
|
('modifier_info', models.CharField(max_length=100, null=True)),
|
||||||
|
('trash', models.BooleanField(default=False)),
|
||||||
|
('name', models.CharField(max_length=250)),
|
||||||
|
('en_name', models.CharField(max_length=250, null=True)),
|
||||||
|
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createddby', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='QuotaPriceCalculationItems',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('create_date', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('modify_date', models.DateTimeField(auto_now=True)),
|
||||||
|
('creator_info', models.CharField(max_length=100, null=True)),
|
||||||
|
('modifier_info', models.CharField(max_length=100, null=True)),
|
||||||
|
('trash', models.BooleanField(default=False)),
|
||||||
|
('name', models.CharField(max_length=250)),
|
||||||
|
('value', models.PositiveBigIntegerField(default=0)),
|
||||||
|
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createddby', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('pricing_type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pricing_items', to='product.quotafinalpricetypes')),
|
||||||
|
('quota', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='pricing_items', to='product.quota')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -449,6 +449,40 @@ class Quota(BaseModel):
|
|||||||
return super(Quota, self).save(*args, **kwargs)
|
return super(Quota, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class QuotaFinalPriceTypes(BaseModel):
|
||||||
|
name = models.CharField(max_length=250)
|
||||||
|
en_name = models.CharField(max_length=250, null=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.name}'
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
return super(QuotaFinalPriceTypes, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class QuotaPriceCalculationItems(BaseModel):
|
||||||
|
quota = models.ForeignKey(
|
||||||
|
Quota,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='pricing_items',
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
pricing_type = models.ForeignKey(
|
||||||
|
'QuotaFinalPriceTypes',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='pricing_items',
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
name = models.CharField(max_length=250)
|
||||||
|
value = models.PositiveBigIntegerField(default=0)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.quota.quota_id}-{self.pricing_type.name}-{self.name}'
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
return super(QuotaPriceCalculationItems, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class QuotaStats(BaseModel):
|
class QuotaStats(BaseModel):
|
||||||
quota = models.OneToOneField(
|
quota = models.OneToOneField(
|
||||||
Quota,
|
Quota,
|
||||||
|
|||||||
@@ -19,8 +19,13 @@ class POSFreeProductSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
product = attrs['product']
|
product = attrs['product']
|
||||||
organization = attrs['organization']
|
organization = attrs['organization']
|
||||||
|
device = self.context['device']
|
||||||
|
|
||||||
if self.Meta.model.objects.filter(organization=organization, product=product).exists():
|
if self.Meta.model.objects.filter(
|
||||||
|
organization=organization,
|
||||||
|
product=product,
|
||||||
|
device=device
|
||||||
|
).exists():
|
||||||
raise FreePOSProductUniqueCheck()
|
raise FreePOSProductUniqueCheck()
|
||||||
|
|
||||||
return attrs
|
return attrs
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from apps.product.services.services import quota_live_stock_allocation_info, quota_incentive_plans_info, \
|
from apps.product.services.services import quota_live_stock_allocation_info, quota_incentive_plans_info, \
|
||||||
quota_attribute_value
|
quota_attribute_value, quota_pricing_items_by_type
|
||||||
from apps.herd.services.services import get_rancher_statistics, rancher_quota_weight
|
from apps.herd.services.services import get_rancher_statistics, rancher_quota_weight
|
||||||
from apps.pos_device.services.services import pos_organizations_sharing_information
|
from apps.pos_device.services.services import pos_organizations_sharing_information
|
||||||
from rest_framework.exceptions import APIException
|
from rest_framework.exceptions import APIException
|
||||||
@@ -116,20 +116,10 @@ class QuotaDistributionSerializer(serializers.ModelSerializer):
|
|||||||
'sharing': pos_organizations_sharing_information(
|
'sharing': pos_organizations_sharing_information(
|
||||||
device,
|
device,
|
||||||
instance.quota,
|
instance.quota,
|
||||||
distribution=instance
|
distribution=instance,
|
||||||
|
owner_org=organization
|
||||||
),
|
),
|
||||||
'base_prices': [
|
'base_prices': quota_pricing_items_by_type(instance.quota)
|
||||||
{
|
|
||||||
"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():
|
if 'rancher' in self.context.keys():
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class POSFreeProductsViewSet(SoftDeleteMixin, viewsets.ModelViewSet, DynamicSear
|
|||||||
'device': device.id,
|
'device': device.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
serializer = product_serializers.POSFreeProductSerializer(data=request.data)
|
serializer = product_serializers.POSFreeProductSerializer(data=request.data, context={'device': device})
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save()
|
serializer.save()
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
from apps.product.models import Quota, QuotaLivestockAllocation
|
from collections import defaultdict
|
||||||
|
|
||||||
|
from apps.product.models import (
|
||||||
|
Quota,
|
||||||
|
QuotaLivestockAllocation,
|
||||||
|
QuotaPriceCalculationItems,
|
||||||
|
QuotaFinalPriceTypes
|
||||||
|
)
|
||||||
from apps.warehouse.models import InventoryEntry
|
from apps.warehouse.models import InventoryEntry
|
||||||
from apps.herd.models import Rancher
|
from apps.herd.models import Rancher
|
||||||
|
from django.db.models import Sum
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
|
|
||||||
@@ -86,3 +94,42 @@ def quota_attribute_value(quota: Quota) -> typing.Any:
|
|||||||
} for attr in attributes]
|
} for attr in attributes]
|
||||||
|
|
||||||
return attribute_values_list
|
return attribute_values_list
|
||||||
|
|
||||||
|
|
||||||
|
def quota_pricing_items_by_type(quota: Quota) -> typing.Any:
|
||||||
|
"""
|
||||||
|
information of quota pricing items by final price type
|
||||||
|
Optimized: fetch all pricing items once, group by pricing_type
|
||||||
|
"""
|
||||||
|
# مرحله ۱: همهی آیتمهای مربوط به این quota رو یکجا بگیر
|
||||||
|
items = (
|
||||||
|
QuotaPriceCalculationItems.objects
|
||||||
|
.filter(quota=quota)
|
||||||
|
.select_related("pricing_type")
|
||||||
|
.values("pricing_type_id", "pricing_type__en_name", "pricing_type__name", "name", "value")
|
||||||
|
)
|
||||||
|
|
||||||
|
# مرحله ۲: گروهبندی آیتمها بر اساس pricing_type
|
||||||
|
grouped = defaultdict(list)
|
||||||
|
for item in items:
|
||||||
|
key = item["pricing_type__en_name"]
|
||||||
|
grouped[key].append({
|
||||||
|
"name": item["name"],
|
||||||
|
"value": item["value"]
|
||||||
|
})
|
||||||
|
|
||||||
|
# مرحله ۳: جمع کل هر گروه
|
||||||
|
result = []
|
||||||
|
for en_name, group_items in grouped.items():
|
||||||
|
total_price = sum(i["value"] for i in group_items if i["value"])
|
||||||
|
fa_name = next(
|
||||||
|
(i["pricing_type__name"] for i in items if i["pricing_type__en_name"] == en_name),
|
||||||
|
en_name
|
||||||
|
)
|
||||||
|
result.append({
|
||||||
|
en_name: group_items,
|
||||||
|
f"{en_name}_fa": fa_name,
|
||||||
|
f"{en_name}_total_price": total_price,
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
|||||||
@@ -259,3 +259,15 @@ class QuotaLiveStockAgeLimitationSerializer(serializers.ModelSerializer):
|
|||||||
instance.save()
|
instance.save()
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
class QuotaPriceCalculationPriceItemsSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = product_models.QuotaPriceCalculationItems
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class QuotaFinalPriceTypeSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = product_models.QuotaFinalPriceTypes
|
||||||
|
fields = '__all__'
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ router.register(r'incentive_plan', product_api.IncentivePlanViewSet, basename='i
|
|||||||
router.register(r'rancher_incentive_plan', product_api.IncentivePlanRancherViewSet, basename='rancher_incentive_plan')
|
router.register(r'rancher_incentive_plan', product_api.IncentivePlanRancherViewSet, basename='rancher_incentive_plan')
|
||||||
router.register(r'stats', product_api.ProductStatsViewSet, basename='stats')
|
router.register(r'stats', product_api.ProductStatsViewSet, basename='stats')
|
||||||
router.register(r'quota', quota_api.QuotaViewSet, basename='quota')
|
router.register(r'quota', quota_api.QuotaViewSet, basename='quota')
|
||||||
|
router.register(r'quota_pricing_items', quota_api.QuotaPriceCalculationItemsViewSet, basename='quota_pricing_items')
|
||||||
|
router.register(r'quota_final_price_type', quota_api.QuotaFinalPriceTypeViewSet, basename='quota_final_price_type')
|
||||||
router.register(r'quota_distribution', distribution_apis.QuotaDistributionViewSet, basename='quota_distribution')
|
router.register(r'quota_distribution', distribution_apis.QuotaDistributionViewSet, basename='quota_distribution')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
|||||||
@@ -128,13 +128,26 @@ class QuotaViewSet(SoftDeleteMixin, viewsets.ModelViewSet, DynamicSearchMixin):
|
|||||||
)
|
)
|
||||||
livestock_age_limits.append(age_limit_creation_object)
|
livestock_age_limits.append(age_limit_creation_object)
|
||||||
|
|
||||||
|
# create quota price calculation items for final price types
|
||||||
|
price_calculation_items = []
|
||||||
|
if 'price_calculation_items' in request.data.keys():
|
||||||
|
for price_item in request.data['price_calculation_items']:
|
||||||
|
price_item.update({'quota': quota.id})
|
||||||
|
price_item_creation_object = CustomOperations().custom_create(
|
||||||
|
request=request,
|
||||||
|
view=QuotaPriceCalculationItemsViewSet(),
|
||||||
|
data=price_item
|
||||||
|
)
|
||||||
|
price_calculation_items.append(price_item_creation_object)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'quota': serializer.data,
|
'quota': serializer.data,
|
||||||
'incentive_plan': plans_list, # noqa
|
'incentive_plan': plans_list, # noqa
|
||||||
'attribute_values': attributes_value_list,
|
'attribute_values': attributes_value_list,
|
||||||
'broker_values': broker_data_list,
|
'broker_values': broker_data_list,
|
||||||
'live_stock_allocations': allocations_list,
|
'live_stock_allocations': allocations_list,
|
||||||
'livestock_age_limitations': livestock_age_limits
|
'livestock_age_limitations': livestock_age_limits,
|
||||||
|
'price_calculation_items': price_calculation_items
|
||||||
}
|
}
|
||||||
|
|
||||||
# call save method to generate id & calculate quota final price
|
# call save method to generate id & calculate quota final price
|
||||||
@@ -241,13 +254,30 @@ class QuotaViewSet(SoftDeleteMixin, viewsets.ModelViewSet, DynamicSearchMixin):
|
|||||||
)
|
)
|
||||||
livestock_age_limits.append(age_limit_creation_object)
|
livestock_age_limits.append(age_limit_creation_object)
|
||||||
|
|
||||||
|
# create quota price calculation items for final price types
|
||||||
|
price_calculation_items = []
|
||||||
|
if 'price_calculation_items' in request.data.keys():
|
||||||
|
|
||||||
|
# remove live stock age limit relations
|
||||||
|
quota.pricing_items.all().delete()
|
||||||
|
|
||||||
|
for price_item in request.data['price_calculation_items']:
|
||||||
|
price_item.update({'quota': quota.id})
|
||||||
|
price_item_creation_object = CustomOperations().custom_create(
|
||||||
|
request=request,
|
||||||
|
view=QuotaPriceCalculationItemsViewSet(),
|
||||||
|
data=price_item
|
||||||
|
)
|
||||||
|
price_calculation_items.append(price_item_creation_object)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'quota': serializer.data,
|
'quota': serializer.data,
|
||||||
'incentive_plan': plans_list, # noqa
|
'incentive_plan': plans_list, # noqa
|
||||||
'attribute_values': attributes_value_list,
|
'attribute_values': attributes_value_list,
|
||||||
'broker_values': broker_data_list,
|
'broker_values': broker_data_list,
|
||||||
'live_stock_allocations': allocations_list,
|
'live_stock_allocations': allocations_list,
|
||||||
'livestock_age_limitations': livestock_age_limits
|
'livestock_age_limitations': livestock_age_limits,
|
||||||
|
'price_calculation_items': price_calculation_items
|
||||||
}
|
}
|
||||||
|
|
||||||
# call save method to generate id & calculate quota final price
|
# call save method to generate id & calculate quota final price
|
||||||
@@ -602,3 +632,13 @@ class QuotaLiveStockAgeLimitation(SoftDeleteMixin, viewsets.ModelViewSet):
|
|||||||
return Response(status=status.HTTP_200_OK)
|
return Response(status=status.HTTP_200_OK)
|
||||||
except APIException as e:
|
except APIException as e:
|
||||||
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
return Response(e, status=status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
|
|
||||||
|
class QuotaPriceCalculationItemsViewSet(viewsets.ModelViewSet):
|
||||||
|
queryset = product_models.QuotaPriceCalculationItems.objects.all().select_related('quota', 'pricing_type')
|
||||||
|
serializer_class = quota_serializers.QuotaPriceCalculationPriceItemsSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class QuotaFinalPriceTypeViewSet(viewsets.ModelViewSet):
|
||||||
|
queryset = product_models.QuotaFinalPriceTypes.objects.all()
|
||||||
|
serializer_class = quota_serializers.QuotaFinalPriceTypeSerializer
|
||||||
|
|||||||
@@ -141,29 +141,6 @@ class InventoryQuotaSaleTransactionViewSet(viewsets.ModelViewSet, DynamicSearchM
|
|||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN)
|
return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
@action(
|
|
||||||
methods=['get'],
|
|
||||||
detail=False,
|
|
||||||
url_path='transactions',
|
|
||||||
url_name='transactions',
|
|
||||||
name='transactions',
|
|
||||||
)
|
|
||||||
@transaction.atomic
|
|
||||||
def transactions(self, request):
|
|
||||||
""" pos transactions list """
|
|
||||||
|
|
||||||
# get device object
|
|
||||||
device = self.get_pos_device()
|
|
||||||
|
|
||||||
queryset = self.queryset.filter(pos_device=device)
|
|
||||||
queryset = self.filter_query(queryset)
|
|
||||||
|
|
||||||
# paginate & response
|
|
||||||
page = self.paginate_queryset(queryset)
|
|
||||||
if page is not None:
|
|
||||||
serializer = self.get_serializer(page, many=True)
|
|
||||||
return self.get_paginated_response(serializer.data)
|
|
||||||
|
|
||||||
|
|
||||||
class QuotaPreSaleItemViewSet(viewsets.ModelViewSet, DynamicSearchMixin, POSDeviceMixin):
|
class QuotaPreSaleItemViewSet(viewsets.ModelViewSet, DynamicSearchMixin, POSDeviceMixin):
|
||||||
queryset = warehouse_models.QuotaPreSaleItem.objects.all().select_related(
|
queryset = warehouse_models.QuotaPreSaleItem.objects.all().select_related(
|
||||||
|
|||||||
Reference in New Issue
Block a user