Skip to content

Commit cf1a767

Browse files
committed
Open editing form for destination address
1 parent e4c8a31 commit cf1a767

File tree

5 files changed

+108
-3
lines changed

5 files changed

+108
-3
lines changed

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingAddresses/WooShippingEditAddressViewModel.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ final class WooShippingEditAddressViewModel: ObservableObject, Identifiable {
158158
/// Closure called when an origin address is done being edited and the changes are confirmed.
159159
private(set) var onOriginAddressEdited: ((WooShippingOriginAddress) -> Void)?
160160

161+
/// Closure called when a destination address is done being edited and the changes are confirmed.
162+
private(set) var onDestinationAddressEdited: ((WooShippingAddress) -> Void)?
163+
161164
init(type: AddressType,
162165
id: String,
163166
name: String,
@@ -176,7 +179,8 @@ final class WooShippingEditAddressViewModel: ObservableObject, Identifiable {
176179
stores: StoresManager = ServiceLocator.stores,
177180
storageManager: StorageManagerType = ServiceLocator.storageManager,
178181
debounceDelayInSeconds: Double = 1,
179-
onOriginAddressEdited: ((WooShippingOriginAddress) -> Void)? = nil) {
182+
onOriginAddressEdited: ((WooShippingOriginAddress) -> Void)? = nil,
183+
onDestinationAddressEdited: ((WooShippingAddress) -> Void)? = nil) {
180184
self.addressType = type
181185
self.id = id
182186
self.name = WooShippingAddressField(type: .name, value: name, required: company.isEmpty, validate: { _ in return nil })
@@ -266,6 +270,31 @@ final class WooShippingEditAddressViewModel: ObservableObject, Identifiable {
266270
onOriginAddressEdited: onAddressEdited)
267271
}
268272

273+
convenience init(address: WooShippingAddress?,
274+
isVerified: Bool,
275+
stores: StoresManager = ServiceLocator.stores,
276+
storageManager: StorageManagerType = ServiceLocator.storageManager,
277+
onAddressEdited: ((WooShippingAddress) -> Void)? = nil) {
278+
self.init(type: .destination,
279+
id: UUID().uuidString,
280+
name: address?.name ?? "",
281+
company: address?.company ?? "",
282+
country: address?.country ?? "",
283+
address: address?.combinedAddress ?? "",
284+
city: address?.city ?? "",
285+
state: address?.state ?? "",
286+
postalCode: address?.postcode ?? "",
287+
email: "",
288+
phone: address?.phone ?? "",
289+
isDefaultAddress: false,
290+
showCompanyField: address?.company.isNotEmpty == true,
291+
isVerified: isVerified,
292+
phoneNumberRequired: false, // TODO: Check phone number requirements for destination address.
293+
stores: stores,
294+
storageManager: storageManager,
295+
onDestinationAddressEdited: onAddressEdited)
296+
}
297+
269298
/// Validates the address remotely.
270299
@MainActor
271300
func remotelyValidateAddress() async {

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsView.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,11 +224,18 @@ private extension WooShippingCreateLabelsView {
224224
}
225225
.frame(maxWidth: .infinity, alignment: .leading)
226226
PencilEditButton {
227-
// TODO: Open destination address editing flow.
227+
viewModel.editDestinationAddress()
228228
}
229229
.buttonStyle(TextButtonStyle())
230230
}
231231
.padding(Layout.bottomSheetPadding)
232+
.sheet(item: $viewModel.addressToEdit) { addressToEdit in
233+
NavigationStack {
234+
WooShippingEditAddressView(viewModel: addressToEdit)
235+
.navigationTitle(Localization.BottomSheet.editDestination)
236+
.navigationBarTitleDisplayMode(.inline)
237+
}
238+
}
232239
}
233240

234241
/// View showing the order details, such as order items and shipping costs.
@@ -431,6 +438,9 @@ private extension WooShippingCreateLabelsView {
431438
value: "Purchase Label · %1$@",
432439
comment: "Label for button to purchase the shipping label on the shipping label creation screen, " +
433440
"including the label price. Reads like: 'Purchase Label · $7.63'")
441+
static let editDestination = NSLocalizedString("wooShipping.createLabels.bottomSheet.editDestination",
442+
value: "Edit Destination",
443+
comment: "Title for the edit destination address screen in the shipping label creation flow")
434444
}
435445

