#include "fivewin.ch"
#DEFINE _KEY 1
#DEFINE _PAID 1
#DEFINE _EXPECTED 2
#DEFINE _PENDING 3
STATIC aItems := { { "Id 1", { "Line 1", 100.00, 200.00, 0.00 },;
{ "Line 2", 150.00, 100.00, 0.00 } },;
{ "Id 2", { "Line 1", 300.00, 200.00, 0.00 },;
{ "Line 2", 450.00, 100.00, 0.00 } },;
{ "Id 3", { "Line 1", 100.00, 200.00, 0.00 },;
{ "Line 2", 150.00, 100.00, 0.00 } },;
{ "Id 4", { "Line 1", 300.00, 200.00, 0.00 },;
{ "Line 2", 450.00, 100.00, 0.00 } } }
//------------------------------------------------------------------------------------------------
FUNCTION start()
LOCAL oApp := TApp():New()
oApp:CreateTree()
oApp:Init()
ACTIVATE WINDOW oApp:oWnd ON INIT oApp:ReCalculateCompleteTree()
RETURN NIL
//------------------------------------------------------------------------------------------------
CLASS TApp
DATA oBrw, oWnd, oTree, oFont12_bold
METHOD New() INLINE SELF
METHOD init()
METHOD CreateTree()
METHOD SubTree()
METHOD ReCalculate()
METHOD ReCalculateCompleteTree()
METHOD PayEachLeaf()
ENDCLASS
//------------------------------------------------------------------------------------------------
METHOD init()
DEFINE FONT ::oFont12_bold NAME "ARIAL" SIZE 6,-12 BOLD
DEFINE WINDOW ::oWnd
@ 0, 0 XBROWSE ::oBrw OF ::oWnd FOOTERS FASTEDIT
::oBrw:SetTree( ::oTree )
ADD TO ::oBrw DATA ::oBrw:oTreeItem:Cargo[ _PAID ] HEADER "AmtPaid" //2
ADD TO ::oBrw DATA ::oBrw:oTreeItem:Cargo[ _EXPECTED ] HEADER "Expected" PICTURE "9,999,999.99"
ADD TO ::oBrw DATA ::oBrw:oTreeItem:Cargo[ _PENDING ] HEADER "Pending" PICTURE "9,999,999.99"
WITH OBJECT ::oBrw:AmtPaid
:bOnPostEdit := { |o,x| ::oBrw:oTreeItem:Cargo[ _PAID ]:= x , ::ReCalculate() }
:nEditType := EDIT_GET_BUTTON
:bEditBlock := { |R, C, o, K| ;
IF( ::oBrw:oTreeItem:nLevel == 1, ;
::PayEachLeaf(), ;
iif( EMPTY( ::oBrw:oTreeItem:Cargo[ _PAID ] ),;
::oBrw:oTreeItem:Cargo[ _PAID ] := ::oBrw:oTreeItem:Cargo[ _EXPECTED ],;
::oBrw:oTreeItem:Cargo[ _PAID ] := 0.00 ) ),;
::ReCalculate() }
END
AEVAL( ::oBrw:aCols, { |o| o:oDataFont := {|| iif( ::oBrw:oTreeItem:nLevel == 1, ::oFont12_bold, ::oBrw:oFont ) } } )
AEVAL( ::oBrw:aCols, { |e| e:nDataStrAlign := AL_RIGHT,;
e:nWidth := 70,;
e:cEditPicture := "999,999.99",;
e:nFooterType := AGGR_TOTAL,;
e:oFooterFont := ::oFont12_bold,;
e:nFootStrAlign := AL_RIGHT }, 2, 4 )
::oBrw:CreateFromCode()
::oWnd:oClient := ::oBrw
return nil
//------------------------------------------------------------------------------------------------
METHOD CreateTree()
LOCAL aItem, oItem
TREE ::oTree //::oTree is type Tlinklist
FOR EACH aItem IN aItems
oItem := ::oTree:Add( aItem[ 1 ] ) //each oItem is type TTreeItem
oItem:Cargo := { 0.00, 0.00, 0.00 }
oItem:nLevel := 1
oItem:bAction := { |o| o:SetTree( ::SubTree( o ) ), o:bAction := Nil }
EVAL( oItem:bAction, oItem )
END
ENDTREE
RETURN NIL
//------------------------------------------------------------------------------------------------
METHOD SubTree( oParent )
LOCAL nLevel
LOCAL oTree, oItem
LOCAL aItem
LOCAL cId := ALLTRIM( oParent:cPrompt )
LOCAL nAt := aSCAN( aItems, { |e| e[ 1 ] == cId } )
nLevel := oParent:nLevel + 1
TREE oTree
FOR EACH aItem IN aItems[ nAt ]
IF VALTYPE( aItem ) != "A" ;LOOP ;ENDIF
TREEITEM oItem PROMPT aItem[ 1 ] //creates a new leaf
oItem:nlevel := nLevel
oItem:Cargo := { aItem[ 2 ], aItem[ 3 ] , aItem[ 4 ] }
NEXT
ENDTREE
RETURN oTree
//----------------------------------------------------------------------------//
METHOD PayEachLeaf()
LOCAL nPaid := ::oBrw:oTreeItem:Cargo[ _PAID ]
LOCAL oItem := ::oBrw:oTreeItem:GetNext()
WHILE oItem != NIL .AND. oItem:nLevel == 2
oItem:Cargo[ _PAID ] := IIF( nPaid == 0.00, oItem:Cargo[ _EXPECTED ], 0.00 )
oItem := oItem:GetNext()
END
RETURN NIL
//------------------------------------------------------------------------------------------------
METHOD ReCalculateCompleteTree()
LOCAL oBranch := ::oBrw:oTree:oFirst
WHILE oBranch != NIL
::Recalculate( oBranch )
oBranch := oBranch:GetNext()
END
RETURN NIL
//------------------------------------------------------------------------------------------------
METHOD Recalculate( oItem )
LOCAL bAddTotals, oBranch, oParent
LOCAL nTotPend := 0.00
LOCAL nTotExp := 0.00
LOCAL ntotPaid := 0.00
LOCAL nAt := ::oBrw:oTreeItem:ItemNo()
DEFAULT oItem := ::oBrw:oTreeItem
bAddTotals := { | o | nTotExp += o:Cargo[ _EXPECTED ],;
nTotPend += o:Cargo[ _PENDING ],;
nTotPaid += o:Cargo[ _PAID ] }
oParent := IIF( oItem:nLevel == 2, oItem:Parent(), oItem )
oParent:Open()
oBranch := oParent:GetNext()
//Visit each branch leaf
WHILE oBranch != NIL .AND. oBranch:nLevel == 2
EVAL( bAddTotals, oBranch )
oBranch := oBranch:GetNext()
END
oParent:Cargo[ _EXPECTED ] := nTotExp
oParent:Cargo[ _PAID ] := nTotPaid
oParent:Cargo[ _PENDING ] := oParent:Cargo[ _EXPECTED ] - oParent:Cargo[ _PAID ]
::oBrw:MakeTotals()
::oBrw:Refresh()
EVAL( ::oBrw:bBookmark, nAt )
RETURN NIL