Skip to content

Commit 6568ace

Browse files
committed
Merge branch 'trunk' into feat/WOOMOB-1100-pos-sync-settings-ui-only
2 parents 62a78d7 + 42063c4 commit 6568ace

File tree

84 files changed

+4075
-446
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+4075
-446
lines changed

Modules/Sources/Fakes/Networking.generated.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1774,7 +1774,10 @@ extension Networking.Site {
17741774
isAdmin: .fake(),
17751775
wasEcommerceTrial: .fake(),
17761776
hasSSOEnabled: .fake(),
1777-
applicationPasswordAvailable: .fake()
1777+
applicationPasswordAvailable: .fake(),
1778+
isGarden: false,
1779+
gardenName: nil,
1780+
gardenPartner: nil
17781781
)
17791782
}
17801783
}

Modules/Sources/Networking/Model/Copiable/Models+Copiable.generated.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2747,7 +2747,10 @@ extension Networking.Site {
27472747
isAdmin: CopiableProp<Bool> = .copy,
27482748
wasEcommerceTrial: CopiableProp<Bool> = .copy,
27492749
hasSSOEnabled: CopiableProp<Bool> = .copy,
2750-
applicationPasswordAvailable: CopiableProp<Bool> = .copy
2750+
applicationPasswordAvailable: CopiableProp<Bool> = .copy,
2751+
isGarden: CopiableProp<Bool> = .copy,
2752+
gardenName: CopiableProp<String?> = .copy,
2753+
gardenPartner: CopiableProp<String?> = .copy
27512754
) -> Networking.Site {
27522755
let siteID = siteID ?? self.siteID
27532756
let name = name ?? self.name
@@ -2772,6 +2775,9 @@ extension Networking.Site {
27722775
let wasEcommerceTrial = wasEcommerceTrial ?? self.wasEcommerceTrial
27732776
let hasSSOEnabled = hasSSOEnabled ?? self.hasSSOEnabled
27742777
let applicationPasswordAvailable = applicationPasswordAvailable ?? self.applicationPasswordAvailable
2778+
let isGarden = isGarden ?? self.isGarden
2779+
let gardenName = gardenName ?? self.gardenName
2780+
let gardenPartner = gardenPartner ?? self.gardenPartner
27752781

27762782
return Networking.Site(
27772783
siteID: siteID,
@@ -2796,7 +2802,10 @@ extension Networking.Site {
27962802
isAdmin: isAdmin,
27972803
wasEcommerceTrial: wasEcommerceTrial,
27982804
hasSSOEnabled: hasSSOEnabled,
2799-
applicationPasswordAvailable: applicationPasswordAvailable
2805+
applicationPasswordAvailable: applicationPasswordAvailable,
2806+
isGarden: isGarden,
2807+
gardenName: gardenName,
2808+
gardenPartner: gardenPartner
28002809
)
28012810
}
28022811
}

Modules/Sources/Networking/Model/Site.swift

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,18 @@ public struct Site: Decodable, Equatable, Hashable, GeneratedFakeable, Generated
9797
///
9898
public let applicationPasswordAvailable: Bool
9999

100+
/// Whether the site is running on Garden architecture
101+
///
102+
public let isGarden: Bool
103+
104+
/// The site Garden name is present
105+
///
106+
public let gardenName: String?
107+
108+
/// The site Garden partner if present
109+
///
110+
public let gardenPartner: String?
111+
100112
/// Decodable Conformance.
101113
///
102114
public init(from decoder: Decoder) throws {
@@ -140,6 +152,10 @@ public struct Site: Decodable, Equatable, Hashable, GeneratedFakeable, Generated
140152
return jetpackModules.contains(OptionKeys.sso.rawValue) == true
141153
}()
142154

155+
let isGarden = try siteContainer.decodeIfPresent(Bool.self, forKey: .isGarden) ?? false
156+
let gardenName = try siteContainer.decodeIfPresent(String.self, forKey: .gardenName)
157+
let gardenPartner = try siteContainer.decodeIfPresent(String.self, forKey: .gardenPartner)
158+
143159
self.init(siteID: siteID,
144160
name: name,
145161
description: description,
@@ -162,7 +178,10 @@ public struct Site: Decodable, Equatable, Hashable, GeneratedFakeable, Generated
162178
isAdmin: isAdmin,
163179
wasEcommerceTrial: wasEcommerceTrial,
164180
hasSSOEnabled: hasSSOEnabled,
165-
applicationPasswordAvailable: false) // to be updated by fetching SiteAPI
181+
applicationPasswordAvailable: false, // to be updated by fetching SiteAPI
182+
isGarden: isGarden,
183+
gardenName: gardenName,
184+
gardenPartner: gardenPartner)
166185
}
167186

168187
/// Designated Initializer.
@@ -189,7 +208,10 @@ public struct Site: Decodable, Equatable, Hashable, GeneratedFakeable, Generated
189208
isAdmin: Bool,
190209
wasEcommerceTrial: Bool,
191210
hasSSOEnabled: Bool,
192-
applicationPasswordAvailable: Bool) {
211+
applicationPasswordAvailable: Bool,
212+
isGarden: Bool,
213+
gardenName: String?,
214+
gardenPartner: String?) {
193215
self.siteID = siteID
194216
self.name = name
195217
self.description = description
@@ -213,6 +235,9 @@ public struct Site: Decodable, Equatable, Hashable, GeneratedFakeable, Generated
213235
self.wasEcommerceTrial = wasEcommerceTrial
214236
self.hasSSOEnabled = hasSSOEnabled
215237
self.applicationPasswordAvailable = applicationPasswordAvailable
238+
self.isGarden = isGarden
239+
self.gardenName = gardenName
240+
self.gardenPartner = gardenPartner
216241
}
217242
}
218243

@@ -264,6 +289,9 @@ private extension Site {
264289
case isJetpackConnected = "jetpack_connection"
265290
case wasEcommerceTrial = "was_ecommerce_trial"
266291
case jetpackModules = "jetpack_modules"
292+
case isGarden = "is_garden"
293+
case gardenName = "garden_name"
294+
case gardenPartner = "garden_partner"
267295
}
268296

269297
enum PlanInfo: String, CodingKey {

Modules/Sources/Networking/Model/WordPressSite.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,10 @@ public extension WordPressSite {
110110
isAdmin: false,
111111
wasEcommerceTrial: false,
112112
hasSSOEnabled: false,
113-
applicationPasswordAvailable: false)
113+
applicationPasswordAvailable: false,
114+
isGarden: false,
115+
gardenName: nil,
116+
gardenPartner: nil)
114117
}
115118

116119
struct Authentication: Decodable {

Modules/Sources/Networking/Remote/POSCatalogSyncRemote.swift

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,18 @@ public protocol POSCatalogSyncRemoteProtocol {
3939
/// - pageNumber: Page number for pagination.
4040
/// - Returns: Paginated list of POS product variations.
4141
func loadProductVariations(siteID: Int64, pageNumber: Int) async throws -> PagedItems<POSProductVariation>
42+
43+
/// Gets the total count of products for the specified site.
44+
///
45+
/// - Parameter siteID: Site ID to get product count for.
46+
/// - Returns: Total number of products.
47+
func getProductCount(siteID: Int64) async throws -> Int
48+
49+
/// Gets the total count of product variations for the specified site.
50+
///
51+
/// - Parameter siteID: Site ID to get variation count for.
52+
/// - Returns: Total number of variations.
53+
func getProductVariationCount(siteID: Int64) async throws -> Int
4254
}
4355

4456
/// POS Catalog Sync: Remote Endpoints
@@ -174,6 +186,58 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
174186

175187
return createPagedItems(items: variations, responseHeaders: responseHeaders, currentPageNumber: pageNumber)
176188
}
189+
190+
// MARK: - Count Endpoints
191+
192+
/// Gets the total count of products for the specified site.
193+
///
194+
/// - Parameter siteID: Site ID to get product count for.
195+
/// - Returns: Total number of products.
196+
public func getProductCount(siteID: Int64) async throws -> Int {
197+
let path = Path.products
198+
let parameters = [
199+
ParameterKey.page: String(1),
200+
ParameterKey.perPage: String(1),
201+
ParameterKey.fields: POSProductVariation.requestFields.first ?? ""
202+
]
203+
204+
let request = JetpackRequest(
205+
wooApiVersion: .mark3,
206+
method: .get,
207+
siteID: siteID,
208+
path: path,
209+
parameters: parameters,
210+
availableAsRESTRequest: true
211+
)
212+
let responseHeaders = try await enqueueWithResponseHeaders(request)
213+
214+
return totalItemsCount(from: responseHeaders) ?? 0
215+
}
216+
217+
/// Gets the total count of product variations for the specified site.
218+
///
219+
/// - Parameter siteID: Site ID to get variation count for.
220+
/// - Returns: Total number of variations.
221+
public func getProductVariationCount(siteID: Int64) async throws -> Int {
222+
let path = Path.variations
223+
let parameters = [
224+
ParameterKey.page: String(1),
225+
ParameterKey.perPage: String(1),
226+
ParameterKey.fields: POSProductVariation.requestFields.first ?? ""
227+
]
228+
229+
let request = JetpackRequest(
230+
wooApiVersion: .wcAnalytics,
231+
method: .get,
232+
siteID: siteID,
233+
path: path,
234+
parameters: parameters,
235+
availableAsRESTRequest: true
236+
)
237+
let responseHeaders = try await enqueueWithResponseHeaders(request)
238+
239+
return totalItemsCount(from: responseHeaders) ?? 0
240+
}
177241
}
178242

179243
// MARK: - Constants

Modules/Sources/Networking/Remote/SiteRemote.swift

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,12 +338,37 @@ extension SiteRemote {
338338
enum SiteParameter {
339339
enum Fields {
340340
static let key = "fields"
341-
static let value = "ID,name,description,URL,options,jetpack,jetpack_connection,capabilities,was_ecommerce_trial,plan,jetpack_modules"
341+
static let value = [
342+
"ID",
343+
"name",
344+
"description",
345+
"URL",
346+
"options",
347+
"jetpack",
348+
"jetpack_connection",
349+
"capabilities",
350+
"was_ecommerce_trial",
351+
"plan",
352+
"jetpack_modules",
353+
"is_garden",
354+
"garden_name",
355+
"garden_partner"
356+
].joined(separator: ",")
342357
}
343358
enum Options {
344359
static let key = "options"
345-
static let value =
346-
"timezone,is_wpcom_store,woocommerce_is_active,gmt_offset,jetpack_connection_active_plugins,admin_url,login_url,frame_nonce,blog_public,can_blaze"
360+
static let value = [
361+
"timezone",
362+
"is_wpcom_store",
363+
"woocommerce_is_active",
364+
"gmt_offset",
365+
"jetpack_connection_active_plugins",
366+
"admin_url",
367+
"login_url",
368+
"frame_nonce",
369+
"blog_public",
370+
"can_blaze"
371+
].joined(separator: ",")
347372
}
348373
}
349374
}

Modules/Sources/NetworkingCore/Remote/OrdersRemote.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,24 @@ public extension OrdersRemote {
598598
case customerID
599599
case currency
600600
}
601+
602+
/// Loads a single order asynchronously for POS
603+
/// - Parameters:
604+
/// - siteID: Site for which we'll fetch the order.
605+
/// - orderID: ID of the order to load.
606+
/// - Returns: The loaded Order.
607+
/// - Throws: Network or parsing errors.
608+
func loadPOSOrder(siteID: Int64, orderID: Int64) async throws -> Order {
609+
let path = "\(Constants.ordersPath)/\(orderID)"
610+
let request = JetpackRequest(wooApiVersion: .mark3,
611+
method: .get,
612+
siteID: siteID,
613+
path: path,
614+
availableAsRESTRequest: true)
615+
let mapper = OrderMapper(siteID: siteID)
616+
617+
return try await enqueue(request, mapper: mapper)
618+
}
601619
}
602620

603621
private extension OrdersRemote.OrderCreationSource {

Modules/Sources/NetworkingCore/Remote/POSOrdersRemoteProtocol.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public protocol POSOrdersRemoteProtocol {
1919
order: Order,
2020
fields: [OrdersRemote.CreateOrderField]) async throws -> Order
2121

22+
func loadPOSOrder(siteID: Int64, orderID: Int64) async throws -> Order
23+
2224
func loadPOSOrders(siteID: Int64,
2325
pageNumber: Int,
2426
pageSize: Int) async throws -> PagedItems<Order>

Modules/Sources/NetworkingCore/Remote/Remote.swift

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,23 @@ open class Remote: NSObject {
248248
throw mapNetworkError(error: error, for: request)
249249
}
250250
}
251+
252+
/// Enqueues the specified Network Request using Swift Concurrency, for fetching the headers
253+
///
254+
/// - Important:
255+
/// - No data will be parsed. This is intended for use with `HEAD` requests, but will make whatever request you specify
256+
///
257+
/// - Parameter request: Request that should be performed.
258+
/// - Returns: The headers from the response
259+
public func enqueueWithResponseHeaders(_ request: Request) async throws -> [String: String] {
260+
do {
261+
let (_, headers) = try await network.responseDataAndHeaders(for: request)
262+
return headers ?? [:]
263+
} catch {
264+
handleResponseError(error: error, for: request)
265+
throw mapNetworkError(error: error, for: request)
266+
}
267+
}
251268
}
252269

253270
private extension Remote {
@@ -382,12 +399,16 @@ public extension Remote {
382399

383400
let hasMorePages = totalPages.map { currentPageNumber < $0 } ?? true
384401

402+
let totalItems = totalItemsCount(from: responseHeaders)
403+
404+
return PagedItems(items: items, hasMorePages: hasMorePages, totalItems: totalItems)
405+
}
406+
407+
func totalItemsCount(from responseHeaders: [String: String]?) -> Int? {
385408
// Extract total count from response headers (case insensitive)
386-
let totalItems = responseHeaders?.first(where: {
409+
responseHeaders?.first(where: {
387410
$0.key.lowercased() == PaginationHeaderKey.totalCount.lowercased()
388411
}).flatMap { Int($0.value) }
389-
390-
return PagedItems(items: items, hasMorePages: hasMorePages, totalItems: totalItems)
391412
}
392413
}
393414

Modules/Sources/Storage/Model/MIGRATIONS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
This file documents changes in the WCiOS Storage data model. Please explain any changes to the data model as well as any custom migrations.
44

5+
## Model 126 (Release 23.3.0.0)
6+
- @rafaelkayumov 2025-09-15
7+
- Added `isGarden` attribute to `Site` entity.
8+
- Added `gardenName` attribute to `Site` entity.
9+
- Added `gardenPartner` attribute to `Site` entity.
10+
511
## Model 125 (Release 23.2.0.0)
612
- @itsmeichigo 2025-09-04
713
- Added `hazmatCategory` attribute to `ShippingLabel` entity.

0 commit comments

Comments
 (0)