Aqui les dejo un ejemplo de una clase para planning de reservas de hotel (fue a peticion de un usuario)
Maneja los estatus de habitaciones de forma personalizada junto con los colores de las mismas, es decir, cada quien decide que tipo de estatus manejara...
La clase se encarga del pintado, el manejo de los datos va por cuenta de los programadores, tiene la opcion de mover las reservas mas no de ampliar/reducir los dias
Code: Select all
#include "fivewin.ch"
#include "ord.ch"
#include "planning.ch"
#include "dtpicker.ch"
REQUEST DBFCDX
REQUEST HB_Lang_ES
REQUEST HB_CODEPAGE_ESWIN
#define PLANNING_RESERVED 1
#define PLANNING_CONFIRMED 2
#define PLANNING_OCCUPIED 3
#define PLANNING_CANCELED 4
#define PLANNING_EMPTY 5
function Main()
SET DATE FORMAT "MM/DD/YYYY"
SET DELETE ON
HB_LangSelect("ES")
HB_CDPSELECT("ESWIN")
SamplePlan():New()
return nil
// status 01 reserved
// status 02 confirmed
// status 03 occupied
// status 04 canceled
//---------------------------------------------------//
CLASS SamplePlan
DATA oPlann
DATA oWnd
DATA aStatus
DATA dStart, dEnd
METHOD New()
METHOD BuildDbf()
METHOD BuildDialog()
METHOD BuildPlanning()
METHOD BuildPop()
METHOD DeleteData( oPlan, dCheckIn )
METHOD ColorData( oData )
METHOD LoadData()
METHOD LoadRooms()
METHOD MoveReservation( nRow, nCol, nType )
ENDCLASS
//---------------------------------------------------//
METHOD New() CLASS SamplePlan
local oMenu, oBrush
local oSelf := Self
::aStatus = { "Reserved", "Confirmed", "Occupied", "Canceled", "Empty" }
MENU oMenu
ENDMENU
DEFINE BRUSH oBrush COLOR CLR_WHITE
::BuildDbf()
DEFINE WINDOW ::oWnd BRUSH obrush
::BuildPlanning()
::LoadRooms()
::LoadData()
::oWnd:oClient = ::oPlann
ACTIVATE WINDOW ::oWnd
oBrush:End()
RETURN Self
//---------------------------------------------------//
METHOD BuildDbf() CLASS SamplePlan
local aStructure
local i
if ! File( "rooms.dbf" )
aStructure = { { "id" , "C", 4, 0 },;
{ "name" , "C", 30, 0 },;
{ "type" , "C", 2, 0 } }
DBCreate( "rooms", aStructure, "DBFCDX" )
endif
if ! File( "reserva.dbf" )
aStructure = { { "date" , "D", 8, 0 },;
{ "rooms_id" , "C", 4, 0 },;
{ "check_in" , "D", 8, 0 },;
{ "check_out", "D", 8, 0 },;
{ "status" , "C", 2, 0 },;
{ "guest" , "C", 30, 0 } }
DBCreate( "reserva", aStructure, "DBFCDX" )
ENDIF
USE ROOMS ALIAS ROOMS VIA "DBFCDX" NEW
INDEX ON ROOMS->ID TAG rooms_id TO rooms
USE RESERVA ALIAS RESERVA VIA "DBFCDX" NEW
INDEX ON RESERVA->ROOMS_ID + DToS( RESERVA->CHECK_IN ) TAG room_in TO reserva
if ROOMS->( LastRec() ) == 0
for i = 1 to 30
ROOMS->( DbAppend() )
ROOMS->ID = StrZero( i, 2 )
ROOMS->NAME = "Room " + StrZero( i, 2 )
ROOMS->TYPE = StrZero( i % 5, 2 )
next
endif
RETURN nil
//---------------------------------------------------//
METHOD BuildDialog( oPlan, dCheckIn, dCheckOut ) CLASS SamplePlan
local oDlg, oCbx
local lSave := .F.
local lNew := .T.
local cVar, cName := Space( 30 )
local nAt := 1
if oPlan:oLastData != NIL
lNew = ! oPlan:oLastData:lSelected
endif
DEFINE DIALOG oDlg TITLE "Adding Data" SIZE 350, 370
if ! lNew
RESERVA->( DBSeek( oPlan:GetRowID() + DToS( dCheckIn ) ) )
cName := RESERVA->GUEST
nAt := Val( RESERVA->STATUS )
endif
//cCheckIn = oPlan:aSelected[ 1 ]
@ 10, 10 SAY "Room: " + oPlan:GetRowText() OF oDlg PIXEL
@ 25, 10 SAY "Check In: " + DToC( dCheckIn ) OF oDlg PIXEL
@ 40, 10 SAY "Check Out:" + DToC( dCheckOut ) OF oDlg PIXEL
@ 55, 10 SAY "Status:" OF oDlg PIXEL
@ 55, 55 COMBOBOX oCbx VAR cVar;
ITEMS ::aStatus;
STYLE CBS_DROPDOWN PIXEL
@ 70, 10 SAY "Guest Name:" OF oDlg PIXEL
@ 70, 55 GET cName OF oDlg PIXEL
@ 170, 10 BUTTON "OK" PIXEL ACTION ( lSave := .T., oDlg:End() )
@ 170, 100 BUTTON "CANCEL" PIXEL ACTION ( oDlg:End() )
ACTIVATE DIALOG oDlg CENTERED;
ON INIT oCbx:Select( nAt )
IF lSave
if lNew
RESERVA->( DBAppend() )
else
RESERVA->( DBSeek( oPlan:GetRowID() + DToS( dCheckIn ) ) )
endif
RESERVA->DATE = Date()
RESERVA->ROOMS_ID = oPlan:GetRowID()
RESERVA->CHECK_IN = dCheckIn
RESERVA->CHECK_OUT = dCheckOut
RESERVA->STATUS = StrZero( oCbx:nAt, 2 )
RESERVA->GUEST = cName
RESERVA->( DbCommitAll() )
::LoadData()
oPlan:Refresh()
ENDIF
RETURN nil
//---------------------------------------------------//
METHOD BuildPlanning() CLASS SamplePlan
LOCAL oSelf := Self
DEFINE PLANNING ::oPlann OF ::oWnd;
COLOR HEADER ( If( Dow( dDate ) == 1 .OR. Dow( dDate ) == 7, CLR_WHITE, ::oPlann:nClrText ) );
COLOR CELL ::ColorData( oData ) ;
START DAY Date() - 5;
END DAY Date() + 5;
ON RIGHT SELECT oSelf:BuildPop( nRow, nCol, Self, dCheckIn, dCheckOut )
::oPlann:bOnCapture = { | nRow, nCol, pHitTest | If( pHitTest:nMoveType != 0, ::MoveReservation(nRow, nCol, pHitTest:nMoveType), ) }
::dStart = ::oPlann:dStart
::dEnd = ::oPlann:dEnd
@ 10, 10 DTPICKER ::dStart OF ::oPlann pixel ;
ON CHANGE ( if( oSelf:dStart != oSelf:oPlann:dStart, ( oSelf:oPlann:SetDates( oSelf:dStart ), oSelf:LoadData() ), ) )
@ 10, 120 DTPICKER ::dEnd OF ::oPlann pixel;
ON CHANGE ( if( oSelf:dEnd != oSelf:oPlann:dEnd, ( oSelf:oPlann:SetDates( , oSelf:dEnd ), oSelf:LoadData() ), ) )
RETURN nil
//---------------------------------------------------//
METHOD BuildPop( nRow, nCol, oPlan, dCheckIn, dCheckOut ) CLASS SamplePlan
local oMenu
local oSelf := Self
local lNew := .T.
if oPlan:oLastData != NIL
lNew = ! oPlan:oLastData:lSelected
endif
MENU oMenu POPUP
MENUITEM If( lNew, "New Reserve",;
"Modify Reserve" ) ACTION oSelf:BuildDialog( oPlan, dCheckIn, dCheckOut )
if ! lNew
MENUITEM "Delete Reserve" ACTION If( MsgYesNo( "Are you sure?" ), oSelf:DeleteData( oPlan, dCheckIn ) , )
endif
ENDMENU
ACTIVATE POPUP oMenu OF oPlan AT nRow, nCol
RETURN nil
//---------------------------------------------------//
METHOD DeleteData( oPlan, dCheckIn ) CLASS SamplePlan
if RESERVA->( DBSeek( oPlan:GetRowID() + DToS( dCheckIn ) ) )
RESERVA->( DBDelete() )
oPlan:DeleteData( oPlan:oLastData )
endif
RETURN nil
//---------------------------------------------------//
METHOD ColorData( oData ) CLASS SamplePlan
local aGrad
//"Reserved", "Confirmed", "Occupied", "Calceled", "Empty"
switch oData:Cargo
case PLANNING_RESERVED
aGrad = { { 1, RGB(0x9a,0xcd,0x32), RGB(0x9a,0xcd,0x32) } }
exit
case PLANNING_CONFIRMED
aGrad = { { 1, RGB(0x00,0x80,0xff) , RGB(0x00,0x80,0xff) } }
exit
case PLANNING_OCCUPIED
aGrad = { { 1, RGB(0xff,0xff,0x80), RGB(0xff,0xff,0x80) } }
exit
case PLANNING_CANCELED
aGrad = { { 1, RGB(0xff,0x00,0x00), RGB(0xff,0x00,0x00) } }
exit
case PLANNING_EMPTY
aGrad = { { 1, RGB(0xc0,0xc0,0xc0), RGB(0xc0,0xc0,0xc0) } }
endswitch
return aGrad
//---------------------------------------------------//
METHOD LoadData() CLASS SamplePlan
local cDescribe
local nStatus
local cTooltip, oData
//Clear scopes
RESERVA->( OrdSetFocus( "room_in" ) )
RESERVA->( OrdScope( TOPSCOPE, NIL ) )
RESERVA->( OrdScope( BOTTOMSCOPE, NIL ) )
RESERVA->( DBGoTop() )
RESERVA->( OrdScope( TOPSCOPE, Month( ::oPlann:dStart ) ) )
RESERVA->( OrdScope( BOTTOMSCOPE, Month( ::oPlann:dEnd ) ) )
RESERVA->( DBGoTop() )
DO WHILE ! RESERVA->( Eof() )
if DToS( RESERVA->CHECK_OUT ) > DToS( ::oPlann:dStart ) .AND. DToS( RESERVA->CHECK_IN ) < DToS( ::oPlann:dEnd )
cDescribe = "Empty..."
nStatus = Val( RESERVA->STATUS )
if nStatus > 0 .and. nStatus < 5
cDescribe = ::aStatus[ nStatus ]
endif
ROOMS->( DbSeek( RESERVA->ROOMS_ID ) )
cTooltip = "Room : " + ROOMS->NAME + CRLF
cTooltip += "Guest : " + RESERVA->GUEST + CRLF
cTooltip += "Check In : " + DToC( RESERVA->CHECK_IN ) + CRLF
cTooltip += "Check Out: " + DToC( RESERVA->CHECK_OUT )
oData = ::oPlann:AddData( RESERVA->ROOMS_ID,;
RESERVA->CHECK_IN,;
RESERVA->CHECK_OUT,;
cDescribe, cToolTip )
if oData != NIL
oData:Cargo = nStatus
endif
endif
RESERVA->( DbSkip() )
ENDDO
return NIL
//---------------------------------------------------//
METHOD LoadRooms() CLASS SamplePlan
local n
local cRowName, cRowText
local oData
ROOMS->( DbGoTop() )
DO WHILE ! ROOMS->( Eof() )
::oPlann:AddRow( ROOMS->ID, ROOMS->NAME )
ROOMS->( DbSkip() )
ENDDO
RETURN nil
//---------------------------------------------------//
METHOD MoveReservation( nRow, nCol, nType ) CLASS SamplePlan
local oPlann := ::oPlann
local oItem := oPlann:oLastData
local cDescribe, cTooltip, oData, nStatus
if nType > 0
cDescribe = oItem:cDescribe
nStatus = oItem:Cargo
oPlann:DeleteData( oItem, .F. )
RESERVA->( DBSeek( oPlann:GetRowID() + DToS( oItem:dStart ) ) )
endif
switch nType
case PLANNING_MOVE_RIGTH
RESERVA->CHECK_IN = RESERVA->CHECK_IN + 1
RESERVA->CHECK_OUT = RESERVA->CHECK_OUT + 1
RESERVA->( DbCommitAll() )
exit
case PLANNING_MOVE_LEFT
RESERVA->CHECK_IN = RESERVA->CHECK_IN - 1
RESERVA->CHECK_OUT = RESERVA->CHECK_OUT - 1
RESERVA->( DbCommitAll() )
exit
case PLANNING_MOVE_UP
case PLANNING_MOVE_DOWN
RESERVA->ROOMS_ID = oPlann:GetRowID(oPlann:GetAtRow( nRow ))
RESERVA->( DbCommitAll() )
exit
endswitch
if nType > 0
cTooltip = "Room : " + ROOMS->NAME + CRLF
cTooltip += "Guest : " + RESERVA->GUEST + CRLF
cTooltip += "Check In : " + DToC( RESERVA->CHECK_IN ) + CRLF
cTooltip += "Check Out: " + DToC( RESERVA->CHECK_OUT )
oData = oPlann:AddData( RESERVA->ROOMS_ID,;
RESERVA->CHECK_IN,;
RESERVA->CHECK_OUT,;
cDescribe, cToolTip )
oData:Cargo = nStatus
oPlann:oLastData = NIL
oPlann:SelectCell( nRow, nCol )
oPlann:Refresh()
endif
RETURN nil
//---------------------------------------------------//
function HB_COMPILEFROMBUF()
return nil
function curdrive()
return nil