# Generated by Django 4.2.16 on 2024-11-28 04:31

from django.db import migrations, connection


def update_shipment_date(apps, schema_editor):
    """
    Update the shipment date for existing SalesOrderAllocation objects
    """

    from order.status_codes import SalesOrderStatusGroups

    SalesOrder = apps.get_model('order', 'SalesOrder')

    # Find any orders which are "complete" but missing a shipment date
    orders = SalesOrder.objects.filter(
        status__in=SalesOrderStatusGroups.COMPLETE,
        shipment_date__isnull=True
    )

    update_count = 0

    cursor = connection.cursor()

    for order in orders:

        # Check that the shipment date is actually null here
        assert order.shipment_date is None, f"SalesOrder {order.pk} has non-null shipment_date"

        # Find the latest shipment date for any associated allocations
        shipments = order.shipments.filter(shipment_date__isnull=False)
        latest_shipment = shipments.order_by('-shipment_date').first()

        if not latest_shipment:
            continue

        # Update the order with the new shipment date
        shipment_date = latest_shipment.shipment_date

        # Raw SQL to prevent some weird migration "order of operations" issues
        # Reference: https://github.com/inventree/InvenTree/pull/8814
        query = f"UPDATE order_salesorder SET shipment_date = '{shipment_date}' WHERE id = {order.pk}"
        cursor.execute(query)

        # Fetch the updated object, check that the shipment date has been updated
        order.refresh_from_db()
        assert order.shipment_date is not None, f"SalesOrder {order.pk} still has missing shipment_date"

        update_count += 1

    if update_count > 0:
        print(f"Updated {update_count} SalesOrder shipment dates")


class Migration(migrations.Migration):

    dependencies = [
        ('order', '0104_alter_returnorderlineitem_quantity'),
    ]

    operations = [
        migrations.RunPython(
            update_shipment_date,
            reverse_code=migrations.RunPython.noop
        )
    ]
