This commit is contained in:
@@ -0,0 +1,24 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("jvm") version "2.1.10"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "ru.soune"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2")
|
||||||
|
implementation("io.insert-koin:koin-core:4.1.1")
|
||||||
|
implementation("io.insert-koin:koin-core-jvm:4.1.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(21)
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package ru.soune
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
println("Hello World!")
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package ru.soune.actions
|
||||||
|
|
||||||
|
abstract class NoCopyAction
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package ru.soune.actions.free
|
||||||
|
|
||||||
|
import ru.soune.actions.NoCopyAction
|
||||||
|
|
||||||
|
sealed class NoCopyFreeAction : NoCopyAction()
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package ru.soune.actions.paid
|
||||||
|
|
||||||
|
import ru.soune.actions.NoCopyAction
|
||||||
|
|
||||||
|
sealed class NoCopyPaidAction : NoCopyAction() {
|
||||||
|
|
||||||
|
abstract val cost: Double
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package ru.soune
|
||||||
|
|
||||||
|
interface Referral {
|
||||||
|
|
||||||
|
val userId: String
|
||||||
|
val referralLink: String
|
||||||
|
val inviter: String?
|
||||||
|
val currentLevel: String
|
||||||
|
val totalIncome: Int
|
||||||
|
val availableIncome: Int
|
||||||
|
val holdBalance: Int
|
||||||
|
val active: Boolean
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package ru.soune
|
||||||
|
|
||||||
|
data class ReferralInvitee(
|
||||||
|
val email: String,
|
||||||
|
val isActive: Boolean,
|
||||||
|
val regDate: String,
|
||||||
|
)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package ru.soune
|
||||||
|
|
||||||
|
interface ReferralLevel {
|
||||||
|
val id: String
|
||||||
|
val name: String
|
||||||
|
val share: Int
|
||||||
|
val minInvitee: Int
|
||||||
|
val maxInvitee: Int
|
||||||
|
val next: String?
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package ru.soune
|
||||||
|
|
||||||
|
interface ReferralLevelProvider {
|
||||||
|
|
||||||
|
fun getAvailableReferralLevels(): List<ReferralLevel>
|
||||||
|
|
||||||
|
fun getInitialReferralLevelId(): String
|
||||||
|
|
||||||
|
fun getReferralLevelById(levelId: String): ReferralLevel
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package ru.soune
|
||||||
|
|
||||||
|
interface ReferralRepo {
|
||||||
|
|
||||||
|
fun getUserReferralLink(userId: String): String
|
||||||
|
|
||||||
|
fun getUserIdByLink(link: String): String
|
||||||
|
|
||||||
|
fun getInviterIdForUser(userId: String): String?
|
||||||
|
|
||||||
|
fun getReferralLevelForUser(userId: String): String
|
||||||
|
|
||||||
|
fun getReferralByUserId(userId: String): Referral
|
||||||
|
|
||||||
|
fun getReferralInvitees(userId: String, pageSize: Int, pageNumber: Int): List<ReferralInvitee>
|
||||||
|
|
||||||
|
// создаем новую запись в БД
|
||||||
|
fun createReferralEntity(entity: Referral)
|
||||||
|
|
||||||
|
// прибавить к totalIncome и availableIncome значение transferAmount
|
||||||
|
fun increaseIncome(userId: String, transferAmount: Int)
|
||||||
|
|
||||||
|
// установить active в true
|
||||||
|
fun activateUser(userId: String): Boolean
|
||||||
|
|
||||||
|
// посчитать записи, у которых inviter == userId и active == true
|
||||||
|
fun getActiveInviteeForUser(userId: String): Int
|
||||||
|
|
||||||
|
// посчитать записи, у которых inviter == userId
|
||||||
|
fun getTotalInviteeForUser(userId: String): Int
|
||||||
|
|
||||||
|
fun upgradeReferralLevelForUser(userId: String, newLevelId: String)
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package ru.soune
|
||||||
|
|
||||||
|
class ReferralService(
|
||||||
|
private val referralLevelProvider: ReferralLevelProvider,
|
||||||
|
private val referralRepo: ReferralRepo,
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun onRegister(userId: String, inviterReferralLink: String?) {
|
||||||
|
val initialReferralLevel = referralLevelProvider.getInitialReferralLevelId()
|
||||||
|
val referralLink = referralRepo.getUserReferralLink(userId)
|
||||||
|
val inviter = inviterReferralLink?.let(referralRepo::getUserIdByLink)
|
||||||
|
|
||||||
|
val referral = object : Referral {
|
||||||
|
override val userId = userId
|
||||||
|
override val referralLink = referralLink
|
||||||
|
override val inviter = inviter
|
||||||
|
override val currentLevel = initialReferralLevel
|
||||||
|
override val totalIncome = 0
|
||||||
|
override val availableIncome = 0
|
||||||
|
override val holdBalance: Int = 0
|
||||||
|
override val active: Boolean = false
|
||||||
|
}
|
||||||
|
|
||||||
|
referralRepo.createReferralEntity(referral)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onUserAccountRefill(userId: String, transferAmount: Int) {
|
||||||
|
val wasActivated = referralRepo.activateUser(userId)
|
||||||
|
val inviterId = referralRepo.getInviterIdForUser(userId) ?: return
|
||||||
|
val currentInviterLevel = referralRepo.getReferralLevelForUser(inviterId)
|
||||||
|
.let { referralLevelProvider.getReferralLevelById(it) }
|
||||||
|
val reward = transferAmount * currentInviterLevel.share / 100
|
||||||
|
|
||||||
|
referralRepo.increaseIncome(inviterId, reward)
|
||||||
|
|
||||||
|
if (!wasActivated) return
|
||||||
|
|
||||||
|
val currentCount = referralRepo.getActiveInviteeForUser(inviterId)
|
||||||
|
val nextLevel = currentInviterLevel.next
|
||||||
|
|
||||||
|
if (currentCount + 1 > currentInviterLevel.maxInvitee && nextLevel != null) {
|
||||||
|
referralRepo.upgradeReferralLevelForUser(inviterId, nextLevel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getReferralLevels(): List<ReferralLevel> =
|
||||||
|
referralLevelProvider.getAvailableReferralLevels()
|
||||||
|
|
||||||
|
|
||||||
|
fun getReferralLevelForUser(userId: String): ReferralLevel =
|
||||||
|
referralRepo.getReferralLevelForUser(userId)
|
||||||
|
.let { referralLevelProvider.getReferralLevelById(it) }
|
||||||
|
|
||||||
|
fun getReferralStatForUser(userId: String): ReferralStat {
|
||||||
|
var referral = referralRepo.getReferralByUserId(userId)
|
||||||
|
return ReferralStat(
|
||||||
|
totalInvitee = referralRepo.getTotalInviteeForUser(userId),
|
||||||
|
activeInvitee = referralRepo.getActiveInviteeForUser(userId),
|
||||||
|
totalIncome = referral.totalIncome,
|
||||||
|
availableIncome = referral.availableIncome,
|
||||||
|
holdBalance = referral.holdBalance,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getInviteeForUser(userId: String, pageSize: Int, pageNumber: Int): List<ReferralInvitee> =
|
||||||
|
referralRepo.getReferralInvitees(userId, pageSize, pageNumber)
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package ru.soune
|
||||||
|
|
||||||
|
data class ReferralStat(
|
||||||
|
val totalInvitee: Int,
|
||||||
|
val activeInvitee: Int,
|
||||||
|
val totalIncome: Int,
|
||||||
|
val availableIncome: Int,
|
||||||
|
val holdBalance: Int,
|
||||||
|
)
|
||||||
@@ -3,4 +3,5 @@ plugins {
|
|||||||
}
|
}
|
||||||
rootProject.name = 'no-copy'
|
rootProject.name = 'no-copy'
|
||||||
include 'referral'
|
include 'referral'
|
||||||
|
include 'finance'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user