578 lines
13 KiB
C++
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;
|
|
|
|
|
|
|
|
}
|