// PM.cpp : implementation file // #include "stdafx.h" #include "sp.h" #include "PM.h" #include "SimpleDate.h" #include "PartsDlg.h" #include "WOTypesDlg.h" #include "ProjectsDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CPM dialog CPM::CPM(CWnd* pParent /*=NULL*/) : CDialog(CPM::IDD, pParent) , m_bResave(false) { //{{AFX_DATA_INIT(CPM) //}}AFX_DATA_INIT m_pApp= (CSpApp*)AfxGetApp(); /* rs=new GZRset("Error: PM dialog"); rs->SetConnect(m_pApp->strConnectString); cbrs=new GZRset("Error: PM dialog cbRS"); cbrs->SetConnect(m_pApp->strConnectString); */ //Initialize recordset pointer rs=m_pApp->rsPool->GetRS("CPM (RS)"); cbrs=m_pApp->rsPool->GetRS("CPM (cbrs)"); m_strSelectedTech.Empty(); m_bAddMode=false; m_bEditing=false; } void CPM::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CPM) DDX_Control(pDX, IDC_LBL_SERIES, m_lblSeries); DDX_Control(pDX, IDC_ED_SERIES, m_edSeries); DDX_Control(pDX, IDC_LBLTIME5, m_lblTime5); DDX_Control(pDX, IDC_LBLTIME4, m_lblTime4); DDX_Control(pDX, IDC_EDTIMEREPEATEVERYWEEKS, m_edTimeRepeatEveryWeeks); DDX_Control(pDX, IDC_EDTIMEREPEATEVERYDAYS, m_edTimeRepeatEveryDays); DDX_Control(pDX, IDC_CBCATEGORY, m_cbCategories); DDX_Control(pDX, IDC_LBLTYPE, m_lblType); DDX_Control(pDX, IDC_LBLPROJECT, m_lblProject); DDX_Control(pDX, IDC_CKQUICK, m_ckQuick); DDX_Control(pDX, IDC_CKONSITE, m_ckOnsite); DDX_Control(pDX, IDC_CBPROJECTS, m_cbProjects); DDX_Control(pDX, IDC_BTNEDIT, m_btnEdit); DDX_Control(pDX, IDC_CKHOLD, m_ckHold); DDX_Control(pDX, IDC_LBLQUANT, m_lblQuant); DDX_Control(pDX, IDC_LBLPARTSLIST, m_lblPartsList); DDX_Control(pDX, IDC_LBLPART, m_lblPart); DDX_Control(pDX, IDC_LBPARTSREQ, m_lbParts); DDX_Control(pDX, IDC_EDQUANTITY, m_edPartQuantity); DDX_Control(pDX, IDC_BTNREMOVEPART, m_btnRemovePart); DDX_Control(pDX, IDC_BTNADDPART, m_btnAddPart); DDX_Control(pDX, IDC_CBPARTS, m_cbParts); DDX_Control(pDX, IDC_RDTIME, m_rdTime); DDX_Control(pDX, IDC_RDMETRIC, m_rdMetric); DDX_Control(pDX, IDC_RDAGE, m_rdAge); DDX_Control(pDX, IDC_LBLTIME3, m_lblTime3); DDX_Control(pDX, IDC_LBLTIME2, m_lblTime2); DDX_Control(pDX, IDC_LBLTIME1, m_lblTime1); DDX_Control(pDX, IDC_LBLTECH, m_lblTech); DDX_Control(pDX, IDC_LBLPMLIST, m_lblPMList); DDX_Control(pDX, IDC_LBLMETER4, m_lblMeter4); DDX_Control(pDX, IDC_LBLMETER3, m_lblMeter3); DDX_Control(pDX, IDC_LBLMETER2, m_lblMeter2); DDX_Control(pDX, IDC_LBLMETER1, m_lblMeter1); DDX_Control(pDX, IDC_LBLDAYOFWEEK, m_lblDayOfWeek); DDX_Control(pDX, IDC_LBLCONVERTMETER, m_lblConvertMeter); DDX_Control(pDX, IDC_LBLCONVERTDAYS, m_lblConvertDays); DDX_Control(pDX, IDC_LBLAGE5, m_lblAge5); DDX_Control(pDX, IDC_LBLAGE4, m_lblAge4); DDX_Control(pDX, IDC_LBLAGE3, m_lblAge3); DDX_Control(pDX, IDC_LBLAGE2, m_lblAge2); DDX_Control(pDX, IDC_LBLAGE1, m_lblAge1); DDX_Control(pDX, IDC_EDTIMEREPEATEVERYMONTHS, m_edTimeRepeatEveryMonths); DDX_Control(pDX, IDC_EDNOTES, m_edNotes); DDX_Control(pDX, IDC_EDMETERREPEAT, m_edMeterRepeat); DDX_Control(pDX, IDC_EDMETERLASTREADING, m_edMeterLastReading); DDX_Control(pDX, IDC_EDMETERFIRSTSERVICE, m_edMeterFirstService); DDX_Control(pDX, IDC_EDDESCRIPTION, m_edDescription); DDX_Control(pDX, IDC_EDCONVERTTOWOAFTER, m_edConvertToWoAfter); DDX_Control(pDX, IDC_EDAGEYRS, m_edAgeYears); DDX_Control(pDX, IDC_EDAGEREPEAT, m_edAgeRepeat); DDX_Control(pDX, IDC_EDAGEMONTHS, m_edAgeMonths); DDX_Control(pDX, IDC_DTTIMENEXTSERVICEDATE, m_dtTimeNextServiceDate); DDX_Control(pDX, IDC_DTAGEFIRSTSERVICEDATE, m_dtAgeFirstServiceDate); DDX_Control(pDX, IDC_CKAUTOWO, m_ckAutoWO); DDX_Control(pDX, IDC_CKAUTOREPEAT, m_ckAutoRepeat); DDX_Control(pDX, IDC_CBTECH, m_cbTech); DDX_Control(pDX, IDC_CBPMLIST, m_cbPMList); DDX_Control(pDX, IDC_CBDAYOFWEEK, m_cbDayOfWeek); DDX_Control(pDX, IDC_BTNDONE, m_btnDone); DDX_Control(pDX, IDC_BTNDELETE, m_btnDelete); DDX_Control(pDX, IDC_BTNCLONE, m_btnClone); DDX_Control(pDX, IDC_BTNADD, m_btnAdd); //}}AFX_DATA_MAP DDX_Control(pDX, IDC_LBL_START_TIME, m_lblStartTime); DDX_Control(pDX, IDC_LBL_END_TIME, m_lblEndTime); DDX_Control(pDX, IDC_DTSTART, m_dtStartTime); DDX_Control(pDX, IDC_DTEND, m_dtEndtime); } BEGIN_MESSAGE_MAP(CPM, CDialog) //{{AFX_MSG_MAP(CPM) ON_BN_CLICKED(IDC_RDAGE, OnRdage) ON_BN_CLICKED(IDC_RDMETRIC, OnRdmetric) ON_BN_CLICKED(IDC_RDTIME, OnRdtime) ON_BN_CLICKED(IDC_BTNDONE, OnBtndone) ON_BN_CLICKED(IDC_CKAUTOREPEAT, OnCkautorepeat) ON_BN_CLICKED(IDC_CKAUTOWO, OnCkautowo) ON_BN_CLICKED(IDC_BTNADD, OnBtnadd) ON_CBN_CLOSEUP(IDC_CBPMLIST, OnCloseupCbpmlist) ON_BN_CLICKED(IDC_BTNADDPART, OnBtnaddpart) ON_BN_CLICKED(IDC_BTNREMOVEPART, OnBtnremovepart) ON_BN_CLICKED(IDC_BTNEDIT, OnBtnedit) ON_BN_CLICKED(IDC_BTNDELETE, OnBtndelete) ON_EN_KILLFOCUS(IDC_EDAGEYRS, OnKillfocusEdageyrs) ON_EN_KILLFOCUS(IDC_EDAGEMONTHS, OnKillfocusEdagemonths) ON_EN_KILLFOCUS(IDC_EDMETERLASTREADING, OnKillfocusEdmeterlastreading) ON_BN_CLICKED(IDC_CKQUICK, OnCkquick) ON_BN_CLICKED(IDC_LBLPART, OnLblpart) ON_BN_CLICKED(IDC_LBLPROJECT, OnLblproject) ON_BN_CLICKED(IDC_LBLTYPE, OnLbltype) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPM message handlers CPM::~CPM() { m_pApp->rsPool->ReleaseRS(&rs->m_nID); m_pApp->rsPool->ReleaseRS(&cbrs->m_nID); } BOOL CPM::OnInitDialog() { CDialog::OnInitDialog(); //1.9.4.4 m_edDescription.SetLimitText(50); Security(); //make "hyperlinks" m_lblPart.SetTextColor(RGB(0,0,255)); m_lblPart.SetFontUnderline(TRUE); m_lblPart.SetLink(TRUE); m_lblPart.SetLinkCursor(m_pApp->hcHand); m_lblPart.SetLinkURL(""); m_lblType.SetTextColor(RGB(0,0,255)); m_lblType.SetFontUnderline(TRUE); m_lblType.SetLink(TRUE); m_lblType.SetLinkCursor(m_pApp->hcHand); m_lblType.SetLinkURL(""); m_lblProject.SetTextColor(RGB(0,0,255)); m_lblProject.SetFontUnderline(TRUE); m_lblProject.SetLink(TRUE); m_lblProject.SetLinkCursor(m_pApp->hcHand); m_lblProject.SetLinkURL(""); m_bReschedule=false; m_bReadOnly=false; EnableFields(false); SetWindowText(m_strPrompt); m_bAutoRepeat=false; m_bAutoWO=false; m_nCurrentMode=-1;//signifies no selection ASSERT(!m_strCriteria.IsEmpty());//would mean no criteria was passed if(m_strCriteria.IsEmpty()) { AfxMessageBox("Error in PM dialog, no Model or Client criteria."); CDialog::OnCancel(); } FillPartsList(); FillTechList(); FillProjectList(); FillTypeList(); FillPMList(); if(m_bResave) { OnBtnedit();//edit OnBtnadd();//save OnBtndone();//exit } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } //handle a click on a radio button //0=time based, 1=metric, 2=age void CPM::GroupClick(int nClicked) { m_rdAge.SetCheck(FALSE); m_rdMetric.SetCheck(FALSE); m_rdTime.SetCheck(FALSE); switch (nClicked) { case 0: m_rdTime.SetCheck(TRUE); break; case 1: m_rdMetric.SetCheck(TRUE); break; default: m_rdAge.SetCheck(TRUE); break; } m_nCurrentMode=nClicked; SwitchMode(); } void CPM::OnRdage() { if(m_bClientMode) { AfxMessageBox("You can't schedule by Age for a client!\r\nOnly a unit."); return; } CString q; if(!m_bModel) { //Look up the purchase date and abort if none entered q.Format("SELECT units.purchasedate " "FROM units " "WHERE (((units.id)=%s));",m_strCriteria); cbrs->Query(q); if(cbrs->IsEmpty()) { AfxMessageBox("There is no purchase date set for this unit.\r\n" "It can't be scheduled by age. Check the unit record."); //theory is that this will change back to previous //whatever was set since we haven't groupclicked yet. SwitchMode(); return; } cbrs->FetchField("purchasedate",&m_dtUnitPurchasedDate); q.Format( "According to this unit's record, it was purchased on: %s.\r\n\r\n" "This date will be used for age calculation when scheduling.\r\n" "If this date was entered incorrectly, you can change it by\r\n" "editing this unit's record. Then reschedule here.",m_dtUnitPurchasedDate.Format(VAR_DATEVALUEONLY)); AfxMessageBox(q,MB_OK); } GroupClick(2); } void CPM::OnRdmetric() { GroupClick(1); } void CPM::OnRdtime() { GroupClick(0); } //Presets for form. void CPM::PreInitialize(bool bClientMode, bool bModel, CString strCriteria, CString strPrompt,bool bResave) { m_strCriteria = strCriteria; m_bClientMode=bClientMode; m_bModel=bModel; m_strPrompt=strPrompt; m_bResave=bResave; } //mostly for security or no record situations void CPM::EnableFields(bool bEnable) { if(m_bReadOnly) return; if(m_bReadOnlySecurity==true && bEnable==true) return; BOOL enable=bEnable ? TRUE : FALSE; //m_btnDelete.EnableWindow(enable); //m_btnEdit.EnableWindow(enable); //m_btnClone.EnableWindow(enable); m_cbDayOfWeek.EnableWindow(enable); m_dtStartTime.EnableWindow(enable); m_dtEndtime.EnableWindow(enable); m_cbTech.EnableWindow(enable); m_ckAutoRepeat.EnableWindow(enable); m_ckAutoWO.EnableWindow(enable); m_ckHold.EnableWindow(enable); m_dtAgeFirstServiceDate.EnableWindow(enable); m_dtTimeNextServiceDate.EnableWindow(enable); m_edAgeMonths.EnableWindow(enable); m_edAgeRepeat.EnableWindow(enable); m_edAgeYears.EnableWindow(enable); m_edConvertToWoAfter.EnableWindow(enable); m_edDescription.EnableWindow(enable); m_edMeterFirstService.EnableWindow(enable); m_edMeterLastReading.EnableWindow(TRUE); m_edMeterRepeat.EnableWindow(enable); m_edNotes.EnableWindow(enable); m_edTimeRepeatEveryMonths.EnableWindow(enable); m_edTimeRepeatEveryWeeks.EnableWindow(enable); m_edTimeRepeatEveryDays.EnableWindow(enable); m_edSeries.EnableWindow(enable); //Hide the workorder specifics m_ckOnsite.EnableWindow(enable); m_ckQuick.EnableWindow(enable); m_cbProjects.EnableWindow(enable); m_cbCategories.EnableWindow(enable); m_rdTime.EnableWindow(enable); m_rdAge.EnableWindow(enable); m_rdMetric.EnableWindow(enable); //age and meter can only be activated if it's //not client based if(m_bClientMode) { m_rdAge.EnableWindow(FALSE); m_rdMetric.EnableWindow(FALSE); } m_btnAddPart.EnableWindow(enable); m_btnRemovePart.EnableWindow(enable); m_cbParts.EnableWindow(enable); m_edPartQuantity.EnableWindow(enable); } void CPM::OnBtndone() { CDialog::OnOK(); } //change display based on type of p.m. void CPM::SwitchMode() { BOOL wofields; BOOL partsfields=m_bQuick ? FALSE : TRUE; //don't display the parts fields if adding a record if(m_bAddMode) partsfields=FALSE; wofields=m_bAutoWO ? TRUE : FALSE; if(m_bReadOnly || m_nCurrentMode==-1) return; //Hide everything first //Hide the workorder specifics m_lblType.ShowWindow(wofields); m_lblProject.ShowWindow(wofields); m_ckOnsite.ShowWindow(wofields); if(m_bClientMode) m_ckQuick.ShowWindow(wofields); else m_ckQuick.ShowWindow(FALSE); m_cbProjects.ShowWindow(wofields); m_cbCategories.ShowWindow(wofields); //Parts fields only display on standard workorder m_btnAddPart.ShowWindow(partsfields); m_btnRemovePart.ShowWindow(partsfields); m_cbParts.ShowWindow(partsfields); m_edPartQuantity.ShowWindow(partsfields); m_lbParts.ShowWindow(partsfields); m_lblPart.ShowWindow(partsfields); m_lblPartsList.ShowWindow(partsfields); m_lblQuant.ShowWindow(partsfields); //Hide the time based fields: m_dtTimeNextServiceDate.ShowWindow(FALSE); m_edTimeRepeatEveryMonths.ShowWindow(FALSE); m_edTimeRepeatEveryWeeks.ShowWindow(FALSE); m_edTimeRepeatEveryDays.ShowWindow(FALSE); m_lblTime1.ShowWindow(FALSE); m_lblTime2.ShowWindow(FALSE); m_lblTime3.ShowWindow(FALSE); m_lblTime4.ShowWindow(FALSE); m_lblTime5.ShowWindow(FALSE); //Hide the meter based fields m_edMeterFirstService.ShowWindow(FALSE); m_edMeterLastReading.ShowWindow(FALSE); m_edMeterRepeat.ShowWindow(FALSE); m_lblMeter1.ShowWindow(FALSE); m_lblMeter2.ShowWindow(FALSE); m_lblMeter3.ShowWindow(FALSE); m_lblMeter4.ShowWindow(FALSE); //Hide the AGE based fields m_dtAgeFirstServiceDate.ShowWindow(FALSE); m_edAgeMonths.ShowWindow(FALSE); m_edAgeYears.ShowWindow(FALSE); m_edAgeRepeat.ShowWindow(FALSE); m_lblAge1.ShowWindow(FALSE); m_lblAge2.ShowWindow(FALSE); m_lblAge3.ShowWindow(FALSE); m_lblAge4.ShowWindow(FALSE); m_lblAge5.ShowWindow(FALSE); m_lblConvertDays.ShowWindow(FALSE); m_lblConvertMeter.ShowWindow(FALSE); // m_lblConvert.ShowWindow(m_bAutoWO ? TRUE : FALSE); m_edConvertToWoAfter.ShowWindow(m_bAutoWO ? TRUE : FALSE); //HIDE THE series controls m_lblSeries.ShowWindow(FALSE); m_edSeries.ShowWindow(FALSE); switch (m_nCurrentMode) { //TIME BASED case 0: //time interval based m_dtTimeNextServiceDate.ShowWindow(TRUE); m_lblTime1.ShowWindow(TRUE); if(m_bAutoRepeat) { m_edTimeRepeatEveryMonths.ShowWindow(TRUE); m_edTimeRepeatEveryWeeks.ShowWindow(TRUE); m_edTimeRepeatEveryDays.ShowWindow(TRUE); m_lblTime2.ShowWindow(TRUE); m_lblTime3.ShowWindow(TRUE); m_lblTime4.ShowWindow(TRUE); m_lblTime5.ShowWindow(TRUE); m_lblSeries.ShowWindow(TRUE); m_edSeries.ShowWindow(TRUE); } if(m_bAutoWO) m_lblConvertDays.ShowWindow(TRUE); break; //METER BASED case 1: m_edMeterFirstService.ShowWindow(TRUE); m_edMeterLastReading.ShowWindow(TRUE); m_lblMeter1.ShowWindow(TRUE); m_lblMeter4.ShowWindow(TRUE); if(m_bAutoRepeat) { m_edMeterRepeat.ShowWindow(TRUE); m_lblMeter2.ShowWindow(TRUE); m_lblMeter3.ShowWindow(TRUE); m_lblSeries.ShowWindow(TRUE); m_edSeries.ShowWindow(TRUE); } if(m_bAutoWO) m_lblConvertMeter.ShowWindow(TRUE); break; //AGE BASED default: m_dtAgeFirstServiceDate.ShowWindow(TRUE); m_edAgeMonths.ShowWindow(TRUE); m_edAgeYears.ShowWindow(TRUE); m_lblAge1.ShowWindow(TRUE); m_lblAge2.ShowWindow(TRUE); m_lblAge3.ShowWindow(TRUE); if(m_bAutoRepeat) { m_lblAge4.ShowWindow(TRUE); m_lblAge5.ShowWindow(TRUE); m_edAgeRepeat.ShowWindow(TRUE); m_lblSeries.ShowWindow(TRUE); m_edSeries.ShowWindow(TRUE); } if(m_bAutoWO) m_lblConvertDays.ShowWindow(TRUE); //don't bother displaying the next service date //since this is a model which doesn't apply if(m_bModel) { m_dtAgeFirstServiceDate.ShowWindow(FALSE); m_lblAge3.ShowWindow(FALSE); } break; } } void CPM::OnCkautorepeat() { m_bAutoRepeat=m_ckAutoRepeat.GetCheck() ? true : false; SwitchMode(); } void CPM::OnCkautowo() { m_bAutoWO = m_ckAutoWO.GetCheck() ? true : false; SwitchMode(); } void CPM::FillPartsList() { CString strData; CString strIndex; long lData; m_cbParts.Clear(); cbrs->Query("SELECT parts.id, [partnumber] & \" - \" " "& [description] AS name FROM parts " "ORDER BY parts.partnumber;"); if(cbrs->IsEmpty()) return; cbrs->MoveFirst(); do { cbrs->FetchField("name",&strData); cbrs->FetchField("id",&lData); strIndex.Format("%u",lData); m_cbParts.AddRow(strData,strIndex); }while(cbrs->MoveForward()); m_cbParts.SetCurSel(0); } void CPM::FillPMList() { CString strData,strType,q; CString strIndex,strModel; long lData; m_cbPMList.Clear(); if(m_bClientMode) strType="True"; else strType="False"; strModel=m_bModel ? "true" : "false"; //select all schedule records for this //client or unit model q.Format("SELECT pmhead.* FROM pmhead " "WHERE (((pmhead.link)=%s) AND ((pmhead.isclient)=%s) AND ((pmhead.ismodel)=%s)) ORDER BY pmhead.description;",m_strCriteria,strType,strModel); //m_pApp->ShowStuff(q); rs->Query(q); if(rs->IsEmpty()) { m_bNoRecord=true; m_btnDelete.EnableWindow(FALSE); m_btnEdit.EnableWindow(FALSE); ClearFields(); EnableFields(false); return; } m_bNoRecord=false; m_btnDelete.EnableWindow(TRUE); m_btnEdit.EnableWindow(TRUE); rs->MoveFirst(); do { rs->FetchField("description",&strData); rs->FetchField("id",&lData); strIndex.Format("%u",lData); m_cbPMList.AddRow(strData,strIndex); }while(rs->MoveForward()); //pretend user has selected so that other fields get filled in if(m_strSelectedPM.IsEmpty()) //first time in { m_cbPMList.SetCurSel(0); m_strSelectedPM=m_cbPMList.GetCurrentRowID(); } else//something valid was selected before so stick with it m_cbPMList.Select(m_strSelectedPM); FillFields(); } void CPM::FillFields() { CString strData,q; COleDateTime dtData; bool bData; long lData; ClearFields(); q.Format("SELECT pmhead.* FROM pmhead " "WHERE (((pmhead.id)=%s));",m_cbPMList.GetCurrentRowID()); rs->Query(q); EnableFields(false); m_bNoRecord=true; m_bEditing=false; m_btnEdit.ShowWindow(FALSE); if(rs->IsEmpty()) { m_btnDelete.EnableWindow(FALSE); return; } m_btnDelete.EnableWindow(TRUE); m_bNoRecord=false; //EnableFields(true); m_btnEdit.ShowWindow(TRUE); //============================== //get ID number for scheduling functs. rs->FetchField("id",&m_lCurrentRecordID); //IS IT A MODEL? rs->FetchField("ismodel",&m_bModel); //DESCRIPTION rs->FetchField("description",&strData); m_edDescription.SetWindowText(strData); //NOTES rs->FetchField("notes",&strData); m_edNotes.SetWindowText(strData); //TYPE rs->FetchField("type",&lData); m_nCurrentMode=(int)lData; //CLIENTBASED rs->FetchField("isclient",&bData); m_bClientMode=bData; //AUTOWO rs->FetchField("autowo",&m_bAutoWO); m_ckAutoWO.SetCheck(m_bAutoWO ? TRUE : FALSE); //AUTOREPEAT rs->FetchField("autorpt",&m_bAutoRepeat); m_ckAutoRepeat.SetCheck(m_bAutoRepeat ? TRUE : FALSE); //DAYOFWEEK //0 =any 1=monday.....7=sunday rs->FetchField("dow",&lData); m_cbDayOfWeek.SetCurSel((int)lData); //Start / End time rs->FetchField("starttime",&dtData); m_dtStartTime.SetTime(dtData); rs->FetchField("endtime",&dtData); m_dtEndtime.SetTime(dtData); //TECH - preferred rs->FetchField("tech",&lData); m_strSelectedTech.Format("%u",lData); FillTechList(); //m_cbTech.Select(lData); //WOCONVERT rs->FetchField("woconvert",&lData); strData.Format("%u",lData); m_edConvertToWoAfter.SetWindowText(strData); //================================================= //Quick workorder rs->FetchField("woquick",&bData); m_bQuick=bData; m_ckQuick.SetCheck(bData ? TRUE : FALSE); //ONSITE rs->FetchField("woonsite",&bData); m_ckOnsite.SetCheck(bData ? TRUE : FALSE); //Project rs->FetchField("woproject",&lData); m_strSelProject.Format("%u",lData); FillProjectList(); //Category - type rs->FetchField("wotype",&lData); m_strSelCategory.Format("%u",lData); FillTypeList(); //====================================== //NEXT SERVICE DATE nextsrvdate rs->FetchField("nextsrvdate",&dtData); if(m_nCurrentMode!=1)//not metered { if(m_nCurrentMode==0) m_dtTimeNextServiceDate.SetTime(dtData); else m_dtAgeFirstServiceDate.SetTime(dtData); } //NEXT METER SERVICE nextsrvmeter if(m_nCurrentMode==1)//metered { rs->FetchField("nextsrvmeter",&lData); strData.Format("%u",lData); m_edMeterFirstService.SetWindowText(strData); } /*PMDAYS*/ //REPEAT EVERY repeatevery rs->FetchField("repeatevery",&lData); strData.Format("%u",lData); switch (m_nCurrentMode) { case 0://time based //months m_edTimeRepeatEveryMonths.SetWindowText(strData); //weeks rs->FetchField("rptweeks",&lData); strData.Format("%u",lData); m_edTimeRepeatEveryWeeks.SetWindowText(strData); //days rs->FetchField("rptdays",&lData); strData.Format("%u",lData); m_edTimeRepeatEveryDays.SetWindowText(strData); break; case 1://meter based m_edMeterRepeat.SetWindowText(strData); break; default://age based m_edAgeRepeat.SetWindowText(strData); break; } //AGE MONTHS/YEARS if(m_nCurrentMode==2)//age mode { rs->FetchField("ageyears",&lData); strData.Format("%u",lData); m_edAgeYears.SetWindowText(strData); rs->FetchField("agemonths",&lData); strData.Format("%u",lData); m_edAgeMonths.SetWindowText(strData); } //ACTIVE / ON HOLD rs->FetchField("active",&bData); m_ckHold.SetCheck(bData ? FALSE : TRUE); //GET SERIES for scheduling rs->FetchField("series",&lData); m_nSeries=(int)lData; strData.Format("%u",m_nSeries); m_edSeries.SetWindowText(strData); if(!m_bClientMode) UpdateMeterCount(false); GroupClick(m_nCurrentMode); //SwitchMode(); FillRequiredPartsList(); //Added 02/21/2003 Update title bar with object and detail so //people know what their dealing with. SetWindowText("Edit master PM record");//default if below fails in any way CString strTitleBarText="Edit PM for "; int nType=0;//default unit if(m_bClientMode) nType=1; if(m_bModel) nType=2; switch(nType) { case 0://unit q.Format("SELECT units.sn AS USN, clients.company AS OWNER, unitmodels.model AS MODEL, " "nonclients.company_person AS MANU, unitmodels.description AS DESCRIPT " "FROM (((pmhead LEFT JOIN units ON pmhead.link = units.id) " "LEFT JOIN unitmodels ON units.model = unitmodels.id) " "LEFT JOIN clients ON units.client = clients.id) " "LEFT JOIN nonclients ON unitmodels.manufacturer " "= nonclients.id WHERE (((pmhead.id)=%s));",m_cbPMList.GetCurrentRowID()); if(!cbrs->QueryReadOnly(q)) goto BAIL; if(cbrs->IsEmpty()) goto BAIL; //Ok, we have a record and are ready to retrieve the details if(!cbrs->FetchField("USN",&strData)) goto BAIL; strTitleBarText+="Unit - sn:" + strData; if(!cbrs->FetchField("MANU",&strData)) goto BAIL; strTitleBarText+=" " + strData; if(!cbrs->FetchField("MODEL",&strData)) goto BAIL; strTitleBarText+=" " + strData; if(!cbrs->FetchField("DESCRIPT",&strData)) goto BAIL; strTitleBarText+=" " + strData; if(!cbrs->FetchField("OWNER",&strData)) goto BAIL; strTitleBarText+=" Client: " + strData; SetWindowText(strTitleBarText); break; case 1://Client q.Format("SELECT clients.company FROM pmhead LEFT JOIN clients " "ON pmhead.link = clients.id WHERE (((pmhead.id)=%s)); ",m_cbPMList.GetCurrentRowID()); if(!cbrs->QueryReadOnly(q)) goto BAIL; if(cbrs->IsEmpty()) goto BAIL; //Ok, we have a record and are ready to retrieve the details if(!cbrs->FetchField("company",&strData)) goto BAIL; strTitleBarText+=" Client - " + strData; SetWindowText(strTitleBarText); break; case 2://Model q.Format("SELECT pmhead.id, nonclients.company_person, unitmodels.model, " "unitmodels.description, unitmodelcats.name " "FROM (pmhead LEFT JOIN (unitmodels LEFT JOIN " "nonclients ON unitmodels.manufacturer = nonclients.id) " "ON pmhead.link = unitmodels.id) LEFT JOIN unitmodelcats " "ON unitmodels.category = unitmodelcats.id " "WHERE (((pmhead.id)=%s));",m_cbPMList.GetCurrentRowID()); if(!cbrs->QueryReadOnly(q)) goto BAIL; if(cbrs->IsEmpty()) goto BAIL; //Ok, we have a record and are ready to retrieve the details if(!cbrs->FetchField("company_person",&strData)) goto BAIL; strTitleBarText+=" All units of model - " + strData; if(!cbrs->FetchField("model",&strData)) goto BAIL; strTitleBarText+=" " + strData; if(!cbrs->FetchField("description",&strData)) goto BAIL; strTitleBarText+=" " + strData; if(!cbrs->FetchField("name",&strData)) goto BAIL; if(!strData.IsEmpty()) { strTitleBarText+=" (" + strData; strTitleBarText+=")"; } SetWindowText(strTitleBarText); break; } BAIL: m_btnEdit.SetFocus(); //============================== } void CPM::ClearFields() { COleDateTime dtData; m_cbDayOfWeek.SetCurSel(0); dtData.SetTime(8,0,0); m_dtStartTime.SetTime(dtData); dtData.SetTime(9,0,0); m_dtEndtime.SetTime(dtData); m_cbTech.SetCurSel(0); m_ckAutoRepeat.SetCheck(FALSE); m_ckAutoWO.SetCheck(FALSE); m_ckOnsite.SetCheck(TRUE); m_ckQuick.SetCheck(FALSE); m_bQuick=false; m_dtAgeFirstServiceDate.SetTime(COleDateTime::GetCurrentTime()); m_dtTimeNextServiceDate.SetTime(COleDateTime::GetCurrentTime()); m_edAgeMonths.SetWindowText("0"); m_edAgeRepeat.SetWindowText("0"); m_edAgeYears.SetWindowText("0"); m_edConvertToWoAfter.SetWindowText("1"); m_edDescription.SetWindowText(""); m_edMeterFirstService.SetWindowText("0"); m_edMeterLastReading.SetWindowText("0"); m_edMeterRepeat.SetWindowText("0"); m_edNotes.SetWindowText(""); m_edTimeRepeatEveryMonths.SetWindowText("0"); m_edTimeRepeatEveryWeeks.SetWindowText("0"); m_edTimeRepeatEveryDays.SetWindowText("0"); m_rdAge.SetCheck(FALSE); m_rdMetric.SetCheck(FALSE); m_rdTime.SetCheck(TRUE); m_nCurrentMode=0;//default is by time interval m_edSeries.SetWindowText("2"); m_lbParts.Clear(); m_edPartQuantity.SetWindowText("0"); SwitchMode(); } void CPM::FillTechList() { //10/03/00 - fix for the licensing problem //if the m_strSelected tech isn't in the list then //add it "manually" after filling the list as normal //like this: "* Bob Jones (inactive)" CString strData; CString strIndex; CString q; long lData; m_cbTech.Clear(); //any tech default m_cbTech.AddRow("< Any tech. >","0"); //look for selected tech and see if in inactive list: if(!m_strSelectedTech.IsEmpty()) { q.Format("SELECT users.id, [last] & \", \" & [first] AS fullname " "FROM users " "WHERE (((users.id)=%s) AND ((users.active)=False));",m_strSelectedTech); cbrs->Query(q); if(!cbrs->IsEmpty()) //it's an inactive tech put them in the list "manually" { cbrs->FetchField("fullname",&strData); cbrs->FetchField("id",&lData); strIndex.Format("%u",lData); q=" " + strData; m_cbTech.AddRow(q,strIndex); } } //change to active only 10/03/00 q="SELECT users.id, [last] & \", \" & [first] AS fullname FROM users " "WHERE (((users.id)<>1) AND ((users.tech)=True) AND ((users.active)=True)) " "ORDER BY users.last;"; //////////////////m_pApp->ShowStuff(q); cbrs->Query(q); if(!cbrs->IsEmpty()) { cbrs->MoveFirst(); cbrs->FetchField("fullname",&strData); cbrs->FetchField("id",&lData); strIndex.Format("%u",lData); m_cbTech.AddRow(strData,strIndex); while(cbrs->MoveForward()) { cbrs->FetchField("fullname",&strData); cbrs->FetchField("id",&lData); strIndex.Format("%u",lData); m_cbTech.AddRow(strData,strIndex); } } if(!m_strSelectedTech.IsEmpty()) m_cbTech.Select(m_strSelectedTech); else {//attempt to select by current user id m_strSelectedTech.Format("%u",m_pApp->m_lusrID); m_cbTech.Select(m_strSelectedTech); } } //add new item void CPM::OnBtnadd() { CString strData,q,strDescription; bool bData; long lData,lConvert,lDays,lWeeks,lSeries; COleDateTime dtData; lData=0;lDays=0;lWeeks=0;lSeries=0; if(!m_bAddMode && !m_bEditing) { //Go Add mode m_bAddMode=true; m_bQuick=false; EnableFields(true); m_lblPart.ShowWindow(FALSE); m_lblPartsList.ShowWindow(FALSE); m_lblQuant.ShowWindow(FALSE); m_lblPMList.ShowWindow(FALSE); m_cbPMList.ShowWindow(FALSE); m_lbParts.ShowWindow(FALSE); m_btnRemovePart.ShowWindow(FALSE); m_btnAddPart.ShowWindow(FALSE); m_cbParts.ShowWindow(FALSE); m_edPartQuantity.ShowWindow(FALSE); m_btnDone.ShowWindow(FALSE); m_btnAdd.SetWindowText("SAVE"); m_btnDelete.SetWindowText("CANCEL"); /////////////////////////m_btnClone.ShowWindow(FALSE); m_btnEdit.ShowWindow(FALSE); m_edSeries.SetWindowText("5"); ClearFields(); UpdateMeterCount(false); } else { //validate and save //v1.9.4.4 meter based items should not allow first service at meter //count zero when creating a new record or hundreds of workorders will //be created if(m_nCurrentMode==1)//meter based { long lTemp=0; m_edMeterLastReading.GetWindowText(strData); lTemp=atol(strData); m_edMeterFirstService.GetWindowText(strData); lConvert=atol(strData); if(lConvert<1 || lConvert 6) { AfxMessageBox("Series must be greater than 1 and less than 6.\r\n" "The default of 2 is recommended\r\n\r\n" "This value has no effect on the number\r\n" "of times a workorder will be automatically\r\n" "generated, only what is shown at any given time in the \r\n" "preventive maintenance list screen for information\r\n" "and planning purposes."); m_edSeries.SetWindowText("2"); m_edSeries.SetFocus(); return; } //DESCRIPTION m_edDescription.GetWindowText(strDescription); if(strDescription.IsEmpty()) { AfxMessageBox("Description is required to proceed"); return; } //Added 02/20/2003 in case user enters quotes here strDescription.Replace("\"","''"); if(!m_bEditing)//make a new record { //open the recordset rs->Query("SELECT pmhead.* FROM pmhead WHERE (((pmhead.id)=0));"); rs->pTheConnection->BeginTrans(); if(!rs->AddNewRecord()) { AfxMessageBox("PM EDIT: Error opening empty RS for addition"); rs->pTheConnection->RollbackTrans(); return; } else//Added 09/05/2001 to properly set creator created on new record { //Set creator and created dtData=COleDateTime::GetCurrentTime(); rs->UpdateField("creator",&m_pApp->m_lusrID); rs->UpdateField("created",&dtData); } } else //change an existing one { q.Format("SELECT pmhead.* FROM pmhead WHERE (((pmhead.id)=%s));",m_cbPMList.GetCurrentRowID()); if(!rs->Query(q)) { AfxMessageBox("PM EDIT: Error opening existing record for update"); return; } } //if not editing a transaction has already been started, otherwise start one now if(m_bEditing) rs->pTheConnection->BeginTrans(); rs->UpdateField("description",&strDescription); //NOTES m_edNotes.GetWindowText(strData); //Added 02/20/2003 bug with quotation marks strData.Replace("\"","''"); //added to avoid bug where would crash in routines that create workorder if notes were empty if(strData.IsEmpty()) strData="N/A"; rs->UpdateField("notes",&strData); //CLIENT/UNIT LINK lData=atol(m_strCriteria); rs->UpdateField("link",&lData); //TYPE lData=(long)m_nCurrentMode; rs->UpdateField("type",&lData); //CLIENTBASED rs->UpdateField("isclient",&m_bClientMode); //ISMODEL rs->UpdateField("ismodel",&m_bModel); //AUTOWO rs->UpdateField("autowo",&m_bAutoWO); //AUTOREPEAT rs->UpdateField("autorpt",&m_bAutoRepeat); //DAYOFWEEK //0 =any 1=monday.....7=sunday lData=(long)m_cbDayOfWeek.GetCurSel(); rs->UpdateField("dow",&lData); //START / END TIME m_dtStartTime.GetTime(dtData); rs->UpdateField("starttime",&dtData); m_dtEndtime.GetTime(dtData); rs->UpdateField("endtime",&dtData); //TECH - preferred lData=atol(m_cbTech.GetCurrentRowID()); rs->UpdateField("tech",&lData); //WOCONVERT rs->UpdateField("woconvert",&lConvert); //================================================= //Quick workorder if(m_bClientMode) bData=m_ckQuick.GetCheck() ? true : false; else bData=false; rs->UpdateField("woquick",&bData); //ONSITE bData=m_ckOnsite.GetCheck() ? true : false; rs->UpdateField("woonsite",&bData); //Project lData=atol(m_cbProjects.GetCurrentRowID()); rs->UpdateField("woproject",&lData); //Category - type lData=atol(m_cbCategories.GetCurrentRowID()); rs->UpdateField("wotype",&lData); //====================================== //NEXT SERVICE DATE nextsrvdate if(m_nCurrentMode!=1)//not metered { if(m_nCurrentMode==0) m_dtTimeNextServiceDate.GetTime(dtData); else m_dtAgeFirstServiceDate.GetTime(dtData); } rs->UpdateField("nextsrvdate",&dtData); //NEXT METER SERVICE nextsrvmeter if(m_nCurrentMode==1)//metered { m_edMeterFirstService.GetWindowText(strData); lData=atol(strData); rs->UpdateField("nextsrvmeter",&lData); } /*PMDAYS*/ //REPEAT EVERY repeatevery switch (m_nCurrentMode) { case 0://time based //DAYS m_edTimeRepeatEveryDays.GetWindowText(strData); lDays=atol(strData); //WEEKS m_edTimeRepeatEveryWeeks.GetWindowText(strData); lWeeks=atol(strData); //MONTHS m_edTimeRepeatEveryMonths.GetWindowText(strData); break; case 1://meter based m_edMeterRepeat.GetWindowText(strData); break; default://age based m_edAgeRepeat.GetWindowText(strData); break; } lData=atol(strData); if(/*MONTHS if time based:*/lData<1 && lDays<1 && lWeeks<1 && m_bAutoRepeat) { AfxMessageBox( "Warning: the Months/weeks/days or Meter repeat value is 0.\r\n\r\n" "This means that at *all* series of this scheduled item\r\n" "are going to be booked on the same day/meter reading.\r\n\r\n" "You could end up with potentially thousands of workorders in\r\n" "your schedule all at once depending upon the other settings.\r\n\r\n" "AyaNova has automatically changed the Months / Meter \r\n" "value to 999 so you can see which field this message\r\n" "refers to at a glance to correct the problem\r\n\r\n" "If you do not want this item to repeat\r\n" "automatically, uncheck the 'Repeat' box\r\n\r\n" "See the preventive maintenance reference guide\r\n" "in the AyaNova manual for more information." ); lData=999; } rs->UpdateField("repeatevery",&lData); rs->UpdateField("rptweeks",&lWeeks); rs->UpdateField("rptdays",&lDays); /*PMDAYS*/ //AGE MONTHS/YEARS if(m_nCurrentMode==2)//age mode { m_edAgeYears.GetWindowText(strData); lData=atol(strData); rs->UpdateField("ageyears",&lData); m_edAgeMonths.GetWindowText(strData); lData=atol(strData); rs->UpdateField("agemonths",&lData); } //ACTIVE / ON HOLD bData=m_ckHold.GetCheck() ? false : true; rs->UpdateField("active",&bData); //SERIES m_nSeries=(int)lSeries; rs->UpdateField("series",&lSeries); //METER COUNT UpdateMeterCount(true); //CREATOR FIELDS //updated 09/05/2001 to remove creator created here dtData=COleDateTime::GetCurrentTime(); rs->UpdateField("modifier",&m_pApp->m_lusrID); rs->UpdateField("modified",&dtData); if(!rs->SaveRecord()) { MessageBox("Unable to save this record"); rs->pTheConnection->RollbackTrans(); return; } rs->pTheConnection->CommitTrans(); //get ID number rs->FetchField("id",&m_lCurrentRecordID); rs->Close(); m_bEditing=false; m_bAddMode=false; m_lblPart.ShowWindow(TRUE); m_lblPMList.ShowWindow(TRUE); m_cbPMList.ShowWindow(TRUE); m_lbParts.ShowWindow(TRUE); m_btnRemovePart.ShowWindow(TRUE); m_btnAddPart.ShowWindow(TRUE); m_cbParts.ShowWindow(TRUE); m_lblPartsList.ShowWindow(TRUE); m_lblQuant.ShowWindow(TRUE); m_edPartQuantity.ShowWindow(TRUE); m_btnDone.ShowWindow(TRUE); m_btnAdd.SetWindowText("Add new"); m_btnDelete.SetWindowText("Delete"); //////////////////////////m_btnClone.ShowWindow(TRUE); //create the schedule for this item Schedule(); FillPMList(); SwitchMode(); } } void CPM::FillRequiredPartsList() { CString strData,q; CString strIndex; long lData; m_lbParts.Clear(); if(m_bNoRecord) return; q.Format("SELECT parts.id, \"Quantity: \" & [quantity] & \" of \" & [partnumber] & \" - (\" & [description] & \")\" AS name " "FROM pmparts LEFT JOIN parts ON pmparts.partnum = parts.id " "WHERE (((pmparts.pmlink)=%s));",m_strSelectedPM); cbrs->Query(q); if(cbrs->IsEmpty()) return; cbrs->MoveFirst(); do { cbrs->FetchField("name",&strData); cbrs->FetchField("id",&lData); strIndex.Format("%u",lData); m_lbParts.AddRow(strData,strIndex); }while(cbrs->MoveForward()); } void CPM::OnCloseupCbpmlist() { CString temp=m_cbPMList.GetCurrentRowID(); if(temp==m_strSelectedPM) return; m_strSelectedPM=temp; FillFields(); } void CPM::OnBtnaddpart() { CString q,strData; float fData; m_edPartQuantity.GetWindowText(strData); //02/19/2003 Fix crash on empty field if(strData.IsEmpty()) strData="0"; //01/31/2003 convert to a variant bstr _variant_t vtData(strData); //fData=(float)vtData;//cast will cause variant to convert to float using locale specific routine try{//v1.9.4.4 added try / catch mechanism to catch dumb-asses entering text in a numeric field fData=(float)vtData;//cast variant to float (locale friendly) } catch( _com_error &e ) { AfxMessageBox("I could not interpret your entry in the Part quantity field\r\n" "I can't save this field until a valid entry is made.\r\n" "If you want to leave it blank, put a zero in it."); m_edPartQuantity.Undo(); m_edPartQuantity.SetModify(FALSE); m_edPartQuantity.SetFocus(); return; } //v1.9.4.4 moved from top of this function to here to ensure //that validation is done under any circumstances (new record) //this is a guess and might have unintended side effects //but I don't think so and don't have time to screw around tyring //to figure out why this was put here in the first place if(m_bNoRecord) return; q.Format("SELECT pmparts.pmlink FROM pmparts " "WHERE (((pmparts.pmlink)=%s) AND ((pmparts.partnum)=%s));",m_strSelectedPM,m_cbParts.GetCurrentRowID()); cbrs->Query(q); if(!cbrs->IsEmpty())//trying to dupe...tsk tsk { AfxMessageBox("The same part can only be in the list once\r\n" "If you want to change the quantity on a part in the list\r\n" "You will need to delete it first and then re-add\r\n" "with the correct quantity"); return; } //take the value selected and insert it q.Format("INSERT INTO pmparts ( pmlink, partnum, quantity ) " "SELECT %s, %s, %f;",m_strSelectedPM,m_cbParts.GetCurrentRowID(),fData); cbrs->Ex(q); cbrs->Close(); FillRequiredPartsList(); } void CPM::OnBtnremovepart() { CString str,q; if(m_bNoRecord) return; int x = m_lbParts.SelectionCount(); if(x==0) return; //Loop through and delete each item for(int y=0;yEx(q)) break; } FillRequiredPartsList(); } //Allow editing void CPM::OnBtnedit() { m_bEditing=true; //enable fields, hide drop boxes etc. EnableFields(true); m_lblPMList.ShowWindow(FALSE); m_cbPMList.ShowWindow(FALSE); //////////////////////////m_btnClone.ShowWindow(FALSE); m_btnDone.ShowWindow(FALSE); m_btnEdit.ShowWindow(FALSE); m_btnAdd.SetWindowText("SAVE"); m_btnDelete.SetWindowText("CANCEL"); } void CPM::OnBtndelete() { if(m_bAddMode || m_bEditing)//then this is the cancel button { //cancel adding or editing m_bEditing=false; m_bAddMode=false; m_lblPart.ShowWindow(TRUE); m_lblPMList.ShowWindow(TRUE); m_cbPMList.ShowWindow(TRUE); m_lbParts.ShowWindow(TRUE); m_btnRemovePart.ShowWindow(TRUE); m_btnAddPart.ShowWindow(TRUE); m_cbParts.ShowWindow(TRUE); m_lblPartsList.ShowWindow(TRUE); m_lblQuant.ShowWindow(TRUE); m_edPartQuantity.ShowWindow(TRUE); m_btnDone.ShowWindow(TRUE); m_btnAdd.SetWindowText("Add new"); m_btnDelete.SetWindowText("Delete"); /////////////////////m_btnClone.ShowWindow(TRUE); FillPMList(); } else //Delete this record { if(AfxMessageBox( "Caution:\r\n About to delete this preventive maintenance item\r\n" "Continue?",MB_YESNO)==IDNO) return; CString q; //DELETE HEADER RECORD //locate header record ID //delete header record q.Format("DELETE pmhead.*, pmhead.id FROM pmhead WHERE (((pmhead.id)=%s));",m_strSelectedPM); rs->Ex(q); //delete all detail items q.Format("DELETE pmitems.*, pmitems.pmschedlink " "FROM pmitems WHERE (((pmitems.pmschedlink)=%s));",m_strSelectedPM); rs->Ex(q); FillPMList(); } } void CPM::OnOK() { //enter key hack // CDialog::OnOK(); } //empty all occurences of this from the schedule void CPM::ScheduleClear() { CString q; q.Format("DELETE pmitems.*, pmitems.pmschedlink " "FROM pmitems " "WHERE (((pmitems.pmschedlink)=%u));",m_lCurrentRecordID); rs->Ex(q); } //------------------------------------------------- // +Schedule series or one //------------------------------------------------- void CPM::Schedule() { long lRepeat,lTech,lMeter,lTempMeter,lMonths=0,lDays,lWeeks,lData,lClient; CString strData,strHold,strAutoWO,q,strType,strLink; //Added Jan 13 to start date calc loop at -1 if age based so first item is scheduled on date selected //instead of date selected + service interval as was doing previously int yy; bool bDone=false; if(m_bClientMode) strType="True"; else strType="False"; COleDateTime dtData,dtTemp; int nSeries,x,nDOW,d,nTemp; CSimpleDate sdTemp; //remove previous items if any ScheduleClear(); //Get the technician lTech=atol(m_cbTech.GetCurrentRowID()); //Get the DayOfWeek nDOW=m_cbDayOfWeek.GetCurSel(); //Get the hold factor if(m_ckHold.GetCheck()==TRUE) strHold="True"; else strHold="False"; //Get the AutoWO Factor strAutoWO=m_bAutoWO ? "True" : "False"; //Set the number of series to schedule if(m_bAutoRepeat) { nSeries=m_nSeries; } else nSeries=1; //get the repeat value switch (m_nCurrentMode) { case 0://time based m_edTimeRepeatEveryWeeks.GetWindowText(strData); lWeeks=atol(strData); m_edTimeRepeatEveryDays.GetWindowText(strData); lDays=atol(strData); m_edTimeRepeatEveryMonths.GetWindowText(strData); lRepeat=atol(strData); lMeter=0; m_dtTimeNextServiceDate.GetTime(dtData); break; case 1://meter based m_edMeterRepeat.GetWindowText(strData); lRepeat=atol(strData); m_edMeterFirstService.GetWindowText(strData); lMeter=atol(strData); //default date dtData.SetDate(1968,3,12); break; default://age based m_edAgeRepeat.GetWindowText(strData); lRepeat=atol(strData); //Added Jan 13 2003 blatant bug... lDays=0;lWeeks=0; lMeter=0; m_dtAgeFirstServiceDate.GetTime(dtData); break; } //Set the link, will get overwritten if it's a model strLink=m_strCriteria; //model loop starts here if(m_bModel) { /*q.Format("SELECT units.id, units.client, units.purchasedate " "FROM units RIGHT JOIN unitmodels ON units.model = unitmodels.id " "WHERE (((unitmodels.id)=%s));", m_strCriteria);*/ //changed from above 02/21/2003 was including //even units that were not set to include in model's PM (pmreport) q.Format("SELECT units.id, units.client, units.purchasedate FROM " "units RIGHT JOIN unitmodels ON units.model = unitmodels.id " "WHERE (((unitmodels.id)=%s) AND ((units.pmreport)=True)); ",m_strCriteria); cbrs->Query(q); if(cbrs->IsEmpty()) return;//nothing right now to schedule cbrs->FetchField("id",&lData); if(m_nCurrentMode==2)//age based, when a model must use looked up purchase date cbrs->FetchField("purchasedate",&dtData); cbrs->FetchField("client",&lClient); strLink.Format("%u",lData); } else//not a model, either a unit or a client { if(m_bClientMode)//it's a client? lClient=atol(m_strCriteria); else {//it's a single unit q.Format("SELECT units.client FROM units " "WHERE (((units.id)=%s));",m_strCriteria); cbrs->Query(q); if(cbrs->IsEmpty()) lClient=0; else cbrs->FetchField("client",&lClient); } } //this is a hack to force the first pm item to be //age advanced if it's an age based item since //the date would be purchase date and needs to be put ahead. //while in other modes it's whatever the user picks as the first //service date if(m_nCurrentMode==2) nSeries+=1; //================================================================== //do the scheduling while(!bDone) { lMonths=0; lTempMeter=lMeter; if(m_nCurrentMode!=2)//if it's age based, need to add on the age first { //There's always at least one, schedule it now and do others later //this avoids the overhead of calculating future dates for single //only items. q.Format("INSERT INTO pmitems ( pmschedlink, schedate, schedmeter, autowo, hold, schedtech, link, isclient, clientlink) " "SELECT %u, #%s#, %u, %s, %s, %u, %s, %s, %u;", m_lCurrentRecordID,dtData.Format(_T("%m/%d/%Y")),lTempMeter,strAutoWO,strHold,lTech, strLink,strType, lClient); //DATEFIX: date fixed above to conform to int. settings. Nov 3 2000 // m_pApp->ShowStuff(q); //EXECUTE if(!rs->Ex(q)) return; rs->Close(); } //prepare a simpledate class object for multi series CSimpleDate sdOriginal(dtData.GetMonth(),dtData.GetDay(),dtData.GetYear()); /* #ifdef _DEBUG m_pApp->ShowStuff(sdOriginal.GetFullDateString()); #endif */ //Loop X series occurences if repeating or once if not //if date based, add dates then go up day by day until hit //selected weekday //If meter based, just add "every meter" to item and create records //Added Jan 13 to start date calc loop at -1 if age based so first item is scheduled on date selected //instead of date selected + service interval as was doing previously if(m_nCurrentMode==2) yy=-1; else yy=0; for(x=yy;xShowStuff(q); //EXECUTE if(!rs->Ex(q)) return; rs->Close(); } if(m_bModel) { bDone=!cbrs->MoveForward(); if(!bDone) { if(m_nCurrentMode==2)//age based, when a model must use looked up purchase date cbrs->FetchField("purchasedate",&dtData); cbrs->FetchField("client",&lClient); cbrs->FetchField("id",&lData); strLink.Format("%u",lData); } } else bDone=true; }//while not done loop } void CPM::OnKillfocusEdageyrs() { Aging(); } void CPM::OnKillfocusEdagemonths() { Aging(); } void CPM::Aging() { CString strData; int nYears,nMonths,nDOW; COleDateTime dtTemp; m_edAgeYears.GetWindowText(strData); if(strData.IsEmpty()) strData="0"; nYears=atoi(strData); m_edAgeMonths.GetWindowText(strData); if(strData.IsEmpty()) strData="0"; nMonths=atoi(strData); //Get the DayOfWeek nDOW=m_cbDayOfWeek.GetCurSel(); //ADD years and months to the purchase date and update //the date of service control CSimpleDate sdTemp(m_dtUnitPurchasedDate.GetMonth(),m_dtUnitPurchasedDate.GetDay(),m_dtUnitPurchasedDate.GetYear()); sdTemp.AddYears(nYears); sdTemp.AddMonths(nMonths); //Advance to day of week selected. //temporary version of nDOW to matchup sunday as first day of week //make our desired date numeric base match the one returned by the getdayofweek int nTemp,d; if(nDOW==7) //sunday=0 in CSimpleDate land nTemp=0; else nTemp=nDOW; d=sdTemp.GetDayOfWeek(); if(nDOW==0)//any weekday { if(d==0)//sunday sdTemp.AddDays(1);//move to monday if(d==6)//saturday sdTemp.SubtractDays(1);//move to Friday } else//specific day { while(d!=nTemp) { sdTemp.AddDays(1); d=sdTemp.GetDayOfWeek(); } } dtTemp.SetDate(sdTemp.GetYear(),sdTemp.GetMonth(),sdTemp.GetDay()); m_dtAgeFirstServiceDate.SetTime(dtTemp); } //read/write meter count to unit table void CPM::UpdateMeterCount(bool bWriting) { if(m_bClientMode) return; long lData; CString q,strData; q.Format("SELECT units.lastmeter FROM units " "WHERE (((units.id)=%s));",m_strCriteria); cbrs->Query(q); //m_pApp->ShowStuff(q); if(cbrs->IsEmpty()) return; if(bWriting) { m_edMeterLastReading.GetWindowText(strData); if(strData.IsEmpty()) return; //was it modified at all? if(m_edMeterLastReading.GetModify()==FALSE) return; if(AfxMessageBox("Save meter count change to unit record?",MB_YESNO)==IDYES) { lData=atol(strData); cbrs->UpdateField("lastmeter",&lData); cbrs->SaveRecord(); m_edMeterLastReading.SetModify(FALSE); } else { m_edMeterLastReading.Undo(); m_edMeterLastReading.SetModify(FALSE); } return; } else { cbrs->FetchField("lastmeter",&lData); strData.Format("%u",lData); m_edMeterLastReading.SetWindowText(strData); m_edMeterLastReading.SetModify(FALSE); return; } } void CPM::OnKillfocusEdmeterlastreading() { if(!m_bAddMode) UpdateMeterCount(true); } void CPM::FillProjectList() { CString strData; long lData; CString strIndex; //========================================== //PROJECTS m_cbProjects.Clear(); strData="< None >"; strIndex="0"; m_cbProjects.AddRow(strData,strIndex); cbrs->Query("SELECT projects.* FROM projects " "WHERE (((projects.active)=True)) " "ORDER BY projects.name;"); if(!cbrs->IsEmpty()) { do { cbrs->FetchField("name",&strData); cbrs->FetchField("id",&lData); strIndex.Format("%u",lData); m_cbProjects.AddRow(strData,strIndex); }while(cbrs->MoveForward()); } if(m_strSelProject.IsEmpty()) m_cbProjects.Select(0); else m_cbProjects.Select(m_strSelProject); //============================================ } void CPM::FillTypeList() { CString strData; long lData; CString strIndex; //============================================ //CATEGORIES m_cbCategories.Clear(); //first enter default item strData="< None >"; strIndex="0"; m_cbCategories.AddRow(strData,strIndex); cbrs->Query("SELECT wotypes.* FROM wotypes ORDER BY wotypes.category;"); if(!cbrs->IsEmpty()) { do { cbrs->FetchField("category",&strData); cbrs->FetchField("id",&lData); strIndex.Format("%u",lData); m_cbCategories.AddRow(strData,strIndex); }while(cbrs->MoveForward()); } if(m_strSelCategory.IsEmpty()) m_cbCategories.Select(0); else m_cbCategories.Select(m_strSelCategory); //========================================== } void CPM::OnCkquick() { m_bQuick=m_ckQuick.GetCheck() ? true:false; SwitchMode(); } void CPM::OnLblpart() { CPartsDlg d; d.DoModal(); FillPartsList(); } void CPM::OnLblproject() { CProjectsDlg d; d.DoModal(); FillProjectList(); } void CPM::OnLbltype() { CWOTypesDlg d; d.DoModal(); FillTypeList(); } void CPM::Security() { m_bReadOnlySecurity=false; int x=m_pApp->Allowed(RPM,true); if(x==0)//no access allowed { m_pApp->SecurityWarning(); CDialog::OnCancel(); } if(x==2)//read only { m_bReadOnlySecurity=true; m_btnAdd.EnableWindow(FALSE); m_btnDelete.EnableWindow(FALSE); m_btnEdit.EnableWindow(FALSE); m_btnClone.EnableWindow(FALSE); /* CMenu* pMenu=this->GetMenu(); pMenu->EnableMenuItem(1, MF_BYPOSITION | MF_DISABLED | MF_GRAYED); */ } }