Unicode GET cannot be highlighted

Post Reply
Max HK
Posts: 24
Joined: Wed Oct 15, 2008 1:04 pm

Unicode GET cannot be highlighted

Post by Max HK »

I am using FWH 19.12.

I found that in GET field and it is Unicode, the characters cannot be highlighted by SHIFT+arrowkeys, only by mouse selection.
If the field is ANSI, highlight is OK.
Have it be solved in new FWH version?

In new version sample programs, is there a program like YUNUS.PRG but using MariaDB?
Is there a sample program to explain all the power of Xbrowse (eg. different sorting seq, searching by value, save JPG to database, drop files, etc.)?

Thanks.

User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Unicode GET cannot be highlighted

Post by Antonio Linares »

Dear Max,

Lets migrate yunus.prg to use MariaDB:

  1. We install and execute xampp, then we start Apache and MySQL. Then using the internet browser
    we go to localhost/phpmyadmin. We manually create a fwh database and create a user. In our example
    we use fivetec1_antonio as the user name.

  2. We migrate the DBFs to MariaDB using modified samples\maria06.prg:

Modified maria06.prg

Code: Select all | Expand

#include "FiveWin.ch"

REQUEST DBFCDX
REQUEST HB_LANG_ES
REQUEST HB_CODEPAGE_ESWIN

//----------------------------------------------------------------------------//

function Main()

   local oCn, oRs
   local cLog  := cFileSetExt( ExeName(), "log" )

   FErase( cLog )

   RDDSETDEFAULT( "DBFCDX" )
   SET DELETED ON
   SET DATE ITALIAN
   SET CENTURY ON

   HB_CDPSELECT("ESWIN")
   HB_LangSelect( "ES" )

   FW_SetUnicode( .f. )

   oCn := maria_Connect( "localhost", "fwh", "fivetec1_antonio", "1234" )  

   ocn:lLogErr := .t.

   ocn:ImportFromDbf( "invoices.dbf",,,,,,"utf8_spanish2_ci" )

   oRs   := oCn:RowSet( "invoices" )
   XBROWSER oRs FASTEDIT AUTOSORT

   oCn:Close()

   if File( cLog )
      WinExec( "notepad.exe " + cLog )
   endif

return nil

We repeat the process for items.dbf, invitems.dbf and clients2.dbf.

if everything worked as expected then we can see our new MariaDB tables in database fwh from localhost/phpmyadmin

regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Unicode GET cannot be highlighted

Post by Antonio Linares »

Next we modify yunus.prg function OpenDataBases() this way:

Code: Select all | Expand

static function OpenDataBases()  

   local oCn := maria_Connect( "localhost", "fwh", "fivetec1_antonio", "1234" )  
     
if oCn == nil
MsgStop( "Error connecting to the DataBase" )
return nil
endif
return oCn
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Unicode GET cannot be highlighted

Post by Antonio Linares »

Here you have an initial version of yunusm.prg. Copy yunus.rc to yunusm.rc.

You can use items and clients by now. We are working to complete invoices.

yunusm.prg

Code: Select all | Expand

#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,RECNO()"
static nTaxRate   := 0.0
static oCn

