From 4fc6a666b289e902baf81517cf88f01cc587f27a Mon Sep 17 00:00:00 2001 From: Daniel Arantes Loverde Date: Fri, 10 Jul 2026 10:23:59 -0300 Subject: [PATCH] [cart-checkout] Fix delivery fee and address sync using stale cached profile Cart's delivery fee and Checkout's address validation both fetched the customer profile without forcing a cache refresh (2h TTL), then let that possibly-stale address book unconditionally overwrite the just-picked appState.address coordinates before building the fee/validation payload. Result: changing the address on Home didn't reliably move the cart's delivery fee, and Checkout's 'Alterar' could silently revert to the old address when the stale coordinates made the backend report it as not served. Force-refresh the profile fetch and only use it to fill genuine gaps in appState.address, never to override a live user selection. --- Sources/PediFoods/Views/Main/CartView.swift | 26 +++++++++++++------ .../Views/Main/CheckoutView+Logic.swift | 23 +++++++++++----- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/Sources/PediFoods/Views/Main/CartView.swift b/Sources/PediFoods/Views/Main/CartView.swift index 5ccb722..4ba0420 100644 --- a/Sources/PediFoods/Views/Main/CartView.swift +++ b/Sources/PediFoods/Views/Main/CartView.swift @@ -287,7 +287,7 @@ struct CartView: View { defer { isLoadingDeliveryFee = false } do { - let profileResponse = try await ApiService().profile() + let profileResponse = try await ApiService().profile(forceRefresh: true) let addresses = profileResponse.result?.addressBook ?? [] if let selectedId = appState.address.selectedId, selectedId.isEmpty == false { @@ -312,20 +312,30 @@ struct CartView: View { } if let selected = selectedCustomerAddress { - appState.address.selectedId = selected.id - let label = (selected.label ?? "").trimmingCharacters(in: .whitespacesAndNewlines) - if label.isEmpty == false { - appState.address.display = label + // appState.address reflects the address the user just picked — + // authoritative. Only fill in gaps from the address book here, + // never overwrite a live selection with a (possibly stale) + // cached record, or the fee/validation payload below can end + // up built against the wrong coordinates. + if appState.address.selectedId == nil || appState.address.selectedId?.isEmpty == true { + appState.address.selectedId = selected.id } - if let lat = selected.latLong?.first, let lng = selected.latLong?.dropFirst().first { + if appState.address.display.isEmpty || appState.address.display == "Defina seu endereco" { + let label = (selected.label ?? "").trimmingCharacters(in: .whitespacesAndNewlines) + if label.isEmpty == false { + appState.address.display = label + } + } + if appState.address.latitude == nil || appState.address.longitude == nil, + let lat = selected.latLong?.first, let lng = selected.latLong?.dropFirst().first { appState.address.latitude = lat appState.address.longitude = lng } SessionStateStore.saveAddress(appState.address) } - let payloadLat = selectedCustomerAddress?.latLong?.first ?? appState.address.latitude - let payloadLng = selectedCustomerAddress?.latLong?.dropFirst().first ?? appState.address.longitude + let payloadLat = appState.address.latitude ?? selectedCustomerAddress?.latLong?.first + let payloadLng = appState.address.longitude ?? selectedCustomerAddress?.latLong?.dropFirst().first let payload = ValidateDeliveryAddressPayload( address: ValidateDeliveryAddressDataPayload( diff --git a/Sources/PediFoods/Views/Main/CheckoutView+Logic.swift b/Sources/PediFoods/Views/Main/CheckoutView+Logic.swift index 02fabab..2d67163 100644 --- a/Sources/PediFoods/Views/Main/CheckoutView+Logic.swift +++ b/Sources/PediFoods/Views/Main/CheckoutView+Logic.swift @@ -71,7 +71,7 @@ extension CheckoutView { @MainActor func refreshSelectedCustomerAddress() async { do { - let response = try await ApiService().profile() + let response = try await ApiService().profile(forceRefresh: true) if let customer = response.result { appState.profile.id = customer.id appState.profile.name = customer.name @@ -117,12 +117,23 @@ extension CheckoutView { } if let selected = selectedCustomerAddress { - appState.address.selectedId = selected.id - let label = (selected.label ?? "").trimmingCharacters(in: .whitespacesAndNewlines) - if label.isEmpty == false { - appState.address.display = label + // appState.address reflects the address the user just picked — + // authoritative. Only fill in gaps from the address book here, + // never overwrite a live selection with a (possibly stale) + // cached record, or delivery validation below runs against + // the wrong coordinates and can wrongly report the address + // as not served, reverting the user's pick. + if appState.address.selectedId == nil || appState.address.selectedId?.isEmpty == true { + appState.address.selectedId = selected.id } - if let lat = selected.latLong?.first, let lng = selected.latLong?.dropFirst().first { + if appState.address.display.isEmpty || appState.address.display == "Defina seu endereco" { + let label = (selected.label ?? "").trimmingCharacters(in: .whitespacesAndNewlines) + if label.isEmpty == false { + appState.address.display = label + } + } + if appState.address.latitude == nil || appState.address.longitude == nil, + let lat = selected.latLong?.first, let lng = selected.latLong?.dropFirst().first { appState.address.latitude = lat appState.address.longitude = lng }