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
« 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
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
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)
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
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()
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)')
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)
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)')
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')
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')
67class Migration(migrations.Migration):
69 dependencies = [
70 ('order', '0063_alter_purchaseorderlineitem_unique_together'),
71 ]
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 ]