From 9da506c0093c194fffacf52a00a54ec3ac7b3704 Mon Sep 17 00:00:00 2001 From: Mojtaba-z Date: Tue, 30 Sep 2025 11:30:06 +0330 Subject: [PATCH] fix bug of transaction, when is success do not manage inventory again --- apps/pos_device/pos/api/v1/viewsets/device.py | 12 ++++++++++++ ...ntoryquotasaleitem_inventory_calculation.py | 18 ++++++++++++++++++ apps/warehouse/models.py | 1 + apps/warehouse/pos/api/v1/serializers.py | 16 ++++++++++++---- apps/warehouse/signals.py | 8 +++++--- 5 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 apps/warehouse/migrations/0036_inventoryquotasaleitem_inventory_calculation.py diff --git a/apps/pos_device/pos/api/v1/viewsets/device.py b/apps/pos_device/pos/api/v1/viewsets/device.py index 7ed6b8f..bf9d81d 100644 --- a/apps/pos_device/pos/api/v1/viewsets/device.py +++ b/apps/pos_device/pos/api/v1/viewsets/device.py @@ -130,6 +130,12 @@ class POSDeviceViewSet(viewsets.ModelViewSet, POSDeviceMixin): "serial": device.serial, "provider": organization.name, "provider_tell": organization.phone, + "main_company": { + "name": main_company.name, + "phone": main_company.phone, + "shaba": main_company.bank_information.all().first().sheba, # noqa + "amount": 400 + } }, status=status.HTTP_401_UNAUTHORIZED) else: @@ -147,6 +153,12 @@ class POSDeviceViewSet(viewsets.ModelViewSet, POSDeviceMixin): "password": "****", "provider": organization.name, "provider_tell": organization.phone, + "main_company": { + "name": main_company.name, + "phone": main_company.phone, + "shaba": main_company.bank_information.all().first().sheba, # noqa + "amount": 400 + } }, status=status.HTTP_412_PRECONDITION_FAILED) @action( diff --git a/apps/warehouse/migrations/0036_inventoryquotasaleitem_inventory_calculation.py b/apps/warehouse/migrations/0036_inventoryquotasaleitem_inventory_calculation.py new file mode 100644 index 0000000..ebd1008 --- /dev/null +++ b/apps/warehouse/migrations/0036_inventoryquotasaleitem_inventory_calculation.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0 on 2025-09-30 06:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('warehouse', '0035_inventoryquotasaletransaction_pos_date_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='inventoryquotasaleitem', + name='inventory_calculation', + field=models.BooleanField(default=False), + ), + ] diff --git a/apps/warehouse/models.py b/apps/warehouse/models.py index e625f19..f6c9b13 100644 --- a/apps/warehouse/models.py +++ b/apps/warehouse/models.py @@ -179,6 +179,7 @@ class InventoryQuotaSaleItem(BaseModel): is_pre_sale = models.BooleanField(default=False) additional = models.JSONField(default=dict) livestock_statistic = models.JSONField(default=dict) + inventory_calculation = models.BooleanField(default=False) @property def product(self): diff --git a/apps/warehouse/pos/api/v1/serializers.py b/apps/warehouse/pos/api/v1/serializers.py index 78a6340..62e7ad0 100644 --- a/apps/warehouse/pos/api/v1/serializers.py +++ b/apps/warehouse/pos/api/v1/serializers.py @@ -23,6 +23,7 @@ from apps.product.models import ( ) from apps.warehouse import models as warehouse_models from apps.livestock.models import LiveStockType +from django.db.models.signals import post_save from apps.core.models import SystemConfig from django.db.transaction import atomic from apps.warehouse.exceptions import ( @@ -143,7 +144,7 @@ class InventoryQuotaSaleTransactionSerializer(serializers.ModelSerializer): # --- Case 1: success => only update items if transaction.transaction_status == 'success': for item_data in items_data: - warehouse_models.InventoryQuotaSaleItem.objects.filter( + qs = warehouse_models.InventoryQuotaSaleItem.objects.filter( Q(transaction=transaction) & ( Q(free_product_id=item_data.get('free_product', None)) | Q(gov_product_id=item_data.get('gov_product', None)) @@ -163,7 +164,7 @@ class InventoryQuotaSaleTransactionSerializer(serializers.ModelSerializer): 'transaction_date', ]: if field in validated_data: - setattr(transaction, field, validated_data) + setattr(transaction, field, validated_data[field]) transaction.save(update_fields=[ 'transaction_status', @@ -178,12 +179,19 @@ class InventoryQuotaSaleTransactionSerializer(serializers.ModelSerializer): # items can change for item_data in items_data: - warehouse_models.InventoryQuotaSaleItem.objects.filter( + items = warehouse_models.InventoryQuotaSaleItem.objects.filter( Q(transaction=transaction) & ( Q(free_product_id=item_data.get('free_product', None)) | Q(gov_product_id=item_data.get('gov_product', None)) ) - ).update(**item_data) + ) + items.update(**item_data) + + # if transaction status updated as success, call signal for inventory management + if validated_data['transaction_status'] == 'success': + for sale_item in items: + sale_item.inventory_calculation = True + sale_item.save() return transaction diff --git a/apps/warehouse/signals.py b/apps/warehouse/signals.py index 7886168..1032112 100644 --- a/apps/warehouse/signals.py +++ b/apps/warehouse/signals.py @@ -60,8 +60,10 @@ def update_distribution_warehouse_entry(sender, instance, **kwargs): @receiver(post_delete, sender=InventoryQuotaSaleItem) def update_distribution_warehouse_sold_and_balance(sender, instance: InventoryQuotaSaleItem, **kwargs): if instance.quota_distribution and not instance.quota_distribution.pre_sale: - warehouse_sold_and_balance( - quota_distribution=instance.quota_distribution, - ) + # 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_distribution=instance.quota_distribution, + ) else: print("quota distribution is null - warehouse app signals")