//----------------------------------------------------------------------------//

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()

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, oRs
   local oBar, oMsgBar, oMsgDeleted

   if oWndClients == nil
      oRs = 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 oRs 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.

   if lNew
      oRec:Date      := Date()
      oRec:TaxRate   := nTaxRate
      aItems         := { AClone( aBlankItem ) }
   else
      aItems         := IIT->( FW_DbfToArray( cItemFlds, { || IIT->INVNUM == oRec:InvNum } ) )
   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 ) .or. INVOICES->( Duplicate( oRec:InvNum, "INVNUM", oRec:RecNo ) ) )

   @ 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( "CLIENTS", 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 )
        AEval( oBrw:aDeleted, { |a| a[ 9 ] := -a[ 9 ] } )
        IIT->( FW_SaveArrayToDBF( cItemFlds, oBrw:aDeleted ) )
     endif
     AEval( aItems, { |a| a[ 1 ] := oRec:InvNum } )
     AEval( aItems, { |a,i| a[ 2 ] := i } )
     IIT->( FW_SaveArrayToDBF( cItemFlds, aItems ) )
     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 nSaveRec := CLIENTS->( RECNO() )
   local lValid   := .f.

   if CLIENTS->( DBSEEK( oRec:Code ) )
      oRec:Client    := TRIM( CLIENTS->FIRST ) + " " + TRIM( CLIENTS->LAST )
      oRec:Address   := CLIENTS->( PickAddress() )
      lValid         := .t.
   endif
   CLIENTS->( DBGOTO( nSaveRec ) )

   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 nSaveRec := ITEMS->( RECNO() )
   local lValid   := .f.

   if ITEMS->( DBSEEK( aRow[ 3 ] ) )
      aRow[ 4 ]      := TRIM( ITEMS->NAME )
      if aRow[ 5 ] == 0
         aRow[ 5 ]   := 1
      endif
      aRow[ 6 ]      := ITEMS->UNIT
      aRow[ 7 ]      := ITEMS->PRICE
      lValid         := .t.
   endif
   ITEMS->( DBGOTO( nSaveRec ) )

   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 := InvItems->( ;
                   FW_DbfToArray( nil, ;
                   { || InvItems->INVNUM == Invoices->INVNUM } ) )

   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 11

   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() 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 ] } ) ( uSource )->( DBSEEK( oCol:Value, .t. ), If( Eof(), DBGOBOTTOM(), nil ) ) 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 uSource 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 if ValType( uSource ) == 'C' :cFilterFld := "DBRECORDINFO( 7 )" endif :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() 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 := InvItems->( ; FW_DbfToArray( nil, ; { || InvItems->INVNUM == Invoices->INVNUM } ) ) *---------------------------------------------------------- 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 //----------------------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Unicode GET cannot be highlighted

Post by Antonio Linares »

Enhanced version:

yunusm.prg

Code: Select all | Expand

#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.

   if lNew
      oRec:InvNum    := ""
      oRec:Date      := Date()
      oRec:TaxRate   := nTaxRate
      oRec:InvNum    := "     "
      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 )
        AEval( oBrw:aDeleted, { |a| a[ 9 ] := -a[ 9 ] } )
        IIT->( FW_SaveArrayToDBF( cItemFlds, oBrw:aDeleted ) )
     endif
     AEval( aItems, { |a| a[ 1 ] := oRec:InvNum } )
     AEval( aItems, { |a,i| a[ 2 ] := i } )
     IIT->( FW_SaveArrayToDBF( cItemFlds, aItems ) )
     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 nSaveRec := ITEMS->( RECNO() )
   local lValid   := .f.

   if ITEMS->( DBSEEK( aRow[ 3 ] ) )
      aRow[ 4 ]      := TRIM( ITEMS->NAME )
      if aRow[ 5 ] == 0
         aRow[ 5 ]   := 1
      endif
      aRow[ 6 ]      := ITEMS->UNIT
      aRow[ 7 ]      := ITEMS->PRICE
      lValid         := .t.
   endif
   ITEMS->( DBGOTO( nSaveRec ) )

   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 := InvItems->( ;
                   FW_DbfToArray( nil, ;
                   { || InvItems->INVNUM == Invoices->INVNUM } ) )

   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 11

   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() 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 ] } ) ( uSource )->( DBSEEK( oCol:Value, .t. ), If( Eof(), DBGOBOTTOM(), nil ) ) 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 uSource 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 if ValType( uSource ) == 'C' :cFilterFld := "DBRECORDINFO( 7 )" endif :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() 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 := InvItems->( ; FW_DbfToArray( nil, ; { || InvItems->INVNUM == Invoices->INVNUM } ) ) *---------------------------------------------------------- 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 //----------------------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Unicode GET cannot be highlighted

Post by Antonio Linares »

Enhanced version: Invoices already working :wink:

yunusm.prg

Code: Select all | Expand

#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 //----------------------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Unicode GET cannot be highlighted

Post by Antonio Linares »

FWH samples yunus.prg working with MariaDb :D

Image

regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Unicode GET cannot be highlighted

Post by Antonio Linares »

Regarding your unicode GET question here you have a fine working example with FWH 25.09:

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

local oDlg, cVar := "中国版 (China)"

FW_SetUnicode( .T. )

DEFINE DIALOG oDlg 

@ 2, 2 GET cVar 

ACTIVATE DIALOG oDlg CENTERED 

return nil    
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply