Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import org.junit.Test
- import java.util.Date
- class Ledger(val ledgerId: String) {
- var balance: Double = 0.0
- var credit: Double = 0.0
- var locked: Double = 0.0
- val balanceHistory = ArrayList<BalanceLog>()
- val lockHistory = ArrayList<LockLog>()
- @Synchronized
- fun lock(lockId: String, amount: Double, metaData: Map<String, Any> = mapOf()): Boolean {
- if (lockHistory.filter { it.lockId == lockId }.isEmpty()) {
- if (getAvailable() >= amount) {
- locked += amount
- addLockLog(lockId, amount, metaData)
- return true
- } else {
- return false
- }
- } else {
- return true
- }
- }
- @Synchronized
- fun unlock(lockId: String): Boolean {
- val lockLog = lockHistory.filter { it.lockId == lockId }.firstOrNull()
- if (lockLog != null) {
- if (!lockLog.unlocked) {
- locked -= lockLog.dealtAmount
- lockLog.unlocked = true
- return true
- } else {
- return false
- }
- } else {
- return true
- }
- }
- @Synchronized
- fun debit(
- updateId: String,
- amount: Double,
- metaData: Map<String, Any> = mapOf(),
- lockedId: String? = null
- ): Boolean {
- if (balanceHistory.filter { it.updateId == updateId }.isEmpty()) {
- if (lockedId != null) {
- unlock(lockedId)
- }
- if (getAvailable() >= amount) {
- addBalanceLog(updateId, -amount, metaData)
- return true
- } else {
- return false
- }
- } else {
- return true
- }
- }
- @Synchronized
- fun credit(updateId: String, amount: Double, metaData: Map<String, Any> = mapOf()): Boolean {
- if (balanceHistory.filter { it.updateId == updateId }.isEmpty()) {
- addBalanceLog(updateId, amount, metaData)
- return true
- } else {
- return true
- }
- }
- private fun getAvailable(): Double {
- return balance + credit - locked
- }
- private fun addLockLog(lockId: String, amount: Double, metaData: Map<String, Any>) {
- lockHistory.add(
- LockLog(
- lockId = lockId,
- balance = balance,
- credit = credit,
- locked = locked,
- dealtAmount = amount,
- metaData = metaData
- )
- )
- }
- private fun addBalanceLog(updateId: String, amount: Double, metaData: Map<String, Any>) {
- val newBalance = balance + amount
- balanceHistory.add(
- BalanceLog(
- updateId = updateId,
- dealtAmount = amount,
- lastBalance = balance,
- balance = newBalance,
- credit = credit,
- locked = locked,
- metaData = metaData
- )
- )
- balance = newBalance
- }
- }
- data class BalanceLog(
- val updateId: String,
- val lastBalance: Double,
- val balance: Double,
- val credit: Double,
- val locked: Double,
- val dealtAmount: Double,
- val metaData: Map<String, Any>,
- val createAt: Date = Date()
- )
- data class LockLog(
- val lockId: String,
- val balance: Double = 0.0,
- val credit: Double = 0.0,
- val locked: Double = 0.0,
- val dealtAmount: Double = 0.0,
- val metaData: Map<String, Any>,
- var unlocked: Boolean = false,
- val createAt: Date = Date()
- )
- class WalletTest {
- @Test
- fun test() {
- val ledger = Ledger("my:USD")
- ledger.credit = 40.0
- println(ledger.credit("c1", 50.0, mapOf()))
- println(ledger.lock("l1", 60.0))
- println(ledger.lock("l2", 60.0))
- println(ledger.lock("l3", 20.0)) // failed
- println(ledger.debit("d0", 10.0, mapOf()))
- println(ledger.debit("d1", 60.0, mapOf(), "l1"))
- println(ledger.debit("d2", 20.0, mapOf(), "l2")) // failed
- println(ledger.debit("d3", 10.0, mapOf(), "l3"))
- println("balances: " + ledger.balanceHistory.map { "\n" + it.toString() })
- println("locks: " + ledger.lockHistory.map { "\n" + it.toString() })
- //
- println("all balance spends: " + ledger.balanceHistory.filter { it.lastBalance >= 0 && it.dealtAmount < 0 }
- .map { if (it.balance > 0) -it.dealtAmount else it.lastBalance }.sum())
- println("all credit spends: " + ledger.balanceHistory.filter { it.balance < 0 && it.dealtAmount < 0 }
- .map { if (it.lastBalance > 0) it.lastBalance + it.balance else -it.dealtAmount }.sum())
- /** test result
- balances: [
- BalanceLog(updateId=c1, lastBalance=0.0, balance=50.0, credit=40.0, locked=0.0, dealtAmount=50.0, metaData={}, createAt=Fri Sep 06 16:02:16 AEST 2019),
- BalanceLog(updateId=d0, lastBalance=50.0, balance=40.0, credit=40.0, locked=80.0, dealtAmount=-10.0, metaData={}, createAt=Fri Sep 06 16:02:16 AEST 2019),
- BalanceLog(updateId=d1, lastBalance=40.0, balance=-20.0, credit=40.0, locked=20.0, dealtAmount=-60.0, metaData={}, createAt=Fri Sep 06 16:02:16 AEST 2019),
- BalanceLog(updateId=d3, lastBalance=-20.0, balance=-30.0, credit=40.0, locked=0.0, dealtAmount=-10.0, metaData={}, createAt=Fri Sep 06 16:02:16 AEST 2019)]
- locks: [
- LockLog(lockId=l1, balance=50.0, credit=40.0, locked=60.0, dealtAmount=60.0, metaData={}, unlocked=true, createAt=Fri Sep 06 16:02:16 AEST 2019),
- LockLog(lockId=l3, balance=50.0, credit=40.0, locked=80.0, dealtAmount=20.0, metaData={}, unlocked=true, createAt=Fri Sep 06 16:02:16 AEST 2019)]
- all balance spends: 50.0
- all credit spends: 30.0
- */
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement