1
\$\begingroup\$

I am working on a sample banking system and have the following for deposit functionality, I was wondering if this is idiomatic, and how it can be improved. I have separated the algebra of the service using a trait but not sure how to enforce that two accounts should not be the same with types

type AccountNumber = String
type Amount = BigDecimal

sealed trait Account {
  val number: AccountNumber
  val balance: Amount
}

case class OpenAccount(number :AccountNumber, balance: Amount) extends Account
case class ClosedAccount(number :AccountNumber, balance: Amount) extends Account

trait BankServices {
  case class Response(from: OpenAccount, to: OpenAccount)
  def deposit(from: OpenAccount, to:OpenAccount, amount: Amount): Option[Response]
  def withdrawal(from: OpenAccount, to:OpenAccount, amount: Amount): Option[Response]

  def closeAccount(account: OpenAccount): ClosedAccount

}

object BankService extends BankServices {

  override def deposit(from: OpenAccount, to: OpenAccount, amount: Amount): Option[Response] = {
    if (from.balance < amount || from.number == to.number) {
      None
    } else {
      val f = OpenAccount(from.number, from.balance - amount)
      val t = OpenAccount(to.number, to.balance + amount)
      Some(Response(f, t))
    }
  }

  override def withdrawal(from: OpenAccount, to: OpenAccount, amount: Amount): Option[Response] = ???

  override def closeAccount(account: OpenAccount): ClosedAccount = ???
}

val c = OpenAccount("125", 80)
val b = OpenAccount("123", 100)

for {
  x  <- BankService.deposit(c, b, 10)
  y  <- BankService.deposit(x.from, x.to, 10)
} yield y
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.