In [35]:
// Зависимости
import scala.collection.mutable.ListBuffer
import scala.collection.mutable.Map
import scala.util.Random
import java.util.Calendar


Out[35]:
import scala.collection.mutable.ListBuffer

import scala.collection.mutable.Map

import scala.util.Random

import java.util.Calendar

In [36]:
case class AccountType(val name:String, val credit_percent:Double, val deposit_percent:Double, 
                       val giveaway_percent:Double, val contribution_percent:Double)


class Helpers{
    def printTransactionInfo(trans:Transaction){ 
        println("type: " + trans.kind + "     amount: " + trans.amount + "      date: " + trans.datetime.getTime)
    }
    
    def printContributionInfo(contr:Contribution){
        println("amount: " + contr.amount + "     years: " + contr.years + "    start date: " + contr.startTime.getTime + "  percent: " + contr.account.accountType.contribution_percent)
    }
    
    def printCreditInfo(credit:Credit){
        println("amount: " + credit.amount + "     months: " + credit.months + "    start date: " + credit.startTime.getTime + "  percent: " + credit.account.accountType.credit_percent)
    }
    
    def printContributionsList(allcontr:ListBuffer[Contribution]){
        println("Contributions:")
        for(i <- allcontr)
            printContributionInfo(i)
    }
    def printCreditList(allcred:ListBuffer[Credit]){
        println("Credits:")
        for(i <- allcred)
            printCreditInfo(i)
    }
    
    def printTransactionsList(alltrans:ListBuffer[Transaction]){
        println("Transactions:")
        for(i <- alltrans)
            printTransactionInfo(i)
    }

    def printAccountInfo(account:Account){
        print ("balance: " + account.balance + "      Type: " + account.accountType.name + "\n")
        printTransactionsList(account.transactions)
        printContributionsList(account.contributions)
        printCreditList(account.credits)
    }
    def printCustomerInfo(user:Customer){
        print("name: " + user.name + "\nAccounts:\n")
        for(i <- user.accounts){
            printAccountInfo(i)
            print("\n")
        }
    }
}
class Bank {
    // Клиенты банка
    var customers = new ListBuffer[Customer]

    // Добавить клиента
    def addCustomer(customer: Customer) { customers += customer }
    
    //типы аккаунтов, у разных типов разные проценты на депозиты, переводы, кредиты и вклады
    var accTypes:Map[String, AccountType] = Map("basic" -> new AccountType("basic", 1.2, 0.9, 0.9, 1.10),
                                                "VIP" -> new AccountType("VIP", 1.1, 0.95, 0.95, 1.20),
                                                "premier" -> new AccountType("premier", 1.05,0.99, 0.99,1.30)) 
    def getAccType(accType:String):AccountType={
        return accTypes(accType)
    }
    def getAllUsers():ListBuffer[Customer]={
        return customers
    }
    
    //симуляция работы банка
    def work()={
        var help = new Helpers()
        var flag = true
        for(user <- customers){
            for(account <- user.accounts){
                for(contribution <- account.contributions){
                    contribution.startTime = Calendar.getInstance
                }
                for(credit <- account.credits){
                    credit.startTime = Calendar.getInstance
                }
            }
        }
        var iteration = 1
        while(flag == true){
            flag = false
            for(user <- customers){
                for(account <- user.accounts){
                    for(contribution <- account.contributions){
                        if(iteration%12 == 0){
                            println("Contrbutions")
                            help.printContributionInfo(contribution)
                            contribution.upgrade()
                        }
                        flag = true
                    }
                    for(credit <- account.credits){
                        println("credits")
                        help.printCreditInfo(credit)
                        credit.upgrade()
                        flag = true
                    }
                }
            }
            if(flag == true){
                println("Прошел месяц....")
                Thread.sleep(1000)
            }
            iteration+=1
        }
    }
    
    def block_account(account:Account)=account.blocked = true
    
    def unblock_account(account:Account)=account.blocked = false
    
    //оплатить весь долг по кредиту(менеджер)
    def pay_for_credit(credit:Credit){
        credit.payAll()
    }
    
    //вывести деньги из вклада(менеджер)
    def get_contribution_back(contribution:Contribution){
        contribution.getMoneyBack()
    }
}

class Transaction(val kind:String, val amount:Double){
    val datetime = Calendar.getInstance()
}

// Пользователи

class Customer(val name: String) {

