#!/usr/local/qddb/bin/qtclsh

#
# monthly_close.tcl --
#
#     monthly_close.tcl is run at the end of each month to
#     apply interest(if arg specified) and to update the
#     recent/30/60/90 buckets on the Client tuple.
#
#     Synopsis:
#         monthly_close <interest rate optional>
#
#         NOTE: if no interest rate specified on command line, then
#               no service charge will be applied.
# 
#     Process:
#         Each customer in the Clients relation is processed
#         to apply a service charge and to move the appropriate
#         balance buckets.  If a customer has any outstanding
#         balance in the 30/60/90 buckets, then a service charge
#         will be entered as an Invoice Item and applied 
#         appropriately to the Client tuple.
#

#
# Append the necessary utils libraries
#
set tcl_precision 17 
lappend auto_path . $qddb_library/fx /usr/local/Qba/bin/library

if {$argc > 1} {
    puts "Usage: monthly_close <optional interest rate>\n"
    puts "Note: if run with no args, no interest rate will be applied."
    exit
}

if {$argc == 1} {
    set ir [expr [lindex $argv 0] * 0.01]
} else {
    set ir 0
}

puts "Applying interest of $ir to delinquent customers:"

#
# Open the Clients relation and then loop through each client 
# tuple to update balances(recent/30/60/90).  If interest
# was specified as command line arg, then apply and update
# via a Service Charge Transaction
#
set s [qddb_schema open /var/lib/qdDBs/Qba/Clients]
set k [qddb_search $s -prunebyattr Company.Contact.ID regexp .*]
foreach i [qddb_keylist get $k] {
    set t [qddb_tuple read $s $i]
    if { $t == "" } {
	puts "Corrupt data in Client Relation, contact someone."
	exit
    }
    set v [qddb_view define $t {
	{ Company.Contact.ID         carr(Company.Contact.ID) }
	{ CurrentBalance             carr(CurrentBalance) }
	{ Recent                     carr(Recent) }
	{ Balance30                  carr(Balance30) }
	{ Balance60                  carr(Balance60) }
	{ Balance90                  carr(Balance90) }
	{ Transaction.Date           carr(Transaction.Date) }
	{ Transaction.Clock          carr(Transaction.Clock) }
	{ Transaction.TType          carr(Transaction.TType) }
	{ Transaction.InvoiceNumber  carr(Transaction.InvoiceNumber) }
	{ Transaction.Amount         carr(Transaction.Amount) }
	{ Transaction.RunningBalance carr(Transaction.RunningBalance) }
    }]
    #
    # If no outstanding balance, don't update this client, go to next one.
    #
    if { $carr(CurrentBalance) <= 0 } {
	qddb_tuple delete $t
	qddb_keylist delete $i
	continue
    }
    #
    # if interest rate, add new service charge transaction
    #
    if {$ir != 0} {
	set ip [expr $ir * $carr(CurrentBalance)]
	set ip [currency_format $ip ROUND]
	qddb_instance switch $v Transaction \
		[qddb_instance new $v Transaction]
	set carr(Transaction.Date) \
		[qddb_util formatdate "%m/%d/%y" today]
	set carr(Transaction.Clock) [qddb_util formatdate "%X" now]
	set carr(Transaction.TType) "Late Payment Charge"
	set carr(Transaction.InvoiceNumber) ""
	set carr(Transaction.Amount) $ip
	set carr(Transaction.RunningBalance) [expr $carr(CurrentBalance) + $ip]
	set carr(CurrentBalance) $carr(Transaction.RunningBalance)
    }

    # Adjust the balance buckets like so:
    #     90d += 60d
    #     60d = 30d
    #     30d = Recent
    #     Recent = 0
    set carr(Balance90) [expr $carr(Balance90) + $carr(Balance60)]
    set carr(Balance60) $carr(Balance30)
    set carr(Balance30) $carr(Recent)
    set carr(Recent) $ip

    # output to stdout to let you know what's happening...
    puts "Client ID:      $carr(Company.Contact.ID)"
    puts "Service Charge: $ip"
    puts "New Balance:    $carr(CurrentBalance)"
    puts "\n\n"

    # store the updates
    qddb_tuple write $t

    qddb_tuple delete $t
    qddb_keylist delete $i
}

qddb_schema close $s
