Coverage Summary for Class: AccountKeyAlgorithm (ru.eda.plgn.bizgen.core.utils)

Class Class, % Method, % Branch, % Line, % Instruction, %
AccountKeyAlgorithm 100% (1/1) 100% (2/2) 100% (10/10) 100% (14/14) 100% (205/205)


 package ru.eda.plgn.bizgen.core.utils
 
 /**
  * Алгоритм расчёта контрольного ключа лицевого счёта по Положению ЦБ РФ № 515 от 08.09.1997.
  *
  * Контрольный ключ рассчитывается с использованием весовых коэффициентов,
  * устанавливаемых каждому разряду из совокупности реквизитов:
  * - условный номер РКЦ (если счёт открыт в РКЦ) или кредитной организации (если в КО)
  * - номер лицевого счёта
  *
  * **See Also:** [Положение ЦБ РФ № 515](https://www.consultant.ru/document/cons_doc_LAW_16053/)
  *
  * @author Dmitry_Emelyanenko
  */
 object AccountKeyAlgorithm {
 
   private val WEIGHTS = intArrayOf(7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1)
 
   /**
    * Рассчитывает контрольный ключ для лицевого счёта по Положению 515.
    *
    * @param bik банковский идентификационный код (9 цифр)
    * @param accountNumber номер лицевого счёта (20 цифр, контрольный ключ игнорируется — приравнивается 0)
    * @param isRkc `true` для счетов в РКЦ (корреспондентские счета), `false` для счетов в кредитной организации
    * @return контрольный ключ (0–9)
    */
   fun calculateControlKey(bik: String, accountNumber: String, isRkc: Boolean): Int {
     require(bik.length == 9 && bik.all { it.isDigit() }) { "БИК должен содержать 9 цифр" }
     require(accountNumber.length == 20 && accountNumber.all { it.isDigit() }) {
       "Номер счёта должен содержать 20 цифр"
     }
 
     val conditionalCode = if (isRkc) {
       "0" + bik.substring(4, 6)
     } else {
       bik.substring(6, 9)
     }
 
     val accountWithK0 = accountNumber.substring(0, 8) + "0" + accountNumber.substring(9)
 
     val base = conditionalCode + accountWithK0
 
     var sum = 0
     base.forEachIndexed { index, char ->
       sum += char.digitToInt() * WEIGHTS[index]
     }
 
     return (sum % 10) * 3 % 10
   }
 }