Advertisement
Guest User

Untitled

a guest
Sep 17th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.67 KB | None | 0 0
  1. import org.junit.Test
  2. import java.util.Date
  3.  
  4.  
  5. class Ledger(val ledgerId: String) {
  6. var balance: Double = 0.0
  7. var credit: Double = 0.0
  8. var locked: Double = 0.0
  9.  
  10. val balanceHistory = ArrayList<BalanceLog>()
  11. val lockHistory = ArrayList<LockLog>()
  12.  
  13. @Synchronized
  14. fun lock(lockId: String, amount: Double, metaData: Map<String, Any> = mapOf()): Boolean {
  15. if (lockHistory.filter { it.lockId == lockId }.isEmpty()) {
  16. if (getAvailable() >= amount) {
  17. locked += amount
  18. addLockLog(lockId, amount, metaData)
  19. return true
  20. } else {
  21. return false
  22. }
  23. } else {
  24. return true
  25. }
  26. }
  27.  
  28. @Synchronized
  29. fun unlock(lockId: String): Boolean {
  30. val lockLog = lockHistory.filter { it.lockId == lockId }.firstOrNull()
  31. if (lockLog != null) {
  32. if (!lockLog.unlocked) {
  33. locked -= lockLog.dealtAmount
  34. lockLog.unlocked = true
  35. return true
  36. } else {
  37. return false
  38. }
  39. } else {
  40. return true
  41. }
  42. }
  43.  
  44. @Synchronized
  45. fun debit(
  46. updateId: String,
  47. amount: Double,
  48. metaData: Map<String, Any> = mapOf(),
  49. lockedId: String? = null
  50. ): Boolean {
  51. if (balanceHistory.filter { it.updateId == updateId }.isEmpty()) {
  52. if (lockedId != null) {
  53. unlock(lockedId)
  54. }
  55.  
  56. if (getAvailable() >= amount) {
  57. addBalanceLog(updateId, -amount, metaData)
  58. return true
  59. } else {
  60. return false
  61. }
  62. } else {
  63. return true
  64. }
  65. }
  66.  
  67. @Synchronized
  68. fun credit(updateId: String, amount: Double, metaData: Map<String, Any> = mapOf()): Boolean {
  69. if (balanceHistory.filter { it.updateId == updateId }.isEmpty()) {
  70. addBalanceLog(updateId, amount, metaData)
  71. return true
  72. } else {
  73. return true
  74. }
  75. }
  76.  
  77. private fun getAvailable(): Double {
  78. return balance + credit - locked
  79. }
  80.  
  81. private fun addLockLog(lockId: String, amount: Double, metaData: Map<String, Any>) {
  82. lockHistory.add(
  83. LockLog(
  84. lockId = lockId,
  85. balance = balance,
  86. credit = credit,
  87. locked = locked,
  88. dealtAmount = amount,
  89. metaData = metaData
  90. )
  91. )
  92. }
  93.  
  94. private fun addBalanceLog(updateId: String, amount: Double, metaData: Map<String, Any>) {
  95. val newBalance = balance + amount
  96. balanceHistory.add(
  97. BalanceLog(
  98. updateId = updateId,
  99. dealtAmount = amount,
  100. lastBalance = balance,
  101. balance = newBalance,
  102. credit = credit,
  103. locked = locked,
  104. metaData = metaData
  105. )
  106. )
  107. balance = newBalance
  108. }
  109. }
  110.  
  111.  
  112. data class BalanceLog(
  113. val updateId: String,
  114. val lastBalance: Double,
  115. val balance: Double,
  116. val credit: Double,
  117. val locked: Double,
  118. val dealtAmount: Double,
  119.  
  120. val metaData: Map<String, Any>,
  121. val createAt: Date = Date()
  122. )
  123.  
  124. data class LockLog(
  125. val lockId: String,
  126. val balance: Double = 0.0,
  127. val credit: Double = 0.0,
  128. val locked: Double = 0.0,
  129. val dealtAmount: Double = 0.0,
  130.  
  131. val metaData: Map<String, Any>,
  132. var unlocked: Boolean = false,
  133. val createAt: Date = Date()
  134. )
  135.  
  136.  
  137. class WalletTest {
  138. @Test
  139. fun test() {
  140. val ledger = Ledger("my:USD")
  141. ledger.credit = 40.0
  142.  
  143. println(ledger.credit("c1", 50.0, mapOf()))
  144.  
  145. println(ledger.lock("l1", 60.0))
  146. println(ledger.lock("l2", 60.0))
  147. println(ledger.lock("l3", 20.0)) // failed
  148.  
  149. println(ledger.debit("d0", 10.0, mapOf()))
  150. println(ledger.debit("d1", 60.0, mapOf(), "l1"))
  151. println(ledger.debit("d2", 20.0, mapOf(), "l2")) // failed
  152. println(ledger.debit("d3", 10.0, mapOf(), "l3"))
  153.  
  154. println("balances: " + ledger.balanceHistory.map { "\n" + it.toString() })
  155. println("locks: " + ledger.lockHistory.map { "\n" + it.toString() })
  156.  
  157. //
  158. println("all balance spends: " + ledger.balanceHistory.filter { it.lastBalance >= 0 && it.dealtAmount < 0 }
  159. .map { if (it.balance > 0) -it.dealtAmount else it.lastBalance }.sum())
  160.  
  161. println("all credit spends: " + ledger.balanceHistory.filter { it.balance < 0 && it.dealtAmount < 0 }
  162. .map { if (it.lastBalance > 0) it.lastBalance + it.balance else -it.dealtAmount }.sum())
  163.  
  164. /** test result
  165. balances: [
  166. 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),
  167. 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),
  168. 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),
  169. 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)]
  170. locks: [
  171. 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),
  172. 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)]
  173. all balance spends: 50.0
  174. all credit spends: 30.0
  175.  
  176. */
  177. }
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement