Files

578 lines
13 KiB
C++

// 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 <stdlib.h>
#include <crtdbg.h>
/////////////////////////////////////////////////////////////////////////////
// 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(" <Untracked miscellaneous part>","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;
}