I'm currently working on a project that requires a variable fee schedule.
E.g.
Product Name | Category | Feature | Value | Date Range | Functional Setting Applicability | |
---|---|---|---|---|---|---|
General ACH Generation | ||||||
ACH Generation Fees | ACH Transaction Fee | 1.00 | Account Open Date | Account Closed Date | 0 to 10 transactions | |
ACH Transaction Fee | .50 | Account Open Date | Account Closed Date | 10 or more transactions | ||
Credit Card Generation Fees | CC Transaction Fee | 1.00 | Account Open Date | Account Closed Date | 0 to 10 transactions | |
CC Transaction Fee | .50 | Account Open Date | Account Closed Date | 10 or more transactions |
I need a way to specify the date range that would include things such as account open date and plus 3 months and transaction ranges. Groovy DSL seems like the perfect fit. See Guillame Laforge's example here.
I came up with the following:
package com.aps.utils
import com.aps.util.DateUtil
import org.codehaus.groovy.runtime.TimeCategory
class ProductCatalogDSLTests extends GroovyTestCase {
def account
void setUp() {
account = new Account(from: DateUtil.sdf.parse("01-01-2010"))
}
void testAccountOpenedDate() {
def rule = 'transactionDate > account.from'
def binding = new Binding()
binding.account = account
def shell = new GroovyShell(binding)
def date = DateUtil.sdf.parse('01-10-2010')
binding.transactionDate = date
assert shell.evaluate(rule)
binding.transactionDate = DateUtil.sdf.parse('05-10-2009')
assertFalse shell.evaluate(rule)
}
void testAccountOpenedDate_plus3() {
def rule = 'transactionDate < account.from+6.months'
def binding = new Binding()
binding.account = account
def shell = new GroovyShell(binding)
def date = DateUtil.sdf.parse('01-10-2010')
binding.transactionDate = date
use(TimeCategory) {
assert shell.evaluate(rule)
binding.transactionDate = DateUtil.sdf.parse('05-10-2010')
assert shell.evaluate(rule)
}
}
void testTransactionMinimum() {
def rule1 = 'account.transactions.size < 10'
def rule2 = 'account.transactions.size >= 10'
def date = DateUtil.sdf.parse('01-10-2010')
0..5.each {
account.transactions << new AccountTransaction(amount: 15.00, postDate: date)
}
def binding = new Binding()
binding.account = account
def shell = new GroovyShell(binding)
binding.transactionDate = date
use(TimeCategory) {
assert shell.evaluate(rule1)
assertFalse shell.evaluate(rule2)
}
}
void testTransactionMinimumThisMonth() {
def rule1 = 'account.transactions.collect{it.postDate.month == transactionDate.month}.size < 10'
def rule2 = 'account.transactions.collect{it.postDate.month == transactionDate.month}.size >= 10'
def date = DateUtil.sdf.parse('01-10-2010')
use(TimeCategory) {
assertEquals 0 , date.month
assertEquals 10 , date.date
assertEquals 2010 - 1900 , date.year
0..5.each {
account.transactions << new AccountTransaction(amount: 15.00, postDate: date)
}
def binding = new Binding()
binding.account = account
def shell = new GroovyShell(binding)
binding.transactionDate = date
assert shell.evaluate(rule1)
assertFalse shell.evaluate(rule2)
}
}
}
class Account {
Date from
Date to
def transactions = []
}
class AccountTransaction {
BigDecimal amount
Date postDate
}
It ended up working well for dynamic business rule selectors.