sss.openstar.controller.ChargeHelper.scala Maven / Gradle / Ivy
package sss.openstar.controller
import sss.openstar.UniqueNodeIdentifier
import sss.openstar.account.NodeIdentity
import sss.openstar.contacts.ContactService
import sss.openstar.identityledger.{IdentityServiceQuery, ProviderChargeAttribute, RemoveAttribute, SetAttribute, SystemAttributeCategory}
import sss.openstar.tools.SendTxSupport.SendTx
import sss.openstar.ui.rpc._
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
class ChargeHelper(potentialProviders: Set[String])(implicit identityServiceQuery: IdentityServiceQuery,
contactService: ContactService) {
private def canBeProvider(potentialProvider: UniqueNodeIdentifier): Boolean = potentialProviders.contains(potentialProvider)
def getProviderCharge(provider: UniqueNodeIdentifier): Option[Option[Long]] = {
if (canBeProvider(provider)) { Some(
identityServiceQuery.listAttributes(provider)
.collectFirst {
case ProviderChargeAttribute(amount) => amount
})
} else None
}
def setProviderCharge(providerIdentity: NodeIdentity,
amountOpt: Option[Long]
)(implicit send: SendTx,
ec: ExecutionContext): Future[Result[Option[Option[Long]]]]= {
val isValidProvider = getProviderCharge(providerIdentity.id)
if(isValidProvider.isDefined) {
val currentCharge = isValidProvider.get
(amountOpt match {
case Some(amount) =>
if (currentCharge.isEmpty || currentCharge.get != amount) {
Some(SetAttribute(providerIdentity.id, ProviderChargeAttribute(amount)))
} else None
case None =>
if (currentCharge.isDefined) {
Some(RemoveAttribute(providerIdentity.id, SystemAttributeCategory.ProviderCharge))
} else None
}) match {
case Some(tx) =>
Utils.simplySignedIdentityLedgerItem(providerIdentity, tx) flatMap { le =>
send(le).whenCommitted.map(_.internalCommit).toResult[Option[Option[Long]]](Some(amountOpt))
}
case None =>
Future.successful(success(Some(None)))
}
} else Future.successful(success(None))
}
def getTotalChargeFromTo(from: UniqueNodeIdentifier, to: UniqueNodeIdentifier): Try[Long] = {
for {
paywallCharge <- getPaywallChargeFromTo(from, to)
providerCharge <- getIdentitiesProviderCharge(to)
} yield (paywallCharge + providerCharge)
}
def getIdentitiesProviderCharge(identityToReach: UniqueNodeIdentifier): Try[Long] = Try {
identityServiceQuery.listAttributes(identityToReach).collectFirst {
//the destination *is* a provider.
case ProviderChargeAttribute(amount) => amount
}.getOrElse {
//the destination *has* a provider
val allProviderCharges = identityServiceQuery.messageStores(identityToReach).flatMap(store => {
identityServiceQuery.listAttributes(store).collect {
case ProviderChargeAttribute(amount) => amount
}
})
if(allProviderCharges.isEmpty) 0
else allProviderCharges.min
}
}
def getDefaultPaywallCharge(identity: String): Long = {
identityServiceQuery.getCurrentCharge(identity)
}
def getPaywallChargeFromTo(from: UniqueNodeIdentifier, to: UniqueNodeIdentifier): Try[Long] = Try {
contactService.findUser(from) match {
case None =>
identityServiceQuery.getCurrentCharge(to)
//throw new IllegalArgumentException(s"No such user ${from} in contacts.")
case Some(fromUser) =>
fromUser.getCategoryDetails(to) match {
case None =>
identityServiceQuery.getCurrentCharge(to)
case Some(details) =>
identityServiceQuery.getCurrentCharge(to, details.contactCategoryForName)
}
}
}
}