Skip to content

Commit cea0e8e

Browse files
authored
Merge branch 'trunk' into woomob-1252-check-eligibility-in-sync-coordinator
2 parents 61a7497 + 4d19368 commit cea0e8e

File tree

48 files changed

+1094
-539
lines changed

Some content is hidden

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

48 files changed

+1094
-539
lines changed

Modules/Sources/Networking/Remote/ReceiptRemote.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,27 +53,31 @@ public final class ReceiptRemote: Remote {
5353
/// - Parameters:
5454
/// - siteID: Site which hosts the Order.
5555
/// - orderID: ID of the order that the receipt is associated to.
56-
public func sendPOSReceipt(siteID: Int64, orderID: Int64) async throws {
56+
public func sendPOSReceipt(siteID: Int64, orderID: Int64, emailAddress: String) async throws {
5757
let sendEmailPath = "\(Constants.ordersPath)/\(orderID)/\(Constants.actionsPath)/send_email"
5858
let sendEmailRequest = JetpackRequest(wooApiVersion: .mark3,
5959
method: .post,
6060
siteID: siteID,
6161
path: sendEmailPath,
6262
parameters: [
63-
ParameterKeys.templateID: POSConstants.receiptTemplateID
63+
ParameterKeys.templateID: POSConstants.receiptTemplateID,
64+
ParameterKeys.email: emailAddress,
65+
ParameterKeys.forceEmailUpdate: true
6466
],
6567
availableAsRESTRequest: true)
6668
try await enqueue(sendEmailRequest)
6769
}
6870
}
6971

70-
extension ReceiptRemote: POSReceiptsRemoteProtocol { }
72+
extension ReceiptRemote: POSReceiptsRemoteProtocol {}
7173

7274
private extension ReceiptRemote {
7375
enum ParameterKeys {
7476
static let expirationDays: String = "expiration_days"
7577
static let forceRegenerate: String = "force_new"
7678
static let templateID: String = "template_id"
79+
static let forceEmailUpdate: String = "force_email_update"
80+
static let email: String = "email"
7781
}
7882

7983
enum Constants {

Modules/Sources/NetworkingCore/Remote/OrdersRemote.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,24 @@ extension OrdersRemote: POSOrdersRemoteProtocol {
451451
}
452452
}
453453

454+
public func updatePOSOrderEmail(siteID: Int64, orderID: Int64, emailAddress: String) async throws {
455+
let parameters: [String: Any] = [
456+
"billing": [
457+
"email": emailAddress
458+
]
459+
]
460+
461+
let path = "\(Constants.ordersPath)/\(orderID)"
462+
let request = JetpackRequest(wooApiVersion: .mark3,
463+
method: .post,
464+
siteID: siteID,
465+
path: path,
466+
parameters: parameters,
467+
availableAsRESTRequest: true)
468+
469+
try await enqueue(request)
470+
}
471+
454472
public func loadPOSOrders(siteID: Int64, pageNumber: Int, pageSize: Int) async throws -> PagedItems<Order> {
455473
let parameters: [String: Any] = [
456474
ParameterKeys.page: String(pageNumber),

Modules/Sources/NetworkingCore/Remote/POSOrdersRemoteProtocol.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Foundation
22

33
public protocol POSReceiptsRemoteProtocol {
44
func sendReceipt(siteID: Int64, orderID: Int64) async throws
5-
func sendPOSReceipt(siteID: Int64, orderID: Int64) async throws
5+
func sendPOSReceipt(siteID: Int64, orderID: Int64, emailAddress: String) async throws
66
}
77

88
public protocol POSOrdersRemoteProtocol {
@@ -11,6 +11,10 @@ public protocol POSOrdersRemoteProtocol {
1111
cashPaymentChangeDueAmount: String?,
1212
fields: [OrdersRemote.UpdateOrderField]) async throws -> Order
1313

14+
func updatePOSOrderEmail(siteID: Int64,
15+
orderID: Int64,
16+
emailAddress: String) async throws
17+
1418
func createPOSOrder(siteID: Int64,
1519
order: Order,
1620
fields: [OrdersRemote.CreateOrderField]) async throws -> Order

Modules/Sources/Storage/GRDB/Migrations/V001InitialSchema.swift

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ struct V001InitialSchema {
2929
// not derive them from a Swift class.
3030
// https://swiftpackageindex.com/groue/grdb.swift/v7.6.1/documentation/grdb/migrations#Good-Practices-for-Defining-Migrations
3131
try db.create(table: "product") { productTable in
32-
productTable.primaryKey("id", .integer).notNull()
32+
productTable.column("id", .integer).notNull()
33+
productTable.primaryKey(["siteID", "id"]) // SiteID column created by belongsTo relationship
3334
productTable.belongsTo("site", onDelete: .cascade).notNull()
3435

3536
productTable.column("name", .text).notNull()
@@ -56,7 +57,12 @@ struct V001InitialSchema {
5657
try db.create(table: "productAttribute") { productAttributeTable in
5758
// This table holds local product attributes only. Global attributes belong to a site.
5859
productAttributeTable.autoIncrementedPrimaryKey("id").notNull()
59-
productAttributeTable.belongsTo("product", onDelete: .cascade).notNull()
60+
productAttributeTable.column("siteID", .integer).notNull()
61+
productAttributeTable.column("productID", .integer).notNull()
62+
productAttributeTable.foreignKey(["siteID", "productID"],
63+
references: "product",
64+
columns: ["siteID", "id"],
65+
onDelete: .cascade)
6066

6167
productAttributeTable.column("name", .text).notNull()
6268
productAttributeTable.column("position", .integer).notNull()
@@ -68,8 +74,14 @@ struct V001InitialSchema {
6874

6975
private static func createProductImageTable(_ db: Database) throws {
7076
try db.create(table: "productImage") { productImageTable in
71-
productImageTable.primaryKey("id", .integer).notNull()
72-
productImageTable.belongsTo("product", onDelete: .cascade).notNull()
77+
productImageTable.column("siteID", .integer).notNull()
78+
productImageTable.column("id", .integer).notNull()
79+
productImageTable.primaryKey(["siteID", "id"])
80+
productImageTable.column("productID", .integer).notNull()
81+
productImageTable.foreignKey(["siteID", "productID"],
82+
references: "product",
83+
columns: ["siteID", "id"],
84+
onDelete: .cascade)
7385

7486
productImageTable.column("dateCreated", .datetime).notNull()
7587
productImageTable.column("dateModified", .datetime)
@@ -82,9 +94,14 @@ struct V001InitialSchema {
8294

8395
private static func createProductVariationTable(_ db: Database) throws {
8496
try db.create(table: "productVariation") { productVariationTable in
85-
productVariationTable.primaryKey("id", .integer).notNull()
97+
productVariationTable.column("id", .integer).notNull()
98+
productVariationTable.primaryKey(["siteID", "id"]) // SiteID column created by belongsTo relationship
99+
productVariationTable.column("productID", .integer).notNull()
86100
productVariationTable.belongsTo("site", onDelete: .cascade).notNull()
87-
productVariationTable.belongsTo("product", onDelete: .cascade).notNull()
101+
productVariationTable.foreignKey(["siteID", "productID"],
102+
references: "product",
103+
columns: ["siteID", "id"],
104+
onDelete: .cascade)
88105

89106
productVariationTable.column("sku", .text)
90107
productVariationTable.column("globalUniqueID", .text)
@@ -104,7 +121,12 @@ struct V001InitialSchema {
104121
try db.create(table: "productVariationAttribute") { productVariationAttributeTable in
105122
// This table holds local variation attributes only. Global attributes belong to a site.
106123
productVariationAttributeTable.autoIncrementedPrimaryKey("id").notNull()
107-
productVariationAttributeTable.belongsTo("productVariation", onDelete: .cascade).notNull()
124+
productVariationAttributeTable.column("siteID", .integer).notNull()
125+
productVariationAttributeTable.column("productVariationID", .integer).notNull()
126+
productVariationAttributeTable.foreignKey(["siteID", "productVariationID"],
127+
references: "productVariation",
128+
columns: ["siteID", "id"],
129+
onDelete: .cascade)
108130

109131
productVariationAttributeTable.column("name", .text).notNull()
110132
productVariationAttributeTable.column("option", .text).notNull()
@@ -113,8 +135,14 @@ struct V001InitialSchema {
113135

114136
private static func createProductVariationImageTable(_ db: Database) throws {
115137
try db.create(table: "productVariationImage") { productVariationImageTable in
116-
productVariationImageTable.primaryKey("id", .integer).notNull()
117-
productVariationImageTable.belongsTo("productVariation", onDelete: .cascade).notNull()
138+
productVariationImageTable.column("siteID", .integer).notNull()
139+
productVariationImageTable.column("id", .integer).notNull()
140+
productVariationImageTable.primaryKey(["siteID", "id"])
141+
productVariationImageTable.column("productVariationID", .integer).notNull()
142+
productVariationImageTable.foreignKey(["siteID", "productVariationID"],
143+
references: "productVariation",
144+
columns: ["siteID", "id"],
145+
onDelete: .cascade)
118146

119147
productVariationImageTable.column("dateCreated", .datetime).notNull()
120148
productVariationImageTable.column("dateModified", .datetime)

Modules/Sources/Storage/GRDB/Model/PersistedProduct.swift

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,33 @@ public struct PersistedProduct: Codable {
5353
extension PersistedProduct: FetchableRecord, PersistableRecord {
5454
public static var databaseTableName: String { "product" }
5555

56+
public static var primaryKey: [String] { [CodingKeys.siteID.stringValue, CodingKeys.id.stringValue] }
57+
5658
public enum Columns {
57-
static let id = Column(CodingKeys.id)
58-
static let siteID = Column(CodingKeys.siteID)
59-
static let name = Column(CodingKeys.name)
60-
static let productTypeKey = Column(CodingKeys.productTypeKey)
61-
static let fullDescription = Column(CodingKeys.fullDescription)
62-
static let shortDescription = Column(CodingKeys.shortDescription)
63-
static let sku = Column(CodingKeys.sku)
64-
static let globalUniqueID = Column(CodingKeys.globalUniqueID)
65-
static let price = Column(CodingKeys.price)
66-
static let downloadable = Column(CodingKeys.downloadable)
67-
static let parentID = Column(CodingKeys.parentID)
68-
static let manageStock = Column(CodingKeys.manageStock)
69-
static let stockQuantity = Column(CodingKeys.stockQuantity)
70-
static let stockStatusKey = Column(CodingKeys.stockStatusKey)
59+
public static let id = Column(CodingKeys.id)
60+
public static let siteID = Column(CodingKeys.siteID)
61+
public static let name = Column(CodingKeys.name)
62+
public static let productTypeKey = Column(CodingKeys.productTypeKey)
63+
public static let fullDescription = Column(CodingKeys.fullDescription)
64+
public static let shortDescription = Column(CodingKeys.shortDescription)
65+
public static let sku = Column(CodingKeys.sku)
66+
public static let globalUniqueID = Column(CodingKeys.globalUniqueID)
67+
public static let price = Column(CodingKeys.price)
68+
public static let downloadable = Column(CodingKeys.downloadable)
69+
public static let parentID = Column(CodingKeys.parentID)
70+
public static let manageStock = Column(CodingKeys.manageStock)
71+
public static let stockQuantity = Column(CodingKeys.stockQuantity)
72+
public static let stockStatusKey = Column(CodingKeys.stockStatusKey)
7173
}
7274

73-
public static let images = hasMany(PersistedProductImage.self)
74-
public static let attributes = hasMany(PersistedProductAttribute.self)
75+
public static let images = hasMany(PersistedProductImage.self,
76+
using: ForeignKey([PersistedProductImage.CodingKeys.siteID.stringValue,
77+
PersistedProductImage.CodingKeys.productID.stringValue],
78+
to: primaryKey))
79+
public static let attributes = hasMany(PersistedProductAttribute.self,
80+
using: ForeignKey([PersistedProductAttribute.CodingKeys.siteID.stringValue,
81+
PersistedProductAttribute.CodingKeys.productID.stringValue],
82+
to: primaryKey))
7583
}
7684

7785
// periphery:ignore - TODO: remove ignore when populating database

Modules/Sources/Storage/GRDB/Model/PersistedProductAttribute.swift

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import GRDB
44
// periphery:ignore - TODO: remove ignore when populating database
55
public struct PersistedProductAttribute: Codable {
66
public private(set) var id: Int64?
7+
public let siteID: Int64
78
public let productID: Int64
89
public let name: String
910
public let position: Int64
@@ -12,13 +13,15 @@ public struct PersistedProductAttribute: Codable {
1213
public let options: [String]
1314

1415
public init(id: Int64? = nil,
16+
siteID: Int64,
1517
productID: Int64,
1618
name: String,
1719
position: Int64,
1820
visible: Bool,
1921
variation: Bool,
2022
options: [String]) {
2123
self.id = id
24+
self.siteID = siteID
2225
self.productID = productID
2326
self.name = name
2427
self.position = position
@@ -32,26 +35,32 @@ public struct PersistedProductAttribute: Codable {
3235
extension PersistedProductAttribute: FetchableRecord, MutablePersistableRecord {
3336
public static var databaseTableName: String { "productAttribute" }
3437

38+
public static var primaryKey: [String] { [CodingKeys.id.stringValue] }
39+
3540
public enum Columns {
36-
static let id = Column(CodingKeys.id)
41+
public static let id = Column(CodingKeys.id)
42+
public static let siteID = Column(CodingKeys.siteID)
3743
public static let productID = Column(CodingKeys.productID)
38-
static let name = Column(CodingKeys.name)
39-
static let position = Column(CodingKeys.position)
40-
static let visible = Column(CodingKeys.visible)
41-
static let variation = Column(CodingKeys.variation)
42-
static let options = Column(CodingKeys.options)
44+
public static let name = Column(CodingKeys.name)
45+
public static let position = Column(CodingKeys.position)
46+
public static let visible = Column(CodingKeys.visible)
47+
public static let variation = Column(CodingKeys.variation)
48+
public static let options = Column(CodingKeys.options)
4349
}
4450

4551
public mutating func didInsert(_ inserted: InsertionSuccess) {
4652
id = inserted.rowID
4753
}
54+
55+
public static let product = belongsTo(PersistedProduct.self)
4856
}
4957

5058

5159
// periphery:ignore - TODO: remove ignore when populating database
52-
private extension PersistedProductAttribute {
60+
extension PersistedProductAttribute {
5361
enum CodingKeys: String, CodingKey {
5462
case id
63+
case siteID
5564
case productID
5665
case name
5766
case position

Modules/Sources/Storage/GRDB/Model/PersistedProductImage.swift

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import GRDB
33

44
// periphery:ignore - TODO: remove ignore when populating database
55
public struct PersistedProductImage: Codable {
6+
public let siteID: Int64
67
public let id: Int64
78
public let productID: Int64
89
public let dateCreated: Date
@@ -11,13 +12,15 @@ public struct PersistedProductImage: Codable {
1112
public let name: String?
1213
public let alt: String?
1314

14-
public init(id: Int64,
15+
public init(siteID: Int64,
16+
id: Int64,
1517
productID: Int64,
1618
dateCreated: Date,
1719
dateModified: Date?,
1820
src: String,
1921
name: String?,
2022
alt: String?) {
23+
self.siteID = siteID
2124
self.id = id
2225
self.productID = productID
2326
self.dateCreated = dateCreated
@@ -32,21 +35,25 @@ public struct PersistedProductImage: Codable {
3235
extension PersistedProductImage: FetchableRecord, PersistableRecord {
3336
public static var databaseTableName: String { "productImage" }
3437

38+
public static var primaryKey: [String] { [CodingKeys.siteID.stringValue, CodingKeys.id.stringValue] }
39+
3540
public enum Columns {
36-
static let id = Column(CodingKeys.id)
41+
public static let siteID = Column(CodingKeys.siteID)
42+
public static let id = Column(CodingKeys.id)
3743
public static let productID = Column(CodingKeys.productID)
38-
static let dateCreated = Column(CodingKeys.dateCreated)
39-
static let dateModified = Column(CodingKeys.dateModified)
40-
static let src = Column(CodingKeys.src)
41-
static let name = Column(CodingKeys.name)
42-
static let alt = Column(CodingKeys.alt)
44+
public static let dateCreated = Column(CodingKeys.dateCreated)
45+
public static let dateModified = Column(CodingKeys.dateModified)
46+
public static let src = Column(CodingKeys.src)
47+
public static let name = Column(CodingKeys.name)
48+
public static let alt = Column(CodingKeys.alt)
4349
}
4450
}
4551

4652

4753
// periphery:ignore - TODO: remove ignore when populating database
48-
private extension PersistedProductImage {
54+
extension PersistedProductImage {
4955
enum CodingKeys: String, CodingKey {
56+
case siteID
5057
case id
5158
case productID
5259
case dateCreated

0 commit comments

Comments
 (0)