Skip to content

Commit

Permalink
Merge pull request #188 from ILIYANGERMANOV/loans
Browse files Browse the repository at this point in the history
WIP Loans + easy improvements
  • Loading branch information
ILIYANGERMANOV committed Nov 27, 2021
2 parents ef40024 + 48cd7f5 commit cbd7843
Show file tree
Hide file tree
Showing 44 changed files with 2,405 additions and 114 deletions.
757 changes: 757 additions & 0 deletions app/schemas/com.ivy.wallet.persistence.IvyRoomDatabase/119.json

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions app/src/main/java/com/ivy/wallet/base/UIExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import android.view.inputmethod.InputMethodManager
import androidx.annotation.FloatRange
import androidx.annotation.RequiresApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalView
Expand All @@ -32,6 +35,23 @@ import androidx.core.view.doOnLayout
import kotlin.math.roundToInt


@Composable
fun keyboardVisibleState(): State<Boolean> {
val rootView = LocalView.current

val keyboardVisible = remember {
mutableStateOf(false)
}

onScreenStart {
rootView.addKeyboardListener {
keyboardVisible.value = it
}
}

return keyboardVisible
}

fun View.addKeyboardListener(keyboardCallback: (visible: Boolean) -> Unit) {
doOnLayout {
//get init state of keyboard
Expand Down
83 changes: 83 additions & 0 deletions app/src/main/java/com/ivy/wallet/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ object AppModule {
@Provides
fun provideSettingsDao(db: IvyRoomDatabase): SettingsDao = db.settingsDao()

@Provides
fun provideLoanDao(db: IvyRoomDatabase): LoanDao = db.loanDao()

@Provides
fun provideLoanRecordDao(db: IvyRoomDatabase): LoanRecordDao = db.loanRecordDao()

@Provides
fun provideTrnRecurringRuleDao(db: IvyRoomDatabase): PlannedPaymentRuleDao =
db.plannedPaymentRuleDao()
Expand Down Expand Up @@ -226,6 +232,32 @@ object AppModule {
)
}

@Provides
fun provideLoanUploader(
loanDao: LoanDao,
restClient: RestClient,
ivySession: IvySession
): LoanUploader {
return LoanUploader(
dao = loanDao,
restClient = restClient,
ivySession = ivySession
)
}

@Provides
fun provideLoanRecordUploader(
dao: LoanRecordDao,
restClient: RestClient,
ivySession: IvySession
): LoanRecordUploader {
return LoanRecordUploader(
dao = dao,
restClient = restClient,
ivySession = ivySession
)
}

@Provides
fun provideCategorySync(
sharedPrefs: SharedPrefs,
Expand Down Expand Up @@ -260,6 +292,40 @@ object AppModule {
)
}

@Provides
fun provideLoanSync(
sharedPrefs: SharedPrefs,
dao: LoanDao,
restClient: RestClient,
loanUploader: LoanUploader,
ivySession: IvySession
): LoanSync {
return LoanSync(
sharedPrefs = sharedPrefs,
dao = dao,
restClient = restClient,
uploader = loanUploader,
ivySession = ivySession
)
}

@Provides
fun provideLoanRecordSync(
sharedPrefs: SharedPrefs,
dao: LoanRecordDao,
restClient: RestClient,
uploader: LoanRecordUploader,
ivySession: IvySession
): LoanRecordSync {
return LoanRecordSync(
sharedPrefs = sharedPrefs,
dao = dao,
restClient = restClient,
uploader = uploader,
ivySession = ivySession
)
}

@Provides
fun provideTransactionUploader(
transactionDao: TransactionDao,
Expand Down Expand Up @@ -328,6 +394,8 @@ object AppModule {
transactionSync: TransactionSync,
plannedPaymentSync: PlannedPaymentSync,
budgetSync: BudgetSync,
loanSync: LoanSync,
loanRecordSync: LoanRecordSync,
ivySession: IvySession
): IvySync {
return IvySync(
Expand All @@ -336,6 +404,8 @@ object AppModule {
transactionSync = transactionSync,
plannedPaymentSync = plannedPaymentSync,
budgetSync = budgetSync,
loanSync = loanSync,
loanRecordSync = loanRecordSync,
ivySession = ivySession
)
}
Expand Down Expand Up @@ -518,6 +588,19 @@ object AppModule {
)
}

@Provides
fun provideLoanCreator(
paywallLogic: PaywallLogic,
dao: LoanDao,
uploader: LoanUploader
): LoanCreator {
return LoanCreator(
paywallLogic = paywallLogic,
dao = dao,
uploader = uploader
)
}

@Provides
fun provideAccountCreator(
paywallLogic: PaywallLogic,
Expand Down
99 changes: 99 additions & 0 deletions app/src/main/java/com/ivy/wallet/logic/LoanCreator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.ivy.wallet.logic

import androidx.compose.ui.graphics.toArgb
import com.ivy.wallet.base.ioThread
import com.ivy.wallet.logic.model.CreateLoanData
import com.ivy.wallet.model.entity.Loan
import com.ivy.wallet.persistence.dao.LoanDao
import com.ivy.wallet.sync.uploader.LoanUploader

class LoanCreator(
private val paywallLogic: PaywallLogic,
private val dao: LoanDao,
private val uploader: LoanUploader
) {
suspend fun create(
data: CreateLoanData,
onRefreshUI: suspend (Loan) -> Unit
) {
val name = data.name
if (name.isBlank()) return
if (data.amount <= 0) return

try {
paywallLogic.protectAddWithPaywall(
//TODO: Handle addLoan = true
// addBudget = true,
) {
val newItem = ioThread {
val item = Loan(
name = name.trim(),
amount = data.amount,
type = data.type,
color = data.color.toArgb(),
icon = data.icon,
orderNum = dao.findMaxOrderNum() + 1,
isSynced = false
)

dao.save(item)
item
}

onRefreshUI(newItem)

ioThread {
uploader.sync(newItem)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}


suspend fun edit(
updatedItem: Loan,
onRefreshUI: suspend (Loan) -> Unit
) {
if (updatedItem.name.isBlank()) return
if (updatedItem.amount <= 0.0) return

try {
ioThread {
dao.save(
updatedItem.copy(
isSynced = false
)
)
}

onRefreshUI(updatedItem)

ioThread {
uploader.sync(updatedItem)
}
} catch (e: Exception) {
e.printStackTrace()
}
}

suspend fun delete(
item: Loan,
onRefreshUI: suspend () -> Unit
) {
try {
ioThread {
dao.flagDeleted(item.id)
}

onRefreshUI()

ioThread {
uploader.delete(item.id)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
1 change: 1 addition & 0 deletions app/src/main/java/com/ivy/wallet/logic/PaywallLogic.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class PaywallLogic(
addCategory: Boolean = false,
addBudget: Boolean = false,
action: suspend () -> Unit
//TODO: Handle loan
) {
val paywallReason = checkPaywall {
paywallHitAddItem(
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/java/com/ivy/wallet/logic/model/CreateLoanData.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.ivy.wallet.logic.model

import androidx.compose.ui.graphics.Color
import com.ivy.wallet.model.LoanType

data class CreateLoanData(
val name: String,
val amount: Double,
val type: LoanType,
val color: Color,
val icon: String?
)
5 changes: 5 additions & 0 deletions app/src/main/java/com/ivy/wallet/model/LoanType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.ivy.wallet.model

enum class LoanType {
BORROW, LEND
}
29 changes: 29 additions & 0 deletions app/src/main/java/com/ivy/wallet/model/entity/Loan.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.ivy.wallet.model.entity

import androidx.room.Entity
import androidx.room.PrimaryKey
import com.ivy.wallet.model.LoanType
import com.ivy.wallet.model.Reorderable
import java.util.*

@Entity(tableName = "loans")
data class Loan(
val name: String,
val amount: Double,
val type: LoanType,
val color: Int = 0,
val icon: String? = null,
val orderNum: Double = 0.0,

val isSynced: Boolean = false,
val isDeleted: Boolean = false,

@PrimaryKey
val id: UUID = UUID.randomUUID()
) : Reorderable {
override fun getItemOrderNum() = orderNum

override fun withNewOrderNum(newOrderNum: Double) = this.copy(
orderNum = newOrderNum
)
}
20 changes: 20 additions & 0 deletions app/src/main/java/com/ivy/wallet/model/entity/LoanRecord.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.ivy.wallet.model.entity

import androidx.room.Entity
import androidx.room.PrimaryKey
import java.time.LocalDateTime
import java.util.*

@Entity(tableName = "loan_records")
data class LoanRecord(
val loanId: UUID,
val amount: Double,
val note: String?,
val dateTime: LocalDateTime,

val isSynced: Boolean = false,
val isDeleted: Boolean = false,

@PrimaryKey
val id: UUID = UUID.randomUUID()
)
1 change: 1 addition & 0 deletions app/src/main/java/com/ivy/wallet/network/RestClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ class RestClient private constructor(
val categoryService: CategoryService by lazy { retrofit.create(CategoryService::class.java) }
val accountService: AccountService by lazy { retrofit.create(AccountService::class.java) }
val budgetService: BudgetService by lazy { retrofit.create(BudgetService::class.java) }
val loanService: LoanService by lazy { retrofit.create(LoanService::class.java) }
val transactionService: TransactionService by lazy { retrofit.create(TransactionService::class.java) }
val plannedPaymentRuleService: PlannedPaymentRuleService by lazy {
retrofit.create(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ivy.wallet.network.request.loan

import java.util.*

data class DeleteLoanRecordRequest(
val id: UUID? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ivy.wallet.network.request.loan

import java.util.*

data class DeleteLoanRequest(
val id: UUID? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ivy.wallet.network.request.loan

import com.ivy.wallet.model.entity.LoanRecord

data class LoanRecordsResponse(
val loanRecords: List<LoanRecord>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ivy.wallet.network.request.loan

import com.ivy.wallet.model.entity.Loan

data class LoansResponse(
val loans: List<Loan>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ivy.wallet.network.request.loan

import com.ivy.wallet.model.entity.LoanRecord

data class UpdateLoanRecordRequest(
val loanRecord: LoanRecord? = null
)
Loading

0 comments on commit cbd7843

Please sign in to comment.