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

1from django.contrib.contenttypes.models import ContentType 

2 

3 

4class InventoryMixin: 

5 """ 

6 Mixin class that provides utility methods for working with inventory objects. 

7 

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. 

11 

12 The mixin uses ContentType to dynamically determine the product type. 

13 """ 

14 

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 {} 

21 

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 {} 

27 

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 ) 

34 

35 # Capitalize the model name for display purposes 

36 model_name = product_content_type.model.capitalize() 

37 

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 } 

51 

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) 

57 

58 except Exception: 

59 # Return 0.0 if calculation fails 

60 return 0.0