From 64bd83e752b0a8d0459544fe243fa8cb05938485 Mon Sep 17 00:00:00 2001 From: Rachel McRoberts Date: Thu, 28 Nov 2024 15:51:19 +0000 Subject: [PATCH 1/3] Use add package data to set selected package --- ...WooShippingPackageAndRatePlaceholder.swift | 8 ++++-- .../WooShippingCreateLabelsView.swift | 2 +- .../WooShippingCreateLabelsViewModel.swift | 25 ++++++++++++----- ...ooShippingCreateLabelsViewModelTests.swift | 28 +++++++++++++++++++ 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingPackageAndRatePlaceholder.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingPackageAndRatePlaceholder.swift index 27303159f40..c43d76ef4d1 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingPackageAndRatePlaceholder.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingPackageAndRatePlaceholder.swift @@ -1,7 +1,11 @@ import SwiftUI struct WooShippingPackageAndRatePlaceholder: View { + /// Action to perform when a package is selected. + let onSelectPackage: (WooShippingPackageDataRepresentable) -> Void + @State private var showAddPackage: Bool = false + var body: some View { VStack(spacing: .zero) { Button { @@ -25,7 +29,7 @@ struct WooShippingPackageAndRatePlaceholder: View { .roundedBorder(cornerRadius: Layout.borderCornerRadius, lineColor: Color(.border), lineWidth: Layout.borderLineWidth, dashed: true) .sheet(isPresented: $showAddPackage) { WooShippingAddPackageView { packageData in - // TODO: use packageData + onSelectPackage(packageData) showAddPackage = false } } @@ -58,6 +62,6 @@ private extension WooShippingPackageAndRatePlaceholder { } #Preview { - WooShippingPackageAndRatePlaceholder() + WooShippingPackageAndRatePlaceholder(onSelectPackage: { _ in }) .padding() } diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsView.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsView.swift index 9ee5cde8695..54bc09baa28 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsView.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsView.swift @@ -57,7 +57,7 @@ struct WooShippingCreateLabelsView: View { WooShippingServiceView(viewModel: shippingService) .padding(.horizontal, -16) } else { - WooShippingPackageAndRatePlaceholder() + WooShippingPackageAndRatePlaceholder(onSelectPackage: viewModel.selectPackage) } } .padding(16) diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModel.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModel.swift index 32ce88567fa..596d05ff691 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModel.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModel.swift @@ -141,6 +141,24 @@ final class WooShippingCreateLabelsViewModel: ObservableObject { self.stores = stores } + /// Handles package selection for the shipping label. + /// Selecting a package also refreshes the available rates for the shipping service. + func selectPackage(_ packageData: WooShippingPackageDataRepresentable) { + // For now we support purchasing labels in a single package for a single shipment. + // In future milestones we can handle an array of packages with unique IDs for each shipment. + let package = ShippingLabelPackageSelected(id: "shipment_0", + boxID: packageData.id, + length: Double(packageData.length) ?? 0, + width: Double(packageData.width) ?? 0, + height: Double(packageData.height) ?? 0, + weight: Double(packageData.weight) ?? 0, + isLetter: WooShippingPackageType(rawValue: packageData.packageType) == .envelope, + hazmatCategory: nil, // Hazmat support will be added in a future milestone + customsForm: nil) // Customs form support will be added in a future milestone + selectedPackage = package + shippingService?.loadLabelRates(for: package) + } + /// Purchases a shipping label with the provided label details and settings. func purchaseLabel() { guard isPurchaseButtonEnabled, !isPurchasingLabel, let originSiteAddress, let destinationAddress, let selectedPackage, let selectedRate else { @@ -175,13 +193,6 @@ final class WooShippingCreateLabelsViewModel: ObservableObject { // MARK: Utils private extension WooShippingCreateLabelsViewModel { - /// Handles changes to the selected package. - /// Selecting a package also refreshes the available rates for the shipping service. - func handleNewSelectedPackage(_ selectedPackage: ShippingLabelPackageSelected) { - self.selectedPackage = selectedPackage - shippingService?.loadLabelRates(for: selectedPackage) - } - /// Provides the formatted label and amount for a shipping rate, based on the provided base rate. func formatShippingRate(name: String, rate: Double, basedOn baseRate: Double? = nil) -> (title: String, amount: String) { let amount = { diff --git a/WooCommerce/WooCommerceTests/ViewRelated/Shipping Label/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModelTests.swift b/WooCommerce/WooCommerceTests/ViewRelated/Shipping Label/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModelTests.swift index c4bf75a7689..7fb4590ec45 100644 --- a/WooCommerce/WooCommerceTests/ViewRelated/Shipping Label/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModelTests.swift +++ b/WooCommerce/WooCommerceTests/ViewRelated/Shipping Label/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModelTests.swift @@ -250,6 +250,34 @@ final class WooShippingCreateLabelsViewModelTests: XCTestCase { // Check isPurchaseLabel is false after purchase XCTAssertFalse(viewModel.isPurchasingLabel) } + + func test_selectPackage_sets_selectedPackage_with_package_data() { + // Given + let packageData = WooShippingPackageData(id: "small_flat_box", + name: "Small Flat Rate Box", + length: "21.91", + width: "13.65", + height: "4.13", + dimensionsUnit: "cm", + weight: "0", + weightUnit: "kg", + source: .predefined("usps"), + packageType: "box") + let viewModel = WooShippingCreateLabelsViewModel(order: Order.fake()) + + // When + viewModel.selectPackage(packageData) + + // Then + XCTAssertNotNil(viewModel.selectedPackage) + XCTAssertEqual(viewModel.selectedPackage?.id, "shipment_0") + XCTAssertEqual(viewModel.selectedPackage?.boxID, "small_flat_box") + XCTAssertEqual(viewModel.selectedPackage?.length, 21.91) + XCTAssertEqual(viewModel.selectedPackage?.width, 13.65) + XCTAssertEqual(viewModel.selectedPackage?.height, 4.13) + XCTAssertEqual(viewModel.selectedPackage?.weight, 0) + XCTAssertEqual(viewModel.selectedPackage?.isLetter, false) + } } private extension WooShippingCreateLabelsViewModelTests { From 83226e1c5ec443a2e610e343ce997bee6299bf58 Mon Sep 17 00:00:00 2001 From: Rachel McRoberts Date: Thu, 28 Nov 2024 16:34:25 +0000 Subject: [PATCH 2/3] Ensure unsaved custom packages have the fallback box ID of 0 when sent to the backend --- .../Carriers and Rates/ShippingLabelPackageSelected.swift | 2 +- .../WooShippingAddCustomPackageViewModel.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Networking/Networking/Model/ShippingLabel/Packages/Carriers and Rates/ShippingLabelPackageSelected.swift b/Networking/Networking/Model/ShippingLabel/Packages/Carriers and Rates/ShippingLabelPackageSelected.swift index 88abd163ec6..5a40bdc9a52 100644 --- a/Networking/Networking/Model/ShippingLabel/Packages/Carriers and Rates/ShippingLabelPackageSelected.swift +++ b/Networking/Networking/Model/ShippingLabel/Packages/Carriers and Rates/ShippingLabelPackageSelected.swift @@ -43,7 +43,7 @@ extension ShippingLabelPackageSelected: Encodable { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(id, forKey: .id) - try container.encode(boxID, forKey: .boxID) + try container.encode(boxID.isEmpty ? "0" : boxID, forKey: .boxID) try container.encode(length, forKey: .length) try container.encode(width, forKey: .width) try container.encode(height, forKey: .height) diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingAddCustomPackageViewModel.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingAddCustomPackageViewModel.swift index 0647dadaa9f..77bb3545955 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingAddCustomPackageViewModel.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingAddCustomPackageViewModel.swift @@ -53,7 +53,7 @@ final class WooShippingAddCustomPackageViewModel: ObservableObject { } private var packageDataFromCurrentData: WooShippingPackageDataRepresentable { - return WooShippingPackageData(id: UUID().uuidString, + return WooShippingPackageData(id: packageTemplateName, name: packageTemplateName, length: fieldValues[.length] ?? "", width: fieldValues[.width] ?? "", From 225937ccb997de080b5f0a41762cac2aec5caa32 Mon Sep 17 00:00:00 2001 From: Rachel McRoberts Date: Thu, 28 Nov 2024 17:45:05 +0000 Subject: [PATCH 3/3] Include the item weight in the default total package weight for a selected package --- .../WooShippingCreateLabelsViewModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModel.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModel.swift index 596d05ff691..ab1e7451104 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModel.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingCreateLabelsViewModel.swift @@ -151,7 +151,7 @@ final class WooShippingCreateLabelsViewModel: ObservableObject { length: Double(packageData.length) ?? 0, width: Double(packageData.width) ?? 0, height: Double(packageData.height) ?? 0, - weight: Double(packageData.weight) ?? 0, + weight: itemsDataSource.items.map(\.weight).reduce(0, +) + (Double(packageData.weight) ?? 0), isLetter: WooShippingPackageType(rawValue: packageData.packageType) == .envelope, hazmatCategory: nil, // Hazmat support will be added in a future milestone customsForm: nil) // Customs form support will be added in a future milestone