fix - split signals warehouse / add quota stat on transaction item / add distribuitions in quota stat serializer

This commit is contained in:
2025-11-26 12:27:29 +03:30
parent eeea3b55cf
commit f79c25485b
8 changed files with 113 additions and 26 deletions

View File

@@ -3,32 +3,31 @@ from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from apps.pos_device.models import Device from apps.pos_device.models import Device
from apps.warehouse.models import InventoryEntry
from apps.warehouse.models import product_models from apps.warehouse.models import product_models
from .models import Notification from .models import Notification
@receiver(post_save, sender=InventoryEntry) # @receiver(post_save, sender=InventoryEntry)
def create_inventory_entry_notification(sender, instance, created, **kwargs): # def create_inventory_entry_notification(sender, instance, created, **kwargs):
""" Create notification for organization after inventory entry creation """ # """ Create notification for organization after inventory entry creation """
#
if not created: # if not created:
return # return
#
def _create_notification(): # def _create_notification():
# create notification for organization on pos device # # create notification for organization on pos device
devices = Device.objects.filter(assignment__client__organization=instance.organization) # devices = Device.objects.filter(assignment__client__organization=instance.organization)
for device in devices: # for device in devices:
Notification.objects.create( # Notification.objects.create(
device=device, # device=device,
organization=instance.organization, # organization=instance.organization,
title=f" {instance.distribution.distribution_id} ورودی جدید به انبار از توزیع با کد ", # noqa # title=f" {instance.distribution.distribution_id} ورودی جدید به انبار از توزیع با کد ", # noqa
message=f' مقدار {instance.distribution.weight} کیلوگرم' # noqa # message=f' مقدار {instance.distribution.weight} کیلوگرم' # noqa
f' از توزیع با کد {instance.distribution.distribution_id} به انبار ورود خورده است ', # noqa # f' از توزیع با کد {instance.distribution.distribution_id} به انبار ورود خورده است ', # noqa
type='inventory', # type='inventory',
) # )
#
transaction.on_commit(_create_notification) # transaction.on_commit(_create_notification)
@receiver(post_save, sender=product_models.QuotaDistribution) # noqa @receiver(post_save, sender=product_models.QuotaDistribution) # noqa

View File

@@ -273,6 +273,9 @@ class OrganizationQuotaStatsSerializer(serializers.ModelSerializer):
representation['free_sale'] = instance.quota.free_sale representation['free_sale'] = instance.quota.free_sale
representation['pre_sale'] = instance.quota.pre_sale representation['pre_sale'] = instance.quota.pre_sale
if instance.distributions:
representation['distributions'] = [dist.id for dist in instance.distributions.all()]
if instance.quota: if instance.quota:
representation['quota'] = { representation['quota'] = {
'quota_identity': instance.quota.quota_id, 'quota_identity': instance.quota.quota_id,

View File

@@ -6,4 +6,4 @@ class WarehouseConfig(AppConfig):
name = 'apps.warehouse' name = 'apps.warehouse'
def ready(self): def ready(self):
import apps.warehouse.signals pass

View File

@@ -0,0 +1,20 @@
# Generated by Django 5.0 on 2025-11-26 07:30
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('product', '0097_organizationquotastats_inventory_entry_balance'),
('warehouse', '0044_inventoryentry_org_quota_stat'),
]
operations = [
migrations.AddField(
model_name='inventoryquotasaleitem',
name='quota_stat',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sale_items', to='product.organizationquotastats'),
),
]

View File

@@ -185,6 +185,12 @@ class InventoryQuotaSaleItem(BaseModel):
related_name='sale_items', related_name='sale_items',
null=True null=True
) )
quota_stat = models.ForeignKey(
product_models.OrganizationQuotaStats,
on_delete=models.CASCADE,
related_name='sale_items',
null=True
)
gov_product = models.ForeignKey( gov_product = models.ForeignKey(
product_models.Product, product_models.Product,
on_delete=models.CASCADE, on_delete=models.CASCADE,

View File

View File

@@ -3,9 +3,9 @@ from django.db.models.signals import post_save, post_delete, post_init
from django.dispatch import receiver from django.dispatch import receiver
from apps.product.models import QuotaDistribution from apps.product.models import QuotaDistribution
from .models import InventoryEntry, InventoryQuotaSaleItem from apps.product.services.quota_stat_service import QuotaStatsService
from .services.warehouse_allocation_service import WarehouseAllocationService from apps.warehouse.models import InventoryEntry, InventoryQuotaSaleItem
from ..product.services.quota_stat_service import QuotaStatsService from apps.warehouse.services.warehouse_allocation_service import WarehouseAllocationService
def calculate_warehouse_entry(quota_distribution): def calculate_warehouse_entry(quota_distribution):

View File

@@ -0,0 +1,59 @@
from django.db.models import Sum
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from apps.product.models import OrganizationQuotaStats
from apps.warehouse.models import InventoryQuotaSaleItem
def warehouse_sold_and_balance(quota_stat: OrganizationQuotaStats):
total_sold = quota_stat.sale_items.aggregate(
total=Sum('weight')
)['total'] or 0
quota_stat.sold_amount = total_sold
quota_stat.inventory_entry_balance = quota_stat.inventory_received - total_sold
# if quota_stat.inventory_entry_balance >= 0:
# calculate extra sales & mines total extra sales weight from new inventory entry
# and set the warehouse balance
# extra_sales = quota_distribution.extra_sales.all()
# total_extra_sales_weight = extra_sales.aggregate(total=Sum('weight'))['total'] or 0
# if quota_distribution.free_sale_balance != 0:
# if quota_distribution.warehouse_balance >= quota_distribution.free_sale_balance:
# quota_distribution.warehouse_balance -= total_extra_sales_weight
# quota_distribution.free_sale_balance = 0
# else:
# quota_distribution.free_sale_balance -= quota_distribution.warehouse_balance
# quota_distribution.warehouse_balance = 0
# calculate pre_sales & mines total pre_sales weight from new inventory entry
# and set the warehouse balance
# pre_sales = quota_distribution.pre_sales.all()
# total_pre_sales_weight = pre_sales.aggregate(total=Sum('weight'))['total'] or 0
# if total_pre_sales_weight != 0:
# if quota_distribution.warehouse_balance >= quota_distribution.pre_sale_balance:
# quota_distribution.warehouse_balance -= total_pre_sales_weight
# quota_distribution.pre_sale_balance = 0
# else:
# quota_distribution.pre_sale_balance -= quota_distribution.warehouse_balance
# quota_distribution.warehouse_balance = 0
# 'free_sale_balance', 'pre_sale_balance'
quota_stat.save(update_fields=['sold_amount', 'inventory_entry_balance'])
@receiver(post_save, sender=InventoryQuotaSaleItem)
@receiver(post_delete, sender=InventoryQuotaSaleItem)
def update_distribution_warehouse_sold_and_balance(sender, instance: InventoryQuotaSaleItem, **kwargs):
# if object exists & pre sale is true
if instance.quota_stat and not instance.quota_stat.quota.pre_sale:
# if transaction status is success and warehouse management Done once, inventory_calculation set to true
if instance.transaction.transaction_status == 'success' and instance.inventory_calculation is False:
warehouse_sold_and_balance(
quota_stat=instance.quota_stat,
)
else:
print("quota distribution is null - warehouse app signals")