Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Networking/Networking/Model/OrderAttributionInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public struct OrderAttributionInfo: Equatable, Sendable, GeneratedFakeable, Gene
extension OrderAttributionInfo {
enum Keys: String {
case sourceType = "_wc_order_attribution_source_type"
case salesChannel = "_wc_order_attribution_sales_channel"
case campaign = "_wc_order_attribution_utm_campaign"
case source = "_wc_order_attribution_utm_source"
case medium = "_wc_order_attribution_utm_medium"
Expand All @@ -75,5 +76,11 @@ public extension OrderAttributionInfo {
/// Sent in create order request to mark the order as created from mobile
///
public static let mobileAppSourceType = "mobile_app"
/// Sent in create order request to mark the order as created from mobile POS
///
public static let mobileAppPOSSourceType = "pos"
/// Sent in create order request to mark the order's sales channel from the mobile app
///
public static let mobileAppSalesChannel = "woocommerce_app_ios"
}
}
36 changes: 30 additions & 6 deletions Networking/Networking/Remote/OrdersRemote.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import Foundation
/// Order: Remote Endpoints
///
public class OrdersRemote: Remote {
public enum OrderSourceType {
case mobile
case pointOfSale
}

/// Retrieves all of the `Orders` available.
///
Expand Down Expand Up @@ -161,9 +165,16 @@ public class OrdersRemote: Remote {
/// - order: Order to be created.
/// - giftCard: Optional gift card to apply to the order.
/// - fields: Fields of the order to be created.
/// - source: Source of the order creation.
/// - completion: Closure to be executed upon completion.
///
public func createOrder(siteID: Int64, order: Order, giftCard: String?, fields: [CreateOrderField], completion: @escaping (Result<Order, Error>) -> Void) {
public func createOrder(
siteID: Int64,
order: Order,
giftCard: String?,
fields: [CreateOrderField],
source: OrderSourceType = .mobile,
completion: @escaping (Result<Order, Error>) -> Void
) {
do {
let path = Constants.ordersPath
let mapper = OrderMapper(siteID: siteID)
Expand Down Expand Up @@ -203,9 +214,22 @@ public class OrdersRemote: Remote {
}

// Set source type to mark the order as created from mobile
params[Order.CodingKeys.metadata.rawValue] = try [MetaData(metadataID: 0,
key: OrderAttributionInfo.Keys.sourceType.rawValue,
value: OrderAttributionInfo.Values.mobileAppSourceType).toDictionary()]
let sourceValue: String = {
switch source {
case .mobile:
return OrderAttributionInfo.Values.mobileAppSourceType
case .pointOfSale:
return OrderAttributionInfo.Values.mobileAppPOSSourceType
}
}()
params[Order.CodingKeys.metadata.rawValue] = try [
MetaData(metadataID: 0,
key: OrderAttributionInfo.Keys.sourceType.rawValue,
value: sourceValue).toDictionary(),
MetaData(metadataID: 0,
key: OrderAttributionInfo.Keys.salesChannel.rawValue,
value: OrderAttributionInfo.Values.mobileAppSalesChannel).toDictionary(),
]

return params
}()
Expand Down Expand Up @@ -390,7 +414,7 @@ public class OrdersRemote: Remote {
extension OrdersRemote: POSOrdersRemoteProtocol {
public func createPOSOrder(siteID: Int64, order: Order, fields: [CreateOrderField]) async throws -> Order {
return try await withCheckedThrowingContinuation { continuation in
createOrder(siteID: siteID, order: order, giftCard: nil, fields: fields) { result in
createOrder(siteID: siteID, order: order, giftCard: nil, fields: fields, source: .pointOfSale) { result in
switch result {
case let .success(order):
continuation.resume(returning: order)
Expand Down
27 changes: 25 additions & 2 deletions Networking/NetworkingTests/Remote/OrdersRemoteTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ final class OrdersRemoteTests: XCTestCase {
assertEqual(received, expected)
}

func test_create_order_sets_mobile_app_as_source_type_meta_data() throws {
func test_create_order_from_mobile_app_sets_source_type_and_sales_channel_meta_data() throws {
// Given
let remote = OrdersRemote(network: network)
let order = Order.fake()
Expand All @@ -735,7 +735,30 @@ final class OrdersRemoteTests: XCTestCase {
let received = try XCTUnwrap(request.parameters["meta_data"] as? [[String: AnyHashable]])
let expected: [[String: AnyHashable]] = [["id": 0,
"key": "_wc_order_attribution_source_type",
"value": "mobile_app"]]
"value": "mobile_app"],
["id": 0,
"key": "_wc_order_attribution_sales_channel",
"value": "woocommerce_app_ios"]]
assertEqual(received, expected)
}

func test_create_order_from_pos_sets_source_type_and_sales_channel_meta_data() throws {
// Given
let remote = OrdersRemote(network: network)
let order = Order.fake()

// When
remote.createOrder(siteID: 123, order: order, giftCard: nil, fields: [], source: .pointOfSale) { result in }

// Then
let request = try XCTUnwrap(network.requestsForResponseData.last as? JetpackRequest)
let received = try XCTUnwrap(request.parameters["meta_data"] as? [[String: AnyHashable]])
let expected: [[String: AnyHashable]] = [["id": 0,
"key": "_wc_order_attribution_source_type",
"value": "pos"],
["id": 0,
"key": "_wc_order_attribution_sales_channel",
"value": "woocommerce_app_ios"]]
assertEqual(received, expected)
}

Expand Down