This repository has been archived by the owner on Nov 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 742
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #141 from ILIYANGERMANOV/develop
Milestone progress
- Loading branch information
Showing
19 changed files
with
452 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
app/src/main/java/com/ivy/wallet/logic/SmartTitleSuggestionsLogic.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package com.ivy.wallet.logic | ||
|
||
import com.ivy.wallet.base.capitalizeWords | ||
import com.ivy.wallet.base.isNotNullOrBlank | ||
import com.ivy.wallet.model.entity.Transaction | ||
import com.ivy.wallet.persistence.dao.TransactionDao | ||
import com.ivy.wallet.ui.edit.core.SUGGESTIONS_LIMIT | ||
import java.util.* | ||
|
||
class SmartTitleSuggestionsLogic( | ||
private val transactionDao: TransactionDao | ||
) { | ||
|
||
/** | ||
* Suggests titles based on: | ||
* - title match | ||
* - most used titles for categories | ||
* - if suggestions.size < SUGGESTIONS_LIMIT most used titles for accounts | ||
*/ | ||
fun suggest( | ||
title: String?, | ||
categoryId: UUID?, | ||
accountId: UUID? | ||
): Set<String> { | ||
val suggestions = mutableSetOf<String>() | ||
|
||
if (title != null && title.isNotEmpty()) { | ||
//suggest by title | ||
val suggestionsByTitle = transactionDao.findAllByTitleMatchingPattern("${title}%") | ||
.extractUniqueTitles() | ||
.sortedByMostUsedFirst { | ||
transactionDao.countByTitleMatchingPattern("${it}%") | ||
} | ||
|
||
suggestions.addAll(suggestionsByTitle) | ||
} | ||
|
||
if (categoryId != null) { | ||
//suggest by category | ||
//all titles used for the specific category | ||
//ordered by N times used | ||
|
||
val suggestionsByCategory = transactionDao | ||
.findAllByCategory( | ||
categoryId = categoryId | ||
) | ||
//exclude already suggested suggestions so they're ordered by priority at the end | ||
.extractUniqueTitles(excludeSuggestions = suggestions) | ||
.sortedByMostUsedFirst { | ||
transactionDao.countByTitleMatchingPatternAndCategoryId( | ||
pattern = it, | ||
categoryId = categoryId | ||
) | ||
} | ||
|
||
suggestions.addAll(suggestionsByCategory) | ||
} | ||
|
||
|
||
if (suggestions.size < SUGGESTIONS_LIMIT && accountId != null) { | ||
//last resort, suggest by account | ||
//all titles used for the specific account | ||
//ordered by N times used | ||
|
||
val suggestionsByAccount = transactionDao | ||
.findAllByAccount( | ||
accountId = accountId | ||
) | ||
//exclude already suggested suggestions so they're ordered by priority at the end | ||
.extractUniqueTitles(excludeSuggestions = suggestions) | ||
.sortedByMostUsedFirst { | ||
transactionDao.countByTitleMatchingPatternAndAccountId( | ||
pattern = it, | ||
accountId = accountId | ||
) | ||
} | ||
|
||
suggestions.addAll(suggestionsByAccount) | ||
} | ||
|
||
return suggestions | ||
.filter { it != title } | ||
.toSet() | ||
} | ||
} | ||
|
||
private fun List<Transaction>.extractUniqueTitles( | ||
excludeSuggestions: Set<String>? = null | ||
): Set<String> { | ||
return this | ||
.filter { it.title.isNotNullOrBlank() } | ||
.map { it.title!!.trim().capitalizeWords() } | ||
.filter { excludeSuggestions == null || !excludeSuggestions.contains(it) } | ||
.toSet() | ||
} | ||
|
||
private fun Set<String>.sortedByMostUsedFirst(countUses: (String) -> Long): Set<String> { | ||
val titleCountMap = this | ||
.map { | ||
it to countUses(it) | ||
} | ||
.toMap() | ||
|
||
val sortedSuggestions = this | ||
.sortedByDescending { | ||
titleCountMap.getOrDefault(it, 0) | ||
} | ||
.toSet() | ||
|
||
return sortedSuggestions | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.