Coverage for src/common/mixins.py: 79%
19 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-08-04 12:59 +0300
« prev ^ index » next coverage.py v7.9.2, created at 2025-08-04 12:59 +0300
1from django.contrib.contenttypes.models import ContentType
4class InventoryMixin:
5 """
6 Mixin class that provides utility methods for working with inventory objects.
8 This mixin is designed to work with any object that has an 'inventory' attribute
9 (like shopping bag items and order items). It provides methods
10 to extract standardized product information and calculate prices.
12 The mixin uses ContentType to dynamically determine the product type.
13 """
15 @staticmethod
16 def get_product_info(obj):
17 # Get the inventory object from the passed object
18 inventory = obj.inventory
19 if not inventory:
20 return {}
22 # Get the product from the inventory
23 # This uses getattr for safety in case the attribute doesn't exist
24 product = getattr(inventory, 'product', None)
25 if not product:
26 return {}
28 # Use ContentType to dynamically get the model information
29 # ContentType is a Django utility that stores information about models
30 # This allows us to get the model name without hardcoding it
31 product_content_type = ContentType.objects.get_for_model(
32 product.__class__
33 )
35 # Capitalize the model name for display purposes
36 model_name = product_content_type.model.capitalize()
38 # Return a standardized dictionary with product information
39 return {
40 'product_id': product.id,
41 'collection': str(product.collection),
42 'price': float(inventory.price),
43 'first_image': product.first_image,
44 'available_quantity': inventory.quantity,
45 'size': str(getattr(inventory, 'size', '')),
46 'metal': str(product.metal.name),
47 'stone': str(product.stone.name),
48 'color': str(product.color.name),
49 'category': model_name,
50 }
52 @staticmethod
53 def get_total_price_per_product(obj):
54 try:
55 # Calculate total price by multiplying unit price by quantity
56 return round(obj.inventory.price * obj.quantity, 2)
58 except Exception:
59 # Return 0.0 if calculation fails
60 return 0.0