    // Аккаунты пользователя
    val accounts: ListBuffer[Account] = ListBuffer()
    // Создать новый счёт
    def openAccount(account: Account): Customer = {
        accounts += account
        this
    }

    def get_all_transactions(account:Account):ListBuffer[Transaction] = {
        return account.transactions
    } 
    
    def delete_account(account:Account)={
        accounts -= account
    }
    
    //перевод средств на другой счет
    def give_money(from_account:Account, to_account:Account, sum:Double) = {
        if(from_account.balance < sum)
            throw new IllegalArgumentException("Не достаточно денег на счете")
        else{
            from_account.balance -= sum
            to_account.balance += sum*from_account.accountType.giveaway_percent
        }
        from_account.transactions.append(new Transaction("giveaway", -sum))
        to_account.transactions.append(new Transaction("addition", sum*from_account.accountType.giveaway_percent))
    }
}

class Account(val accountType:AccountType) {
    // Баланс аккаунта
    var balance = 0.0
    val contributions: ListBuffer[Contribution] = ListBuffer()
    val credits: ListBuffer[Credit] = ListBuffer()
    val transactions:ListBuffer[Transaction] = ListBuffer()
    // Uid аккаунта
    val uid =  java.util.UUID.randomUUID.toString
    var blocked = false

    // Добавление денег на аккаунт
    def deposit(amount: Double) {
        if(blocked)
            println("Аккаунт заблокирован, невозможно произвести операцию")
        else if (amount <= 0)
            throw new IllegalArgumentException("У вас должно быть больше денег чем 0")
        else
        // Добавить денег
        balance += amount*accountType.deposit_percent
        transactions.append(new Transaction("deposit", amount*accountType.deposit_percent))
    }
    
    //вывод средств со счета
    def remove_money(amount: Double){
        if(blocked)
            println("Аккаунт заблокирован, невозможно произвести операцию")
        if(amount > balance)
            throw new IllegalArgumentException("Не достаточно денег на счете")
        else{
            balance -= amount
            transactions.append(new Transaction("windraw", -amount))
        }
    }
    
        
    def new_contribution(amount:Double, years:Int)={
        if(blocked)
            println("Аккаунт заблокирован, невозможно произвести операцию")
        if(amount > balance)
            throw new IllegalArgumentException("Не достаточно денег на счете")
        else{
            balance -= amount
            contributions.append(new Contribution(amount, years, this))
            transactions.append(new Transaction("contribution", -amount))
        }
    }
        
    def new_credit(amount:Double, years:Int){
        if(blocked)
            println("Аккаунт заблокирован, невозможно произвести операцию")
        balance+=amount
        credits.append(new Credit(amount, years, this))
        transactions.append(new Transaction("credit", amount))
    }
    //оплатить весь долг по кредиту(клиент)
    def pay_for_credit(credit:Credit){
        credit.payAll()
    }
    
    //вывести деньги из вклада(клиент)
    def get_contribution_back(contribution:Contribution){
        contribution.getMoneyBack()
    }
}

class Contribution(var amount:Double, var years:Int, val account:Account){
    var startTime = Calendar.getInstance()
    //обновление вклада(каждый месяц)
    def upgrade() = {
        if(years==0){
            getMoneyBack()
        }
        else
            amount*=account.accountType.contribution_percent
        years-=1
    }
    //забрать все деньги из вклада
    def getMoneyBack(){
        account.balance += amount
        account.contributions -= this
        account.transactions.append(new Transaction("from contribution", amount))
    }
}

class Credit (var amount:Double, var years:Int, val account:Account){
    var months = years*12
    var startTime = Calendar.getInstance()
    val sumToPay:Double = amount*account.accountType.credit_percent/months
    
    //обновление кредита(каждый месяц)
    def upgrade(){
        if(months==0){
            account.credits -= this
        }
        else
        {
            if(sumToPay > account.balance)
                print("Теперь вы должны банку денег")
            account.balance -= sumToPay
            account.transactions.append(new Transaction("credit pay", -sumToPay))
        }
        months-=1
    }
    
    //заплатить весь долг за кредит
    def payAll(){
        if(account.balance < sumToPay*months)
            print("Не достаточно средств на счете, чтобы оплатить кредит")
        else{
            account.balance -= sumToPay*months
            account.credits -= this
            account.transactions.append(new Transaction("credit pay", -sumToPay*months))
        }
    }
}


