...
 
Commits (2)
......@@ -5,7 +5,7 @@
<groupId>be.rlab</groupId>
<artifactId>domino</artifactId>
<packaging>jar</packaging>
<version>1.5.3-SNAPSHOT</version>
<version>1.5.3</version>
<licenses>
<license>
......@@ -455,7 +455,7 @@
<connection>scm:git:git@git.rlab.be:seykron/domino.git</connection>
<developerConnection>scm:git:git@git.rlab.be:seykron/domino.git</developerConnection>
<url>https://git.rlab.be/seykron/domino</url>
<tag>HEAD</tag>
<tag>domino-1.5.3</tag>
</scm>
<distributionManagement>
......
package be.rlab.domino.application.bot.treasury
import be.rlab.domino.application.BalanceFactory
import be.rlab.domino.application.model.BalanceDTO
import be.rlab.domino.domain.AccountService
import be.rlab.domino.domain.BalanceService
......@@ -23,7 +22,6 @@ class Balance(
override val name: String,
override val scope: List<ChatType>,
private val balanceService: BalanceService,
private val balanceFactory: BalanceFactory,
private val accountService: AccountService,
private val treasuryConfig: TreasuryConfig
) : Command {
......@@ -47,16 +45,11 @@ class Balance(
.withDayOfMonth(1)
.withTimeAtStartOfDay()
}
val previousDate: DateTime = date.minusMonths(1)
val previousBalance: Balance = balanceService.findForTreasury(
year = previousDate.year,
month = previousDate.monthOfYear
)
val balance: Balance = balanceService.findForTreasury(
year = date.year,
month = date.monthOfYear
)
val result: BalanceDTO = balanceFactory.create(previousBalance, balance)
val result: BalanceDTO = BalanceDTO.from(balance)
context.talk("""
# Balance de período ${date.year}/${date.monthOfYear}
......
package be.rlab.domino.application.model
import be.rlab.domino.domain.model.Balance
import be.rlab.domino.domain.model.Value
data class BalanceDTO(
......@@ -10,4 +11,16 @@ data class BalanceDTO(
val income: Value,
val monthlyBalance: Value,
val totalBalance: Value
)
) {
companion object {
fun from(balance: Balance): BalanceDTO = BalanceDTO(
previousBalance = -balance.previousBalance,
bills = balance.bills.map(BillDTO.Companion::from),
debtsTotal = -balance.debtsTotal,
debtsPending = -balance.debtsPending,
income = -balance.income,
monthlyBalance = -balance.monthlyBalance,
totalBalance = -balance.totalBalance
)
}
}
package be.rlab.domino.application.model
import be.rlab.domino.domain.model.Bill
import be.rlab.domino.domain.model.Value
import org.joda.time.DateTime
......@@ -11,18 +12,14 @@ data class BillDTO(
val pending: Boolean
) {
companion object {
fun new(
serviceName: String,
debt: Value,
total: Value,
dueDate: DateTime?,
pending: Boolean
fun from(
bill: Bill
): BillDTO = BillDTO(
serviceName = serviceName,
debt = debt,
total = total,
dueDate = dueDate,
pending = pending
serviceName = bill.creditor().userName,
debt = bill.credit.debt,
total = bill.debt.value,
dueDate = bill.dueDate,
pending = bill.pending
)
}
}
package be.rlab.domino.application.web
import be.rlab.domino.application.BalanceFactory
import be.rlab.domino.application.model.BalanceDTO
import be.rlab.domino.domain.BalanceService
import be.rlab.domino.domain.model.Balance
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.ui.set
......@@ -13,8 +12,7 @@ import org.springframework.web.bind.annotation.RequestParam
@Controller
class BalanceController(
private val balanceService: BalanceService,
private val balanceFactory: BalanceFactory
private val balanceService: BalanceService
) : ViewController() {
override val viewName: String = "balance"
......@@ -29,16 +27,11 @@ class BalanceController(
val now: DateTime = DateTime.now()
val resolvedYear: Int = year ?: now.year
val resolvedMonth: Int = month ?: now.monthOfYear
val previousDate = DateTime(resolvedYear, resolvedMonth, 1, 0, 0, DateTimeZone.UTC).minusMonths(1)
val previousBalance: Balance = balanceService.findForTreasury(
year = previousDate.year,
month = previousDate.monthOfYear
)
val balance: Balance = balanceService.findForTreasury(
year = resolvedYear,
month = resolvedMonth
)
model["balance"] = balanceFactory.create(previousBalance, balance)
model["balance"] = BalanceDTO.from(balance)
model["year"] = resolvedYear
model["month"] = resolvedMonth
......
......@@ -108,7 +108,6 @@ object CommandBeans {
name = "/balance",
scope = listOf(ChatType.GROUP, ChatType.PRIVATE),
balanceService = ref(),
balanceFactory = ref(),
accountService = ref(),
treasuryConfig = ref()
)
......
package be.rlab.domino.config
import be.rlab.domino.application.BalanceFactory
import be.rlab.domino.domain.BalanceFactory
import be.rlab.domino.domain.*
import be.rlab.domino.domain.persistence.*
import be.rlab.domino.util.ObjectMapperFactory
......
......@@ -12,7 +12,7 @@ import org.springframework.web.reactive.config.ResourceHandlerRegistry
import org.springframework.web.reactive.config.ViewResolverRegistry
import org.springframework.web.reactive.config.WebFluxConfigurer
import org.springframework.web.reactive.result.view.freemarker.FreeMarkerConfigurer
import java.util.*
@Configuration
@EnableWebFlux
......@@ -40,6 +40,9 @@ open class WebConfig : WebFluxConfigurer {
@Bean
open fun freemarkerConfig(): FreeMarkerConfigurer {
val freeMarkerConfigurer = FreeMarkerConfigurer()
freeMarkerConfigurer.setFreemarkerSettings(Properties().apply {
setProperty("number_format", "##0.00")
})
freeMarkerConfigurer.setTemplateLoaderPath("classpath:/views/")
return freeMarkerConfigurer
}
......
package be.rlab.domino.application
package be.rlab.domino.domain
import be.rlab.domino.application.model.BalanceDTO
import be.rlab.domino.application.model.BillDTO
import be.rlab.domino.domain.model.Balance
import be.rlab.domino.domain.model.Bill
import be.rlab.domino.domain.model.TransactionType
import be.rlab.domino.domain.model.Value
import be.rlab.domino.domain.model.*
import be.rlab.domino.domain.model.Value.Companion.ZERO
import be.rlab.domino.domain.persistence.BlockSignatureDAO
import org.joda.time.DateTime
class BalanceFactory(
private val blockSignatureDAO: BlockSignatureDAO
) {
class BalanceFactory {
fun create(
previousBalance: Balance,
balance: Balance
): BalanceDTO {
val previousTotal: Value = calculateTotal(previousBalance)
val total: Value = calculateTotal(balance)
val income: Value = calculateIncome(balance)
val debt: Value = calculateDebt(balance)
val pendingDebt: Value = calculatePendingDebt(balance)
account: Account,
from: DateTime,
to: DateTime,
description: String,
previousBalance: Balance?,
transactions: List<Transaction>,
bills: List<Bill>
): Balance {
val previousTotal: Value = previousBalance?.monthlyBalance ?: ZERO
val total: Value = calculateTotal(transactions)
val income: Value = calculateIncome(transactions)
val debt: Value = calculateDebt(transactions)
val validBills: List<Bill> = resolveValidBills(bills)
val pendingDebt: Value = calculatePendingDebt(validBills)
return BalanceDTO(
previousBalance = -previousTotal,
bills = resolveValidBills(balance.bills).map { bill ->
BillDTO.new(
serviceName = bill.creditor().userName,
debt = bill.credit.debt,
total = bill.debt.value,
dueDate = bill.dueDate,
pending = bill.pending
)
},
return Balance.new(
previousSignature = blockSignatureDAO.lastSignature(account.id),
account = account,
description = description,
from = from,
to = to,
transactions = transactions,
bills = resolveValidBills(bills),
previousBalance = previousTotal,
debtsTotal = debt,
debtsPending = pendingDebt,
income = -income,
monthlyBalance = -total,
totalBalance = -(previousTotal + total)
income = income,
monthlyBalance = total,
totalBalance = previousTotal + total
)
}
private fun calculateDebt(balance: Balance): Value {
return balance.transactions.fold(ZERO) { totalDebt, transaction ->
private fun calculateDebt(transactions: List<Transaction>): Value {
return transactions.fold(ZERO) { totalDebt, transaction ->
if (transaction.type == TransactionType.DEBT) {
totalDebt + transaction.value
} else {
......@@ -48,9 +52,7 @@ class BalanceFactory {
}
}
private fun calculatePendingDebt(balance: Balance): Value {
val bills: List<Bill> = resolveValidBills(balance.bills)
private fun calculatePendingDebt(bills: List<Bill>): Value {
return bills.fold(ZERO) { pendingDebt, billInfo ->
if (billInfo.pending) {
pendingDebt + billInfo.credit.debt
......@@ -60,8 +62,8 @@ class BalanceFactory {
}
}
private fun calculateIncome(balance: Balance): Value {
return balance.transactions.fold(ZERO) { totalIncome, transaction ->
private fun calculateIncome(transactions: List<Transaction>): Value {
return transactions.fold(ZERO) { totalIncome, transaction ->
if (transaction.type != TransactionType.DEBT) {
totalIncome + transaction.value
} else {
......@@ -70,8 +72,8 @@ class BalanceFactory {
}
}
private fun calculateTotal(balance: Balance): Value {
return balance.transactions.fold(ZERO) { total, transaction ->
private fun calculateTotal(transactions: List<Transaction>): Value {
return transactions.fold(ZERO) { total, transaction ->
total + transaction.value
}
}
......
......@@ -6,7 +6,6 @@ import be.rlab.domino.domain.model.Bill
import be.rlab.domino.domain.model.Transaction
import be.rlab.domino.domain.persistence.BalanceDAO
import be.rlab.domino.domain.persistence.BillDAO
import be.rlab.domino.domain.persistence.BlockSignatureDAO
import be.rlab.domino.domain.persistence.TransactionDAO
import be.rlab.domino.util.persistence.TransactionSupport
import org.joda.time.DateTime
......@@ -18,9 +17,9 @@ class BalanceService(
private val balanceDAO: BalanceDAO,
private val transactionDAO: TransactionDAO,
private val billDAO: BillDAO,
private val blockSignatureDAO: BlockSignatureDAO,
private val treasuryConfig: TreasuryConfig,
private val accountService: AccountService
private val accountService: AccountService,
private val balanceFactory: BalanceFactory
) : TransactionSupport() {
/** Finds the balance for the treasury account within a period.
......@@ -36,24 +35,18 @@ class BalanceService(
year: Int,
month: Int
): Balance = transaction {
val account: Account = treasuryAccount()
val from = DateTime(year, month, 1, 0, 0, DateTimeZone.UTC)
val to = from.plusMonths(1)
val transactions: List<Transaction> = transactionDAO.findValidByPeriod(
treasuryConfig.group, from, to
)
val bills: List<Bill> = billDAO.findByPeriod(
treasuryConfig.group, from, to
)
resolveBalance(
balanceDAO.getByPeriod(account.id, from, to) ?: newBalance(
year = year,
month = month,
from = from,
to = to,
account = treasuryAccount(),
transactions = transactions,
bills = bills
account = account,
transactions = transactionDAO.findValidByPeriod(treasuryConfig.group, from, to),
bills = billDAO.findByPeriod(treasuryConfig.group, from, to)
)
}
......@@ -73,26 +66,18 @@ class BalanceService(
val from = DateTime(year, month, 1, 0, 0, DateTimeZone.UTC)
val to = from.plusMonths(1)
resolveBalance(
balanceDAO.getByPeriod(account.id, from, to) ?: newBalance(
year = year,
month = month,
from = from,
to = to,
account = account,
transactions = transactionDAO.findByPeriod(
accountId = account.id,
from = from,
to = to
),
bills = billDAO.findByPeriod(
accountId = account.id,
from = from.withZone(DateTimeZone.UTC),
to = to.withZone(DateTimeZone.UTC)
)
transactions = transactionDAO.findByPeriod(account.id, from, to),
bills = billDAO.findByPeriod(account.id, from, to)
)
}
private fun resolveBalance(
private fun newBalance(
year: Int,
month: Int,
from: DateTime,
......@@ -102,26 +87,32 @@ class BalanceService(
bills: List<Bill>
): Balance {
val currentDate: DateTime = DateTime.now()
.withDayOfMonth(1)
.withTimeAtStartOfDay()
.withZone(DateTimeZone.UTC)
val balance: Balance = Balance.new(
previousSignature = blockSignatureDAO.lastSignature(account.id),
val previousDate: DateTime = DateTime(year, month, 1, 0, 0, DateTimeZone.UTC)
.minusMonths(1)
.withTimeAtStartOfDay()
val previousBalance: Balance? = balanceDAO.getByPeriod(account.id, previousDate, previousDate.plusMonths(1))
val balance: Balance = balanceFactory.create(
account = account,
description = "Balance del período $year/$month",
from = from,
to = to,
description = "Balance del período $year/$month",
previousBalance = previousBalance,
transactions = transactions,
bills = bills
)
return balanceDAO.getByPeriod(account.id, from, to) ?:
if (year >= currentDate.year && month >= currentDate.monthOfYear)
// Current month.
balance
else
// Closed balance.
balanceDAO.saveOrUpdate(balance)
return if (year >= currentDate.year && month >= currentDate.monthOfYear) {
// Current month, balance is still open.
balance
} else {
// Closed balance.
balanceDAO.saveOrUpdate(balance)
}
}
private fun treasuryAccount(): Account =
......
......@@ -17,9 +17,10 @@ interface Activity {
val description: String
/** Returns the blockchain's block identity.
* @param signatureVersion Version of the signature to generate the block id for.
* @return a unique identity for this transaction.
*/
fun blockId(): String
fun blockId(signatureVersion: Int): String
/** Returns a short identifier for this activity.
* The short identifier is the absolute value of the [id] hashCode.
......
......@@ -22,10 +22,19 @@ data class Balance(
val from: DateTime,
val to: DateTime,
val transactions: List<Transaction>,
val bills: List<Bill>
val bills: List<Bill>,
val previousBalance: Value,
val debtsTotal: Value,
val debtsPending: Value,
val income: Value,
val monthlyBalance: Value,
val totalBalance: Value
) : Activity {
companion object {
private const val SIGNATURE_VERSION_1: Int = 1
private const val SIGNATURE_VERSION_2: Int = 2
fun new(
previousSignature: String,
account: Account,
......@@ -33,7 +42,13 @@ data class Balance(
from: DateTime,
to: DateTime,
transactions: List<Transaction>,
bills: List<Bill>
bills: List<Bill>,
previousBalance: Value,
debtsTotal: Value,
debtsPending: Value,
income: Value,
monthlyBalance: Value,
totalBalance: Value
): Balance {
val id: UUID = UUID.randomUUID()
val creationDate: DateTime = DateTime.now().withZone(DateTimeZone.UTC)
......@@ -42,15 +57,23 @@ data class Balance(
id = id,
creationDate = creationDate,
signature = calculateSignature(
previousSignature, id, creationDate, account.id,
description, from, to, transactionsId(transactions), billsId(bills)
SIGNATURE_VERSION_2, previousSignature, id, creationDate, account.id,
description, from, to, transactionsId(transactions), billsId(bills),
previousBalance, debtsTotal, debtsPending, income, monthlyBalance,
totalBalance
),
description = description,
account = account,
from = from,
to = to,
transactions = transactions,
bills = bills
bills = bills,
previousBalance = previousBalance,
debtsTotal = debtsTotal,
debtsPending = debtsPending,
income = income,
monthlyBalance = monthlyBalance,
totalBalance = totalBalance
)
}
......@@ -67,7 +90,19 @@ data class Balance(
}
}
override fun blockId(): String = buildSignature(
fields = listOf(from, to, transactionsId(transactions), billsId(bills))
)
override fun blockId(signatureVersion: Int): String {
return when (signatureVersion) {
SIGNATURE_VERSION_1 -> buildSignature(
fields = listOf(from, to, transactionsId(transactions), billsId(bills))
)
SIGNATURE_VERSION_2 -> buildSignature(
fields = listOf(
from, to, transactionsId(transactions), billsId(bills),
previousBalance, debtsTotal, debtsPending, income, monthlyBalance,
totalBalance
)
)
else -> throw IllegalArgumentException("Invalid signature version: $signatureVersion")
}
}
}
......@@ -125,7 +125,7 @@ data class Bill(
*/
fun partial(): Boolean = credit.payments.isNotEmpty()
override fun blockId(): String = buildSignature(
override fun blockId(signatureVersion: Int): String = buildSignature(
fields = listOf(credit.signature, debt.signature)
)
}
......@@ -71,7 +71,7 @@ data class Credit(
income = invalidIncome
)
override fun blockId(): String = buildSignature(
override fun blockId(signatureVersion: Int): String = buildSignature(
fields = listOf(debtor.id, income.signature)
)
}
......@@ -38,7 +38,7 @@ data class CreditNote(
}
}
override fun blockId(): String = buildSignature(
override fun blockId(signatureVersion: Int): String = buildSignature(
fields = listOf(transaction.id)
)
}
......@@ -87,7 +87,7 @@ data class Transaction(
}
}
override fun blockId(): String = buildSignature(
override fun blockId(signatureVersion: Int): String = buildSignature(
fields = listOf(type, value)
)
......
......@@ -20,9 +20,24 @@ object SignatureUtils {
accountId: UUID,
description: String,
vararg blockId: Any?
): BlockSignature = calculateSignature(
CURRENT_VERSION, previousSignature, id, creationDate,
accountId, description, *blockId
)
/** Calculates the signature for a transaction.
*/
fun calculateSignature(
signatureVersion: Int,
previousSignature: String,
id: UUID,
creationDate: DateTime,
accountId: UUID,
description: String,
vararg blockId: Any?
): BlockSignature {
return BlockSignature.new(
version = CURRENT_VERSION,
version = signatureVersion,
accountId = accountId,
creationDate = creationDate,
previous = previousSignature,
......@@ -41,15 +56,16 @@ object SignatureUtils {
fun calculateSignature(
activity: Activity
): BlockSignature {
val version: Int = activity.signature.version
return BlockSignature.new(
version = activity.signature.version,
version = version,
accountId = activity.account.id,
creationDate = activity.creationDate,
previous = activity.signature.previous,
signature = buildSignature(
fields = listOf(
activity.signature.previous, activity.id, activity.creationDate,
activity.account.id, activity.description, activity.blockId()
activity.account.id, activity.description, activity.blockId(version)
),
hash = true
)
......@@ -60,7 +76,10 @@ object SignatureUtils {
* @param fields Fields to build the signature.
* @param hash true to hash the signature, false otherwise.
*/
fun buildSignature(fields: List<Any?>, hash: Boolean = false): String {
fun buildSignature(
fields: List<Any?>,
hash: Boolean = false
): String {
val signature: String = fields.joinToString("!#")
return if (hash) {
......
package be.rlab.domino.application
import be.rlab.domino.application.model.BalanceDTO
import be.rlab.domino.domain.model.*
import be.rlab.domino.domain.model.Value.Companion.valueOf
import org.joda.time.DateTime
import org.junit.Test
class BalanceFactoryTest {
@Test
fun create() {
val previousBalance: Balance = TestBalance(
transactions = listOf(income(100.0), debt(200.0)),
bills = emptyList()
).new()
val balance: Balance = TestBalance(
transactions = listOf(
debt(300.0), debt(150.0), income(500.0), income(200.0)
),
bills = listOf(
TestBill(
debt = debt(200.0).invalidate(),
description = "factura de luz 1"
).new(),
TestBill(
debt = debt(300.0),
credit = TestCredit(
account = TestAccount(owner = TestAgent(userName = "foo").new()).new(),
income = income(300.0)
).new().cancel(valueOf(Currency.ARS, 50.0)),
description = "factura de luz 2",
dueDate = DateTime.parse("2019-07-30")
).new(),
TestBill(
debt = debt(150.0),
credit = TestCredit(
account = TestAccount(owner = TestAgent(userName = "bar").new()).new(),
income = income(150.0)
).new(),
description = "factura de agua",
dueDate = DateTime.parse("2019-07-28")
).new()
)
).new()
val factory = BalanceFactory()
val balanceDto: BalanceDTO = factory.create(previousBalance, balance)
assert(balanceDto.previousBalance == valueOf(Currency.ARS, -100.0))
assert(balanceDto.monthlyBalance == valueOf(Currency.ARS, 250.0))
assert(balanceDto.debtsPending == valueOf(Currency.ARS, 400.0))
assert(balanceDto.debtsTotal == valueOf(Currency.ARS, 450.0))
assert(balanceDto.income == valueOf(Currency.ARS, 700.0))
assert(balanceDto.totalBalance == valueOf(Currency.ARS, 150.0))
assert(balanceDto.bills.size == 2)
assert(balanceDto.bills[0].pending)
assert(balanceDto.bills[0].debt == valueOf(Currency.ARS, 250.0))
assert(balanceDto.bills[0].dueDate == DateTime.parse("2019-07-30"))
assert(balanceDto.bills[0].total == valueOf(Currency.ARS, 300.0))
assert(balanceDto.bills[0].serviceName == "foo")
assert(balanceDto.bills[1].pending)
assert(balanceDto.bills[1].debt == valueOf(Currency.ARS, 150.0))
assert(balanceDto.bills[1].dueDate == DateTime.parse("2019-07-28"))
assert(balanceDto.bills[1].total == valueOf(Currency.ARS, 150.0))
assert(balanceDto.bills[1].serviceName == "bar")
}
private fun debt(value: Double): Transaction {
return TestTransaction(
type = TransactionType.DEBT,
value = valueOf(Currency.ARS, value)
).new()
}
private fun income(value: Double): Transaction {
return TestTransaction(
type = TransactionType.DEPOSIT,
value = valueOf(Currency.ARS, -value)
).new()
}
}
\ No newline at end of file
package be.rlab.domino.domain
import be.rlab.domino.application.model.BillDTO
import be.rlab.domino.domain.model.*
import be.rlab.domino.domain.model.Value.Companion.valueOf
import be.rlab.domino.util.mock.TestBlockSignatureDAO
import org.joda.time.DateTime
import org.junit.Test
class BalanceFactoryTest {
private val blockSignatureDAO: TestBlockSignatureDAO = TestBlockSignatureDAO()
@Test
fun create() {
val previousBalance: Balance = TestBalance(
transactions = emptyList(),
bills = emptyList(),
monthlyBalance = valueOf(Currency.ARS, 100.0)
).new()
val transactions: List<Transaction> = listOf(
debt(300.0), debt(150.0), income(500.0), income(200.0)
)
val bills: List<Bill> = listOf(
TestBill(
debt = debt(200.0).invalidate(),
description = "factura de luz 1"
).new(),
TestBill(
debt = debt(300.0),
credit = TestCredit(
account = TestAccount(owner = TestAgent(userName = "foo").new()).new(),
income = income(300.0)
).new().cancel(valueOf(Currency.ARS, 50.0)),
description = "factura de luz 2",
dueDate = DateTime.parse("2019-07-30")
).new(),
TestBill(
debt = debt(150.0),
credit = TestCredit(
account = TestAccount(owner = TestAgent(userName = "bar").new()).new(),
income = income(150.0)
).new(),
description = "factura de agua",
dueDate = DateTime.parse("2019-07-28")
).new()
)
val account: Account = TestAccount().new()
val factory = BalanceFactory(
blockSignatureDAO = blockSignatureDAO
.lastSignature(account.id, "signature")
.instance
)
val to: DateTime = DateTime.now()
val from: DateTime = to.minusMonths(1)
val balance: Balance = factory.create(
account = account,
from = from,
to = to,
description = "test balance",
previousBalance = previousBalance,
transactions = transactions,
bills = bills
)
assert(balance.previousBalance == valueOf(Currency.ARS, 100.0))
assert(balance.monthlyBalance == valueOf(Currency.ARS, -250.0))
assert(balance.debtsPending == valueOf(Currency.ARS, 400.0))
assert(balance.debtsTotal == valueOf(Currency.ARS, 450.0))
assert(balance.income == valueOf(Currency.ARS, -700.0))
assert(balance.totalBalance == valueOf(Currency.ARS, -150.0))
assert(balance.bills.size == 2)
val bill1: BillDTO = BillDTO.from(balance.bills[0])
val bill2: BillDTO = BillDTO.from(balance.bills[1])
assert(bill1.pending)
assert(bill1.debt == valueOf(Currency.ARS, 250.0))
assert(bill1.dueDate == DateTime.parse("2019-07-30"))
assert(bill1.total == valueOf(Currency.ARS, 300.0))
assert(bill1.serviceName == "foo")
assert(bill2.pending)
assert(bill2.debt == valueOf(Currency.ARS, 150.0))
assert(bill2.dueDate == DateTime.parse("2019-07-28"))
assert(bill2.total == valueOf(Currency.ARS, 150.0))
assert(bill2.serviceName == "bar")
}
private fun debt(value: Double): Transaction {
return TestTransaction(
type = TransactionType.DEBT,
value = valueOf(Currency.ARS, value)
).new()
}
private fun income(value: Double): Transaction {
return TestTransaction(
type = TransactionType.DEPOSIT,
value = valueOf(Currency.ARS, -value)
).new()
}
}
\ No newline at end of file
......@@ -14,7 +14,7 @@ class BalanceServiceTest {
private val balanceDAO: TestBalanceDAO = TestBalanceDAO()
private val billDAO: TestBillDAO = TestBillDAO()
private val accountService: TestAccountService = TestAccountService()
private val blockSignatureDAO: TestBlockSignatureDAO = TestBlockSignatureDAO()
private val balanceFactory: TestBalanceFactory = TestBalanceFactory()
@Test
fun find_exists() {
......@@ -28,11 +28,9 @@ class BalanceServiceTest {
.instance,
transactionDAO = transactionDAO.instance,
billDAO = billDAO.instance,
blockSignatureDAO = blockSignatureDAO
.lastSignature(account.id, "test-signature")
.instance,
treasuryConfig = mock(),
accountService = accountService.instance
accountService = accountService.instance,
balanceFactory = balanceFactory.instance
))
assert(service.find(account, 2019, 6) == balance)
}
......@@ -40,14 +38,17 @@ class BalanceServiceTest {
@Test
fun find_createNew() {
val from = DateTime(2019, 5, 1, 0, 0, DateTimeZone.UTC)
val previousDate: DateTime = DateTime(2019, 5, 1, 0, 0, DateTimeZone.UTC).minusMonths(1)
val to = from.plusMonths(1)
val account: Account = TestAccount().new()
val balance: Balance = mock()
val balance: Balance = TestBalance().new()
val previousBalance: Balance = TestBalance().new()
val bills: List<Bill> = emptyList()
val transactions: List<Transaction> = emptyList()
val service = initTransaction(BalanceService(
balanceDAO = balanceDAO
.getByPeriod(account.id, from, to, null)
.getByPeriod(account.id, previousDate, previousDate.plusMonths(1), previousBalance)
.saveOrUpdate(balance)
.instance,
transactionDAO = transactionDAO
......@@ -56,11 +57,11 @@ class BalanceServiceTest {
billDAO = billDAO
.findByPeriod(account.id, from, to, bills)
.instance,
blockSignatureDAO = blockSignatureDAO
.lastSignature(account.id, "test-signature")
.instance,
treasuryConfig = mock(),
accountService = accountService.instance
accountService = accountService.instance,
balanceFactory = balanceFactory
.create(account, from, to, "Balance del período 2019/5", previousBalance, transactions, bills, balance)
.instance
))
assert(service.find(account, 2019, 5) == balance)
......@@ -68,13 +69,7 @@ class BalanceServiceTest {
transactionDAO.verifyAll()
balanceDAO.verifyAll()
val result: Balance = balanceDAO.capturedValue("saveOrUpdate")
assert(result.account == account)
assert(result.description == "Balance del período 2019/5")
assert(result.from == from)
assert(result.to == to)
assert(result.transactions == transactions)
assert(result.bills == bills)
assert(balance == balanceDAO.capturedValue("saveOrUpdate"))
}
@Test
......@@ -95,13 +90,11 @@ class BalanceServiceTest {
billDAO = billDAO
.findByPeriod("rlyeh", from, to, bills)
.instance,
blockSignatureDAO = blockSignatureDAO
.lastSignature(treasuryAccount.id, "test-signature")
.instance,
treasuryConfig = TreasuryConfig("rlyeh", 100),
accountService = accountService
.findTreasuryAccount(treasuryAccount)
.instance
.instance,
balanceFactory = balanceFactory.instance
))
assert(service.findForTreasury(2019, 5) == balance)
......@@ -113,14 +106,17 @@ class BalanceServiceTest {
@Test
fun findForTreasury_new() {
val from = DateTime(2019, 5, 1, 0, 0, DateTimeZone.UTC)
val previousDate: DateTime = DateTime(2019, 5, 1, 0, 0, DateTimeZone.UTC).minusMonths(1)
val to = from.plusMonths(1)
val treasuryAccount: Account = TestAccount().new()
val balance: Balance = mock()
val balance: Balance = TestBalance().new()
val previousBalance: Balance = TestBalance().new()
val bills: List<Bill> = emptyList()
val transactions: List<Transaction> = emptyList()
val service = initTransaction(BalanceService(
balanceDAO = balanceDAO
.getByPeriod(treasuryAccount.id, from, to, null)
.getByPeriod(treasuryAccount.id, previousDate, previousDate.plusMonths(1), previousBalance)
.saveOrUpdate(balance)
.instance,
transactionDAO = transactionDAO
......@@ -129,12 +125,14 @@ class BalanceServiceTest {
billDAO = billDAO
.findByPeriod("rlyeh", from, to, bills)
.instance,
blockSignatureDAO = blockSignatureDAO
.lastSignature(treasuryAccount.id, "test-signature")
.instance,
treasuryConfig = TreasuryConfig("rlyeh", 100),
accountService = accountService
.findTreasuryAccount(treasuryAccount)
.instance,
balanceFactory = balanceFactory
.create(treasuryAccount, from, to, "Balance del período 2019/5",
previousBalance, transactions, bills, balance
)
.instance
))
assert(service.findForTreasury(2019, 5) == balance)
......@@ -143,13 +141,7 @@ class BalanceServiceTest {
transactionDAO.verifyAll()
balanceDAO.verifyAll()
val result: Balance = balanceDAO.capturedValue("saveOrUpdate")
assert(result.account == treasuryAccount)
assert(result.description == "Balance del período 2019/5")
assert(result.from == from)
assert(result.to == to)
assert(result.transactions == transactions)
assert(result.bills == bills)
assert(balance == balanceDAO.capturedValue("saveOrUpdate"))
}
@Test
......@@ -158,13 +150,19 @@ class BalanceServiceTest {
.withZone(DateTimeZone.UTC)
.withDayOfMonth(1)
.withTimeAtStartOfDay()
val previousDate: DateTime = DateTime(from.year, from.monthOfYear, 1, 0, 0, DateTimeZone.UTC)
.minusMonths(1)
.withTimeAtStartOfDay()
val to = from.plusMonths(1)
val treasuryAccount: Account = TestAccount().new()
val bills: List<Bill> = emptyList()
val transactions: List<Transaction> = emptyList()
val previousBalance: Balance = TestBalance().new()
val balance: Balance = TestBalance().new()
val service = initTransaction(BalanceService(
balanceDAO = balanceDAO
.getByPeriod(treasuryAccount.id, from, to, null)
.getByPeriod(treasuryAccount.id, previousDate, previousDate.plusMonths(1), previousBalance)
.instance,
transactionDAO = transactionDAO
.findByPeriod("rlyeh", from, to, transactions)
......@@ -172,12 +170,14 @@ class BalanceServiceTest {
billDAO = billDAO
.findByPeriod("rlyeh", from, to, bills)
.instance,
blockSignatureDAO = blockSignatureDAO
.lastSignature(treasuryAccount.id, "test-signature")
.instance,
treasuryConfig = TreasuryConfig("rlyeh", 100),
accountService = accountService
.findTreasuryAccount(treasuryAccount)
.instance,
balanceFactory = balanceFactory
.create(treasuryAccount, from, to, "Balance del período ${from.year}/${from.monthOfYear}",
previousBalance, transactions, bills, balance
)
.instance
))
......@@ -186,11 +186,6 @@ class BalanceServiceTest {
transactionDAO.verifyAll()
balanceDAO.verifyAll()
assert(result.account == treasuryAccount)
assert(result.description == "Balance del período ${from.year}/${from.monthOfYear}")
assert(result.from == from)
assert(result.to == to)
assert(result.transactions == transactions)
assert(result.bills == bills)
assert(result == balance)
}
}
\ No newline at end of file
......@@ -46,7 +46,7 @@ data class TestActivity(
}
}
override fun blockId(): String = buildSignature(
override fun blockId(signatureVersion: Int): String = buildSignature(
fields = listOf()
)
}
......@@ -9,7 +9,13 @@ data class TestBalance(
val from: DateTime = DateTime.now().minusDays(60),
val to: DateTime = DateTime.now().minusDays(30),
val transactions: List<Transaction> = emptyList(),
val bills: List<Bill> = emptyList()
val bills: List<Bill> = emptyList(),
val previousBalance: Value = Value.ZERO,
val debtsTotal: Value = Value.ZERO,
val debtsPending: Value = Value.ZERO,
val income: Value = Value.ZERO,
val monthlyBalance: Value = Value.ZERO,
val totalBalance: Value = Value.ZERO
) {
fun new(): Balance = Balance.new(
previousSignature = INITIAL_SIGNATURE,
......@@ -18,6 +24,12 @@ data class TestBalance(
from = from,
to = to,
transactions = transactions,
bills = bills
bills = bills,
previousBalance = previousBalance,
debtsTotal = debtsTotal,
debtsPending = debtsPending,
income = income,
monthlyBalance = monthlyBalance,
totalBalance = totalBalance
)
}
......@@ -28,8 +28,15 @@ class BalanceDAOTest : ActivityDAOTestSupport() {
from = from,
to = to,
transactions = listOf(transaction),
bills = listOf(bill)
bills = listOf(bill),
previousBalance = Value.ZERO,
debtsTotal = Value.ZERO,
debtsPending = Value.ZERO,
income = Value.ZERO,
monthlyBalance = Value.ZERO,
totalBalance = Value.ZERO
)
assert(balanceDAO.saveOrUpdate(balance) == balance)
}
}
package be.rlab.domino.util.mock
import be.rlab.domino.domain.BalanceFactory
import be.rlab.domino.domain.model.Account
import be.rlab.domino.domain.model.Balance
import be.rlab.domino.domain.model.Bill
import be.rlab.domino.domain.model.Transaction
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import org.joda.time.DateTime
class TestBalanceFactory {
val instance: BalanceFactory = mock()
fun create(
account: Account,
from: DateTime,
to: DateTime,
description: String,
previousBalance: Balance?,
transactions: List<Transaction>,
bills: List<Bill>,
result: Balance
): TestBalanceFactory {
whenever(instance.create(
account, from, to, description, previousBalance,
transactions, bills
)).thenReturn(result)
return this
}
}