#!/usr/local/qddb/bin/qwish -f
#
# payments.tcl --
#
# This module paints the Payment window and handles the actions
# on the Payments relation.  The payments window provides user's 
# with another option, other than the invoice window, to enter 
# a customer's payment.
#

set tcl_precision 17
set ISPUTIL /var/lib/ISPutil
lappend auto_path . $qddb_library/fx $blt_library $blt_library/dd_protocols \
	$ISPUTIL/bin/library


#
# Payment Class
#     This class paints the Payments window.  Most of the work
#     is handled by Qddb Fx library.
#
itcl_class Payment {
    constructor {config} {
	global fx_config_dir DragDrop
	wm title . "Payment Received: <Search Mode>"
	wm withdraw .
	if {[catch "qddb_schema open Payments" s] != 0} {
	    puts "Cannot open Schema for Payments, contact someone"; exit 1
	}
	set fx_config_dir .payment_config
	Fx:Init $s
	Fx_Menubar menubar -w .mb -schema $s -array gv_myattr \
		-config_dir .client_config \
		-afteraddmode {wm title . "Payment Received: <Add Mode>"} \
		-aftersearchmode {wm title . "Payment Received: <Search Mode>"}\
		-afterchangemode  [list $this afterchangemode] \
		-beforesave [list $this beforeSave] \
		-restrict [glob ~]/.qba_config/Payments
	set gv_search_entry [menubar SearchForEntry]
	frame .f1  -relief groove -bd 2
	frame .f1.a 
	frame .f1.b
	frame .f1.c
 	Fx_Entry company     -w .f1.a.company  -attr Company \
		-setschema $s -searchfor_entry $gv_search_entry \
		-restrict [glob ~]/.qba_config/Payments
	Fx_Entry dateofpmt   -w .f1.a.date     -attr DateOfPayment
	Fx_Entry first       -w .f1.b.first    -attr Name.First
	Fx_Entry last        -w .f1.b.last     -attr Name.Last
	Fx_Entry id          -w .f1.b.id       -attr Name.ID
	Fx_Entry uname       -w .f1.c.uname    -attr Name.Username
	Fx_Entry ssn         -w .f1.c.ssn      -attr Name.SSN
	pack forget .f1.a.company .f1.a.date .f1.b.first .f1.b.last \
		.f1.b.id .f1.c.ssn .f1.c.uname
	pack .f1.a .f1.b .f1.c -side top  -fill x -expand yes
	pack .f1               -side top  -fill x -expand yes
	pack .f1.a.company     -side left -fill x -expand yes
	pack .f1.a.date        -side left
	pack .f1.b.first .f1.b.last .f1.b.id -side left
	pack .f1.c.uname -side left
	pack .f1.c.ssn -side left -fill x -expand yes
	.f1.a.company.f_0.l configure -text "Company:"  -width $lwidth
	.f1.a.date.f_0.l    configure -text "Date:"     -width 6
	.f1.a.date.e        configure -width 10
	.f1.b.first.f_0.l   configure -text "First/Last/ID:" -width $lwidth
	.f1.b.last.f_0.l    configure -bitmap @$bitmapdir/bluedot.xpm
	.f1.b.id.f_0.l      configure -bitmap @$bitmapdir/bluedot.xpm
	.f1.c.uname.f_0.l   configure -text "Username:" -width $lwidth
	.f1.c.ssn.f_0.l     configure -text "SSN:" -width 8

	frame .f2  -relief groove -bd 2
	frame .f2.a 
	frame .f2.b
	Fx_Entry mop  -w .f2.a.mop   -attr MethodOfPayment -type Radiobutton \
	    -default_values "Visa Mastercard Check Cash"
	Fx_Entry cc   -w .f2.b.cc       -attr CreditCard
	Fx_Entry doe  -w .f2.b.doe      -attr DateOfExp
	pack forget .f2.a.mop .f2.b.cc .f2.b.doe
	pack .f2.a .f2.b -side top  -fill x -expand yes
	pack .f2         -side top  -fill x -expand yes
	pack .f2.a.mop   -side top  -fill x -expand yes
	pack .f2.b.cc    -side left -fill x -expand yes
	pack .f2.b.doe   -side left -fill x -expand yes
	.f2.a.mop.f_0.l  configure -text "Method of Payment:"  -width $lwidth
	.f2.b.cc.f_0.l   configure -text "Credit Card#:"       -width $lwidth
	.f2.b.cc.e       configure -width 20
	.f2.b.doe.f_0.l  configure -text "Date of Expiration:" -width $lwidth

	frame .f3  -relief groove -bd 2
	frame .f3.a
	Fx_Entry amt  -w .f3.a.amt      -attr Amount
	pack forget .f3.a.amt
	pack .f3.a       -side top -fill x -expand yes
	pack .f3         -side top  -fill x -expand yes
	pack .f3.a.amt   -side top -anchor w
	.f3.a.amt.f_0.l  configure -text "Amount of Payment:"  -width $lwidth
	.f3.a.amt.e      configure -width 10

	frame .f4 -bd 4 -relief groove
	pack .f4 -side top -fill x -expand yes
	Fx_Entry comments -w .f4.comments -attr Comments  -type Text \
		-height 3 -side top
	#
	# Set the drop area to the entire window; makes it easier for user.
	#
	blt::drag&drop target . handler customer  [list $this dragDropCustomer]
	blt::drag&drop target . handler inventory [list $this dragDropCustomer]
	blt::drag&drop errors [list $this dragDropErrorHandler]

	menubar configure -instances [Fx_Entry::GetInstances] \
		-frames [Fx_Frame::GetInstances]
	menubar SearchModeProc
	wm deiconify .
    }
    method config {config} {}
    method afterchangemode {} {
	global gv_myattr
	wm title . "Payment Received: $gv_myattr(Name.First) \ $gv_myattr(Name.Last)"
    }

    #
    # Before saving the payment, be sure to update Clients
    # If customer exists, then add this transaction to Transaction attr.
    # If customer does not exist, then display a confirm dialog box
    # to confirm adding new customer to Clients
    #
    method beforeSave {} {
	global gv_myattr carr gv_pmtamt fx:status_variable
	#
	# Update customer. Key on customer ID for now (later, make this better)
	# If customer ID not found, have user first create the customer on the
	# client screen.  Then, drag the customer to the invoice screen
	#
	if {[catch "qddb_schema open Clients" c_s] != 0} {
	    puts "Cannot open Clients Schema"; exit 1
	}
	set c_k [qddb_search $c_s -prunebyattr \
		Company.Contact.Username word $gv_myattr(Name.Username)]
	set c_k1 [qddb_keylist get $c_k]
	set c_t [isUniqueTuple $c_k1 $c_s]
	if { $c_t == "" } {
	    tk_dialog .dialog "Info" \
		    "Customer not found, or duplicate customer." info 0 Ok 
	    qddb_keylist delete all
	    qddb_tuple delete all
	    qddb_schema close $c_s
	    return
	}
	while {[qddb_tuple lock $c_t] == 0} {
	    set fx:status_variable "Waiting for Customer screen to be closed...."
	    update idletasks
	    exec sleep 2
	    set fx:status_variable ""
	    update idletasks
	}	    
	set c_v [qddb_view define $c_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) }
	}]
	qddb_instance switch $c_v Transaction \
		[qddb_instance new $c_v Transaction]
	::set carr(Transaction.Date)          $gv_myattr(DateOfPayment)
	::set carr(Transaction.Clock)         [qddb_util formatdate "%X" now]
	::set carr(Transaction.TType)         "Payment"
	::set carr(Transaction.InvoiceNumber) "0"
	::set carr(Transaction.Amount)        $gv_myattr(Amount)
	::set carr(Transaction.RunningBalance) \
		[expr $carr(CurrentBalance) - $gv_myattr(Amount)]
	::set carr(CurrentBalance) $carr(Transaction.RunningBalance)

	set gv_pmtamt $gv_myattr(Amount)
        if { $gv_pmtamt > 0 } {
	    #
	    # Since, there was a payment, first subtract from 90,60,30
	    # in that order
	    #
	    set remainder $gv_pmtamt
	    if { $carr(Balance90) > 0 } {
		if {$carr(Balance90) >= $gv_pmtamt} {
		    ::set carr(Balance90) [expr $carr(Balance90) - $gv_pmtamt]
		    set remainder 0
		} else {
		    set remainder [expr $gv_pmtamt - $carr(Balance90)]
		    ::set carr(Balance90) 0
		}
	    }
	    if { $remainder != 0 && $carr(Balance60) > 0 } {
		if {$carr(Balance60) >= $remainder} {
		    ::set carr(Balance60) [expr $carr(Balance60) - $remainder]
		    set remainder 0
		} else {
		    set remainder [expr $remainder - $carr(Balance60)]
		    ::set carr(Balance60) 0
		}
	    }
	    if { $remainder != 0 && $carr(Balance30) > 0 } {
		if {$carr(Balance30) >= $remainder} {
		    ::set carr(Balance30) [expr $carr(Balance30) - $remainder]
		    set remainder 0
		} else {
		    ::set remainder [expr $remainder - $carr(Balance30)]
		    ::set carr(Balance30) 0
		}
	    }
	    if { $remainder != 0 } {
		if {$carr(Recent) >= $remainder} {
		    ::set carr(Recent) [expr $carr(Recent) - $remainder]
		    set remainder 0
		} else {
		    ::set carr(Recent) "-[expr $remainder - $carr(Recent)]"
		}
	    }
	}
	qddb_tuple write $c_t
	qddb_tuple delete $c_t
	qddb_schema close $c_s
    }
    method dragDropErrorHandler {} {
    }
    method dragDropCustomer {} {
	global DragDrop gv_myattr fx:mode_variable
	if { ${fx:mode_variable} == "Read-only Mode" } {
	    tk_dialog .dialog "Info" \
		    "Unable to Drag-n-Drop in Read-only mode." \
		    info 0 Ok 
	    return 0
	}
	::set gv_myattr(Company)            [lindex $DragDrop(inventory) 0 ]
	::set gv_myattr(Name.First)         [lindex $DragDrop(inventory) 1 ]
	::set gv_myattr(Name.Last)          [lindex $DragDrop(inventory) 2 ]
	::set gv_myattr(Name.ID)            [lindex $DragDrop(inventory) 3 ]

	set type [lindex $DragDrop(inventory) 15 ]
	::set gv_myattr(CreditCard)     [lindex $DragDrop(inventory) 17 ]
	::set gv_myattr(DateOfExp)      [lindex $DragDrop(inventory) 18 ]
	#
	# choose Cash radiobutton and disable payment method to prevent
	# user selecting anything else -- if customer is COD/Cash only
	#
	if { $type == "COD/Cash only" } {
	    ::set gv_myattr(MethodOfPayment) "Cash"
	    .f2.a.mop.e.r0 configure -state disabled
	    .f2.a.mop.e.r1 configure -state disabled
	    .f2.a.mop.e.r2 configure -state disabled
	} else {
	    ::set gv_myattr(MethodOfPayment) $default_payment
	}
    }
    public rootdir /var/lib/ISPutil/bin {}
    public bitmapdir /var/lib/ISPutil/bitmaps {}
    ##public fx_config_dir .client_config
    public lwidth 25 {}
}

Payment payment