Out[36]:
defined class AccountType
defined class Helpers
defined class Bank
defined class Transaction
defined class Customer
defined class Account
defined class Contribution
defined class Credit

In [37]:
val bank = new Bank


Out[37]:
bank: Bank = $sess.cmd35Wrapper$Helper$Bank@16a0f564

In [38]:
var help = new Helpers //объект класса - помощник по выводу
var user = new Customer("Даня Ололоев")
bank.addCustomer(user)
var account = new Account(bank.getAccType("basic"))
user.openAccount(account) 
var account2 = new Account(bank.getAccType("VIP"))
user.openAccount(account2)


Out[38]:
help: Helpers = $sess.cmd35Wrapper$Helper$Helpers@43c5cba2
user: Customer = $sess.cmd35Wrapper$Helper$Customer@437163f2
account: Account = $sess.cmd35Wrapper$Helper$Account@492f6796
res37_4: Customer = $sess.cmd35Wrapper$Helper$Customer@437163f2
account2: Account = $sess.cmd35Wrapper$Helper$Account@48097be0
res37_6: Customer = $sess.cmd35Wrapper$Helper$Customer@437163f2

In [39]:
account.deposit(400)
account2.deposit(400)

In [40]:
help.printCustomerInfo(user)


name: Даня Ололоев
Accounts:
balance: 360.0      Type: basic
Transactions:
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:39 MSK 2017
Contributions:
Credits:

balance: 380.0      Type: VIP
Transactions:
type: deposit     amount: 380.0      date: Mon Jun 19 10:02:39 MSK 2017
Contributions:
Credits:


In [41]:
bank.block_account(account)

In [42]:
account.deposit(400)


Аккаунт заблокирован, невозможно произвести операцию

In [43]:
bank.unblock_account(account)

In [44]:
user.give_money(account, account2, 100)

In [45]:
help.printCustomerInfo(user)


name: Даня Ололоев
Accounts:
balance: 260.0      Type: basic
Transactions:
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:39 MSK 2017
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:41 MSK 2017
type: giveaway     amount: -100.0      date: Mon Jun 19 10:02:42 MSK 2017
Contributions:
Credits:

balance: 470.0      Type: VIP
Transactions:
type: deposit     amount: 380.0      date: Mon Jun 19 10:02:39 MSK 2017
type: addition     amount: 90.0      date: Mon Jun 19 10:02:42 MSK 2017
Contributions:
Credits:


In [46]:
account2.remove_money(80)

In [47]:
account2.new_credit(100, 2)
account2.new_contribution(100, 3)

In [48]:
help.printCustomerInfo(user)


name: Даня Ололоев
Accounts:
balance: 260.0      Type: basic
Transactions:
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:39 MSK 2017
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:41 MSK 2017
type: giveaway     amount: -100.0      date: Mon Jun 19 10:02:42 MSK 2017
Contributions:
Credits:

balance: 390.0      Type: VIP
Transactions:
type: deposit     amount: 380.0      date: Mon Jun 19 10:02:39 MSK 2017
type: addition     amount: 90.0      date: Mon Jun 19 10:02:42 MSK 2017
type: windraw     amount: -80.0      date: Mon Jun 19 10:02:43 MSK 2017
type: credit     amount: 100.0      date: Mon Jun 19 10:02:43 MSK 2017
type: contribution     amount: -100.0      date: Mon Jun 19 10:02:43 MSK 2017
Contributions:
amount: 100.0     years: 3    start date: Mon Jun 19 10:02:43 MSK 2017  percent: 1.2
Credits:
amount: 100.0     months: 24    start date: Mon Jun 19 10:02:43 MSK 2017  percent: 1.1


In [49]:
bank.pay_for_credit(account2.credits(0)) //сразу отдаем весь долг по кредиту
bank.get_contribution_back(account2.contributions(0)) //забираем деньги из вклада

In [50]:
help.printCustomerInfo(user)


name: Даня Ололоев
Accounts:
balance: 260.0      Type: basic
Transactions:
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:39 MSK 2017
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:41 MSK 2017
type: giveaway     amount: -100.0      date: Mon Jun 19 10:02:42 MSK 2017
Contributions:
Credits:

