Skip to content

Commit 4b4f412

Browse files
authored
Merge pull request #710 from Syn-McJ/feat/dashspend-filter-improvements
feat(dashspend): filter improvements
2 parents 854f6ea + 9658add commit 4b4f412

73 files changed

Lines changed: 1808 additions & 1738 deletions

File tree

Some content is hidden

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

DashWallet.xcodeproj/project.pbxproj

Lines changed: 29 additions & 61 deletions
Large diffs are not rendered by default.

DashWallet/Sources/Models/Explore Dash/ExploreDash.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,23 +167,23 @@ public class ExploreDash {
167167

168168
extension ExploreDash {
169169
func onlineMerchants(query: String?, onlineOnly: Bool, paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?,
170-
userPoint: CLLocationCoordinate2D?, offset: Int = 0,
170+
sortBy: PointOfUseListFilters.SortBy?, userPoint: CLLocationCoordinate2D?, denominationType: PointOfUseListFilters.DenominationType?, offset: Int = 0,
171171
completion: @escaping (Swift.Result<PaginationResult<ExplorePointOfUse>, Error>) -> Void) {
172-
merchantDAO.onlineMerchants(query: query, onlineOnly: onlineOnly, userPoint: userPoint, paymentMethods: paymentMethods, offset: offset, completion: completion)
172+
merchantDAO.onlineMerchants(query: query, onlineOnly: onlineOnly, userPoint: userPoint, sortBy: sortBy, paymentMethods: paymentMethods, denominationType: denominationType, offset: offset, completion: completion)
173173
}
174174

175175
func nearbyMerchants(by query: String?, in bounds: ExploreMapBounds?, userPoint: CLLocationCoordinate2D?,
176-
paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?, sortBy: PointOfUseListFilters.SortBy?, territory: Territory?, offset: Int = 0,
176+
paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?, sortBy: PointOfUseListFilters.SortBy?, territory: Territory?, denominationType: PointOfUseListFilters.DenominationType?, offset: Int = 0,
177177
completion: @escaping (Swift.Result<PaginationResult<ExplorePointOfUse>, Error>) -> Void) {
178-
merchantDAO.nearbyMerchants(by: query, in: bounds, userPoint: userPoint, paymentMethods: paymentMethods, sortBy: sortBy, territory: territory, offset: offset, completion: completion)
178+
merchantDAO.nearbyMerchants(by: query, in: bounds, userPoint: userPoint, paymentMethods: paymentMethods, sortBy: sortBy, territory: territory, denominationType: denominationType, offset: offset, completion: completion)
179179
}
180180

181181
func allMerchants(by query: String?, in bounds: ExploreMapBounds?, userPoint: CLLocationCoordinate2D?,
182182
paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?,
183183
sortBy: PointOfUseListFilters.SortBy?,
184-
territory: Territory?, offset: Int = 0,
184+
territory: Territory?, denominationType: PointOfUseListFilters.DenominationType?, offset: Int = 0,
185185
completion: @escaping (Swift.Result<PaginationResult<ExplorePointOfUse>, Error>) -> Void) {
186-
merchantDAO.allMerchants(by: query, in: bounds, userPoint: userPoint, paymentMethods: paymentMethods, sortBy: sortBy, territory: territory, offset: offset, completion: completion)
186+
merchantDAO.allMerchants(by: query, in: bounds, userPoint: userPoint, paymentMethods: paymentMethods, sortBy: sortBy, territory: territory, denominationType: denominationType, offset: offset, completion: completion)
187187
}
188188

189189
func allLocations(for merchantId: String, in bounds: ExploreMapBounds?, userPoint: CLLocationCoordinate2D?,

DashWallet/Sources/Models/Explore Dash/Infrastructure/DAO Impl/MerchantDAO.swift

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class MerchantDAO: PointOfUseDAO {
4646
paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?,
4747
sortBy: PointOfUseListFilters.SortBy?,
4848
territory: Territory?,
49+
denominationType: PointOfUseListFilters.DenominationType?,
4950
offset: Int,
5051
completion: @escaping (Swift.Result<PaginationResult<Item>, Error>) -> Void) {
5152
serialQueue.async { [weak self] in
@@ -56,6 +57,7 @@ class MerchantDAO: PointOfUseDAO {
5657
let typeColumn = ExplorePointOfUse.type
5758
let paymentMethodColumn = ExplorePointOfUse.paymentMethod
5859
let territoryColumn = ExplorePointOfUse.territory
60+
let denominationsTypeColumn = ExplorePointOfUse.denominationsType
5961

6062
var queryFilter = Expression<Bool>(value: true)
6163

@@ -70,6 +72,21 @@ class MerchantDAO: PointOfUseDAO {
7072
if let methods = paymentMethods {
7173
queryFilter = queryFilter && methods.map { $0.rawValue }.contains(paymentMethodColumn)
7274
}
75+
76+
// Add denomination type filter (only applies to gift card merchants)
77+
if let denominationType = denominationType {
78+
switch denominationType {
79+
case .fixed:
80+
// Include all dash merchants OR gift card merchants with "fixed" denomination
81+
queryFilter = queryFilter && (paymentMethodColumn == "dash" || Expression<Bool>(literal: "denominationsType = 'fixed'"))
82+
case .flexible:
83+
// Include all dash merchants OR gift card merchants with "min-max" denomination
84+
queryFilter = queryFilter && (paymentMethodColumn == "dash" || Expression<Bool>(literal: "denominationsType = 'min-max'"))
85+
case .both:
86+
// No additional filter needed - include all
87+
break
88+
}
89+
}
7390

7491
if let territory {
7592
queryFilter = queryFilter && territoryColumn.like(territory)
@@ -110,9 +127,21 @@ class MerchantDAO: PointOfUseDAO {
110127
}
111128

112129
let nameOrdering = name.collate(.nocase).asc
113-
114-
if let sortBy, sortBy == .name {
115-
query = query.order(nameOrdering)
130+
let discountOrdering = ExplorePointOfUse.savingPercentage.desc
131+
132+
if let sortBy {
133+
switch sortBy {
134+
case .name:
135+
query = query.order(nameOrdering)
136+
case .distance:
137+
if userLocation != nil {
138+
query = query.order([distanceSorting, nameOrdering])
139+
} else {
140+
query = query.order(nameOrdering)
141+
}
142+
case .discount:
143+
query = query.order([discountOrdering, nameOrdering])
144+
}
116145
} else if userLocation != nil {
117146
query = query.order([distanceSorting, nameOrdering])
118147
} else if bounds == nil && types.count == 3 {
@@ -144,24 +173,24 @@ class MerchantDAO: PointOfUseDAO {
144173
}
145174

146175
extension MerchantDAO {
147-
func onlineMerchants(query: String?, onlineOnly: Bool, userPoint: CLLocationCoordinate2D?,
148-
paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?, offset: Int = 0,
176+
func onlineMerchants(query: String?, onlineOnly: Bool, userPoint: CLLocationCoordinate2D?, sortBy: PointOfUseListFilters.SortBy?,
177+
paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?, denominationType: PointOfUseListFilters.DenominationType?, offset: Int = 0,
149178
completion: @escaping (Swift.Result<PaginationResult<ExplorePointOfUse>, Error>) -> Void) {
150179
items(query: query, bounds: nil, userLocation: userPoint, types: [.online, .onlineAndPhysical],
151-
paymentMethods: paymentMethods, sortBy: nil, territory: nil, offset: offset, completion: completion)
180+
paymentMethods: paymentMethods, sortBy: sortBy, territory: nil, denominationType: denominationType, offset: offset, completion: completion)
152181
}
153182

154183
func nearbyMerchants(by query: String?, in bounds: ExploreMapBounds?, userPoint: CLLocationCoordinate2D?,
155-
paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?, sortBy: PointOfUseListFilters.SortBy?, territory: Territory?, offset: Int = 0,
184+
paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?, sortBy: PointOfUseListFilters.SortBy?, territory: Territory?, denominationType: PointOfUseListFilters.DenominationType?, offset: Int = 0,
156185
completion: @escaping (Swift.Result<PaginationResult<ExplorePointOfUse>, Error>) -> Void) {
157186
items(query: query, bounds: bounds, userLocation: userPoint, types: [.physical, .onlineAndPhysical],
158-
paymentMethods: paymentMethods, sortBy: sortBy, territory: territory, offset: offset, completion: completion)
187+
paymentMethods: paymentMethods, sortBy: sortBy, territory: territory, denominationType: denominationType, offset: offset, completion: completion)
159188
}
160189

161190
func allMerchants(by query: String?, in bounds: ExploreMapBounds?, userPoint: CLLocationCoordinate2D?,
162-
paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?, sortBy: PointOfUseListFilters.SortBy?, territory: Territory?, offset: Int = 0,
191+
paymentMethods: [ExplorePointOfUse.Merchant.PaymentMethod]?, sortBy: PointOfUseListFilters.SortBy?, territory: Territory?, denominationType: PointOfUseListFilters.DenominationType?, offset: Int = 0,
163192
completion: @escaping (Swift.Result<PaginationResult<ExplorePointOfUse>, Error>) -> Void) {
164-
items(query: query, bounds: bounds, userLocation: userPoint, types: [.online, .onlineAndPhysical, .physical], paymentMethods: paymentMethods, sortBy: sortBy, territory: territory, offset: offset,
193+
items(query: query, bounds: bounds, userLocation: userPoint, types: [.online, .onlineAndPhysical, .physical], paymentMethods: paymentMethods, sortBy: sortBy, territory: territory, denominationType: denominationType, offset: offset,
165194
completion: completion)
166195
}
167196

DashWallet/Sources/Models/Explore Dash/Model/DAO/GiftCardsDAO.swift

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ import Combine
2222
// MARK: - GiftCardsDAO
2323

2424
protocol GiftCardsDAO {
25+
var giftCardTxIdPublisher: AnyPublisher<Data?, Never> { get }
26+
2527
func create(dto: GiftCard) async
2628
func get(byTxId txId: Data) async -> GiftCard?
27-
func observeCard(byTxId txId: Data) -> AnyPublisher<GiftCard?, Never>
2829
func observeAll() -> AnyPublisher<[GiftCard], Never>
2930
func update(dto: GiftCard) async
3031
func updateCardDetails(txId: Data, number: String, pin: String?) async
@@ -38,9 +39,13 @@ protocol GiftCardsDAO {
3839
class GiftCardsDAOImpl: NSObject, GiftCardsDAO {
3940
private var db: Connection { DatabaseConnection.shared.db }
4041
private var cache: [String: GiftCard] = [:]
41-
private var subjects: [String: CurrentValueSubject<GiftCard?, Never>] = [:]
42+
@Published private var giftCardTxId: Data?
4243
private var allCardsSubject = CurrentValueSubject<[GiftCard], Never>([])
4344

45+
var giftCardTxIdPublisher: AnyPublisher<Data?, Never> {
46+
$giftCardTxId.eraseToAnyPublisher()
47+
}
48+
4449
static let shared = GiftCardsDAOImpl()
4550

4651
override init() {
@@ -65,7 +70,7 @@ class GiftCardsDAOImpl: NSObject, GiftCardsDAO {
6570
try await execute(insert)
6671
let key = dto.txId.hexEncodedString()
6772
self.cache[key] = dto
68-
self.subjects[key]?.send(dto)
73+
self.giftCardTxId = dto.txId
6974
updateAllCardsSubject()
7075
} catch {
7176
print(error)
@@ -87,20 +92,6 @@ class GiftCardsDAOImpl: NSObject, GiftCardsDAO {
8792
return nil
8893
}
8994

90-
func observeCard(byTxId txId: Data) -> AnyPublisher<GiftCard?, Never> {
91-
let key = txId.hexEncodedString()
92-
93-
if subjects[key] == nil {
94-
subjects[key] = CurrentValueSubject<GiftCard?, Never>(cache[key])
95-
96-
Task {
97-
let card = await get(byTxId: txId)
98-
subjects[key]?.send(card)
99-
}
100-
}
101-
102-
return subjects[key]!.eraseToAnyPublisher()
103-
}
10495

10596
func observeAll() -> AnyPublisher<[GiftCard], Never> {
10697
return allCardsSubject.eraseToAnyPublisher()
@@ -133,7 +124,7 @@ class GiftCardsDAOImpl: NSObject, GiftCardsDAO {
133124
)
134125
let key = txId.hexEncodedString()
135126
cache[key] = updatedCard
136-
subjects[key]?.send(updatedCard)
127+
self.giftCardTxId = txId
137128
updateAllCardsSubject()
138129
}
139130
} catch {
@@ -163,7 +154,7 @@ class GiftCardsDAOImpl: NSObject, GiftCardsDAO {
163154
)
164155
let key = txId.hexEncodedString()
165156
cache[key] = updatedCard
166-
subjects[key]?.send(updatedCard)
157+
self.giftCardTxId = txId
167158
updateAllCardsSubject()
168159
}
169160
} catch {
@@ -174,7 +165,7 @@ class GiftCardsDAOImpl: NSObject, GiftCardsDAO {
174165
func delete(byTxId txId: Data) async {
175166
let key = txId.hexEncodedString()
176167
self.cache[key] = nil
177-
self.subjects[key]?.send(nil)
168+
self.giftCardTxId = txId
178169

179170
do {
180171
let deleteQuery = GiftCard.table.filter(GiftCard.txId == txId).delete()

DashWallet/Sources/Models/Explore Dash/Model/Entites/CTXSpendModels.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,6 @@ struct MerchantInfo: Codable {
147147
}
148148

149149
enum DenominationType: String, Codable {
150-
case Range = "range"
150+
case Range = "min-max"
151151
case Fixed = "fixed"
152152
}

DashWallet/Sources/Models/Explore Dash/Model/Entites/ExplorePointOfUse.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ extension ExplorePointOfUse {
5858
let type: `Type`
5959
let deeplink: String?
6060
let savingsBasisPoints: Int // in basis points 1 = 0.001%
61+
let denominationsType: String?
6162

6263
func toSavingPercentages() -> Double {
6364
return Double(savingsBasisPoints) / 100
@@ -191,6 +192,7 @@ extension ExplorePointOfUse: RowDecodable {
191192
static let source = Expression<String>("source")
192193
static let manufacturer = Expression<String?>("manufacturer")
193194
static let savingPercentage = Expression<Int>("savingsPercentage")
195+
static let denominationsType = Expression<String?>("denominationsType")
194196

195197
init(row: Row) {
196198
let name = row[ExplorePointOfUse.name]
@@ -227,9 +229,9 @@ extension ExplorePointOfUse: RowDecodable {
227229
let type: Merchant.`Type`! = .init(rawValue: row[ExplorePointOfUse.type])
228230
let deeplink = row[ExplorePointOfUse.deeplink]
229231
let savingsPercentage = row[ExplorePointOfUse.savingPercentage]
230-
category = .merchant(Merchant(merchantId: merchantId,
231-
paymentMethod: Merchant.PaymentMethod(rawValue: paymentMethodRaw)!,
232-
type: type, deeplink: deeplink, savingsBasisPoints: savingsPercentage))
232+
let denominationsType = row[ExplorePointOfUse.denominationsType]
233+
category = .merchant(Merchant(merchantId: merchantId, paymentMethod: Merchant.PaymentMethod(rawValue: paymentMethodRaw)!,
234+
type: type, deeplink: deeplink, savingsBasisPoints: savingsPercentage, denominationsType: denominationsType))
233235
} else if let manufacturer = try? row.get(ExplorePointOfUse.manufacturer) {
234236
let type: Atm.`Type`! = .init(rawValue: row[ExplorePointOfUse.type])
235237
category = .atm(Atm(manufacturer: manufacturer, type: type))

0 commit comments

Comments
 (0)