436446
enum AddressVerification {

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModel.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Combine
88
final class WooShippingCreateLabelsViewModel: ObservableObject {
99
private let currencyFormatter: CurrencyFormatter
1010
private let itemsDataSource: WooShippingItemsDataSource
11-
private let destinationAddress: WooShippingAddress?
11+
private var destinationAddress: WooShippingAddress?
1212
private let stores: StoresManager
1313
private var subscriptions: Set<AnyCancellable> = []
1414
private var debounceDuration: Double = 1
@@ -79,6 +79,10 @@ final class WooShippingCreateLabelsViewModel: ObservableObject {
7979
/// This property can be set to display a notice with the provided label about the destination address status.
8080
@Published var destinationAddressStatusNoticeLabel: String?
8181

82+
/// View model for address to edit.
83+
/// Setting this property will navigate to the address edit screen.
84+
@Published var addressToEdit: WooShippingEditAddressViewModel?
85+
8286
/// Shipping lines for the order, with formatted amount.
8387
let shippingLines: [WooShipping_ShippingLineViewModel]
8488

@@ -273,6 +277,20 @@ final class WooShippingCreateLabelsViewModel: ObservableObject {
273277
func onCustomsFormFilled(form: ShippingLabelCustomsForm) {
274278
customsForm = form
275279
}
280+
281+
/// Sets the `addressToEdit` property for editing the destination address.
282+
/// After the address is edited, the destination address is replaced with the updated address.
283+
func editDestinationAddress() {
284+
addressToEdit = WooShippingEditAddressViewModel(address: destinationAddress,
285+
isVerified: destinationAddressStatus == .verified,
286+
onAddressEdited: { [weak self] editedAddress in
287+
guard let self else {
288+
return
289+
}
290+
destinationAddress = editedAddress
291+
addressToEdit = nil // Dismisses address edit screen
292+
})
293+
}
276294
}
277295

278296
// MARK: Remote

WooCommerce/WooCommerceTests/ViewRelated/Shipping Label/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModelTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,17 @@ final class WooShippingCreateLabelsViewModelTests: XCTestCase {
500500
XCTAssertEqual(viewModel.destinationAddressStatus, .missing)
501501
XCTAssertNotNil(viewModel.destinationAddressStatusNoticeLabel)
502502
}
503+
504+
func test_editDestinationAddress_sets_addressToEdit_view_model() throws {
505+
// Given
506+
let viewModel = WooShippingCreateLabelsViewModel(order: Order.fake())
507+
508+
// When
509+
viewModel.editDestinationAddress()
510+
511+
// Then
512+
XCTAssertNotNil(viewModel.addressToEdit)
513+
}
503514
}
504515

505516
private extension WooShippingCreateLabelsViewModelTests {

WooCommerce/WooCommerceTests/ViewRelated/Shipping Label/WooShipping Create Shipping Labels/WooShippingEditAddressViewModelTests.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,43 @@ final class WooShippingEditAddressViewModelTests: XCTestCase {
102102
XCTAssertEqual(viewModel.countries.count, 1, "Should only include USPS-supported countries for origin addresses")
103103
}
104104

105+
func test_destination_address_inits_with_expected_values() {
106+
// Given
107+
let storageManager = MockStorageManager()
108+
let state = StateOfACountry(code: "NY", name: "New York")
109+
let countries = [Country(code: "US", name: "United States", states: [state]), Country(code: "CA", name: "Canada", states: [])]
110+
storageManager.insertSampleCountries(readOnlyCountries: countries)
111+
let address = WooShippingAddress(company: "HEADQUARTERS",
112+
name: "JANE DOE",
113+
phone: "223-456-7890",
114+
country: "US",
115+
state: "NY",
116+
address1: "15 ALGONKIN ST",
117+
address2: "STE 100",
118+
city: "TICONDEROGA",
119+
postcode: "12883-1487")
120+
121+
// When
122+
let viewModel = WooShippingEditAddressViewModel(address: address,
123+
isVerified: false,
124+
storageManager: storageManager)
125+
126+
// Then
127+
XCTAssertEqual(viewModel.name.value, address.name)
128+
XCTAssertEqual(viewModel.country.value, address.country)
129+
XCTAssertEqual(viewModel.company.value, address.company)
130+
XCTAssertEqual(viewModel.address.value, address.combinedAddress)
131+
XCTAssertEqual(viewModel.city.value, address.city)
132+
XCTAssertEqual(viewModel.state.value, address.state)
133+
XCTAssertEqual(viewModel.postalCode.value, address.postcode)
134+
XCTAssertEqual(viewModel.phone.value, address.phone)
135+
XCTAssertEqual(viewModel.email.value, "")
136+
XCTAssertTrue(viewModel.showCompanyField)
137+
XCTAssertEqual(viewModel.status, .missingInformation)
138+
XCTAssertFalse(viewModel.showSaveAsDefault)
139+
XCTAssertEqual(viewModel.countries.count, 2, "Should include all countries for destination addresses")
140+
}
141+
105142
func test_it_validates_address_with_missing_information_and_sets_expected_status_on_init() {
106143
// Given & When
107144
let viewModel = WooShippingEditAddressViewModel(type: .destination,

0 commit comments

Comments
 (0)