Coverage for src/backend/InvenTree/order/migrations/0064_purchaseorderextraline_salesorderextraline.py: 42%

42 statements  

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

1# Generated by Django 3.2.12 on 2022-03-27 01:11 

2 

3import InvenTree.fields 

4import django.core.validators 

5from django.core import serializers 

6from django.db import migrations, models 

7import django.db.models.deletion 

8import djmoney.models.fields 

9import djmoney.models.validators 

10 

11 

12def _convert_model(apps, line_item_ref, extra_line_ref, price_ref): 

13 """Convert the OrderLineItem instances if applicable to new ExtraLine instances""" 

14 OrderLineItem = apps.get_model('order', line_item_ref) 

15 OrderExtraLine = apps.get_model('order', extra_line_ref) 

16 

17 items_to_change = OrderLineItem.objects.filter(part=None) 

18 if items_to_change.count() == 0: 18 ↛ 21line 18 didn't jump to line 21 because the condition on line 18 was always true

19 return 

20 

21 print(f'\nFound {items_to_change.count()} old {line_item_ref} instance(s)') 

22 print(f'Starting to convert - currently at {OrderExtraLine.objects.all().count()} {extra_line_ref} / {OrderLineItem.objects.all().count()} {line_item_ref} instance(s)') 

23 for lineItem in items_to_change: 

24 newitem = OrderExtraLine( 

25 order=lineItem.order, 

26 notes=lineItem.notes, 

27 price=getattr(lineItem, price_ref), 

28 quantity=lineItem.quantity, 

29 reference=lineItem.reference, 

30 ) 

31 newitem.context = {'migration': serializers.serialize('json', [lineItem, ])} 

32 newitem.save() 

33 

34 lineItem.delete() 

35 print(f'Done converting line items - now at {OrderExtraLine.objects.all().count()} {extra_line_ref} / {OrderLineItem.objects.all().count()} {line_item_ref} instance(s)') 

36 

37 

38def _reconvert_model(apps, line_item_ref, extra_line_ref): # pragma: no cover 

39 """Convert ExtraLine instances back to OrderLineItem instances""" 

40 OrderLineItem = apps.get_model('order', line_item_ref) 

41 OrderExtraLine = apps.get_model('order', extra_line_ref) 

42 

43 print(f'\nStarting to convert - currently at {OrderExtraLine.objects.all().count()} {extra_line_ref} / {OrderLineItem.objects.all().count()} {line_item_ref} instance(s)') 

44 for extra_line in OrderExtraLine.objects.all(): 

45 # regenreate item 

46 if extra_line.context: 

47 context_string = getattr(extra_line.context, 'migration') 

48 if not context_string: 

49 continue 

50 [item.save() for item in serializers.deserialize('json', context_string)] 

51 extra_line.delete() 

52 print(f'Done converting line items - now at {OrderExtraLine.objects.all().count()} {extra_line_ref} / {OrderLineItem.objects.all().count()} {line_item_ref} instance(s)') 

53 

54 

55def convert_line_items(apps, schema_editor): 

56 """convert line items""" 

57 _convert_model(apps, 'PurchaseOrderLineItem', 'PurchaseOrderExtraLine', 'purchase_price') 

58 _convert_model(apps, 'SalesOrderLineItem', 'SalesOrderExtraLine', 'sale_price') 

59 

60 

61def nunconvert_line_items(apps, schema_editor): # pragma: no cover 

62 """reconvert line items""" 

63 _reconvert_model(apps, 'PurchaseOrderLineItem', 'PurchaseOrderExtraLine') 

64 _reconvert_model(apps, 'SalesOrderLineItem', 'SalesOrderExtraLine') 

65 

66 

67class Migration(migrations.Migration): 

68 

69 dependencies = [ 

70 ('order', '0063_alter_purchaseorderlineitem_unique_together'), 

71 ] 

72 

73 operations = [ 

74 migrations.CreateModel( 

75 name='SalesOrderExtraLine', 

76 fields=[ 

77 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 

78 ('quantity', InvenTree.fields.RoundingDecimalField(decimal_places=5, default=1, help_text='Item quantity', max_digits=15, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Quantity')), 

79 ('reference', models.CharField(blank=True, help_text='Line item reference', max_length=100, verbose_name='Reference')), 

80 ('notes', models.CharField(blank=True, help_text='Line item notes', max_length=500, verbose_name='Notes')), 

81 ('target_date', models.DateField(blank=True, help_text='Target shipping date for this line item', null=True, verbose_name='Target Date')), 

82 ('context', models.JSONField(blank=True, help_text='Additional context for this line', null=True, verbose_name='Context')), 

83 ('price_currency', djmoney.models.fields.CurrencyField(choices=[], default='', editable=False, max_length=3)), 

84 ('price', InvenTree.fields.InvenTreeModelMoneyField(blank=True, currency_choices=[], decimal_places=4, default_currency='', help_text='Unit price', max_digits=19, null=True, validators=[djmoney.models.validators.MinMoneyValidator(0)], verbose_name='Price')), 

85 ('order', models.ForeignKey(help_text='Sales Order', on_delete=django.db.models.deletion.CASCADE, related_name='extra_lines', to='order.salesorder', verbose_name='Order')), 

86 ], 

87 options={ 

88 'abstract': False, 

89 'verbose_name': 'Sales Order Extra Line', 

90 }, 

91 ), 

92 migrations.CreateModel( 

93 name='PurchaseOrderExtraLine', 

94 fields=[ 

95 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 

96 ('quantity', InvenTree.fields.RoundingDecimalField(decimal_places=5, default=1, help_text='Item quantity', max_digits=15, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Quantity')), 

97 ('reference', models.CharField(blank=True, help_text='Line item reference', max_length=100, verbose_name='Reference')), 

98 ('notes', models.CharField(blank=True, help_text='Line item notes', max_length=500, verbose_name='Notes')), 

99 ('target_date', models.DateField(blank=True, help_text='Target shipping date for this line item', null=True, verbose_name='Target Date')), 

100 ('context', models.JSONField(blank=True, help_text='Additional context for this line', null=True, verbose_name='Context')), 

101 ('price_currency', djmoney.models.fields.CurrencyField(choices=[], default='', editable=False, max_length=3)), 

102 ('price', InvenTree.fields.InvenTreeModelMoneyField(blank=True, currency_choices=[], decimal_places=4, default_currency='', help_text='Unit price', max_digits=19, null=True, validators=[djmoney.models.validators.MinMoneyValidator(0)], verbose_name='Price')), 

103 ('order', models.ForeignKey(help_text='Purchase Order', on_delete=django.db.models.deletion.CASCADE, related_name='extra_lines', to='order.purchaseorder', verbose_name='Order')), 

104 ], 

105 options={ 

106 'abstract': False, 

107 'verbose_name': 'Purchase Order Extra Line', 

108 }, 

109 ), 

110 migrations.RunPython(convert_line_items, reverse_code=nunconvert_line_items), 

111 ]