// WOTABParts.cpp : implementation file // #include "stdafx.h" #include "sp.h" #include "WOTABParts.h" #include "PartsDlg.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 #include ///////////////////////////////////////////////////////////////////////////// // CWOTABParts dialog CWOTABParts::CWOTABParts(CWnd* pParent /*=NULL*/) : CDialog(CWOTABParts::IDD, pParent) , m_strSelectedItem(_T("")) { //{{AFX_DATA_INIT(CWOTABParts) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT m_pApp = (CSpApp*)AfxGetApp(); /* rs = new GZRset("Error: Standard workorder (parts tab)"); rs->SetConnect(m_pApp->strConnectString); */ //Initialize recordset pointer rs=m_pApp->rsPool->GetRS("CWOTABParts"); cfm = new CgzCurrencyFormatter; m_bPromptDelete=true; bModified=false; } CWOTABParts::~CWOTABParts() { m_pApp->rsPool->ReleaseRS(&rs->m_nID); delete cfm; } void CWOTABParts::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CWOTABParts) DDX_Control(pDX, IDC_EDSN, m_edSN); DDX_Control(pDX, IDC_LBPARTS, m_lbParts); DDX_Control(pDX, IDC_LBLPART, m_lblPart); DDX_Control(pDX, IDC_LBLMISC, m_lblMisc); DDX_Control(pDX, IDC_EDQUANTITY, m_edQuantity); DDX_Control(pDX, IDC_EDPRICE, m_edPrice); DDX_Control(pDX, IDC_EDMISC, m_edMisc); DDX_Control(pDX, IDC_CBPARTS, m_cbParts); DDX_Control(pDX, IDC_BTNREMOVE, m_btnRemove); DDX_Control(pDX, IDC_BTNADD, m_btnAdd); //}}AFX_DATA_MAP DDX_Control(pDX, IDC_BTNUPDATE, m_btnUpdatePart); DDX_Control(pDX, IDC_EDMISCCOST, m_edMiscCost); DDX_Control(pDX, IDC_LBL_MISC_COST, m_lblMiscCost); } BEGIN_MESSAGE_MAP(CWOTABParts, CDialog) //{{AFX_MSG_MAP(CWOTABParts) ON_CBN_CLOSEUP(IDC_CBPARTS, OnCloseupCbparts) ON_BN_CLICKED(IDC_BTNADD, OnBtnadd) ON_LBN_SELCHANGE(IDC_LBPARTS, OnSelchangeLbparts) ON_BN_CLICKED(IDC_BTNREMOVE, OnBtnremove) ON_BN_CLICKED(IDC_LBLPART, OnLblpart) //}}AFX_MSG_MAP ON_BN_CLICKED(IDC_BTNUPDATE, OnBnClickedBtnupdate) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CWOTABParts message handlers BOOL CWOTABParts::OnInitDialog() { CDialog::OnInitDialog(); //"Hyperlink-o-size" labels 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_edSN.SetLimitText(255); m_edMisc.SetLimitText(50); FillPartsCB(); FillPartsLB(); Security(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } //********************************************** void CWOTABParts::OnCloseupCbparts() { CString str,q,strData; COleCurrency crData; //Set variable that indicates users last //selection within the list box display //to empty since this function will //rebuild the list anyway m_strSelectedItem.Empty(); m_btnUpdatePart.ShowWindow(FALSE); str=m_cbParts.GetCurrentRowID(); if(str=="0") { m_edMisc.ShowWindow(TRUE); m_lblMisc.ShowWindow(TRUE); m_edMiscCost.ShowWindow(TRUE); m_lblMiscCost.ShowWindow(TRUE); } else { m_edMisc.ShowWindow(FALSE); m_lblMisc.ShowWindow(FALSE); m_edMisc.SetWindowText(""); m_edMiscCost.SetWindowText(""); m_edMiscCost.ShowWindow(FALSE); m_lblMiscCost.ShowWindow(FALSE); } q.Format("SELECT parts.retail, parts.avgcost " "FROM parts WHERE (((parts.id)=%s));",m_cbParts.GetCurrentRowID()); rs->QueryReadOnly(q); if(!rs->IsEmpty()) { rs->FetchField("retail",&crData); m_edPrice.SetWindowText(cfm->Format(crData)); m_edQuantity.SetWindowText("1"); rs->FetchField("avgcost",&crData); m_edMiscCost.SetWindowText(cfm->Format(crData)); } else { m_edPrice.SetWindowText(""); m_edQuantity.SetWindowText("0"); m_edMiscCost.SetWindowText(""); } } //******************************* //ADD PART TO LIST void CWOTABParts::OnBtnadd() { CString quant,price,misc,partnum,partdesc,q,strSN,cost; COleCurrency crData; float fData; //if just added, then nothing is selected m_strSelectedItem.Empty(); m_btnUpdatePart.ShowWindow(FALSE); partnum=m_cbParts.GetCurrentRowID(); m_cbParts.GetWindowText(partdesc); partdesc.Replace("\"","''"); m_edMisc.GetWindowText(misc); misc.Replace("\"","''"); //misc cost doubles as regular part cost //user just doesn't see it is all m_edMiscCost.GetWindowText(cost); if(cost.IsEmpty()) cost="0"; ASSERT(!cost.IsEmpty()); m_edPrice.GetWindowText(price); m_edQuantity.GetWindowText(quant); m_edSN.GetWindowText(strSN); strSN.Replace("\"","''"); if(price.IsEmpty() || quant.IsEmpty()) { AfxMessageBox("A price and quantity are required to proceed"); return; } if(crData.ParseCurrency(price)!=TRUE) { AfxMessageBox("Could not interpret your entry in the price field as a currency amount\r\n"); return ; } //set part cost to zero if undeterminable if(crData.ParseCurrency(cost)!=TRUE) { cost="0"; AfxMessageBox("Could not interpret your entry in the Cost field as a currency amount\r\n"); return; } //01/31/2003 convert to a variant bstr _variant_t vtData(quant); //fData=(float)vtData;//cast variant to float (locale friendly) //v1.9.4.4 added try / catch mechanism to catch dumb-asses entering text in a numeric field try { fData=(float)vtData;//cast variant to float (locale friendly) } catch( _com_error &e ) { AfxMessageBox("Could not interpret your entry in the Part quantity field as a valid number\r\n"); return; } if(misc.IsEmpty()) misc="Null"; else misc="\"" + misc + "\""; if(strSN.IsEmpty()) strSN="Null"; else strSN="\"" + strSN + "\""; q.Format("INSERT INTO woparts ( link, partnum, misc, quantity, price, usedby, sn, cost ) " "SELECT %s, %s, %s, %g, '%s', %u, %s, '%s';", *m_pstrProblemID,partnum,misc,fData/*quant*/,price,m_pApp->m_lusrID,strSN,cost); rs->Ex(q); rs->Close(); FillPartsLB(); bModified=true; } //****************************** void CWOTABParts::FillPartsLB() { CString q,strData,strIndex,str,strSN; long lData; float fData; COleCurrency crData; m_lbParts.Clear(); q.Format("SELECT woparts.id, woparts.sn, woparts.partnum, parts.partnumber, woparts.quantity, woparts.price, " "IIf([partnum]=0,[misc],[description]) AS name " "FROM woparts LEFT JOIN parts ON woparts.partnum = parts.id " "WHERE (((woparts.link)=%s));",*m_pstrProblemID); rs->QueryReadOnly(q); if(!rs->IsEmpty()) { rs->MoveFirst(); do {//5 at 34.95 each of 26006 - labour john and joyce rs->FetchField("quantity",&fData); rs->FetchField("name",&strData); rs->FetchField("price",&crData); rs->FetchField("partnumber",&strIndex); rs->FetchField("sn",&strSN); if(!strSN.IsEmpty()) strSN="(sn:"+strSN+")"; str.Format("%s @ %s each of %s - %s %s",FtoA(fData),cfm->Format(crData),strIndex,strData,strSN); rs->FetchField("id",&lData); strIndex.Format("%u",lData); m_lbParts.AddRow(str,strIndex); }while(rs->MoveForward()); } } //change appearance of delete button //in future maybe allow editing of //part in list...maybe. //Oct 7 2002: THE FUTURE IS NOW (see above comment) //changes to allow editing in place of parts //why this wasn't made editable is a mystery, //but it's pissed off a lot of people. //won't make that mistake again void CWOTABParts::OnSelchangeLbparts() { CString strID,q,strData; long lData; float fData; COleCurrency crData; //reset last selected item m_strSelectedItem.Empty(); m_btnUpdatePart.ShowWindow(FALSE); //have to force a kill focus //so that the list gets filled m_lbParts.RebuildIndex(); strID=m_lbParts.GetSelectedItem(0); if(strID=="")//no selection { m_btnRemove.ShowWindow(FALSE); m_btnUpdatePart.ShowWindow(TRUE); return; } if(!m_bReadOnly) { //Show "remove" button m_btnRemove.ShowWindow(TRUE); //show update button m_btnUpdatePart.ShowWindow(TRUE); } //Fill fields with previous values q.Format("SELECT woparts.partnum FROM woparts WHERE (((woparts.id)=%s));",strID); if(!rs->QueryReadOnly(q)) return; if(!rs->FetchField("partnum",&lData)) return; m_cbParts.Select(lData); if(lData==0) { m_edMisc.ShowWindow(TRUE); m_lblMisc.ShowWindow(TRUE); m_edMiscCost.ShowWindow(TRUE); m_lblMiscCost.ShowWindow(TRUE); } else { m_edMisc.ShowWindow(FALSE); m_lblMisc.ShowWindow(FALSE); m_edMisc.SetWindowText(""); m_edMiscCost.ShowWindow(FALSE); m_lblMiscCost.ShowWindow(FALSE); } q.Format("SELECT woparts.* FROM woparts WHERE (((woparts.id)=%s));",strID); if(!rs->QueryReadOnly(q)) return; rs->FetchField("misc",&strData); m_edMisc.SetWindowText(strData); rs->FetchField("quantity",&fData); //LOCALEFIX //01/31/2003 localization fix for floats //convert float to localized string m_edQuantity.SetWindowText(FtoA(fData)); rs->FetchField("price",&crData); m_edPrice.SetWindowText(cfm->Format(crData)); rs->FetchField("cost",&crData); m_edMiscCost.SetWindowText(cfm->Format(crData)); rs->FetchField("sn",&strData); m_edSN.SetWindowText(strData); //persist the selected item so update knows what to work with m_strSelectedItem=strID; } //DELETE void CWOTABParts::OnBtnremove() { CString strID,q; //have to force a kill focus //so that the list gets filled m_lbParts.RebuildIndex(); strID=m_lbParts.GetSelectedItem(0); if(strID=="")//no selection return; if(m_bPromptDelete) { if(AfxMessageBox("Delete selected part - are you sure?",MB_YESNO)==IDNO) return; } //if deleting then nothing is selected m_strSelectedItem.Empty(); m_btnUpdatePart.ShowWindow(FALSE); m_bPromptDelete=false; q.Format("DELETE woparts.*, woparts.id FROM woparts " "WHERE (((woparts.id)=%s));",strID); rs->Ex(q); rs->Close(); FillPartsLB(); bModified=true; } void CWOTABParts::OnLblpart() { CPartsDlg d; d.DoModal(); FillPartsCB(); } //************************************* void CWOTABParts::FillPartsCB() { //FILL PART LIST CString strData; CString strIndex; long lData; m_cbParts.Clear(); m_cbParts.AddRow(" ","0"); rs->QueryReadOnly("SELECT parts.id, [partnumber] & \" - \" " "& [description] AS name FROM parts " "WHERE (((parts.active)=True)) ORDER BY parts.partnumber;"); if(!rs->IsEmpty()) { rs->MoveFirst(); do { rs->FetchField("name",&strData); rs->FetchField("id",&lData); strIndex.Format("%u",lData); m_cbParts.AddRow(strData,strIndex); }while(rs->MoveForward()); } m_cbParts.Select("0"); } void CWOTABParts::Security() { m_bReadOnly=false; int x=m_pApp->Allowed(RWORKORDER,false); if(x==0)//no access allowed { m_pApp->SecurityWarning(); CDialog::OnCancel(); } //modified 8/28/00 to allow dispatch by non-tech //if(x==2 || (!m_pApp->m_bTech))//read only if(x==2)//read only { m_bReadOnly=true; m_btnAdd.ShowWindow(FALSE); m_btnRemove.ShowWindow(FALSE); m_btnUpdatePart.ShowWindow(FALSE); m_cbParts.EnableWindow(FALSE); m_edMisc.SetReadOnly(TRUE); //v1.9.4.2 m_edSN.SetReadOnly(TRUE); m_edPrice.SetReadOnly(TRUE); m_edMiscCost.SetReadOnly(TRUE); m_edQuantity.SetReadOnly(TRUE); m_lblMisc.EnableWindow(FALSE); m_lblPart.EnableWindow(FALSE); m_lbParts.EnableWindow(FALSE); } } void CWOTABParts::OnOK() {/*enter key avoidance hack*/} void CWOTABParts::OnBnClickedBtnupdate() { CString quant,price,misc,partnum,partdesc,q,strSN,cost; COleCurrency crData; if(m_strSelectedItem.IsEmpty() || m_strSelectedItem=="0") { AfxMessageBox("There is no selected item to update"); return; } partnum=m_cbParts.GetCurrentRowID(); m_cbParts.GetWindowText(partdesc); partdesc.Replace("\"","''"); m_edMisc.GetWindowText(misc); misc.Replace("\"","''"); m_edPrice.GetWindowText(price); m_edQuantity.GetWindowText(quant); m_edMiscCost.GetWindowText(cost); m_edSN.GetWindowText(strSN); strSN.Replace("\"","''"); if(price.IsEmpty() || quant.IsEmpty()) { AfxMessageBox("A price and quantity are required to proceed"); return; } if(crData.ParseCurrency(price)!=TRUE) { AfxMessageBox("Could not interpret your entry in the price field as a currency amount\r\n"); return ; } if(crData.ParseCurrency(cost)!=TRUE) { cost="0"; } if(misc.IsEmpty()) misc="Null"; else misc="\"" + misc + "\""; if(strSN.IsEmpty()) strSN="Null"; else strSN="\"" + strSN + "\""; q.Format( "UPDATE woparts SET woparts.partnum = %s, woparts.misc " "= %s, woparts.quantity = %s, woparts.price = " "'%s', woparts.sn = %s, woparts.usedby = %u, woparts.cost='%s' WHERE " "(((woparts.id)=%s));",partnum,misc,quant,price,strSN,m_pApp->m_lusrID,cost,m_strSelectedItem); rs->Ex(q); rs->Close(); FillPartsLB(); bModified=true; }