#include "FiveWin.ch"
#include "easyrep.ch"
REQUEST DBFCDX
static oWndMain, oWndInvoices, oWndClients, oWndItems
static aBlankItem
static cItemFlds := "INVNUM,SERIAL,ITEMCODE,ITEMNAME,QUANTITY,UNIT,PRICE,DISCOUNT,ID"
static nTaxRate := 0.0
static oCn, oRsClients
//----------------------------------------------------------------------------//
function Main()
local oBrush, oFont
OpenDataBases()
DEFINE BRUSH oBrush RESOURCE "background"
DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-12
// SetDlgGradient( { { 1, RGB( 199, 216, 237 ), RGB( 237, 242, 248 ) } } )
DEFINE WINDOW oWndMain TITLE "Invoicing" MDI MENU BuildMenu() VSCROLL HSCROLL BRUSH oBrush
oWndMain:SetFont( oFont )
BuildMainBar()
DEFINE MSGBAR PROMPT "Invoicing app" ;
OF oWndMain 2007 KEYBOARD DATE
ACTIVATE WINDOW oWndMain MAXIMIZED
RELEASE BRUSH oBrush
return nil
//----------------------------------------------------------------------------//
INIT PROCEDURE inv_init
SET DATE BRITISH
SET CENTURY ON
SET EPOCH TO ( YEAR( DATE() ) - 50 )
RDDSETDEFAULT( "DBFCDX" )
SET DELETED ON
SetGetColorFocus()
aBlankItem := { "", 0, "", "", 0.0, "", 0.0, 0.0, 0 }
return
//----------------------------------------------------------------------------//
static function BuildMainBar()
local oBar
DEFINE BUTTONBAR oBar OF oWndMain 2007 SIZE 70, 60 //70
DEFINE BUTTON OF oBar PROMPT "Invoices" RESOURCE "code" ;
ACTION Invoices()
DEFINE BUTTON OF oBar PROMPT "Clients" RESOURCE "clients" ;
ACTION Clients()
DEFINE BUTTON OF oBar PROMPT "Items" RESOURCE "relation" ;
ACTION Items()
DEFINE BUTTON OF oBar PROMPT "Exit" RESOURCE "exit" ;
ACTION oWndMain:End()
return nil
//----------------------------------------------------------------------------//
static function BuildMenu()
local oMenu
MENU oMenu
MENUITEM "Tasks"
MENU
MENUITEM "Invoices" ACTION Invoices()
//MENUITEM "Invoices items" ACTION ( "invitems" )->( XBrowse() )
MENUITEM "Clients" ACTION Clients()
MENUITEM "Items" ACTION Items()
SEPARATOR
MENUITEM "Exit" ACTION oWndMain:End()
ENDMENU
oMenu:AddMDI()
oMenu:AddHelp( "Invoicing app", "(c) FiveTech Software" )
ENDMENU
return oMenu
//----------------------------------------------------------------------------//
static function Clients()
local oBrw, cClrBack, cAlias
local oBar, oMsgBar, oMsgDeleted
if oWndClients == nil
oRsClients = oCn:RowSet( "SELECT * FROM clients2 ORDER BY code" )
DEFINE WINDOW oWndClients MDICHILD OF oWndMain TITLE "Clients"
@ 2, 0 XBROWSE oBrw OF oWndClients LINES AUTOSORT ;
AUTOCOLS DATASOURCE oRsClients NOBORDER
oBar := BrwBtnBar( @oBrw, oWndClients )
DEFINE BUTTON OF oBar PROMPT "Print" RESOURCE "report" ;
ACTION oBrw:Report( "Clients report",, .F.)
DEFINE BUTTON OF oBar PROMPT "Close" RESOURCE "exit" ;
ACTION oWndClients:End()
cAlias = Alias()
BrwColors( oBrw )
// BrwRecSel( oBrw, "RECNO" )
oBrw:bEdit := { |oRec| EditClients( oRec ) }
oBrw:CreateFromCode()
oBrw:SetFocus()
oBrw:bLDblClick = { || oBrw:EditSource(,, .T.) }
oWndClients:oClient = oBrw
oWndClients:oControl = oBrw
DEFINE MSGBAR oMsgBar OF oWndClients 2007
ACTIVATE WINDOW oWndClients MAXIMIZED ;
VALID ( oWndClients := nil, .T. )
else
oWndClients:SetFocus()
endif
return nil
//----------------------------------------------------------------------------//
static function Items()
local oBrw, cClrBack
local oBar, oMsgBar, oMsgDeleted, oRs
if oWndItems == nil
oRs = oCn:RowSet( "SELECT * FROM items ORDER BY code" )
DEFINE WINDOW oWndItems MDICHILD OF oWndMain TITLE "Items"
@ 2, 0 XBROWSE oBrw OF oWndItems LINES AUTOSORT ;
AUTOCOLS DATASOURCE oRs NOBORDER
oBar := BrwBtnBar( @oBrw, oWndItems )
DEFINE BUTTON OF oBar PROMPT "Print" RESOURCE "report" ;
ACTION oBrw:Report( "Items report",, .F.)
DEFINE BUTTON OF oBar PROMPT "Close" RESOURCE "exit" ;
ACTION oWndItems:End()
BrwColors( oBrw )
// BrwRecSel( oBrw, "RECNO" )
oBrw:bEdit := { |oRec| EditItems( oRec ) }
oBrw:CreateFromCode()
oBrw:SetFocus()
oBrw:bLDblClick = { || oBrw:EditSource(,, .T.) }
oWndItems:oClient = oBrw
oWndItems:oControl = oBrw
DEFINE MSGBAR oMsgBar OF oWndItems 2007
ACTIVATE WINDOW oWndItems MAXIMIZED ;
VALID ( oWndItems := nil, .T. )
else
oWndItems:SetFocus()
endif
return nil
//----------------------------------------------------------------------------//
static function Invoices()
local oBrw, oChild, cClrBack, cCol
local oBar, oMsgBar, oMsgDeleted, oRs1, oRs2
if oWndClients == nil
Clients()
endif
if oWndItems == nil
Items()
endif
if oWndInvoices == nil
oRs1 = oCn:RowSet( "SELECT * FROM invoices ORDER BY code" )
oRs2 = oCn:RowSet( "SELECT * FROM invitems ORDER BY itemcode" )
DEFINE WINDOW oWndInvoices MDICHILD OF oWndMain TITLE "Invoices"
@ 60, 0 XBROWSE oBrw SIZE 0,200 PIXEL OF oWndInvoices LINES AUTOSORT ;
AUTOCOLS DATASOURCE oRs1 NOBORDER FOOTERS
oBar := BrwBtnBar( @oBrw, oWndInvoices )
DEFINE BUTTON OF oBar PROMPT "Print" RESOURCE "report" ;
ACTION ViewInvoice( oBrw )
DEFINE BUTTON OF oBar PROMPT "EasyReport" RESOURCE "report" ;
ACTION ViewInvoiceER( oBrw )
DEFINE BUTTON OF oBar PROMPT "Close" RESOURCE "exit" ;
ACTION oWndInvoices:End()
DEFINE MSGBAR oMsgBar OF oWndInvoices 2007
BrwColors( oBrw )
BrwRecSel( oBrw, "RECNO" )
for each cCol in { "Amount", "Tax", "Total" }
oBrw:oCol( cCol ):nFooterType := AGGR_SUM
next
oBrw:bLDblClick = { || oBrw:EditSource(,, .T.) }
oBrw:bEdit = { | oRec | EditInvoice( oRec ) }
oBrw:MakeTotals()
oBrw:CreateFromCode()
oBrw:SetFocus()
oWndInvoices:oControl = oBrw
@ oBar:nHeight + 200,0 XBROWSE oChild SIZE 0,-oMsgBar:nHeight PIXEL OF oWndInvoices ;
DATASOURCE oRs2 ;
COLUMNS "ItemCode", "ItemName", "Quantity", "Unit", "Price", ;
"ROUND(QUANTITY*PRICE,0)", "DISCOUNT","ROUND(QUANTITY*PRICE,0)-DISCOUNT" ;
HEADERS "ItmCode", nil, nil, nil, nil, "Amount", "Discount", "Net Amount" ;
LINES NOBORDER FOOTERS
BrwColors( oChild )
// BrwRecSel( oChild, "KEY" )
for each cCol in { "Amount", "Discount", "Net Amount" }
WITH OBJECT oChild:oCol( cCol )
:nFooterType := AGGR_SUM
END
next
oChild:MakeTotals()
oChild:CreateFromCode()
oBrw:bChange := { || oChild:Refresh(), oChild:MakeTotals(), oChild:GoTop() }
oWndInvoices:bResized := < ||
local oRect := oWndInvoices:GetCliRect()
oBrw:nHeight := ( oRect:nHeight - oBar:nHeight - oMsgBar:nHeight ) * 0.6
oChild:nTop := oBrw:nTop + oBrw:nHeight
return nil
>
oWndInvoices:bPostEnd := { || oWndInvoices := nil }
ACTIVATE WINDOW oWndInvoices MAXIMIZED
else
oWndInvoices:SetFocus()
endif
return nil
//----------------------------------------------------------------------------//
static function EditInvoice( oRec )
local lNew := ( oRec:RecNo == 0 )
local oDlg, oBrush, oFont, oBold, oLarge
local oBrw, cCol, bInit, oBtn
local aItems
local oGetClient, cClient, bCliInit
local nHt := Int( ScreenHeight() * 0.8 )
local nWd := 1100
local lSave := .f., aItem
if lNew
oRec:Date := Date()
oRec:TaxRate := nTaxRate
oRec:InvNum := Space( 10 )
oRec:Code := Space( 10 )
aItems := { AClone( aBlankItem ) }
else
aItems = FW_RowSetToArray( oCn:RowSet( "SELECT " + cItemFlds + ;
" FROM invitems WHERE INVNUM = '" + oRec:InvNum + "' ORDER BY SERIAL" ),;
cItemFlds )
endif
DEFINE BRUSH oBrush RESOURCE "PAPER"
DEFINE FONT oLarge NAME "VERDANA" SIZE 0,-30 BOLD
DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-15
DEFINE FONT oBold NAME "TAHOMA" SIZE 0,-15 BOLD
DEFINE DIALOG oDlg SIZE nWd, nHt PIXEL FONT oFont TRUEPIXEL ;
TITLE If( lNew, "NEW ", "EDIT " ) + "INVOICE" TRANSPARENT ;
BRUSH oBrush
// @ 20, 40 SAY "INVOICE" SIZE 260,36 PIXEL OF oDlg FONT oLarge ;
@ 20, nWd/2-100 SAY "INVOICE" SIZE 200,36 PIXEL OF oDlg FONT oLarge CENTER
@ 020, nWd - 190 GET oRec:InvNum PICTURE "@!" SIZE 150,26 PIXEL OF oDlg ;
VALID ! Empty( oRec:InvNum )
@ 050, nWd - 190 GET oRec:Date SIZE 150,26 PIXEL OF oDlg RIGHT ;
ACTION oRec:Date := Min( MsgDate( oRec:Date ), Date() )
@ 80-60, 40 SAY "Client:" SIZE 100,24 PIXEL OF oDlg
@ 80-60,150 GET oGetClient VAR oRec:Code SIZE 150,26 PIXEL OF oDlg ;
ACTION ( PopupBrowse( oRsClients, oGetClient ), ;
ReadClientInfo( oRec, oDlg ) ) ;
VALID ( ReadClientInfo( oRec, oDlg ) )
@ 125-60, 60 SAY oRec:Client SIZE 200,24 PIXEL OF oDlg FONT oBold UPDATE
@ 150-60, 60 SAY oRec:Address SIZE 200, 60 PIXEL OF oDlg UPDATE
@ 180-60,310 SAY "Text :" SIZE 100,24 PIXEL OF oDlg
@ 204-60,310 GET oRec:Details SIZE nWd-310-40,26 PIXEL OF oDlg UPDATE
@ 240-60,040 XBROWSE oBrw SIZE -40,-150+45 PIXEL OF oDlg ;
DATASOURCE aItems ;
COLUMNS 3,4,5,6,7,8 ;
HEADERS "ITEM", "DETAILS", "QTY", "UNIT","PRICE","DISCOUNT" ;
PICTURES "@!", nil, "9999.999", nil, "999.99", "999,999,999" ;
COLSIZES nil, 30 ;
CELL LINES NOBORDER FASTEDIT FOOTERS
ADD TO oBrw AT 6 HEADER "AMOUNT" DATA ROUND( oBrw:aRow[5] * oBrw:aRow[7], 0 ) ;
PICTURE "999,999,999"
ADD TO oBrw HEADER "NET" DATA ROUND( oBrw:aRow[5] * oBrw:aRow[7] - oBrw:aRow[ 8 ], 0 ) ;
PICTURE "999,999,999"
for each cCol in { "amount", "discount", "net" }
WITH OBJECT oBrw:oCol( cCol )
:nFooterType := AGGR_SUM
END
next
for each cCol in { "qty", "price", "discount" }
WITH OBJECT oBrw:oCol( cCol )
:nEditType := EDIT_GET
:bEditValid := { |o| o:VarGet() >= 0 }
:bOnChange := { || oBrw:MakeTotals( { "amount", "net" } ), oBrw:RefreshFooters(), oDlg:Update() }
END
next
for each cCol in { "details", "unit", "amount", "net" }
oBrw:oCol( cCol ):bClrStd := { || { CLR_BLACK, RGB( 240, 240, 240 ) } }
next
// AutoAppendCode
WITH OBJECT oBrw
:AddVar( "AAPPEND", nil )
:bClrStd := { || If( oBrw:aRow == oBrw:aAppend, { CLR_BLACK, CLR_YELLOW }, { CLR_BLACK, oBrw:nClrPane } ) }
:bChange := { || If( oBrw:nArrayAt < oBrw:nLen, CheckAppendRow( oBrw ), nil ) }
:bPastEof := { || If( oBrw:aAppend != nil .and. Empty( oBrw:aAppend[ 3 ] ), nil, ;
( AAdd( oBrw:aArrayData, oBrw:aAppend := AClone( aBlankItem ) ), ;
oBrw:GoBottom(), oBrw:GoLeftMost(), oBrw:RefreshCurrent(), ;
oBrw:MakeTotals(), oBrw:Refresh() ) ) }
:bKeyDown := { |k| If( k == VK_DELETE, ( oBrw:aAppend := nil, oBrw:Delete(), 0 ), nil ) }
END
WITH OBJECT oBrw:aCols[ 1 ]
:nEditType = EDIT_BUTTON
:bEditBlock = { | nRow, nCol, oCol, nKey | TableLookUp( nRow, nCol, oCol, nKey, "ITEMS" ) }
:bOnChange = { || oBrw:aAppend := nil, ReadItemInfo( oBrw:aRow, oBrw ), oBrw:RefreshCurrent(), ;
oBrw:MakeTotals(), oBrw:RefreshFooters(), oDlg:Update() }
END
WITH OBJECT oBrw
:lFlatStyle := .t.
:nStretchCol := 2
:lHScroll := .f.
:bOnRefresh := { || oDlg:Update() }
//
BrwRecSel( oBrw, "KEYNO" )
//
:MakeTotals()
:CreateFromCode()
END
@ nHt - 139 + 45, nWd - 380 SAY "TAX @" ;
SIZE 80,24 PIXEL OF oDlg RIGHT
@ nHt - 140 + 45, nWd - 280 GET oRec:TaxRate PICTURE "99.99 %" ;
SIZE 100,26 PIXEL OF oDlg RIGHT ;
VALID ( If( oRec:TaxRate >= 0, ( oDlg:Update(), .t. ), .f. ) )
@ nHT - 139 + 45, nWd - 170 SAY ;
( oRec:Tax := ROUND( oBrw:Net:nTotal * oRec:TaxRate / 100, 0 ) ) ;
PICTURE "999,999,999" SIZE 105,24 PIXEL OF oDlg UPDATE RIGHT
@ nHt - 105 + 45, nWd - 270 SAY "TOTAL" SIZE 80, 24 PIXEL OF oDlg RIGHT
@ nHt - 105 + 45, nWd - 170 SAY ;
( oRec:Total := oBrw:Net:nTotal + oRec:Tax ) ;
PICTURE "999,999,999" SIZE 105, 24 PIXEL OF oDlg UPDATE RIGHT
/*
@ nHt - 60, nWd - 260 BTNBMP PROMPT "Save" SIZE 100,30 PIXEL OF oDlg FLAT ;
ACTION ( lSave := .t., oDlg:End() )
@ nHt - 60, nWd - 140 BTNBMP oBtn PROMPT "Cancel" SIZE 100,30 PIXEL OF oDlg FLAT ;
ACTION oDlg:End()
oBtn:lCancel := .t.
*/
@ nHt - 60, 040 BTNBMP PROMPT "Save" SIZE 100,30 PIXEL OF oDlg FLAT ;
ACTION ( lSave := .t., oDlg:End() )
@ nHt - 60, 160 BTNBMP oBtn PROMPT "Cancel" SIZE 100,30 PIXEL OF oDlg FLAT ;
ACTION oDlg:End()
oBtn:lCancel := .t.
ACTIVATE DIALOG oDlg CENTERED ;
ON PAINT ( oDlg:Box( 110-60, 40, 230-60, 300 ), ;
oDlg:Line( nHt - 112 + 45, nWd - 170, nHt - 112 + 45, nWd - 55 ), ;
oDlg:Line( nHt - 78 + 45, nWd - 170, nHt - 78 + 45, nWd - 55 ), ;
oDlg:Line( nHt - 75 + 45, nWd - 170, nHt - 75 + 45, nWd - 55 ) )
if lSave
CheckAppendRow( oBrw )
if Empty( aItems ) .or. Empty( oRec:InvNum ) .or. Empty( oRec:Code ) .or. oRec:Total <= 0
else
oRec:Amount := oBrw:Net:nTotal
if ! Empty( oBrw:aDeleted )
for each aItem in oBrw:aDeleted
oCn:Execute( "DELETE FROM invitems WHERE id = " + Str( ABS( aItem[9] ) ) )
next
endif
AEval( aItems, { |a| a[ 1 ] := oRec:InvNum } )
AEval( aItems, { |a,i| a[ 2 ] := i } )
for each aItem in aItems
oCn:Execute( "INSERT INTO invitems (invnum, serial, itemcode, itemname, quantity, unit, price, discount) VALUES ('" + aItem[1] + "', " + Str(aItem[2]) + ", '" + Str( aItem[3] ) + "', '" + aItem[4] + "', " + Str(aItem[5]) + ", '" + aItem[6] + "', " + Str(aItem[7]) + ", " + Str(aItem[8]) + ") ON DUPLICATE KEY UPDATE itemname = VALUES(itemname), quantity = VALUES(quantity), unit = VALUES(unit), price = VALUES(price), discount = VALUES(discount)" )
next
oRec:Save()
WITH OBJECT oRec:oBrw
:MakeTotals()
:RefreshFooters()
Eval( :bChange, oRec:oBrw )
END
endif
endif
RELEASE FONT oFont, oLarge
RELEASE BRUSH oBrush
return nil
//----------------------------------------------------------------------------//
static function CheckAppendRow( oBrw, aAppend )
if Empty( ATail( oBrw:aArrayData )[ 3 ] )
ASize( oBrw:aArrayData, oBrw:nLen - 1 )
oBrw:aAppend := nil
oBrw:Refresh()
endif
return nil
//----------------------------------------------------------------------------//
static function ReadClientInfo( oRec, oDlg )
local oRs := oCn:RowSet( "SELECT first, last, address1, address2, city, zipcode FROM clients2 WHERE code = '" + oRec:Code + "'" )
local lValid := .f.
local aRet := {}
if oRs:RecCount > 0
oRs:GoTop()
oRec:Client := TRIM( oRs:FIRST ) + " " + TRIM( oRs:LAST )
if ! Empty( oRs:ADDRESS1 ); AAdd( aRet, TRIM( oRs:ADDRESS1 ) ); endif
if ! Empty( oRs:ADDRESS2 ); AAdd( aRet, TRIM( oRs:ADDRESS2 ) ); endif
if ! Empty( oRs:CITY ); AAdd( aRet, TRIM( oRs:CITY ) + " " + TRIM( oRs:ZIPCODE ) ); endif
oRec:Address := If( Empty( aRet ), "", FW_ArrayAsList( aRet, CRLF ) )
lValid := .t.
endif
if oDlg != nil
oDlg:Update()
endif
return lValid
//----------------------------------------------------------------------------//
static function PickAddress()
local aRet := {}
if ! Empty( FIELD->ADDRESS1 ); AAdd( aRet, TRIM( FIELD->ADDRESS1 ) ); endif
if ! Empty( FIELD->ADDRESS2 ); AAdd( aRet, TRIM( FIELD->ADDRESS2 ) ); endif
if ! Empty( FIELD->CITY ); AAdd( aRet, TRIM( FIELD->CITY ) + " " + TRIM( FIELD->ZIPCODE ) ); endif
if Empty( aRet )
return ""
endif
return FW_ArrayAsList( aRet, CRLF )
static function ReadItemInfo( aRow, oBrw )
local oRs := oCn:RowSet( "SELECT name, unit, price FROM items WHERE code = '" + AllTrim( Str( aRow[ 3 ] ) ) + "'" )
local lValid := .f.
if oRs:RecCount > 0
oRs:GoTop()
aRow[ 4 ] := TRIM( oRs:NAME )
if aRow[ 5 ] == 0
aRow[ 5 ] := 1
endif
aRow[ 6 ] := oRs:UNIT
aRow[ 7 ] := oRs:PRICE
lValid := .t.
endif
if oBrw != nil
oBrw:RefreshCurrent()
oBrw:MakeTotals()
oBrw:oWnd:Update()
endif
return lValid
//----------------------------------------------------------------------------//
static function ViewInvoice( oBrw )
local oPrn, oFontTitle, oFontBold, oFontText, oPen, n
local nVal, nPage, nItemsByPage := 10
local aItems := FW_RowSetToArray( oCn:RowSet( "SELECT " + cItemFlds + ;
" FROM invitems WHERE INVNUM = '" + ;
oBrw:InvNum:Value + "' ORDER BY SERIAL" ), cItemFlds )
PRINT oPrn NAME "INVOICE" PREVIEW
DEFINE FONT oFontTitle NAME "Arial" SIZE 0, -19 BOLD OF oPrn
DEFINE FONT oFontBold NAME "Arial" SIZE 0, -12 BOLD OF oPrn
DEFINE FONT oFontText NAME "Arial" SIZE 0, -12 OF oPrn
DEFINE PEN oPen WIDTH 2
for nPage = 1 to ( Len( aItems ) / nItemsByPage ) + 1
PAGE
oPrn:CmSay( 3.1, 2.3, "Company Name", oFontTitle )
oPrn:CmBox( 4.4, 10.9, 7.7, 20.15, oPen )
oPrn:CmSay( 4.7, 11.5, oBrw:Client:Value, oFontBold )
/*
oPrn:CmSay( 5.4, 11.5, "Address 1", oFontText )
oPrn:CmSay( 6.1, 11.5, "Address 2", oFontText )
oPrn:CmSay( 6.8, 11.5, "City", oFontText )
*/
@ 5.4, 11.5 PRINT TO oPrn TEXT oBrw:Address:Value SIZE 7.0 CM FONT oFontText
oPrn:CmBox( 8.15, 2.20, 8.75, 20.15, oPen )
oPrn:CmSay( 8.16, 2.30, "C.I.F.:", oFontBold )
oPrn:CmSay( 8.16, 6.00, "Invoice n�:", oFontBold )
oPrn:CmSay( 8.16, 8.30, oBrw:InvNum:Value, oFontText )
oPrn:CmSay( 8.16, 11.20, "Date:", oFontBold )
oPrn:CmSay( 8.20, 12.45, DToC( oBrw:Date:Value ), oFontText )
oPrn:CmSay( 8.16, 15.60, "PayDate:", oFontBold )
oPrn:CmSay( 8.20, 17.50, DToC( oBrw:PayDate:Value ), oFontText )
oPrn:CmBox( 8.90, 2.20, 9.50, 20.15, oPen )
oPrn:CmSay ( 8.91, 2.30, "Observations:", oFontBold )
oPrn:CmBox( 9.65, 2.20, 23.25, 20.15, oPen )
oPrn:CmLine( 9.65, 5.20, 23.25, 5.20, oPen )
oPrn:CmLine( 9.65, 12.20, 23.25, 12.20, oPen )
oPrn:CmLine( 9.65, 13.80, 23.25, 13.80, oPen )
oPrn:CmLine( 9.65, 16.10, 23.25, 16.10, oPen )
oPrn:CmLine( 9.65, 17.10, 23.25, 17.10, oPen )
oPrn:CmLine( 10.20, 2.20, 10.20, 20.15, oPen )
oPrn:CmSay( 9.66, 2.30, "Code", oFontBold )
oPrn:CmSay( 9.66, 5.30, "Description", oFontBold )
oPrn:CmSay( 9.66, 12.30, "Quantity", oFontBold )
oPrn:CmSay( 9.66, 14.00, "Price", oFontBold )
oPrn:CmSay( 9.66, 16.15, "Disc", oFontBold )
oPrn:CmSay( 9.66, 18.20, "Amount", oFontBold )
// "INVNUM,SERIAL,ITEMCODE,ITEMNAME,QUANTITY,UNIT,PRICE,DISCOUNT,RECNO()"
// 1 2 3 4 5 6 7 8
for n = ( ( nPage - 1 ) * nItemsByPage ) + 1 to Min( Len( aItems ), nItemsByPage * nPage )
oPrn:CmSay( 9.66 + n - ( ( nPage - 1 ) * nItemsByPage ), 3, aItems[ n ][ 3 ], oFontText )
oPrn:CmSay( 9.66 + n - ( ( nPage - 1 ) * nItemsByPage ), 5.5, aItems[ n ][ 4 ], oFontText )
oPrn:CmSay( 9.66 + n - ( ( nPage - 1 ) * nItemsByPage ), 12.8, AllTrim( Str( aItems[ n ][ 5 ] ) ), oFontText )
oPrn:CmSay( 9.66 + n - ( ( nPage - 1 ) * nItemsByPage ), 14.5, AllTrim( Str( aItems[ n ][ 7 ] ) ), oFontText )
oPrn:CmSay( 9.66 + n - ( ( nPage - 1 ) * nItemsByPage ), 16.5, AllTrim( Str( aItems[ n ][ 8 ] ) ), oFontText )
nVal := ROUND( aItems[ n ][ 5 ] * aItems[ n ][ 7 ] - aItems[ n ][ 8 ], 0 )
oPrn:CmSay( 9.66 + n - ( ( nPage - 1 ) * nItemsByPage ), 18.5, AllTrim( Str( nVal ) ), oFontText )
next
oPrn:CmBox( 23.40, 2.20, 27.20, 20.15, oPen )
oPrn:CmLine( 24.00, 2.20, 24.00, 20.15, oPen )
oPrn:CmLine( 23.40, 4.95, 26.20, 4.95, oPen )
oPrn:CmLine( 23.40, 6.45, 26.20, 6.45, oPen )
oPrn:CmLine( 23.40, 9.35, 26.20, 9.35, oPen )
oPrn:CmLine( 23.40, 10.95, 26.20, 10.95, oPen )
oPrn:CmLine( 23.40, 13.80, 26.20, 13.80, oPen )
oPrn:CmLine( 23.40, 16.65, 26.20, 16.65, oPen )
oPrn:CmSay( 23.50, 2.40, "BASE", oFontBold )
oPrn:CmSay( 23.50, 5.20, "%VAT", oFontBold )
oPrn:CmSay( 23.50, 6.75, "CUOTE", oFontBold )
oPrn:CmSay( 23.50, 9.60, "%RE", oFontBold )
oPrn:CmSay( 23.50, 11.20, "CUOTE", oFontBold )
oPrn:CmSay( 23.50, 14.10, "AMOUNT", oFontBold )
oPrn:CmSay( 23.50, 16.95, "SUM BASES:", oFontBold )
oPrn:CmSay( 23.50 + 1.5, 2.40, cValToStr( oBrw:Amount:Value ), oFontText )
oPrn:CmSay( 23.50 + 1.5, 5.20, cValToStr( oBrw:TaxRate:Value ), oFontText )
oPrn:CmSay( 26.44, 2.40, "TOTAL VAT:", oFontBold )
oPrn:CmSay( 26.44, 5.50, cValToStr( oBrw:Tax:Value ), oFontText )
oPrn:CmSay( 26.44, 7.70, "TOTAL R.E.:", oFontBold )
oPrn:CmSay( 26.44, 13.35, "TOTAL INVOICE", oFontBold )
oPrn:CmSay( 26.44, 17.50, cValToStr( oBrw:Total:Value ), oFontBold )
ENDPAGE
next
ENDPRINT
oFontTitle:End()
oFontBold:End()
oFontText:End()
oPen:End()
return nil
//----------------------------------------------------------------------------//
static function OpenDataBases()
oCn = maria_Connect( "localhost", "fwh", "fivetec1_antonio", "1234" )
if oCn == nil
MsgStop( "Error connecting to the DataBase" )
return nil
endif
return oCn
//----------------------------------------------------------------------------//
static function BrwBtnBar( oBrw, oWnd )
local oBar
DEFINE BUTTONBAR oBar OF oWnd 2007 SIZE 70, 60 //70
DEFINE BUTTON OF oBar PROMPT "New" RESOURCE "add" ;
ACTION oBrw:EditSource( .T. )
DEFINE BUTTON OF oBar PROMPT "Edit" RESOURCE "edit" ;
ACTION oBrw:EditSource()
DEFINE BUTTON OF oBar PROMPT "Delete" RESOURCE "del"
/*
DEFINE BUTTON OF oBar PROMPT "Preview" RESOURCE "report" ;
ACTION ViewInvoice( oBrw )
DEFINE BUTTON OF oBar PROMPT "Close" RESOURCE "exit" ;
ACTION oWndInvoices:End()
*/
return oBar
//----------------------------------------------------------------------------//
static function BrwColors( oBrw )
local cClrBack
oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
oBrw:bClrStd = { || If( oBrw:KeyNo() % 2 == 0, ;
{ If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
RGB( 198, 255, 198 ) }, ;
{ If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_BLACK ),;
RGB( 232, 255, 232 ) } ) }
oBrw:bClrSel = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
RGB( 0x33, 0x66, 0xCC ) } }
cClrBack = Eval( oBrw:bClrSelFocus )[ 2 ]
oBrw:bClrSelFocus = { || { If( ( oBrw:cAlias )->( Deleted() ), CLR_HRED, CLR_WHITE ),;
cClrBack } }
oBrw:SetColor( CLR_BLACK, RGB( 232, 255, 232 ) )
oBrw:lHScroll := .f.
return nil
//----------------------------------------------------------------------------//
static function BrwRecSel( oBrw, cHead )
WITH OBJECT oBrw
:lFooter := .t.
if "REC" $ Upper( cHead )
:bRecSelHeader := { || "RecNo" }
:bRecSelData := { |o| o:BookMark }
:bRecSelClick := { |o| ( o:cAlias )->( OrdSetFocus( 0 ) ), ;
AEval( o:aCols, { |c| c:cOrder := "" } ), ;
o:Refresh() }
else
:bRecSelHeader := { || "SlNo" }
:bRecSelData := { |o| o:KeyNo }
endif
:bRecSelFooter := { |o| o:nLen }
:nRecSelWidth := Replicate( '9', Len( cValToChar( Eval( oBrw:bKeyCount, oBrw ) ) ) + 1 )
END
retur nil
//----------------------------------------------------------------------------//
static function EditItems( oRec )
local oDlg
local lSave := .F.
local oFont
local oBtn
local lAdd := ( oRec:RecNo == 0 )
DEFINE FONT oFont NAME "Tahoma" SIZE 0, -15
DEFINE DIALOG oDlg SIZE 402, 158 PIXEL FONT oFont ;
TITLE If( lAdd, "New Item", "Edit Item" )
@ 12, 10 SAY "Code:" OF oDlg SIZE 19, 8 PIXEL FONT oFont
@ 10, 36 GET oRec:Code OF oDlg SIZE 55, 12 PIXEL FONT oFont PICTURE "@!" UPDATE ;
VALID ! Empty( oRec:Code )
@ 26, 10 SAY "Name:" OF oDlg SIZE 21, 8 PIXEL FONT oFont
@ 24, 36 GET oRec:Name OF oDlg SIZE 155, 12 PIXEL FONT oFont ;
VALID !Empty( oRec:Name ) UPDATE
@ 40, 10 SAY "Unit:" OF oDlg SIZE 18, 8 PIXEL FONT oFont
// @ 38, 36 GET oRec:Unit OF oDlg SIZE 44, 12 PIXEL FONT oFont RIGHT ;
@ 38,38 COMBOBOX oRec:Unit SIZE 44,12 PIXEL OF oDlg ;
ITEMS { "Items","K.G","Metre","Litre" }
@ 40, 10 + 111 SAY "Price:" OF oDlg SIZE 18, 8 PIXEL FONT oFont
@ 38, 36 + 111 GET oRec:Price OF oDlg SIZE 44, 12 PIXEL PICTURE "9999999.99" FONT oFont RIGHT ;
VALID oRec:Price > 0 UPDATE
@ 60, 111 BTNBMP oBtn PROMPT "Save" OF oDlg SIZE 42, 14 PIXEL FLAT ;
WHEN oRec:Modified() ACTION (oDlg:End(), lSave := .T.)
@ 60, 155 BTNBMP oBtn PROMPT "Cancel" OF oDlg SIZE 42, 14 PIXEL FLAT ACTION (oDlg:End())
oBtn:lCancel := .t.
// oRec:bValid := { || !Duplicate( oRec:Code, "CODE", oRec:RecNo ) }
ACTIVATE DIALOG oDlg CENTERED ;
ON PAINT ( oDlg:Box( 10, 10, 110, 392 ) )
if lSave
oRec:Save( .T. ) // Param .t. to check oRec:bValid
endif
return nil
//----------------------------------------------------------------------------//
static function EditClients( oRec )
local oDlg
local lSave := .F.
local oFont
local oBtn
local lAdd := ( oRec:RecNo == 0 )
DEFINE FONT oFont NAME "TAHOMA" SIZE 0, 15
DEFINE DIALOG oDlg SIZE 422, 326 PIXEL ; //FROM 100, 100 TO 426,522;
TITLE If( lAdd, "New Client", "Edit Client" ) FONT oFont
@ 12, 10 SAY "Code:" OF oDlg SIZE 19, 8 PIXEL
@ 10, 46 GET oRec:Code OF oDlg SIZE 55, 12 PIXEL PICTURE "@!" UPDATE ;
VALID ! Empty( oRec:Code )
@ 26, 10 SAY "First:" OF oDlg SIZE 15, 8 PIXEL
@ 24, 46 GET oRec:First OF oDlg SIZE 105, 12 PIXEL UPDATE ;
VALID ! Empty( oRec:First )
@ 40, 10 SAY "Last:" OF oDlg SIZE 15, 8 PIXEL
@ 38, 46 GET oRec:Last OF oDlg SIZE 105, 12 PIXEL UPDATE
@ 54, 10 SAY "Address1:" OF oDlg SIZE 31, 8 PIXEL
@ 52, 46 GET oRec:Address1 OF oDlg SIZE 155, 12 PIXEL UPDATE
@ 68, 10 SAY "Address2:" OF oDlg SIZE 31, 8 PIXEL FONT oFont
@ 66, 46 GET oRec:Address2 OF oDlg SIZE 155, 12 PIXEL UPDATE
@ 82, 10 SAY "City:" OF oDlg SIZE 13, 8 PIXEL
@ 80, 46 GET oRec:City OF oDlg SIZE 105, 12 PIXEL UPDATE
@ 96, 10 SAY "Zipcode:" OF oDlg SIZE 28, 8 PIXEL
@ 94, 46 GET oRec:Zipcode OF oDlg SIZE 105, 12 PIXEL UPDATE
@ 110, 10 SAY "Phone:" OF oDlg SIZE 23, 8 PIXEL
@ 108, 46 GET oRec:Phone OF oDlg SIZE 105, 12 PIXEL UPDATE
@ 124, 10 SAY "Email:" OF oDlg SIZE 19, 8 PIXEL
@ 122, 46 GET oRec:Email OF oDlg SIZE 105, 12 PIXEL UPDATE
@ 144, 121 BTNBMP oBtn PROMPT "Save" OF oDlg SIZE 42, 14 PIXEL FLAT ACTION (oDlg:End(), lSave := .T.) ;
WHEN oRec:Modified()
@ 144, 165 BTNBMP oBtn PROMPT "Cancel" OF oDlg SIZE 42, 14 PIXEL FLAT ACTION (oDlg:End())
oBtn:lCancel := .t.
// oRec:bValid := { || !Duplicate( oRec:Code, "CODE", oRec:RecNo ) }
ACTIVATE DIALOG oDlg CENTERED ;
ON PAINT ( oDlg:Box( 10, 10, 278, 412 ) )
IF lSave
oRec:Save( .T. )
ENDIF
RETURN NIL
//----------------------------------------------------------------------------//
static function Duplicate( uVal, cOrder, nThisRec )
local nSaveRec := RECNO()
local cSaveOrd := OrdSetFocus()
local lExists := .f.
DEFAULT nThisRec := nSaveRec
OrdSetFocus( cOrder )
lExists := DBSEEK( uVal ) .and. RECNO() != nThisRec
if ! Empty( cSaveOrd )
OrdSetFocus( cSaveOrd )
endif
DBGOTO( nSaveRec )
return lExists
//----------------------------------------------------------------------------//
static function TableLookUp( nRow, nCol, oCol, nKey, uSource, uRetCol, aCols )
local oDlg, oBrw, uRet
local aPoint
local oFont, oBold
local aCellCoor := oCol:oBrw:aCellCoor()
local oRs
DEFAULT uRetCol := 1
DEFINE FONT oFont NAME "ARIAL" SIZE 0,-12
DEFINE FONT oBold NAME "ARIAL" SIZE 0,-12 BOLD
aPoint := ClientToScreen( oCol:oBrw:hWnd, { aCellCoor[ 1 ], aCellCoor[ 2 ] } )
oRs = oCn:RowSet( "SELECT * FROM " + Lower(uSource) + " ORDER BY code" )
DEFINE DIALOG oDlg SIZE 300,300 PIXEL TRUEPIXEL ;
STYLE WS_POPUP OF oCol:oBrw FONT oFont ;
COLOR CLR_BLACK, 1
oDlg:nSeeThroClr := 1
@ aCellCoor[ 3 ] - aCellCoor[ 1 ],0 XBROWSE oBrw SIZE 0,0 PIXEL OF oDlg ;
DATASOURCE oRs AUTOCOLS ;
AUTOSORT CELL LINES NOBORDER ;
COLOR CLR_BLACK, RGB( 232, 255, 232 )
WITH OBJECT oBrw
:lHScroll := .f.
:lRecordSelector := .f.
:lDrawBorder := .t.
//
:lIncrFilter := .t.
:lSeekWild := .t.
:oCol( uRetCol ):oDataFont := oBold
:bKeyDown := { |nKey| If( nKey == VK_RETURN, ( uRet := oBrw:oCol( uRetCol ):Value, oDlg:End() ), nil ) }
:bKeyChar := { |nKey| If( nKey == VK_ESCAPE, ( oBrw:Seek( "" ), oDlg:End() ), nil ) }
:bLDClickDatas := { || uRet := oBrw:oCol( uRetCol ):Value, oDlg:End() }
:AutoFit()
:CreateFromCode()
:Seek( oCol:Value )
END
@ 00,00 SAY oBrw:oSeek PROMPT oBrw:cSeek PICTURE "@!" ;
SIZE aCellCoor[ 4 ] - aCellCoor[ 2 ], aCellCoor[ 3 ] - aCellCoor[ 1 ] PIXEL OF oDlg COLOR CLR_HRED, CLR_YELLOW ;
FONT oCol:DataFont
WITH OBJECT oBrw:oSeek
:lWantClick := .t.
:bLClicked := { || oDlg:End() }
END
ACTIVATE DIALOG oDlg ;
ON PAINT ( oDlg:Box( 0,0,20,100 ) ) ;
ON INIT BrwHelpDlgInit( oBrw, aPoint ) ;
VALID ( oBrw:Seek( "" ), .t. )
RELEASE FONT oFont, oBold
return uRet
//----------------------------------------------------------------------------//
static function BrwHelpDlgInit( oBrw, aPoint )
local oDlg := oBrw:oWnd
local dy := oDlg:GetRect():nWidth - oDlg:GetCliRect():nWidth
local aSize
aSize := oBrw:BrwFitSize()
oDlg:nWidth := aSize[ 1 ] + dy
oDlg:nHeight := oBrw:nTop + aSize[ 2 ]
oDlg:SetPos( aPoint[ 1 ], aPoint[ 2 ] )
oDlg:Shadow()
return nil
//----------------------------------------------------------------------------//
static function ViewInvoiceER( oBrw )
local oVRD
local lPreview := .t.
local cDruckerName := ""
local nVal
local aItems := FW_RowSetToArray( oCn:RowSet( "SELECT " + cItemFlds + " FROM invitems WHERE INVNUM = '" + oBrw:InvNum:Value + "' ORDER BY SERIAL" ), cItemFlds )
*----------------------------------------------------------
local aID_Strings := {}
local aID := {}
local aStrings := {}
local cLogo := ""
local cBezeichnung := ""
local nPrintArea := 3
local n
*----------------------------------------------------------
TPreview():lListViewHide := .T.
EASYREPORT oVRD NAME "yinvoice\invoice.vrd" PREVIEW lPreview TO cDruckerName PRINTDIALOG IIF( lPreview, .F., .F. ) MODAL
//----------------------------------------------------------------------------//
//header
//----------------------------------------------------------------------------//
#DEFINE ER_COMPANY 201
#DEFINE ER_ADDRESS 500
#DEFINE ER_CIF 501
#DEFINE ER_INVOICE 602
#DEFINE ER_DATE 502
#DEFINE ER_PAYDATE 603
PRINTAREA 5 OF oVRD
PRINTAREA 1 OF oVRD ;
ITEMIDS { ER_COMPANY ,ER_ADDRESS, ER_CIF, ER_INVOICE, ER_DATE, ER_PAYDATE } ;
ITEMVALUES { OBRW:CLIENT:VALUE, OBRW:ADDRESS:VALUE, "100", "220178992", DToC( oBrw:Date:Value ), DToC( oBrw:PayDate:Value ) }
//----------------------------------------------------------------------------//
// Data Header
//----------------------------------------------------------------------------//
PRINTAREA 2 OF oVRD
//----------------------------------------------------------------------------//
// Data
//----------------------------------------------------------------------------//
#DEFINE ER_CODE 200
#DEFINE ER_DESCRIPTION 201
#DEFINE ER_QUANTITY 202
#DEFINE ER_PRICE 203
#DEFINE ER_DISC 204
#DEFINE ER_AMOUNT 205
for n = 1 to Len( aItems )
PRINTAREA nPrintArea OF oVRD ;
ITEMIDS { ER_CODE ,;
ER_DESCRIPTION ,;
ER_QUANTITY ,;
ER_PRICE ,;
ER_DISC ,;
ER_AMOUNT } ;
ITEMVALUES { aItems[ n, 3 ],;
aItems[ n, 4 ],;
AllTrim( Str( aItems[ n, 5 ] ) ),;
AllTrim( Str( aItems[ n, 7 ] ) ),;
AllTrim( Str( aItems[ n, 8 ] ) ),;
AllTrim( Str( ROUND( aItems[ n, 5 ] * aItems[ n, 7 ] - aItems[ n, 8 ], 0 ) ) ) }
if nPrintArea = 3
nPrintArea := 6
else
nPrintArea := 3
endif
next
#UNDEF ER_AMOUNT
//----------------------------------------------------------------------------//
//Footer
//----------------------------------------------------------------------------//
#DEFINE ER_BASE 310
#DEFINE ER_VAT 311
#DEFINE ER_TOTALVAT 312
#DEFINE ER_TOTALINVOICE 313
PRINTAREA 4 OF oVRD ;
ITEMIDS { ER_BASE ,;
ER_VAT ,;
ER_TOTALVAT ,;
ER_TOTALINVOICE } ;
ITEMVALUES { cValToStr( oBrw:Amount:Value ) ,;
cValToStr( oBrw:TaxRate:Value ) ,;
cValToStr( oBrw:Tax:Value ) ,;
cValToStr( oBrw:Total:Value ) }
oVRD:End()
return nil
//----------------------------------------------------------------------------//
function FW_RowSetToArray( oRs, cItemFlds )
local aItems := {}
oRs:GoTop()
while ! oRs:Eof()
AAdd( aItems,;
{ oRs:INVNUM, oRs:SERIAL, oRs:ITEMCODE, oRs:ITEMNAME, oRs:QUANTITY,;
oRs:UNIT, oRs:PRICE, oRs:DISCOUNT, oRs:ID } )
oRs:Skip()
end
return aItems
//----------------------------------------------------------------------------//