Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix relation between order and click and collect address #15697

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions saleor/checkout/complete_checkout.py
Expand Up @@ -145,6 +145,9 @@ def _process_shipping_data_for_order(
if checkout_info.user.addresses.filter(pk=shipping_address.pk).exists():
shipping_address = shipping_address.get_copy()

if shipping_address and delivery_method_info.warehouse_pk:
shipping_address = shipping_address.get_copy()

shipping_method = delivery_method_info.delivery_method
tax_class = getattr(shipping_method, "tax_class", None)

Expand Down
Expand Up @@ -3105,7 +3105,7 @@ def test_complete_checkout_for_local_click_and_collect(
order_count = Order.objects.count()
checkout = checkout_with_item_for_cc
checkout.collection_point = warehouse_for_cc
checkout.shipping_address = None
checkout.shipping_address = warehouse_for_cc.address
checkout.save(update_fields=["collection_point", "shipping_address"])

variables = {
Expand Down Expand Up @@ -3147,7 +3147,8 @@ def test_complete_checkout_for_local_click_and_collect(

assert order.collection_point == warehouse_for_cc
assert order.shipping_method is None
assert order.shipping_address == warehouse_for_cc.address
assert order.shipping_address
assert order.shipping_address.id != warehouse_for_cc.address.id
assert order.shipping_price == zero_taxed_money(payment.currency)
assert order.lines.count() == 1

Expand Down Expand Up @@ -3215,7 +3216,8 @@ def test_complete_checkout_for_global_click_and_collect(

assert order.collection_point == warehouse_for_cc
assert order.shipping_method is None
assert order.shipping_address == warehouse_for_cc.address
assert order.shipping_address
assert order.shipping_address.id != warehouse_for_cc.address.id
assert order.shipping_price == zero_taxed_money(payment.currency)
assert order.lines.count() == 1

Expand Down
Expand Up @@ -2773,7 +2773,8 @@ def test_complete_checkout_for_local_click_and_collect(

assert order.collection_point == warehouse_for_cc
assert order.shipping_method is None
assert order.shipping_address == warehouse_for_cc.address
assert order.shipping_address
assert order.shipping_address.id != warehouse_for_cc.address.id
assert order.shipping_price == zero_taxed_money(order.channel.currency_code)
assert order.lines.count() == 1

Expand Down Expand Up @@ -2833,7 +2834,8 @@ def test_complete_checkout_for_global_click_and_collect(

assert order.collection_point == warehouse_for_cc
assert order.shipping_method is None
assert order.shipping_address == warehouse_for_cc.address
assert order.shipping_address
assert order.shipping_address.id != warehouse_for_cc.address.id
assert order.shipping_price == zero_taxed_money(order.channel.currency_code)
assert order.lines.count() == 1

Expand Down
39 changes: 39 additions & 0 deletions saleor/order/migrations/0172_update_order_cc_addresses.py
@@ -0,0 +1,39 @@
from django.db import migrations
from django.db.models import Exists, OuterRef
from django.forms.models import model_to_dict

from .tasks.saleor3_19 import update_order_addresses_task

# The batch of size 250 takes ~0.5 second and consumes ~20MB memory at peak
ADDRESS_UPDATE_BATCH_SIZE = 250


def update_order_addresses(apps, schema_editor):
Order = apps.get_model("order", "Order")
Warehouse = apps.get_model("warehouse", "Warehouse")
Address = apps.get_model("account", "Address")
qs = Order.objects.filter(
Exists(Warehouse.objects.filter(address_id=OuterRef("shipping_address_id"))),
)
order_ids = qs.values_list("pk", flat=True)[:ADDRESS_UPDATE_BATCH_SIZE]
addresses = []
if order_ids:
orders = Order.objects.filter(id__in=order_ids)
for order in orders:
if cc_address := order.shipping_address:
order_address = Address(**model_to_dict(cc_address, exclude=["id"]))
order.shipping_address = order_address
addresses.append(order_address)
Address.objects.bulk_create(addresses, ignore_conflicts=True)
Order.objects.bulk_update(orders, ["shipping_address"])
update_order_addresses_task.delay()


class Migration(migrations.Migration):
dependencies = [
("order", "0171_order_order_user_email_user_id_idx"),
]

operations = [
migrations.RunPython(update_order_addresses, migrations.RunPython.noop),
]
12 changes: 12 additions & 0 deletions saleor/order/migrations/0176_merge_20240325_1315.py
@@ -0,0 +1,12 @@
# Generated by Django 3.2.22 on 2024-03-25 13:15

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("order", "0172_update_order_cc_addresses"),
("order", "0175_merge_20231122_1040"),
]

operations = []
12 changes: 12 additions & 0 deletions saleor/order/migrations/0177_merge_20240325_1329.py
@@ -0,0 +1,12 @@
# Generated by Django 3.2.22 on 2024-03-25 13:29

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("order", "0176_merge_20231122_1346"),
("order", "0176_merge_20240325_1315"),
]

operations = []
12 changes: 12 additions & 0 deletions saleor/order/migrations/0180_merge_20240325_1333.py
@@ -0,0 +1,12 @@
# Generated by Django 3.2.22 on 2024-03-25 13:33

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("order", "0177_merge_20240325_1329"),
("order", "0179_merge_20231122_1348"),
]

operations = []
12 changes: 12 additions & 0 deletions saleor/order/migrations/0182_merge_20240325_1338.py
@@ -0,0 +1,12 @@
# Generated by Django 3.2.22 on 2024-03-25 13:38

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("order", "0180_merge_20240325_1333"),
("order", "0181_order_subtotal_as_a_field"),
]

operations = []
@@ -0,0 +1,12 @@
# Generated by Django 3.2.22 on 2024-03-25 13:42

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("order", "0182_merge_20240325_1338"),
("order", "0183_order_tax_error"),
]

operations = []
29 changes: 29 additions & 0 deletions saleor/order/migrations/tasks/saleor3_19.py
@@ -0,0 +1,29 @@
from django.db.models import Exists, OuterRef
from django.forms.models import model_to_dict

from ....account.models import Address
from ....celeryconf import app
from ....warehouse.models import Warehouse
from ...models import Order

# The batch of size 250 takes ~0.5 second and consumes ~20MB memory at peak
ADDRESS_UPDATE_BATCH_SIZE = 250


@app.task
def update_order_addresses_task():
qs = Order.objects.filter(
Exists(Warehouse.objects.filter(address_id=OuterRef("shipping_address_id"))),
)
order_ids = qs.values_list("pk", flat=True)[:ADDRESS_UPDATE_BATCH_SIZE]
addresses = []
if order_ids:
orders = Order.objects.filter(id__in=order_ids)
for order in orders:
if cc_address := order.shipping_address:
order_address = Address(**model_to_dict(cc_address, exclude=["id"]))
order.shipping_address = order_address
addresses.append(order_address)
Address.objects.bulk_create(addresses, ignore_conflicts=True)
Order.objects.bulk_update(orders, ["shipping_address"])
update_order_addresses_task.delay()