Coverage for src/backend/InvenTree/stock/migrations/0094_auto_20230220_0025.py: 49%

25 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 17:47 +0000

1# Generated by Django 3.2.18 on 2023-02-20 00:25 

2 

3import logging 

4 

5from django.core.exceptions import FieldError 

6from django.db import migrations 

7 

8logger = logging.getLogger('inventree') 

9 

10 

11def fix_purchase_price(apps, schema_editor): 

12 """Data migration for fixing historical issue with StockItem.purchase_price field. 

13 

14 Ref: https://github.com/inventree/InvenTree/pull/4373 

15 

16 Due to an existing bug, if a PurchaseOrderLineItem was received, 

17 which had: 

18 

19 a) A SupplierPart with a non-unity pack size 

20 b) A defined purchase_price 

21 

22 then the StockItem.purchase_price was not calculated correctly! 

23 

24 Specifically, the purchase_price was not divided through by the pack_size attribute. 

25 

26 This migration fixes this by looking through all stock items which: 

27 

28 - Is linked to a purchase order 

29 - Have a purchase_price field 

30 - Are linked to a supplier_part 

31 - We can determine correctly that the calculation was misapplied 

32 """ 

33 

34 StockItem = apps.get_model('stock', 'stockitem') 

35 

36 items = StockItem.objects.exclude( 

37 purchase_order=None 

38 ).exclude( 

39 supplier_part=None 

40 ).exclude( 

41 purchase_price=None 

42 ) 

43 

44 try: 

45 items = items.exclude(supplier_part__pack_size=1) 

46 except FieldError: 

47 pass 

48 

49 n_updated = 0 

50 

51 for item in items: 51 ↛ 54line 51 didn't jump to line 54 because the loop on line 51 never started

52 # Grab a reference to the associated PurchaseOrder 

53 # Trying to find an absolute match between this StockItem and an associated PurchaseOrderLineItem 

54 po = item.purchase_order 

55 for line in po.lines.all(): 

56 # SupplierPart match 

57 if line.part == item.supplier_part: 

58 # Unit price matches original PurchaseOrder (and is thus incorrect) 

59 if item.purchase_price == line.purchase_price: 

60 item.purchase_price /= item.supplier_part.pack_size 

61 item.save() 

62 

63 n_updated += 1 

64 

65 if n_updated > 0: 65 ↛ 66line 65 didn't jump to line 66 because the condition on line 65 was never true

66 logger.info(f"Corrected purchase_price field for {n_updated} stock items.") 

67 

68 

69class Migration(migrations.Migration): 

70 

71 dependencies = [ 

72 ('company', '0047_supplierpart_pack_size'), 

73 ('stock', '0093_auto_20230217_2140'), 

74 ] 

75 

76 operations = [ 

77 migrations.RunPython( 

78 fix_purchase_price, 

79 reverse_code=migrations.RunPython.noop, 

80 ) 

81 ]