balance: 380.0      Type: VIP
Transactions:
type: deposit     amount: 380.0      date: Mon Jun 19 10:02:39 MSK 2017
type: addition     amount: 90.0      date: Mon Jun 19 10:02:42 MSK 2017
type: windraw     amount: -80.0      date: Mon Jun 19 10:02:43 MSK 2017
type: credit     amount: 100.0      date: Mon Jun 19 10:02:43 MSK 2017
type: contribution     amount: -100.0      date: Mon Jun 19 10:02:43 MSK 2017
type: credit pay     amount: -110.00000000000001      date: Mon Jun 19 10:02:44 MSK 2017
type: from contribution     amount: 100.0      date: Mon Jun 19 10:02:44 MSK 2017
Contributions:
Credits:


In [51]:
account2.new_credit(100, 2)
account2.new_contribution(100, 3)

In [52]:
bank.work //симулятор работы банка
          //кредит отдаётся каждый месяц (сумма зависит от суммы кредита, процентной ставки и срока)
          //вклад пополняется каждый год, начисление на счет происходит только после закрытия вклада


credits
amount: 100.0     months: 24    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 23    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 22    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 21    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 20    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 19    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 18    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 17    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 16    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 15    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 14    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
Contrbutions
amount: 100.0     years: 3    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.2
credits
amount: 100.0     months: 13    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 12    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 11    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 10    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 9    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 8    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 7    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 6    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 5    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 4    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 3    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 2    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
Contrbutions
amount: 120.0     years: 2    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.2
credits
amount: 100.0     months: 1    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
credits
amount: 100.0     months: 0    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.1
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Contrbutions
amount: 144.0     years: 1    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.2
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Прошел месяц....
Contrbutions
amount: 172.79999999999998     years: 0    start date: Mon Jun 19 10:02:45 MSK 2017  percent: 1.2
Прошел месяц....

In [53]:
help.printCustomerInfo(user)


name: Даня Ололоев
Accounts:
balance: 260.0      Type: basic
Transactions:
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:39 MSK 2017
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:41 MSK 2017
type: giveaway     amount: -100.0      date: Mon Jun 19 10:02:42 MSK 2017
Contributions:
Credits:

balance: 442.8000000000004      Type: VIP
Transactions:
type: deposit     amount: 380.0      date: Mon Jun 19 10:02:39 MSK 2017
type: addition     amount: 90.0      date: Mon Jun 19 10:02:42 MSK 2017
type: windraw     amount: -80.0      date: Mon Jun 19 10:02:43 MSK 2017
type: credit     amount: 100.0      date: Mon Jun 19 10:02:43 MSK 2017
type: contribution     amount: -100.0      date: Mon Jun 19 10:02:43 MSK 2017
type: credit pay     amount: -110.00000000000001      date: Mon Jun 19 10:02:44 MSK 2017
type: from contribution     amount: 100.0      date: Mon Jun 19 10:02:44 MSK 2017
type: credit     amount: 100.0      date: Mon Jun 19 10:02:44 MSK 2017
type: contribution     amount: -100.0      date: Mon Jun 19 10:02:44 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:45 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:46 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:47 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:48 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:49 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:50 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:51 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:52 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:53 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:54 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:55 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:56 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:57 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:58 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:02:59 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:03:00 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:03:01 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:03:02 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:03:03 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:03:04 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:03:05 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:03:06 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:03:07 MSK 2017
type: credit pay     amount: -4.583333333333334      date: Mon Jun 19 10:03:08 MSK 2017
type: from contribution     amount: 172.79999999999998      date: Mon Jun 19 10:03:32 MSK 2017
Contributions:
Credits:


In [54]:
user.delete_account(account2)


Out[54]:
res53: ListBuffer[Account] = ListBuffer($sess.cmd35Wrapper$Helper$Account@492f6796)

In [55]:
help.printCustomerInfo(user)


name: Даня Ололоев
Accounts:
balance: 260.0      Type: basic
Transactions:
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:39 MSK 2017
type: deposit     amount: 360.0      date: Mon Jun 19 10:02:41 MSK 2017
type: giveaway     amount: -100.0      date: Mon Jun 19 10:02:42 MSK 2017
Contributions:
Credits:


In [56]:
bank.getAllUsers()//API банка, через user-ов можно получить их счета и переводить на них деньги


Out[56]:
res55: ListBuffer[Customer] = ListBuffer($sess.cmd35Wrapper$Helper$Customer@437163f2)

In [ ]:


In [ ]: