2106 lines
56 KiB
C++
2106 lines
56 KiB
C++
// ScheduleFrm.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "sp.h"
|
|
#include "ScheduleFrm.h"
|
|
#include "WOHeaderDlg.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
//memory leak debugging help
|
|
#define _CRTDBG_MAP_ALLOC
|
|
#include <stdlib.h>
|
|
#include <crtdbg.h>
|
|
#define MARTIN 1
|
|
#define DAYSTOCACHE 15
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CScheduleFrm
|
|
/*
|
|
View scheduled workorders in the system visually
|
|
|
|
Create new workorders by clicking and dragging a bar of time with the mouse
|
|
|
|
Drag an existing workorder to a different time period
|
|
|
|
Drag an existing workorder to a different technician
|
|
|
|
Positioning the mouse over a time bar shows the client and workorder number at the top
|
|
|
|
Double click on a time bar to open that workorder for editing
|
|
|
|
View a day, week, two weeks or a month at a time
|
|
|
|
Print the schedule as it appears onscreen (will print in color if your printer supports it)
|
|
|
|
Change the start or end time of a workorder by clicking and dragging the ends of a time bar
|
|
|
|
|
|
|
|
*/
|
|
IMPLEMENT_DYNCREATE(CScheduleFrm, CFormView)
|
|
|
|
CScheduleFrm::CScheduleFrm()
|
|
: CFormView(CScheduleFrm::IDD)
|
|
, m_bShowProblemDetailsInStatusDisplay(false)
|
|
{
|
|
//{{AFX_DATA_INIT(CScheduleFrm)
|
|
//}}AFX_DATA_INIT
|
|
m_pApp= (CSpApp*)AfxGetApp();
|
|
m_dt1900.SetDate(1900,1,1);
|
|
m_nZoomFactor=60;
|
|
m_bRefresh=true;
|
|
m_bLayoutDone=false;
|
|
m_nTotalAllocated=0;
|
|
m_bTimerIsActive=false;
|
|
m_bZoneView=true;
|
|
|
|
}
|
|
|
|
CScheduleFrm::~CScheduleFrm()
|
|
{
|
|
//KillTimer(1);
|
|
//ClearTimeBarObjects();
|
|
}
|
|
|
|
void CScheduleFrm::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CFormView::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CScheduleFrm)
|
|
DDX_Control(pDX, IDC_LBLZONE, m_lblZone);
|
|
DDX_Control(pDX, IDC_CBZONE, m_cbZone);
|
|
DDX_Control(pDX, IDC_BTNBACK, m_btnBack);
|
|
DDX_Control(pDX, IDC_BTNFORWARD, m_btnForward);
|
|
DDX_Control(pDX, IDC_BTNPRINT, m_btnPrint);
|
|
DDX_Control(pDX, IDC_LBLVIEW, m_lblView);
|
|
DDX_Control(pDX, IDC_LBLSTARTDATE, m_lblStartDate);
|
|
DDX_Control(pDX, IDC_BTNREFRESH, m_btnRefresh);
|
|
DDX_Control(pDX, IDC_CKLOCk, m_ckLock);
|
|
DDX_Control(pDX, IDC_RDWEEK, m_rdWeek);
|
|
DDX_Control(pDX, IDC_RDMONTH, m_rdMonth);
|
|
DDX_Control(pDX, IDC_RDDAY, m_rdDay);
|
|
DDX_Control(pDX, IDC_LBLWODETAILS, m_lblDetails);
|
|
DDX_Control(pDX, IDC_DTDATE, m_dtDate);
|
|
DDX_Control(pDX, IDC_CTSCHED, m_sc);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CScheduleFrm, CFormView)
|
|
//{{AFX_MSG_MAP(CScheduleFrm)
|
|
ON_NOTIFY(DTN_DATETIMECHANGE, IDC_DTDATE, OnDatetimechangeDtdate)
|
|
ON_BN_CLICKED(IDC_BTNPRINT, OnBtnprint)
|
|
ON_BN_CLICKED(IDC_BTNBACK, OnBtnback)
|
|
ON_BN_CLICKED(IDC_BTNFORWARD, OnBtnforward)
|
|
ON_BN_CLICKED(IDC_RDDAY, OnRdday)
|
|
ON_BN_CLICKED(IDC_RDMONTH, OnRdmonth)
|
|
ON_BN_CLICKED(IDC_RDWEEK, OnRdweek)
|
|
ON_BN_CLICKED(IDC_BTNREFRESH, OnBtnrefresh)
|
|
ON_BN_CLICKED(IDC_CKLOCk, OnCKLOCk)
|
|
ON_CBN_CLOSEUP(IDC_CBZONE, OnCloseupCbzone)
|
|
ON_WM_TIMER()
|
|
//}}AFX_MSG_MAP
|
|
ON_WM_HELPINFO()
|
|
ON_WM_DESTROY()
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CScheduleFrm diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CScheduleFrm::AssertValid() const
|
|
{
|
|
CFormView::AssertValid();
|
|
}
|
|
|
|
void CScheduleFrm::Dump(CDumpContext& dc) const
|
|
{
|
|
CFormView::Dump(dc);
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CScheduleFrm message handlers
|
|
|
|
void CScheduleFrm::Activate()
|
|
{
|
|
|
|
m_ulHighLightedBar=RGB(255,0,0);
|
|
m_ulStandardBar=RGB(0,0,255);
|
|
FillZoneList();
|
|
FillView();
|
|
if(!m_bTimerIsActive)
|
|
{
|
|
|
|
//AUTOREFRESH TIMER
|
|
if(m_pApp->m_lSchedRefreshSecs!=0)
|
|
m_nTimer = SetTimer(1, 1000*m_pApp->m_lSchedRefreshSecs, 0);
|
|
//m_nTimer = SetTimer(1, 6000, 0);
|
|
|
|
m_bTimerIsActive=true;
|
|
}
|
|
}
|
|
|
|
void CScheduleFrm::DeActivate()
|
|
{
|
|
KillTimer(1);
|
|
m_bTimerIsActive=false;
|
|
|
|
}
|
|
|
|
void CScheduleFrm::OnInitialUpdate()
|
|
{
|
|
CFormView::OnInitialUpdate();
|
|
m_lblDetails.SetFontName("MS Sans Serif");
|
|
m_lblDetails.SetFontSize(8);
|
|
m_lblDetails.SetFontBold(FALSE);
|
|
m_lblDetails.SetTextColor(RGB(0,0,0));
|
|
m_lblDetails.SetBkColor(RGB(255,255,255));
|
|
|
|
//performance stats
|
|
m_dLast=m_dFastest=m_dSlowest=m_dAverage=0;
|
|
m_uiRefreshCount=0;
|
|
|
|
//start off with a day view
|
|
m_nDayWeekMonth=0;//0-day 1=week 2=Month shown in view
|
|
m_rdDay.SetCheck(TRUE);
|
|
m_ckLock.SetCheck(TRUE);
|
|
m_bLocked=true;
|
|
m_bUndoing=false;
|
|
//lock so that get time bar object won't change it because of another even somewhere
|
|
m_bUpdating=false;
|
|
//m_nBarStyleOverlapping=m_sc.AddBarStyle(8,-2);//<<<<<<<<<<<<<ORIGINAL
|
|
m_nBarStyleOverlapping=m_sc.AddBarStyle(8,-5);//<<<<<<<<<<<<<
|
|
|
|
m_sc.SetStyleStartImage(m_nBarStyleOverlapping,-8);
|
|
m_sc.SetStyleEndImage(m_nBarStyleOverlapping,-8);
|
|
|
|
//added 07/24/2001 to accomodate time off bar style
|
|
m_nBarStyleTimeOff=m_sc.AddBarStyle(14,3);//<<<<<<<<<<<<<<<<<<<<<
|
|
|
|
//added 07/24/2001 to accomodate all day milestone description
|
|
m_nBarStyleAllDayText=m_sc.AddBarStyle(20,0);
|
|
m_sc.SetStyleMilestone(m_nBarStyleAllDayText,TRUE);
|
|
m_sc.SetStyleStartImage(m_nBarStyleAllDayText,-11);
|
|
|
|
|
|
|
|
|
|
|
|
// FillZoneList();
|
|
//FillView();
|
|
|
|
arBar.SetSize(100,10);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CScheduleFrm::FillView()
|
|
{
|
|
m_bShowProblemDetailsInStatusDisplay=true;
|
|
int nCounter;
|
|
pTimer.Start(TRUE);
|
|
LayoutControls();
|
|
CString q,strWOID;
|
|
CString strData,strClient,strProjectName, strTemp;
|
|
COleDateTime dtStart,dtEnd,dtSchedStart,dtSchedEnd,dtTemp,dtTimeScrollStart;
|
|
COleDateTimeSpan dtSpan,dtSpanMinutes,dtSpanDays;
|
|
long lWindowSize;
|
|
lWindowSize=m_pApp->m_lSchedWindowDays/2;
|
|
|
|
|
|
long lTechID,lWOID, lStatID, lDaysStart,lDaysEnd,lMinStart,lMinEnd;
|
|
|
|
//time bar status stuff
|
|
CString strStatus,strWONOTES,strZoneQ;
|
|
long lRed,lGreen,lBlue;
|
|
|
|
bool bActive,bFirstRunThrough,bContinue;
|
|
int count=0;
|
|
int nBar;//used for time bar colors to retrieve and set bar value
|
|
|
|
//added 07/27/01 to accomodate multi-tech scheduled
|
|
long lThisTech;
|
|
bool bMatchingTech;
|
|
int nTech;
|
|
int nMatchingTechNumber;
|
|
|
|
|
|
bFirstRunThrough=true;//used to show non-assigned items
|
|
|
|
//flag used by OnItemMove... to indicate that nothing was
|
|
//ever highlighted before
|
|
m_nOldIndex=m_nOldBar=0;
|
|
|
|
//Get the date from the control
|
|
m_dtDate.GetTime(dtStart);
|
|
|
|
//set the default fore text to white to contrast with
|
|
//every likely color
|
|
m_sc.SetBarDefForeColor(RGB(255,255,255));
|
|
//set time scroll value to something past the possible values
|
|
//this is used to determine the earliest date in the schedule
|
|
//and thus, scroll the schedule to it automatically
|
|
//a thousand years give or take oughta do...
|
|
dtTimeScrollStart.SetDate(3000,1,1);
|
|
//dtTimeScrollStart=COleDateTime::GetCurrentTime();
|
|
|
|
m_sc.SetBarDefBackColor(m_ulStandardBar);
|
|
//m_sc.SetTimeStart();
|
|
|
|
|
|
//if it's not a forced refresh, see if it's within the window
|
|
if(!m_bRefresh)
|
|
{
|
|
if(dtStart > m_dtWindowStop || dtStart < m_dtWindowStart)
|
|
{
|
|
m_bRefresh=true;
|
|
dtSpan.SetDateTimeSpan(lWindowSize,0,0,0);
|
|
m_dtWindowStart=dtStart-dtSpan;
|
|
m_dtWindowStop=dtStart+dtSpan;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
dtSpan.SetDateTimeSpan(lWindowSize,0,0,0);
|
|
m_dtWindowStart=dtStart-dtSpan;
|
|
m_dtWindowStop=dtStart+dtSpan;
|
|
|
|
}
|
|
//*****************************************************************
|
|
|
|
|
|
//*******************************************************
|
|
//Clear the previous schedule if any
|
|
if(m_bRefresh)
|
|
{
|
|
m_sc.ClearSchedule();
|
|
//added 07/27/01 to account for changes to sched markers
|
|
m_sc.ClearColorBars();
|
|
ClearTimeBarObjects();
|
|
}
|
|
//********************************************************
|
|
|
|
|
|
|
|
//Set the zoom factor in the control
|
|
//hours or days (maybe weeks...who knows?)
|
|
if(m_nDayWeekMonth==0)
|
|
{
|
|
m_sc.SetWeekends(0);
|
|
m_sc.SetTimeType(0);//0=hours,1=days,2=weeks
|
|
m_sc.SetTimeDistance(m_nZoomFactor);
|
|
m_sc.SetPrintTimeDistance(m_nZoomFactor);
|
|
m_sc.SetBarTipSize(5);//5 is default
|
|
m_sc.SetBarTipExtension(5);
|
|
|
|
m_sc.SetRulerDivisions(4);
|
|
|
|
}
|
|
else
|
|
{
|
|
m_sc.SetWeekends(65);
|
|
m_sc.SetTimeType(1);
|
|
m_sc.SetRulerDivisions(0);
|
|
m_sc.SetTimeDistance(75);
|
|
m_sc.SetPrintTimeDistance(75);
|
|
m_sc.SetBarTipSize(-200);//5 is default
|
|
m_sc.SetBarTipExtension(-200);
|
|
|
|
|
|
}
|
|
|
|
|
|
dtEnd=dtStart+dtSpan;
|
|
|
|
//Set the start and end dates in the control
|
|
|
|
|
|
//start date days since 1900
|
|
|
|
dtSpan=m_dtWindowStart-m_dt1900;
|
|
lDaysStart=(long)dtSpan.GetTotalDays();
|
|
|
|
//end date days since 1900
|
|
dtSpan=m_dtWindowStop-m_dt1900;
|
|
lDaysEnd=(long)dtSpan.GetTotalDays();
|
|
|
|
m_sc.SetDateStart(lDaysStart);
|
|
m_sc.SetDateEnd(lDaysEnd);
|
|
|
|
|
|
|
|
//read from the database if it's a refresh situation
|
|
if(m_bRefresh)
|
|
{
|
|
CWaitCursor cw;
|
|
|
|
//Start timing here
|
|
m_uiRefreshCount++;
|
|
|
|
|
|
|
|
|
|
|
|
m_bRefresh=false;
|
|
//Initialize recordset pointer
|
|
pTimerSQL.Start(TRUE);
|
|
rs=m_pApp->rsPool->GetRS("CScheduleFrm::FillView (RS)");
|
|
rs2=m_pApp->rsPool->GetRS("CScheduleFrm::FillView (RS2)");
|
|
rs3=m_pApp->rsPool->GetRS("CScheduleFrm::FillView (RS3)");
|
|
pTimerSQL.Stop();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//If by zone.....
|
|
if(m_bZoneView)
|
|
{
|
|
//SELECT USERS BY ZONE
|
|
strZoneQ=m_cbZone.GetCurrentRowID();
|
|
if(strZoneQ=="0")
|
|
strZoneQ.Empty();
|
|
else
|
|
{
|
|
strZoneQ.Format("AND ((users.defzone)=%s)",m_cbZone.GetCurrentRowID());
|
|
|
|
}
|
|
|
|
q.Format("SELECT users.id, users.active, [last] & \", \" & [first] AS fullname FROM users "
|
|
"WHERE (((users.id)<>1) AND ((users.tech)=True) %s ) "
|
|
"ORDER BY users.last;",strZoneQ);
|
|
}
|
|
//-------------------------------------------------------------------------------------------
|
|
else
|
|
{
|
|
//else if by group
|
|
//SELECT USERS BY GROUP
|
|
strZoneQ=m_cbZone.GetCurrentRowID();
|
|
q.Format("SELECT users.id, users.active, [last] & \", \" & [first] AS fullname "
|
|
"FROM schdets LEFT JOIN users ON schdets.techid = users.id "
|
|
"WHERE (((schdets.grpid)=%s) AND ((users.tech)=True) AND ((users.id)<>1)) "
|
|
"ORDER BY users.last;",strZoneQ);
|
|
|
|
|
|
}
|
|
//-------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
pTimerSQL.Start(FALSE);
|
|
rs->QueryReadOnly(q);
|
|
pTimerSQL.Stop();
|
|
if(rs->IsEmpty())
|
|
{
|
|
//AfxMessageBox("There are no technicians for this zone");
|
|
m_pApp->rsPool->ReleaseRS(&rs->m_nID);
|
|
m_pApp->rsPool->ReleaseRS(&rs2->m_nID);
|
|
m_pApp->rsPool->ReleaseRS(&rs3->m_nID);
|
|
//don't bother updatnig timer
|
|
return;
|
|
|
|
|
|
}
|
|
bContinue=true;
|
|
|
|
|
|
do {
|
|
if(bFirstRunThrough)
|
|
{
|
|
strData="To be assigned";
|
|
lTechID=0;
|
|
bActive=true;
|
|
bFirstRunThrough=false;
|
|
}
|
|
else
|
|
{
|
|
pTimerSQL.Start(FALSE);
|
|
rs->FetchField("fullname",&strData);
|
|
rs->FetchField("id",&lTechID);
|
|
rs->FetchField("active",&bActive);
|
|
pTimerSQL.Stop();
|
|
bContinue=rs->MoveForward();
|
|
}
|
|
m_sc.AddItem(strData);
|
|
strData.Format("%u",lTechID);
|
|
m_sc.SetListCargo(count+1,strData);
|
|
count++;
|
|
|
|
if(!bActive)
|
|
{
|
|
m_sc.SetListReadOnly((short)count,TRUE);
|
|
m_sc.SetListItemBackColor((short)count,(unsigned long)RGB(128,128,128));// dark gray
|
|
|
|
}
|
|
else
|
|
m_sc.SetListItemBackColor((short)count,(unsigned long)RGB(255,255,255));//white
|
|
|
|
|
|
|
|
|
|
|
|
//**********************************************
|
|
//********* SHOW TECH TIME OFF BARS ************
|
|
//********* Added 07/24/2001 *******************
|
|
//**********************************************
|
|
//FIND ALL ITEMS FOR THIS TECH BETWEEN
|
|
//m_dtWindowStart and m_dtWindowEnd
|
|
//And then insert time bar in the m_nBarStyleTimeOff style
|
|
//**********************************************
|
|
if(lTechID!=0)
|
|
{
|
|
q.Format("SELECT schedmarkers.startdate, schedmarkers.enddate, schedmarkers.notes, schedmarkers.red, schedmarkers.green, schedmarkers.blue "
|
|
"FROM schedmarkers "
|
|
"WHERE (((schedmarkers.link)=%u) AND "
|
|
"((schedmarkers.startdate) Between #%s# And #%s#));",lTechID,
|
|
m_dtWindowStart.Format(_T("%m/%d/%Y %H:%M:%S")),m_dtWindowStop.Format(_T("%m/%d/%Y %H:%M:%S")));
|
|
|
|
//m_pApp->ShowStuff(q);
|
|
|
|
rs2->QueryReadOnly(q);
|
|
if(!rs2->IsEmpty())
|
|
{
|
|
do {
|
|
rs2->FetchField("notes",&strData);
|
|
rs2->FetchField("startdate",&dtSchedStart);
|
|
rs2->FetchField("enddate",&dtSchedEnd);
|
|
rs2->FetchField("red",&lRed);
|
|
rs2->FetchField("green",&lGreen);
|
|
rs2->FetchField("blue",&lBlue);
|
|
|
|
//start date days since 1900
|
|
dtSpan=dtSchedStart-m_dt1900;
|
|
lDaysStart=(long)dtSpan.GetTotalDays();//<---**********
|
|
|
|
//end date days since 1900
|
|
dtSpan=dtSchedEnd-m_dt1900;
|
|
lDaysEnd=(long)dtSpan.GetTotalDays();//<---------************
|
|
|
|
//Start time minutes since midnight
|
|
//set dttemp to 1 second after midnight
|
|
dtTemp.SetDateTime(
|
|
dtSchedStart.GetYear(),
|
|
dtSchedStart.GetMonth(),
|
|
dtSchedStart.GetDay(),0,0,0);
|
|
dtSpan=dtSchedStart-dtTemp;
|
|
lMinStart = (long) dtSpan.GetTotalMinutes();//<---**********
|
|
|
|
//q.Format("Start time:%s Midnight:%s, minutes:%u",dtSchedStart.Format(),dtTemp.Format(),lMinStart);
|
|
//AfxMessageBox(q);
|
|
//End time hours since midnight
|
|
//set dttemp to 1 second after midnight
|
|
dtTemp.SetDateTime(
|
|
dtSchedEnd.GetYear(),
|
|
dtSchedEnd.GetMonth(),
|
|
dtSchedEnd.GetDay(),0,0,0);
|
|
dtSpan=dtSchedEnd-dtTemp;
|
|
lMinEnd = (long) dtSpan.GetTotalMinutes();//<-------*********
|
|
|
|
//Insert the bar
|
|
nBar=m_sc.AddKeyTimeBar(count,lMinStart,lMinEnd,lDaysStart,lDaysEnd,"off");//all off hours have cargo text id value of off
|
|
m_sc.SetBarText(count,nBar,strData);//set text as specified in schedmarker record
|
|
m_sc.SetBarBackColor(count,nBar,RGB(lRed,lGreen,lBlue));//set back color
|
|
|
|
m_sc.SetBarForeColor(count,nBar,RGB(0,0,0));//set text black
|
|
//m_sc.SetBarTextAlign(count,nBar,2);//set to centered text
|
|
m_sc.SetBarStyle(count,nBar,m_nBarStyleTimeOff);//set to the style for off hours defined in initinstance
|
|
|
|
}while(rs2->MoveForward());
|
|
|
|
|
|
}
|
|
|
|
|
|
}//endif techid<>0
|
|
else//tech ID is zero so here is where the milestone bar should go if it's a full day back color (shop closed etc)
|
|
{
|
|
//**********************************************
|
|
//********* SET SHOP CLOSED DAYS ***************
|
|
//**********************************************
|
|
//FIND ALL ITEMS BETWEEN m_dtWindowStart and m_dtWindowEnd
|
|
|
|
//And then use the m_sc.AddColorBar to color the background
|
|
|
|
//link=0 because non-zero means a tech time off and zero means whole office
|
|
//closed
|
|
//**********************************************
|
|
q.Format("SELECT schedmarkers.startdate, schedmarkers.enddate, schedmarkers.notes, schedmarkers.red, schedmarkers.green, schedmarkers.blue "
|
|
"FROM schedmarkers "
|
|
"WHERE (((schedmarkers.link)=0) AND "
|
|
"((schedmarkers.startdate) Between #%s# And #%s#));",
|
|
m_dtWindowStart.Format(_T("%m/%d/%Y 0:0:0")),m_dtWindowStop.Format(_T("%m/%d/%Y 23:59:59")));
|
|
|
|
//m_pApp->ShowStuff(q);
|
|
|
|
rs2->QueryReadOnly(q);
|
|
if(!rs2->IsEmpty())
|
|
{
|
|
do {
|
|
rs2->FetchField("notes",&strData);
|
|
rs2->FetchField("startdate",&dtSchedStart);
|
|
rs2->FetchField("enddate",&dtSchedEnd);
|
|
rs2->FetchField("red",&lRed);
|
|
rs2->FetchField("green",&lGreen);
|
|
rs2->FetchField("blue",&lBlue);
|
|
|
|
|
|
//start date days since 1900
|
|
dtSpan=dtSchedStart-m_dt1900;
|
|
lDaysStart=(long)dtSpan.GetTotalDays();//<---**********
|
|
|
|
//end date days since 1900
|
|
dtSpan=dtSchedEnd-m_dt1900;
|
|
lDaysEnd=(long)dtSpan.GetTotalDays();//<---------************
|
|
|
|
//Start time minutes since midnight
|
|
//set dttemp to 1 second after midnight
|
|
dtTemp.SetDateTime(
|
|
dtSchedStart.GetYear(),
|
|
dtSchedStart.GetMonth(),
|
|
dtSchedStart.GetDay(),0,0,0);
|
|
dtSpan=dtSchedStart-dtTemp;
|
|
lMinStart = (long) dtSpan.GetTotalMinutes();//<---**********
|
|
|
|
//q.Format("Start time:%s Midnight:%s, minutes:%u",dtSchedStart.Format(),dtTemp.Format(),lMinStart);
|
|
//AfxMessageBox(q);
|
|
//End time hours since midnight
|
|
//set dttemp to 1 second after midnight
|
|
dtTemp.SetDateTime(
|
|
dtSchedEnd.GetYear(),
|
|
dtSchedEnd.GetMonth(),
|
|
dtSchedEnd.GetDay(),0,0,0);
|
|
dtSpan=dtSchedEnd-dtTemp;
|
|
lMinEnd = (long) dtSpan.GetTotalMinutes();//<-------*********
|
|
|
|
//Insert the backcolor as appropriate
|
|
m_sc.AddColorBar(lMinStart,lMinEnd,lDaysStart,lDaysEnd,RGB(lRed,lGreen,lBlue));
|
|
//Insert the bar
|
|
nBar=m_sc.AddKeyTimeBar(count,lMinStart,lMinEnd,lDaysStart,lDaysEnd,"off");//all off hours have cargo text id value of off
|
|
m_sc.SetBarText(count,nBar,strData);//set text as specified in schedmarker record
|
|
//m_sc.SetBarBackColor(count,nBar,RGB(255,128,0));//set back orange
|
|
|
|
m_sc.SetBarForeColor(count,nBar,RGB(0,0,0));//set text black
|
|
//m_sc.SetBarTextAlign(count,nBar,2);//set to centered text
|
|
//m_sc.SetBarTextWrap(TRUE);
|
|
m_sc.SetBarStyle(count,nBar,m_nBarStyleAllDayText);//set to the style for off hours defined in initinstance
|
|
|
|
|
|
}while(rs2->MoveForward());
|
|
|
|
|
|
}//endif !rs2 empty
|
|
|
|
}//endif ltechid=0 (not assigned)
|
|
//************************************************
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Fill view
|
|
//Modified 07/26/01 - added the wotech 2,3,4 in OR statement all else the same
|
|
//PROBLEM: START TIMES SHOULD BE FOR EACH TECH SEPARATELY.
|
|
//LIKE THIS:
|
|
/*
|
|
SELECT wo.id, wo.assigntech, wo.starttime, wo.stoptime, wo.assigntech2, wo.starttime2, wo.stoptime2, wo.assigntech3, wo.starttime3, wo.stoptime3, wo.assigntech4, wo.starttime4, wo.stoptime4, wo.notes, clients.company, clients.last, clients.first, clients.bizphone, probstat.notes AS thestatus, projects.name AS projectname
|
|
FROM wotypes RIGHT JOIN ((probstat RIGHT JOIN (wo LEFT JOIN clients ON wo.client = clients.id) ON probstat.id = wo.status) LEFT JOIN projects ON wo.project = projects.id) ON wotypes.id = wo.type
|
|
WHERE (((wo.anytime)=False) AND ((wo.closed)=#3/12/1968#) AND ((wo.quick)=False)) AND
|
|
|
|
( (((wo.assigntech)=2) AND ((wo.starttime) Between #7/1/2001# And #9/1/2001 23:59:59#)) OR
|
|
(((wo.assigntech2)=2) AND ((wo.starttime2) Between #7/1/2001# And #9/1/2001 23:59:59#)) OR
|
|
(((wo.assigntech3)=2) AND ((wo.starttime3) Between #7/1/2001# And #9/1/2001 23:59:59#)) OR
|
|
(((wo.assigntech4)=2) AND ((wo.starttime4) Between #7/1/2001# And #9/1/2001 23:59:59#)) )
|
|
ORDER BY wo.assigntech;
|
|
|
|
|
|
*/
|
|
/*
|
|
q.Format("SELECT wo.id, wo.anytime, "
|
|
"wo.assigntech, wo.starttime, wo.stoptime, "
|
|
"wo.assigntech2, wo.starttime2, wo.stoptime2, "
|
|
"wo.assigntech3, wo.starttime3, wo.stoptime3, "
|
|
"wo.assigntech4, wo.starttime4, wo.stoptime4, "
|
|
"wo.notes, wo.closed, clients.company, clients.last, clients.first, probstat.id as statid, probstat.red, probstat.green, probstat.blue, probstat.notes as thestatus, projects.name AS projectname "
|
|
"FROM (probstat RIGHT JOIN (wo LEFT JOIN clients ON wo.client = clients.id) ON probstat.id = wo.status) LEFT JOIN projects ON wo.project = projects.id "
|
|
"WHERE (((wo.starttime) Between #%s# And #%s#) AND ((wo.quick)=False) AND ((wo.anytime)=False) AND ((wo.assigntech)=%u) OR ((wo.assigntech2)=%u) OR ((wo.assigntech3)=%u) OR ((wo.assigntech4)=%u)) "
|
|
"ORDER BY wo.assigntech;",m_dtWindowStart.Format(_T("%m/%d/%Y 0:0:0")),m_dtWindowStop.Format(_T("%m/%d/%Y 23:59:59")),lTechID,lTechID,lTechID,lTechID);
|
|
*/
|
|
|
|
CString strSTART=m_dtWindowStart.Format(_T("%m/%d/%Y 0:0:0"));
|
|
CString strSTOP=m_dtWindowStop.Format(_T("%m/%d/%Y 23:59:59"));
|
|
q.Format("SELECT wo.id, wo.anytime, "
|
|
"wo.assigntech, wo.starttime, wo.stoptime, "
|
|
"wo.assigntech2, wo.starttime2, wo.stoptime2, "
|
|
"wo.assigntech3, wo.starttime3, wo.stoptime3, "
|
|
"wo.assigntech4, wo.starttime4, wo.stoptime4, "
|
|
"wo.notes, wo.closed, clients.company, clients.bizphone, clients.last, clients.first, probstat.id as statid, probstat.red, probstat.green, probstat.blue, probstat.notes as thestatus, projects.name AS projectname "
|
|
"FROM (probstat RIGHT JOIN (wo LEFT JOIN clients ON wo.client = clients.id) ON probstat.id = wo.status) LEFT JOIN projects ON wo.project = projects.id "
|
|
"WHERE (((wo.quick)=False) AND ((wo.anytime)=False)) AND "
|
|
|
|
"( (((wo.assigntech)=%u) AND ((wo.starttime) Between #%s# And #%s#)) OR "
|
|
"(((wo.assigntech2)=%u) AND ((wo.starttime2) Between #%s# And #%s#)) OR "
|
|
"(((wo.assigntech3)=%u) AND ((wo.starttime3) Between #%s# And #%s#)) OR "
|
|
"(((wo.assigntech4)=%u) AND ((wo.starttime4) Between #%s# And #%s#)) );",
|
|
//"ORDER BY wo.assigntech;",
|
|
|
|
lTechID,strSTART,strSTOP,
|
|
lTechID,strSTART,strSTOP,
|
|
lTechID,strSTART,strSTOP,
|
|
lTechID,strSTART,strSTOP
|
|
|
|
);
|
|
|
|
#ifdef _DEBUG
|
|
//m_pApp->ShowStuff(q);
|
|
#endif
|
|
|
|
|
|
|
|
//***********************************************************************************
|
|
|
|
|
|
//************************************************************************************
|
|
pTimerSQL.Start(FALSE);
|
|
rs2->QueryReadOnly(q);
|
|
pTimerSQL.Stop();
|
|
if(!rs2->IsEmpty())
|
|
{
|
|
do{
|
|
|
|
|
|
|
|
pTimerSQL.Start(FALSE);
|
|
rs2->FetchField("projectname",&strProjectName);
|
|
rs2->FetchField("statid",&lStatID);
|
|
rs2->FetchField("red",&lRed);
|
|
rs2->FetchField("green",&lGreen);
|
|
rs2->FetchField("blue",&lBlue);
|
|
rs2->FetchField("thestatus",&strStatus);
|
|
rs2->FetchField("notes",&strWONOTES);
|
|
|
|
#ifdef _DEBUG
|
|
rs2->FetchField("anytime",&bMatchingTech);
|
|
ASSERT (bMatchingTech==false);
|
|
#endif
|
|
|
|
|
|
rs2->FetchField("id",&lWOID);
|
|
strWOID.Format("%u",lWOID);
|
|
rs2->FetchField("company",&strClient);
|
|
rs2->FetchField("bizphone",&strTemp);
|
|
strData.Format("%s %s",strClient,strTemp);
|
|
strClient=strData;
|
|
pTimerSQL.Stop();
|
|
|
|
//START OF 4 TIMES LOOP
|
|
//Pick out each incident for this tech and insert a time bar for each one
|
|
for(nTech=0;nTech<4;nTech++)
|
|
{
|
|
|
|
bMatchingTech=false;
|
|
nMatchingTechNumber=0;
|
|
|
|
/*if(lWOID==67)
|
|
lThisTech=-2;*/
|
|
|
|
switch (nTech)
|
|
{
|
|
case 0:
|
|
rs2->FetchField("assigntech",&lThisTech);
|
|
if(lThisTech==lTechID)
|
|
{
|
|
bMatchingTech=true;
|
|
nMatchingTechNumber=1;
|
|
rs2->FetchField("starttime",&dtSchedStart);
|
|
rs2->FetchField("stoptime",&dtSchedEnd);
|
|
}
|
|
break;
|
|
case 1:
|
|
rs2->FetchField("assigntech2",&lThisTech);
|
|
if(lThisTech==lTechID)
|
|
{
|
|
bMatchingTech=true;
|
|
nMatchingTechNumber=2;
|
|
rs2->FetchField("starttime2",&dtSchedStart);
|
|
rs2->FetchField("stoptime2",&dtSchedEnd);
|
|
}
|
|
break;
|
|
case 2:
|
|
rs2->FetchField("assigntech3",&lThisTech);
|
|
if(lThisTech==lTechID)
|
|
{
|
|
bMatchingTech=true;
|
|
nMatchingTechNumber=3;
|
|
rs2->FetchField("starttime3",&dtSchedStart);
|
|
rs2->FetchField("stoptime3",&dtSchedEnd);
|
|
}
|
|
break;
|
|
case 3:
|
|
rs2->FetchField("assigntech4",&lThisTech);
|
|
if(lThisTech==lTechID)
|
|
{
|
|
bMatchingTech=true;
|
|
nMatchingTechNumber=4;
|
|
rs2->FetchField("starttime4",&dtSchedStart);
|
|
rs2->FetchField("stoptime4",&dtSchedEnd);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(bMatchingTech)
|
|
{
|
|
//calculate weird days and minutes
|
|
//timebars are set based on days since
|
|
//jan 1 1900 and time is based on
|
|
//minutes since midnight.
|
|
//lDaysStart,lDaysEnd,lMinStart,lMinEnd;
|
|
|
|
//start date days since 1900
|
|
dtSpan=dtSchedStart-m_dt1900;
|
|
lDaysStart=(long)dtSpan.GetTotalDays();
|
|
|
|
//end date days since 1900
|
|
dtSpan=dtSchedEnd-m_dt1900;
|
|
lDaysEnd=(long)dtSpan.GetTotalDays();
|
|
|
|
//Start time minutes since midnight
|
|
//set dttemp to 1 second after midnight
|
|
dtTemp.SetDateTime(
|
|
dtSchedStart.GetYear(),
|
|
dtSchedStart.GetMonth(),
|
|
dtSchedStart.GetDay(),0,0,0);
|
|
dtSpan=dtSchedStart-dtTemp;
|
|
lMinStart = (long) dtSpan.GetTotalMinutes();
|
|
|
|
//q.Format("Start time:%s Midnight:%s, minutes:%u",dtSchedStart.Format(),dtTemp.Format(),lMinStart);
|
|
//AfxMessageBox(q);
|
|
//End time hours since midnight
|
|
//set dttemp to 1 second after midnight
|
|
dtTemp.SetDateTime(
|
|
dtSchedEnd.GetYear(),
|
|
dtSchedEnd.GetMonth(),
|
|
dtSchedEnd.GetDay(),0,0,0);
|
|
dtSpan=dtSchedEnd-dtTemp;
|
|
lMinEnd = (long) dtSpan.GetTotalMinutes();
|
|
|
|
|
|
//q.Format("End time: time:%s midnight:%s, Minutes:%u",dtSchedEnd.Format(),dtTemp.Format(),lMinEnd);
|
|
//AfxMessageBox(q);
|
|
|
|
//Insert the time bar
|
|
|
|
if(!strStatus.IsEmpty())
|
|
strStatus=" Status: " + strStatus;
|
|
|
|
if(!strProjectName.IsEmpty())
|
|
strProjectName=", PROJECT: " + strProjectName;
|
|
|
|
if(m_bShowProblemDetailsInStatusDisplay)
|
|
{
|
|
strTemp.Format("SELECT probs.brief FROM probs WHERE (((probs.wolink)=%u) "
|
|
"AND ((probs.brief) Is Not Null));",lWOID);
|
|
if(rs3->QueryReadOnly(strTemp))
|
|
{
|
|
if(!rs3->IsEmpty())
|
|
{
|
|
strWONOTES+="\r\n";
|
|
nCounter=0;
|
|
do{
|
|
if(rs3->FetchField("brief",&strTemp))
|
|
{
|
|
nCounter++;
|
|
strData.Format("%u) %s, ",nCounter,strTemp);
|
|
strWONOTES+=strData;
|
|
}
|
|
|
|
}while(rs3->MoveForward());
|
|
strWONOTES.TrimRight(' ');
|
|
strWONOTES.TrimRight(',');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//strData.Format("%s - workorder #:%u, Tech#:%i, %s%s\r\n%s",strClient,lWOID, nMatchingTechNumber, strStatus,strProjectName, strWONOTES);
|
|
strData.Format("%s - WO %u, Tech %i, %s%s, Notes: %s",strClient,lWOID, nMatchingTechNumber, strStatus,strProjectName, strWONOTES);
|
|
//strStatus.Format("%u",lWOID);//original value without tech number
|
|
strStatus.Format("%u,%i",lWOID,nMatchingTechNumber);
|
|
nBar=m_sc.AddKeyTimeBar(count,lMinStart,lMinEnd,lDaysStart,lDaysEnd,strStatus);
|
|
m_sc.SetBarBackColor(count,nBar,RGB(lRed,lGreen,lBlue));
|
|
|
|
|
|
//flag overlapping bars
|
|
if(m_sc.FindFirstBar(count,nBar,count)>0)
|
|
m_sc.SetBarStyle(count,nBar,m_nBarStyleOverlapping);
|
|
|
|
|
|
/*************************///allocate and store a new timebar data object
|
|
m_ptbData=new CScheduleTimeBarData;
|
|
m_ptbData->m_lStatus=lStatID;
|
|
m_ptbData->m_lWOID=lWOID;
|
|
m_ptbData->m_lDateEnd=lDaysEnd;
|
|
m_ptbData->m_lDateStart=lDaysStart;
|
|
m_ptbData->m_lTimeEnd=lMinEnd;
|
|
m_ptbData->m_lTimeStart=lMinStart;
|
|
m_ptbData->m_lTechID=lTechID;
|
|
|
|
//added o7/27/01 to accomodate multitech situation
|
|
m_ptbData->m_nTechNumber=nMatchingTechNumber;
|
|
|
|
m_ptbData->m_strDisplayData=strData;//from above
|
|
m_ptbData->m_nID=arBar.Add(m_ptbData);
|
|
m_nTotalAllocated++;
|
|
|
|
|
|
}//end of ifbmatchingtech
|
|
|
|
//pTimerSQL.Start(TRUE);
|
|
|
|
//pTimerSQL.Stop();
|
|
}//END OF 4 TECHS FOR NEXT LOOP HERE
|
|
}while(rs2->MoveForward());
|
|
}
|
|
|
|
}while(bContinue);
|
|
|
|
//release the recordsets no longer needed
|
|
pTimerSQL.Start(FALSE);
|
|
m_pApp->rsPool->ReleaseRS(&rs->m_nID);
|
|
m_pApp->rsPool->ReleaseRS(&rs2->m_nID);
|
|
m_pApp->rsPool->ReleaseRS(&rs3->m_nID);
|
|
pTimerSQL.Stop();
|
|
|
|
//*********************************************
|
|
//end of if(m_bRefresh...check
|
|
|
|
}//if brefresh
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
//GET TIMING STATS
|
|
//stop timer
|
|
pTimerSQL.Stop();
|
|
pTimer.Stop();//overall timer
|
|
//get this time in ms
|
|
m_dLast=pTimerSQL.Elapsed();
|
|
m_dOverallTime=pTimer.Elapsed();
|
|
|
|
|
|
//add to average time
|
|
m_dAverage+=m_dLast;
|
|
|
|
//set lowest time
|
|
if(m_dLast>m_dSlowest || m_dSlowest==0)
|
|
m_dSlowest=m_dLast;
|
|
|
|
//set fastest time
|
|
if(m_dLast<m_dFastest || m_dFastest==0)
|
|
m_dFastest=m_dLast;
|
|
strTemp.Format("Refresh query time stats (seconds)\r\n"
|
|
"[Overall time:%.3f, Non_db time:%.3f] "
|
|
"[DB times: Last:%.3f, Slowest: %.3f, Fastest:%.3f, Average:%.3f]",
|
|
m_dOverallTime,m_dOverallTime-m_dLast,
|
|
m_dLast,m_dSlowest, m_dFastest,
|
|
m_dAverage/(double)m_uiRefreshCount);
|
|
//m_lblDetails.SetWindowText(strTemp); //<------------un-remark to show stats
|
|
//---------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//scroll the view into place:
|
|
//TimeScrollBar date days since 1900
|
|
dtSpan=dtStart-m_dt1900;
|
|
lDaysStart=(long)dtSpan.GetTotalDays();
|
|
|
|
//Start time minutes since midnight
|
|
//set dttemp to 1 second after midnight
|
|
dtTemp.SetDateTime(
|
|
dtSchedStart.GetYear(),
|
|
dtSchedStart.GetMonth(),
|
|
dtSchedStart.GetDay(),0,0,1);
|
|
dtSpan=dtStart-dtTemp;
|
|
lMinStart = (long) dtSpan.GetTotalMinutes();
|
|
|
|
|
|
GetUserHoursPreferences();
|
|
if(m_sc.GetTimeType()==0)
|
|
{
|
|
m_sc.SetTimeStart(m_lUserStartHour*60);
|
|
m_sc.SetTimeEnd(m_lUserStopHour*60);
|
|
|
|
if(m_pApp->m_bDefSchedOneDay)
|
|
{
|
|
m_sc.SetDateStart(lDaysStart);
|
|
m_sc.SetDateEnd(lDaysStart);
|
|
}
|
|
}
|
|
//scroll over...
|
|
m_sc.TimeScroll(lDaysStart,m_lUserStartHour*60);
|
|
|
|
m_sc.ReDraw(FALSE);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CScheduleFrm::OnDatetimechangeDtdate(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
FillView();
|
|
*pResult = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CScheduleFrm::OnBtnprint()
|
|
{
|
|
|
|
|
|
long lStart,lEnd;
|
|
COleDateTime dtToday;
|
|
COleDateTimeSpan dtSpan;
|
|
|
|
//Get the date from the control
|
|
m_dtDate.GetTime(dtToday);
|
|
|
|
dtSpan=dtToday-m_dt1900;
|
|
lStart=(long)dtSpan.GetTotalDays();
|
|
|
|
//end date days since 1900
|
|
dtSpan=dtToday-m_dt1900;
|
|
lEnd=(long)dtSpan.GetTotalDays();
|
|
|
|
m_sc.SetDateStart(lStart);
|
|
m_sc.SetDateEnd(lEnd);
|
|
|
|
m_sc.PrintSchedule();
|
|
|
|
FillView();
|
|
|
|
}
|
|
|
|
BEGIN_EVENTSINK_MAP(CScheduleFrm, CFormView)
|
|
//{{AFX_EVENTSINK_MAP(CScheduleFrm)
|
|
ON_EVENT(CScheduleFrm, IDC_CTSCHED, 16 /* ItemMove */, OnItemMoveCtsched, VTS_I2 VTS_I2)
|
|
ON_EVENT(CScheduleFrm, IDC_CTSCHED, 4 /* BarDblClick */, OnBarDblClickCtsched, VTS_I2 VTS_I2)
|
|
ON_EVENT(CScheduleFrm, IDC_CTSCHED, 14 /* BarSizing */, OnBarSizingCtsched, VTS_I2 VTS_I2 VTS_I2 VTS_I4 VTS_I4 VTS_I4 VTS_I4)
|
|
ON_EVENT(CScheduleFrm, IDC_CTSCHED, 13 /* BarChanged */, OnBarChangedCtsched, VTS_I2 VTS_I2 VTS_BSTR VTS_I4 VTS_I4 VTS_I4 VTS_I4)
|
|
ON_EVENT(CScheduleFrm, IDC_CTSCHED, 8 /* BarAdded */, OnBarAddedCtsched, VTS_I2 VTS_I2 VTS_BOOL VTS_BOOL)
|
|
ON_EVENT(CScheduleFrm, IDC_CTSCHED, 2 /* BarRightClick */, OnBarRightClickCtsched, VTS_I2 VTS_I2)
|
|
//}}AFX_EVENTSINK_MAP
|
|
END_EVENTSINK_MAP()
|
|
|
|
|
|
|
|
//MOUSE OVER
|
|
void CScheduleFrm::OnItemMoveCtsched(short nIndex, short nBar)
|
|
{
|
|
//do nothing if in the middle of an update
|
|
if(m_bUpdating) return;
|
|
|
|
//in the process of an adjustment?
|
|
if(!m_bLocked)
|
|
return;
|
|
|
|
//not a time bar?
|
|
if(nBar==0) return;
|
|
//same time bar as last time?
|
|
//if((nBar==m_nOldBar) && (nIndex==m_nOldIndex)) return;
|
|
|
|
/*
|
|
if(m_nOldBar!=0)
|
|
m_sc.SetBarText(m_nOldIndex,m_nOldBar,"");
|
|
*/
|
|
|
|
//m_nOldIndex=nIndex;
|
|
// m_nOldBar=nBar;
|
|
//m_sc.SetBarText(nIndex,nBar,"*");
|
|
|
|
|
|
|
|
|
|
//sets the public m_ptbData pointer to the correct record
|
|
GetTimeBarObject(nIndex,nBar);
|
|
|
|
//Bring to front to help with overlapping issue
|
|
m_sc.BringToFront(nIndex,nBar);
|
|
|
|
if(m_ptbData!=NULL)
|
|
m_lblDetails.SetWindowText(m_ptbData->m_strDisplayData);
|
|
}
|
|
|
|
|
|
//open the workorder just double clicked
|
|
void CScheduleFrm::OnBarDblClickCtsched(short nIndex, short nBar)
|
|
{
|
|
CString strWOID;
|
|
//strWOID=GetWoIDFromTimeBar(nIndex,nBar);
|
|
|
|
//sets the public m_ptbData pointer to the correct record
|
|
GetTimeBarObject(nIndex,nBar);
|
|
if(m_ptbData==NULL)
|
|
return;
|
|
|
|
strWOID.Format("%u",m_ptbData->m_lWOID);
|
|
|
|
/*
|
|
strWOID=m_sc.GetBarKeyID(nIndex,nBar);
|
|
if(strWOID=="off") return;
|
|
*/
|
|
CWOHeaderDlg wo;
|
|
wo.SetWorkorderID(strWOID);
|
|
m_bUpdating=true;
|
|
wo.DoModal();
|
|
|
|
FillView();
|
|
m_bRefresh=true;
|
|
FillView();
|
|
m_bUpdating=false;
|
|
|
|
}
|
|
|
|
|
|
//show detailed times in top area to make
|
|
//adjustments easier while moving or sizing a time bar
|
|
void CScheduleFrm::OnBarSizingCtsched(short nIndex, short nBar, short nType, long lTimeStart, long lTimeEnd, long lDateStart, long lDateEnd)
|
|
{
|
|
|
|
//do nothing if in the middle of an update
|
|
if(m_bUpdating) return;
|
|
|
|
COleDateTime dtStart, dtEnd;
|
|
COleDateTimeSpan dtSpan;
|
|
CString q;
|
|
|
|
//convert start time
|
|
dtSpan.SetDateTimeSpan(lDateStart,0,lTimeStart,0);
|
|
dtStart=m_dt1900+dtSpan;
|
|
|
|
//convert end time
|
|
dtSpan.SetDateTimeSpan(lDateEnd,0,lTimeEnd,0);
|
|
dtEnd=m_dt1900+dtSpan;
|
|
|
|
|
|
q.Format("%s -> %s",dtStart.Format(VAR_TIMEVALUEONLY),
|
|
dtEnd.Format(VAR_TIMEVALUEONLY),
|
|
m_sc.GetBarKeyID(nIndex,nBar)); //VAR_TIMEVALUEONLY
|
|
|
|
m_lblDetails.SetWindowText(q);
|
|
|
|
}
|
|
|
|
|
|
//Take a Schedule long date and long time value
|
|
//set passed OleDateTime variable accordingly
|
|
|
|
void CScheduleFrm::SchedToOleDT(long lSchedDateValue, long lSchedTimeValue, COleDateTime *dt)
|
|
{
|
|
COleDateTimeSpan dtSpan;
|
|
dtSpan.SetDateTimeSpan(lSchedDateValue,0,lSchedTimeValue,0);
|
|
*dt=m_dt1900+dtSpan;
|
|
|
|
}
|
|
|
|
|
|
|
|
//update the time and date and technician for this workorder
|
|
//THIS FUNCTION NOW OBSOLETE (RIGHT CLICK REPLACES IT)
|
|
//AND KEPT ONLY UNTIL CONFIRMED NOT REQUIRED
|
|
//FOR SOME OTHER REASON IN FUTURE
|
|
void CScheduleFrm::OnBarChangedCtsched(short nIndex, short nBar, LPCTSTR cKeyID, long lTimeStart, long lTimeEnd, long lDateStart, long lDateEnd)
|
|
{
|
|
//BUGBUG; //this routine is not working with new multi-tech changes
|
|
if(m_bUndoing)
|
|
return;
|
|
Undo(nIndex,nBar);
|
|
return;
|
|
/*
|
|
//do nothing if in the middle of an update
|
|
if(m_bUpdating) return;
|
|
|
|
if(m_bUndoing)
|
|
return;
|
|
//added 08/20/2001 - mouse over to confirm change was changing time bar selected
|
|
m_bUpdating=true;
|
|
|
|
if(m_ckLock.GetCheck()==TRUE)
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
CString strTemp;
|
|
CString strTechNumber;
|
|
|
|
GetTimeBarObject(nIndex,nBar);
|
|
if(m_ptbData==NULL)
|
|
{
|
|
m_bUpdating=false;
|
|
return;
|
|
}
|
|
|
|
#ifdef MARTIN
|
|
//MARTIN TEST TEST TEST
|
|
strTemp.Format("Workorder %u has been changed - allow this?",m_ptbData->m_lWOID);
|
|
|
|
if(AfxMessageBox(strTemp,MB_YESNO)==IDNO)
|
|
{
|
|
m_bUpdating=false;
|
|
Undo(nIndex,nBar);
|
|
return;
|
|
}
|
|
|
|
#endif
|
|
|
|
m_ptbData->m_lDateStart=lDateStart;
|
|
m_ptbData->m_lDateEnd=lDateEnd;
|
|
m_ptbData->m_lTimeStart=lTimeStart;
|
|
m_ptbData->m_lTimeEnd=lTimeEnd;
|
|
|
|
CString q,strWOID;
|
|
COleDateTime dtStart,dtEnd;
|
|
COleDateTimeSpan dtSpan;
|
|
|
|
//CWaitCursor wait;
|
|
|
|
|
|
//convert start time
|
|
dtSpan.SetDateTimeSpan(lDateStart,0,lTimeStart,0);
|
|
dtStart=m_dt1900+dtSpan;
|
|
|
|
//convert end time
|
|
dtSpan.SetDateTimeSpan(lDateEnd,0,lTimeEnd,0);
|
|
dtEnd=m_dt1900+dtSpan;
|
|
|
|
//get workorder number
|
|
// strWOID=GetWoIDFromTimeBar(nIndex,nBar);
|
|
strWOID=m_sc.GetBarKeyID(nIndex,nBar);
|
|
//********************
|
|
//handle multiple techs added 08/20/2001
|
|
|
|
switch (m_ptbData->m_nTechNumber)
|
|
{
|
|
case 1:
|
|
strTechNumber="starttime";
|
|
break;
|
|
case 2:
|
|
strTechNumber="starttime2";
|
|
break;
|
|
case 3:
|
|
strTechNumber="starttime3";
|
|
break;
|
|
case 4:
|
|
strTechNumber="starttime4";
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
|
|
//********************
|
|
q.Format("UPDATE wo SET wo.%s = #%s#, wo.stoptime = #%s# "
|
|
"WHERE (((wo.id)=%u));",strTechNumber,dtStart.Format(_T("%m/%d/%Y %H:%M:%S")),
|
|
dtEnd.Format(_T("%m/%d/%Y %H:%M:%S")),m_ptbData->m_lWOID);
|
|
|
|
|
|
|
|
rs=m_pApp->rsPool->GetRS("OnBarChangedCtsched recordset");
|
|
|
|
rs->Ex(q);
|
|
|
|
//ADDED 07/24/2001 AS IT WAS NOTICED THAT A DRAG CHANGE DOESN'T CATCH
|
|
//THE FIRST TIME.
|
|
rs->Close();
|
|
rs->QueryReadOnly("SELECT defaults.* FROM defaults;");
|
|
rs->Close();
|
|
|
|
|
|
m_pApp->rsPool->ReleaseRS(&rs->m_nID);
|
|
|
|
m_bUpdating=false;
|
|
//relock
|
|
m_ckLock.SetCheck(TRUE);
|
|
m_bLocked=true;
|
|
|
|
m_bRefresh=true;
|
|
FillView();
|
|
|
|
*/
|
|
}
|
|
|
|
|
|
//new workorder
|
|
void CScheduleFrm::OnBarAddedCtsched(short nIndex, short nBar, BOOL bMouseBar, BOOL bKeyedBar)
|
|
{
|
|
//only proceed if added with the mouse
|
|
if(!bMouseBar) return;
|
|
//needed because fillview somehow
|
|
//causes endless loop as it thinks all
|
|
//bars added after first are moused for some obscure bug riddled reason
|
|
if(bKeyedBar) return;
|
|
|
|
long lSchedRndMinutes;//used for rounding to nearest quarter hour
|
|
long lSchedRndHours;//used for rounding
|
|
|
|
|
|
int x=m_pApp->Allowed(RWORKORDER,true);
|
|
if(x!=1)//no write allowed
|
|
{
|
|
m_pApp->SecurityWarning();
|
|
return;
|
|
}
|
|
|
|
//pause the timer and other things
|
|
m_bUpdating=true;
|
|
|
|
COleDateTimeSpan dtSpan;
|
|
CWOHeaderDlg wo;
|
|
|
|
//Set the start date and time
|
|
|
|
//round out to nearest quarter hour?
|
|
if(m_pApp->m_bDefSchedRnd==true)
|
|
{
|
|
//get user selection
|
|
//because it's only minutes set here first so that we can
|
|
//split out hours and minutes for rounding
|
|
dtSpan.SetDateTimeSpan(m_sc.GetBarDateStart(nIndex,nBar),
|
|
0,m_sc.GetBarTimeStart(nIndex,nBar),0);
|
|
|
|
//Get the hours and minutes
|
|
lSchedRndMinutes=dtSpan.GetMinutes();
|
|
lSchedRndHours=dtSpan.GetHours();
|
|
RoundTime(&lSchedRndMinutes,&lSchedRndHours);
|
|
|
|
//Set the time and date again
|
|
dtSpan.SetDateTimeSpan(m_sc.GetBarDateStart(nIndex,nBar),
|
|
(int)lSchedRndHours,lSchedRndMinutes,0);
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
dtSpan.SetDateTimeSpan(m_sc.GetBarDateStart(nIndex,nBar),
|
|
0,m_sc.GetBarTimeStart(nIndex,nBar),0);
|
|
}
|
|
wo.m_oledtPresetStartDate=m_dt1900+dtSpan;
|
|
|
|
|
|
|
|
//Set the end date and time
|
|
//round out to nearest quarter hour?
|
|
if(m_pApp->m_bDefSchedRnd==true)
|
|
{
|
|
//get user selection
|
|
//because it's only minutes set here first so that we can
|
|
//split out hours and minutes for rounding
|
|
dtSpan.SetDateTimeSpan(m_sc.GetBarDateEnd(nIndex,nBar),
|
|
0,m_sc.GetBarTimeEnd(nIndex,nBar),0);
|
|
|
|
//Get the hours and minutes
|
|
lSchedRndMinutes=dtSpan.GetMinutes();
|
|
lSchedRndHours=dtSpan.GetHours();
|
|
RoundTime(&lSchedRndMinutes,&lSchedRndHours);
|
|
|
|
//Set the time and date again
|
|
dtSpan.SetDateTimeSpan(m_sc.GetBarDateEnd(nIndex,nBar),
|
|
(int)lSchedRndHours,lSchedRndMinutes,0);
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
dtSpan.SetDateTimeSpan(m_sc.GetBarDateEnd(nIndex,nBar),
|
|
0,m_sc.GetBarTimeEnd(nIndex,nBar),0);
|
|
}
|
|
wo.m_oledtPresetEndDate=m_dt1900+dtSpan;
|
|
|
|
|
|
|
|
//Set the tech
|
|
wo.m_strSelTech=m_sc.GetListCargo(nIndex);
|
|
|
|
|
|
//Do the workorder
|
|
wo.DoModal();
|
|
m_bRefresh=true;
|
|
FillView();
|
|
|
|
//release the timer and other functions
|
|
m_bUpdating=false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void CScheduleFrm::OnBarRightClickCtsched(short nIndex, short nBar)
|
|
{
|
|
//get a lock on things
|
|
m_bUpdating=true;
|
|
COleDateTime dtStart,dtEnd,dtOriginalStart,dtOriginalEnd;
|
|
long lRed,lGreen,lBlue,lStatus,lWOID;
|
|
CString strOriginalTech;
|
|
CString strTech,strTechNumber,strDateNumber;
|
|
bool bTechChange=false;
|
|
bool bStatusChange=false;
|
|
bool bDateChange=false;
|
|
//strTech=m_sc.GetListCargo(nIndex);
|
|
CString strStatus,q;
|
|
//sets the public m_ptbData pointer to the correct record
|
|
GetTimeBarObject(nIndex,nBar);
|
|
//ASSERT(m_ptbData!=NULL);
|
|
if(m_ptbData==NULL) return;
|
|
strTechNumber.Format("%i",m_ptbData->m_nTechNumber);
|
|
lWOID=m_ptbData->m_lWOID;
|
|
strStatus.Format("%u",m_ptbData->m_lStatus);
|
|
strOriginalTech.Format("%u",m_ptbData->m_lTechID);
|
|
strTech=strOriginalTech;
|
|
|
|
|
|
|
|
CDlgDispStatPopup d;
|
|
|
|
//set start and end date values
|
|
SchedToOleDT(m_ptbData->m_lDateStart,m_ptbData->m_lTimeStart,&dtStart);
|
|
dtOriginalStart=dtStart;
|
|
d.m_pdtStart=&dtStart;
|
|
|
|
SchedToOleDT(m_ptbData->m_lDateEnd,m_ptbData->m_lTimeEnd,&dtEnd);
|
|
dtOriginalEnd=dtEnd;
|
|
d.m_pdtEnd=&dtEnd;
|
|
|
|
|
|
|
|
|
|
d.m_pstrSelectedStatus=&strStatus;
|
|
d.m_plRed=&lRed;
|
|
d.m_plGreen=&lGreen;
|
|
d.m_plBlue=&lBlue;
|
|
d.m_pstrSelectedTech=&strTech;
|
|
d.m_pstrSelectedTechNumber=&strTechNumber;
|
|
|
|
//added for MASS 12/12/2001
|
|
d.m_strWOInfo=m_ptbData->m_strDisplayData;
|
|
|
|
if(d.DoModal()==IDCANCEL)//user cancelled?
|
|
{
|
|
m_bUpdating=false;
|
|
return;
|
|
}
|
|
|
|
lStatus=atol(strStatus);
|
|
if(strTech!=strOriginalTech)
|
|
bTechChange=true;
|
|
|
|
if(lStatus!=m_ptbData->m_lStatus)
|
|
bStatusChange=true;
|
|
|
|
//check for differing date
|
|
if(dtEnd!=dtOriginalEnd || dtStart!=dtOriginalStart)
|
|
bDateChange=true;
|
|
|
|
|
|
|
|
if(bStatusChange || bTechChange || bDateChange)
|
|
{
|
|
|
|
rs=m_pApp->rsPool->GetRS("CScheduleFrm::OnBarRightClickCtsched");
|
|
|
|
|
|
|
|
//Only do a status change if there is one.
|
|
if(bStatusChange)
|
|
{
|
|
q.Format("Workorder %u\r\n\"%s\"\r\n\r\nStatus has changed.\r\nWorkorder will now be updated - allow this?",m_ptbData->m_lWOID,m_ptbData->m_strDisplayData);
|
|
|
|
if(AfxMessageBox(q,MB_YESNO)==IDYES)
|
|
{
|
|
|
|
|
|
q.Format("UPDATE wo SET wo.status = %u WHERE (((wo.id)=%u));"
|
|
, lStatus, m_ptbData->m_lWOID);
|
|
|
|
rs->Ex(q);
|
|
rs->Close();
|
|
m_sc.SetBarBackColor(nIndex,nBar,RGB(lRed,lGreen,lBlue));
|
|
m_ptbData->m_lStatus=lStatus;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//only do a tech change if there is one
|
|
if(bTechChange || bDateChange)
|
|
{
|
|
if(bTechChange && bDateChange)
|
|
{
|
|
q.Format("Workorder %u\r\n\"%s\"\r\n\r\nDate and technician have changed.\r\nWorkorder will now be updated - allow this?",m_ptbData->m_lWOID,m_ptbData->m_strDisplayData);
|
|
}
|
|
else
|
|
{
|
|
if(bDateChange)
|
|
q.Format("Workorder %u\r\n\"%s\"\r\n\r\nDate has changed.\r\nWorkorder will now be updated - allow this?",m_ptbData->m_lWOID,m_ptbData->m_strDisplayData);
|
|
else
|
|
q.Format("Workorder %u\r\n\"%s\"\r\n\r\nAssigned technician has changed.\r\nWorkorder will now be updated - allow this?",m_ptbData->m_lWOID,m_ptbData->m_strDisplayData);
|
|
}
|
|
|
|
if(AfxMessageBox(q,MB_YESNO)==IDYES)
|
|
{
|
|
switch (m_ptbData->m_nTechNumber)
|
|
{
|
|
case 1:
|
|
strTechNumber="";
|
|
break;
|
|
case 2:
|
|
strTechNumber="2";
|
|
break;
|
|
case 3:
|
|
strTechNumber="3";
|
|
break;
|
|
case 4:
|
|
strTechNumber="4";
|
|
break;
|
|
}
|
|
|
|
|
|
//updates date and time as well as tech at the same time either way
|
|
|
|
q.Format("UPDATE wo SET wo.assigntech%s = %s, wo.starttime%s = #%s#, wo.stoptime%s = #%s# "
|
|
"WHERE (((wo.id)=%u));"
|
|
, strTechNumber,strTech,
|
|
strTechNumber,dtStart.Format(_T("%m/%d/%Y %H:%M:%S")),
|
|
strTechNumber,dtEnd.Format(_T("%m/%d/%Y %H:%M:%S")),
|
|
m_ptbData->m_lWOID);
|
|
rs->Ex(q);
|
|
///////////////////////////////////rs->Close();
|
|
m_ptbData->m_lTechID=atol(strTech);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//axe the recordset
|
|
m_pApp->rsPool->ReleaseRS(&rs->m_nID);
|
|
|
|
|
|
|
|
}
|
|
|
|
//release lock on things
|
|
m_bUpdating=false;
|
|
|
|
if(bTechChange || bStatusChange || bDateChange)
|
|
{
|
|
m_bRefresh=true;
|
|
FillView();
|
|
/*
|
|
//Added July 13th 2001 as refresh isn't catching the change
|
|
m_bRefresh=true;
|
|
FillView();
|
|
*/
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//go back a day
|
|
void CScheduleFrm::OnBtnback()
|
|
{
|
|
Scroll(false);
|
|
}
|
|
|
|
//go ahead a day
|
|
void CScheduleFrm::OnBtnforward()
|
|
{
|
|
Scroll(true);
|
|
}
|
|
|
|
void CScheduleFrm::Scroll(bool bForward)
|
|
{
|
|
COleDateTime dtStart;
|
|
COleDateTimeSpan dtSpan;
|
|
|
|
|
|
if(m_nDayWeekMonth==0)//1 day
|
|
dtSpan.SetDateTimeSpan(1,0,0,0);
|
|
else if(m_nDayWeekMonth==1)//one week
|
|
dtSpan.SetDateTimeSpan(8,0,0,0);
|
|
else if(m_nDayWeekMonth==2)//month
|
|
dtSpan.SetDateTimeSpan(31,0,0,0);
|
|
|
|
m_dtDate.GetTime(dtStart);
|
|
if(bForward)
|
|
dtStart=dtStart+dtSpan;
|
|
else
|
|
dtStart=dtStart-dtSpan;
|
|
|
|
m_dtDate.SetTime(dtStart);
|
|
FillView();
|
|
}
|
|
|
|
void CScheduleFrm::ZoomClick(int nItem)
|
|
{
|
|
m_nDayWeekMonth=nItem;
|
|
m_rdDay.SetCheck(FALSE);
|
|
m_rdWeek.SetCheck(FALSE);
|
|
m_rdMonth.SetCheck(FALSE);
|
|
|
|
switch (m_nDayWeekMonth)
|
|
{
|
|
|
|
case 0:
|
|
m_rdDay.SetCheck(TRUE);
|
|
break;
|
|
case 1:
|
|
m_rdWeek.SetCheck(TRUE);
|
|
break;
|
|
default:
|
|
m_rdMonth.SetCheck(TRUE);
|
|
break;
|
|
}
|
|
|
|
m_bRefresh=true;
|
|
FillView();
|
|
|
|
}
|
|
|
|
void CScheduleFrm::OnRdday()
|
|
{
|
|
ZoomClick(0);
|
|
|
|
}
|
|
|
|
void CScheduleFrm::OnRdmonth()
|
|
{
|
|
ZoomClick(2);
|
|
|
|
}
|
|
|
|
void CScheduleFrm::OnRdweek()
|
|
{
|
|
ZoomClick(1);
|
|
|
|
}
|
|
|
|
//get the users set preferences for start and stop times
|
|
//those values are used at the bottom of FillView to
|
|
//set the schedule hours window displayed
|
|
void CScheduleFrm::GetUserHoursPreferences()
|
|
{
|
|
|
|
CString q;
|
|
q.Format("SELECT users.defschedstarthour, users.defschedstophour "
|
|
"FROM users WHERE (((users.id)=%u));",m_pApp->m_lusrID);
|
|
rs->QueryReadOnly(q);
|
|
|
|
rs->FetchField("defschedstarthour",&m_lUserStartHour);
|
|
rs->FetchField("defschedstophour",&m_lUserStopHour);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
//set public pointer to time bar object in question
|
|
//sets to NULL if not found which currently only
|
|
//asserts, no other checking done.
|
|
void CScheduleFrm::GetTimeBarObject(short nIndex, short nBar)
|
|
{
|
|
|
|
int x;
|
|
int nComma=0,nLeft,nRight;
|
|
bool bNoMatch=true;
|
|
long lWOID;
|
|
int nTechNumber;
|
|
CString strWOID=m_sc.GetBarKeyID(nIndex,nBar);
|
|
ASSERT(!strWOID.IsEmpty());
|
|
if(strWOID=="off") //added 07/24/01 to accomodate time off bars
|
|
{
|
|
m_ptbData=NULL;//indicates not a regular time bar
|
|
return;
|
|
}
|
|
|
|
nComma=strWOID.Find(',');
|
|
if(nComma!=-1)
|
|
{
|
|
nLeft=nComma;
|
|
nRight=strWOID.GetLength()-nComma-1;
|
|
lWOID=atol(strWOID.Left(nLeft));
|
|
nTechNumber=atoi(strWOID.Right(nRight));
|
|
|
|
ASSERT(lWOID!=0);
|
|
|
|
//default signalling not a regular time bar
|
|
m_ptbData=NULL;
|
|
|
|
for(x=0;x<m_nTotalAllocated;x++)
|
|
{
|
|
m_ptbData=(CScheduleTimeBarData*)arBar.GetAt(x);
|
|
if(m_ptbData->m_lWOID==lWOID && m_ptbData->m_nTechNumber==nTechNumber)
|
|
{
|
|
bNoMatch=false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(bNoMatch)
|
|
m_ptbData=NULL;//added 07/24/01 to handle non-wo time bars for now
|
|
|
|
}
|
|
|
|
|
|
//Force a refresh
|
|
void CScheduleFrm::OnBtnrefresh()
|
|
{
|
|
|
|
//m_bRefresh=true;
|
|
//FillView();
|
|
|
|
KillTimer(1);
|
|
m_bRefresh=true;
|
|
FillView();
|
|
|
|
|
|
//AUTOREFRESH TIMER
|
|
if(m_pApp->m_lSchedRefreshSecs!=0)
|
|
m_nTimer = SetTimer(1, 1000*m_pApp->m_lSchedRefreshSecs, 0);
|
|
//m_nTimer = SetTimer(1, 6000, 0);
|
|
|
|
m_bTimerIsActive=true;
|
|
|
|
}
|
|
|
|
void CScheduleFrm::OnCKLOCk()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
m_bLocked=m_ckLock.GetCheck() ? true:false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CScheduleFrm::Undo(short nIndex, short nBar)
|
|
{
|
|
m_bUndoing=true;
|
|
GetTimeBarObject(nIndex,nBar);
|
|
//ADDED O7/24/2001 TO HANDLE SPECIAL TIME BARS
|
|
if(m_ptbData==NULL)
|
|
{
|
|
m_bUndoing=false;
|
|
m_bRefresh=true;
|
|
FillView();
|
|
return;
|
|
}
|
|
m_sc.SetBarDateStart(nIndex,nBar,m_ptbData->m_lDateStart);
|
|
m_sc.SetBarDateEnd(nIndex,nBar,m_ptbData->m_lDateEnd);
|
|
m_sc.SetBarTimeStart(nIndex,nBar,m_ptbData->m_lTimeStart);
|
|
m_sc.SetBarTimeEnd(nIndex,nBar,m_ptbData->m_lTimeEnd);
|
|
|
|
m_bUndoing=false;
|
|
}
|
|
|
|
|
|
//Modify layout to accomodate different windows sizes
|
|
void CScheduleFrm::LayoutControls()
|
|
{
|
|
if(m_bLayoutDone) return;
|
|
|
|
|
|
|
|
|
|
CRect rectMain, rectCtl;
|
|
GetWindowRect(rectMain);
|
|
//this is the start of the window in question
|
|
int nOffset=rectMain.top;
|
|
int nLastBottom,nTopOfBottomRow;
|
|
int nHeight;
|
|
|
|
m_lblDetails.GetWindowRect(rectCtl);
|
|
rectCtl.right=rectMain.right-50;
|
|
rectCtl.top-=nOffset;
|
|
rectCtl.bottom-=nOffset;
|
|
m_lblDetails.MoveWindow(rectCtl,TRUE);
|
|
|
|
|
|
m_sc.GetWindowRect(rectCtl);
|
|
rectCtl.right=rectMain.right-50;
|
|
rectCtl.top-=nOffset;
|
|
rectCtl.bottom=rectMain.bottom-85-nOffset;
|
|
m_sc.MoveWindow(rectCtl,TRUE);
|
|
nLastBottom=rectCtl.bottom;
|
|
|
|
m_ckLock.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.top=nLastBottom+1;
|
|
rectCtl.bottom=rectCtl.top+nHeight;
|
|
m_ckLock.MoveWindow(rectCtl,TRUE);
|
|
|
|
m_lblStartDate.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.top=nLastBottom+5;
|
|
//preserve for other controls along bottom
|
|
nTopOfBottomRow=rectCtl.top;
|
|
rectCtl.bottom=rectCtl.top+nHeight;
|
|
m_lblStartDate.MoveWindow(rectCtl,TRUE);
|
|
nLastBottom=rectCtl.bottom;
|
|
|
|
m_dtDate.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.top=nLastBottom+1;
|
|
rectCtl.bottom=rectCtl.top+nHeight;
|
|
m_dtDate.MoveWindow(rectCtl,TRUE);
|
|
|
|
m_lblZone.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.top=nTopOfBottomRow;
|
|
rectCtl.bottom=rectCtl.top+nHeight;
|
|
m_lblZone.MoveWindow(rectCtl,TRUE);
|
|
|
|
|
|
m_cbZone.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.top=nLastBottom+1;
|
|
rectCtl.bottom=rectCtl.top+nHeight;
|
|
m_cbZone.MoveWindow(rectCtl,TRUE);
|
|
|
|
|
|
m_lblView.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.top=nTopOfBottomRow;
|
|
rectCtl.bottom=rectCtl.top+nHeight;
|
|
m_lblView.MoveWindow(rectCtl,TRUE);
|
|
nLastBottom=rectCtl.bottom;
|
|
|
|
m_rdDay.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.bottom=nLastBottom-7;
|
|
rectCtl.top=rectCtl.bottom-nHeight;
|
|
m_rdDay.MoveWindow(rectCtl,TRUE);
|
|
|
|
m_rdMonth.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.bottom=nLastBottom-7;
|
|
rectCtl.top=rectCtl.bottom-nHeight;
|
|
m_rdMonth.MoveWindow(rectCtl,TRUE);
|
|
|
|
m_rdWeek.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.bottom=nLastBottom-7;
|
|
rectCtl.top=rectCtl.bottom-nHeight;
|
|
m_rdWeek.MoveWindow(rectCtl,TRUE);
|
|
|
|
m_btnBack.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.bottom=nLastBottom;
|
|
rectCtl.top=rectCtl.bottom-nHeight;
|
|
m_btnBack.MoveWindow(rectCtl,TRUE);
|
|
|
|
m_btnForward.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.bottom=nLastBottom;
|
|
rectCtl.top=rectCtl.bottom-nHeight;
|
|
m_btnForward.MoveWindow(rectCtl,TRUE);
|
|
|
|
|
|
|
|
m_btnRefresh.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.bottom=nLastBottom;
|
|
rectCtl.top=rectCtl.bottom-nHeight;
|
|
m_btnRefresh.MoveWindow(rectCtl,TRUE);
|
|
|
|
m_btnPrint.GetWindowRect(rectCtl);
|
|
nHeight=rectCtl.Height();
|
|
rectCtl.bottom=nLastBottom;
|
|
rectCtl.top=rectCtl.bottom-nHeight;
|
|
m_btnPrint.MoveWindow(rectCtl,TRUE);
|
|
|
|
|
|
|
|
|
|
//only execute once
|
|
m_bLayoutDone=true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CScheduleFrm::ClearTimeBarObjects()
|
|
{
|
|
//delete all arBar objects
|
|
int x;
|
|
|
|
if(m_nTotalAllocated>0)
|
|
{
|
|
for(x=0;x<m_nTotalAllocated;x++)
|
|
{
|
|
m_ptbData=(CScheduleTimeBarData*)arBar.GetAt(x);
|
|
delete m_ptbData;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
arBar.RemoveAll();
|
|
|
|
//allocate as many as last time for efficiency
|
|
// arBar.SetSize(m_nTotalAllocated,1);
|
|
m_nTotalAllocated=0;
|
|
}
|
|
|
|
void CScheduleFrm::FillZoneList()
|
|
{
|
|
CString q, strData,strIndex;
|
|
long lData;
|
|
|
|
rs=m_pApp->rsPool->GetRS("CScheduleFrm::FillZoneList()");
|
|
|
|
|
|
//fill ZONES
|
|
m_cbZone.Clear();
|
|
m_cbZone.AddRow(" < All Techs >","0");
|
|
q="SELECT zones.id, zones.name FROM zones ORDER BY zones.name;";
|
|
|
|
rs->QueryReadOnly(q);
|
|
if(!rs->IsEmpty())
|
|
{
|
|
do
|
|
{
|
|
rs->FetchField("name",&strData);
|
|
strData+=" zone";
|
|
rs->FetchField("id",&lData);
|
|
strIndex.Format("%u",lData);
|
|
m_cbZone.AddRow(strData,strIndex);
|
|
}while(rs->MoveForward());
|
|
|
|
}
|
|
|
|
|
|
|
|
//Fill groups
|
|
|
|
q="SELECT schdgrps.id, schdgrps.name FROM schdgrps ORDER BY schdgrps.name;";
|
|
|
|
rs->QueryReadOnly(q);
|
|
if(!rs->IsEmpty())
|
|
{
|
|
do
|
|
{
|
|
rs->FetchField("name",&strData);
|
|
strData+=" group";
|
|
rs->FetchField("id",&lData);
|
|
strIndex.Format("%u",lData);
|
|
m_cbZone.AddRow(strData,strIndex);
|
|
}while(rs->MoveForward());
|
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------
|
|
m_pApp->rsPool->ReleaseRS(&rs->m_nID);
|
|
m_cbZone.SetCurSel(0);
|
|
}
|
|
|
|
void CScheduleFrm::OnCloseupCbzone()
|
|
{
|
|
CString strData,strID;
|
|
strID=m_cbZone.GetCurrentRowID();
|
|
strData=m_cbZone.GetCurrentRowText();
|
|
if(strData.Right(4)=="zone" || strID=="0")
|
|
m_bZoneView=true;
|
|
else
|
|
m_bZoneView=false;//by group
|
|
|
|
m_bRefresh=true;
|
|
|
|
FillView();
|
|
}
|
|
|
|
|
|
|
|
|
|
void CScheduleFrm::OnTimer(UINT nIDEvent)
|
|
{
|
|
|
|
|
|
if(nIDEvent==1 && !m_bUpdating)
|
|
{
|
|
|
|
KillTimer(1);
|
|
m_bRefresh=true;
|
|
FillView();
|
|
|
|
|
|
//AUTOREFRESH TIMER
|
|
if(m_pApp->m_lSchedRefreshSecs!=0)
|
|
m_nTimer = SetTimer(1, 1000*m_pApp->m_lSchedRefreshSecs, 0);
|
|
//m_nTimer = SetTimer(1, 6000, 0);
|
|
|
|
m_bTimerIsActive=true;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
CFormView::OnTimer(nIDEvent);
|
|
}
|
|
|
|
//round minutes to nearest quarter hour
|
|
void CScheduleFrm::RoundTime(long *lMinutes, long* lHours)
|
|
{
|
|
if(*lMinutes==0) return;
|
|
if(*lMinutes==15) return;
|
|
if(*lMinutes==30) return;
|
|
if(*lMinutes==45) return;
|
|
|
|
//FIRST QUARTER
|
|
//0-7 = 0
|
|
if(*lMinutes>0 && *lMinutes<8)
|
|
{
|
|
*lMinutes=0;
|
|
return;
|
|
|
|
}
|
|
|
|
//8-14 = 15
|
|
if(*lMinutes>7 && *lMinutes < 15)
|
|
{
|
|
*lMinutes=15;
|
|
return;
|
|
|
|
}
|
|
|
|
//SECOND QUARTER
|
|
//16-22 = 15
|
|
if(*lMinutes>15 && *lMinutes < 23)
|
|
{
|
|
*lMinutes=15;
|
|
return;
|
|
|
|
}
|
|
|
|
//23-29 = 30
|
|
if(*lMinutes>22 && *lMinutes < 30)
|
|
{
|
|
*lMinutes=30;
|
|
return;
|
|
|
|
}
|
|
|
|
//THIRD QUARTER
|
|
//31 - 37= 30
|
|
if(*lMinutes>30 && *lMinutes < 38)
|
|
{
|
|
*lMinutes=30;
|
|
return;
|
|
|
|
}
|
|
|
|
//38-44 = 45
|
|
if(*lMinutes>37 && *lMinutes < 45)
|
|
{
|
|
*lMinutes=45;
|
|
return;
|
|
|
|
}
|
|
|
|
//FOURTH QUARTER
|
|
//46 - 52 = 45
|
|
if(*lMinutes>45 && *lMinutes < 53)
|
|
{
|
|
*lMinutes=45;
|
|
return;
|
|
|
|
}
|
|
|
|
//53-59 = 0
|
|
if(*lMinutes>52 && *lMinutes < 60)
|
|
{
|
|
*lMinutes=0;
|
|
*lHours=*lHours+1;
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
BOOL CScheduleFrm::OnHelpInfo(HELPINFO* pHelpInfo)
|
|
{
|
|
WinHelp (0x00020000 + IDD_SCHEDULEFRM_FORM,HELP_CONTEXT);
|
|
return TRUE;
|
|
}
|
|
|
|
void CScheduleFrm::CleanupForExit(void)
|
|
{
|
|
|
|
}
|
|
|
|
void CScheduleFrm::OnDestroy()
|
|
{
|
|
KillTimer(1);
|
|
ClearTimeBarObjects();
|
|
|
|
CFormView::OnDestroy();
|
|
|
|
// TODO: Add your message handler code here
|
|
}
|