1232 lines
30 KiB
C++
1232 lines
30 KiB
C++
// UsersDlg.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "sp.h"
|
|
#include "UsersDlg.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define LICENSE_SINGLESITE 0x0001
|
|
#define LICENSE_MULTISITE 0x0002
|
|
#define LICENSE_OTHERSITE1 0x0004
|
|
#define LICENSE_OTHERSITE2 0x0008
|
|
|
|
#define LICENSE_STANDARDEVAL 0x0010//010000
|
|
#define LICENSE_REGISTERED 0x0020//100000
|
|
#define LICENSE_TIMELIMITEDEVAL 0x0040
|
|
#define LICENSE_METEREDEVAL 0x0080
|
|
|
|
#define LICENSE_FEATUREH 0x0100
|
|
#define LICENSE_FEATUREI 0x0200
|
|
#define LICENSE_FEATUREJ 0x0400
|
|
#define LICENSE_FEATUREK 0x0800
|
|
|
|
#define LICENSE_FEATUREL 0x1000
|
|
#define LICENSE_FEATUREM 0x2000
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CUsersDlg dialog
|
|
|
|
|
|
CUsersDlg::CUsersDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CUsersDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CUsersDlg)
|
|
//}}AFX_DATA_INIT
|
|
k=new GZK;
|
|
m_pApp= (CSpApp*)AfxGetApp();
|
|
/*
|
|
rs=new GZRset("User setup dialog error:");
|
|
rs->SetConnect(m_pApp->strConnectString);
|
|
|
|
xclusivers=new GZRset("Error: Other users are still in the system!\r\n");
|
|
xclusivers->SetConnect(m_pApp->strConnectStringExclusive);
|
|
|
|
|
|
tcrs=new GZRset("User setup aux. rs error:");
|
|
tcrs->SetConnect(m_pApp->strConnectString);
|
|
*/
|
|
//Initialize recordset pointers
|
|
|
|
rs=m_pApp->rsPool->GetRS("CUsersDlg RS");
|
|
tcrs=m_pApp->rsPool->GetRS("CUsersDlg (TCRS)");
|
|
xclusivers=m_pApp->rsPool->GetRS("CUsersDlg - Other users are still in the system!\r\n");
|
|
xclusivers->m_bExclusiveConnection=true;
|
|
|
|
m_strSelectedUser="";
|
|
//set the pointer to return the selected user
|
|
//string to null so if it doesn't get set
|
|
//by the caller we know not to set it.
|
|
m_pstrReturnString=NULL;
|
|
|
|
//ensure no accidental back door account calling
|
|
//see spview for back door info
|
|
m_bIsBackDoor=false;
|
|
|
|
|
|
|
|
//registered?
|
|
if(m_pApp->m_uiFeatures&LICENSE_REGISTERED)
|
|
m_bEval=false;
|
|
else
|
|
m_bEval=true;
|
|
|
|
}
|
|
|
|
|
|
CUsersDlg::~CUsersDlg()
|
|
{
|
|
delete k;
|
|
|
|
|
|
m_pApp->rsPool->ReleaseRS(&rs->m_nID);
|
|
m_pApp->rsPool->ReleaseRS(&tcrs->m_nID);
|
|
m_pApp->rsPool->ReleaseRS(&xclusivers->m_nID);
|
|
}
|
|
|
|
|
|
void CUsersDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CUsersDlg)
|
|
DDX_Control(pDX, IDC_CKEMAILNOTIFY, m_ckEmailNotify);
|
|
DDX_Control(pDX, IDC_TECHEMAIL, m_edEmail);
|
|
DDX_Control(pDX, IDC_CBZONE, m_cbZone);
|
|
DDX_Control(pDX, IDC_LBLZONE, m_lblZone);
|
|
DDX_Control(pDX, IDC_LBLEVAL, m_lblEval);
|
|
DDX_Control(pDX, IDC_MSG, m_lblMSG);
|
|
DDX_Control(pDX, IDC_USERLIST_LABEL, m_lblUserList);
|
|
DDX_Control(pDX, IDOK, m_btnDone);
|
|
DDX_Control(pDX, IDC_USERLIST, m_cbUsers);
|
|
DDX_Control(pDX, IDC_TECH, m_ckTech);
|
|
DDX_Control(pDX, IDC_LAST, m_edLast);
|
|
DDX_Control(pDX, IDC_INITIALS, m_edInitials);
|
|
DDX_Control(pDX, IDC_GROUP, m_cbGroup);
|
|
DDX_Control(pDX, IDC_FIRST, m_edFirst);
|
|
DDX_Control(pDX, IDC_BTNSAVE, m_btnSave);
|
|
DDX_Control(pDX, IDC_BTNPW, m_btnPW);
|
|
DDX_Control(pDX, IDC_BTNDELETE, m_btnDelete);
|
|
DDX_Control(pDX, IDC_ACTIVE, m_ckActive);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CUsersDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CUsersDlg)
|
|
ON_BN_CLICKED(IDC_ACTIVE, OnActive)
|
|
ON_BN_CLICKED(IDC_BTNDELETE, OnBtndelete)
|
|
ON_BN_CLICKED(IDC_BTNPW, OnBtnpw)
|
|
ON_BN_CLICKED(IDC_BTNSAVE, OnBtnsave)
|
|
ON_EN_KILLFOCUS(IDC_FIRST, OnKillfocusFirst)
|
|
ON_CBN_CLOSEUP(IDC_GROUP, OnCloseupGroup)
|
|
ON_EN_KILLFOCUS(IDC_INITIALS, OnKillfocusInitials)
|
|
ON_EN_KILLFOCUS(IDC_LAST, OnKillfocusLast)
|
|
ON_BN_CLICKED(IDC_TECH, OnTech)
|
|
ON_CBN_CLOSEUP(IDC_USERLIST, OnCloseupUserlist)
|
|
ON_CBN_CLOSEUP(IDC_CBZONE, OnCloseupCbzone)
|
|
ON_EN_KILLFOCUS(IDC_TECHEMAIL, OnKillfocusTechemail)
|
|
ON_BN_CLICKED(IDC_CKEMAILNOTIFY, OnCkemailnotify)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CUsersDlg message handlers
|
|
|
|
void CUsersDlg::FillFields()
|
|
{
|
|
//user has made a selection, update the visible list
|
|
CString q;
|
|
CString strData;
|
|
CString strHashOfData;
|
|
CString strHashFromDataBase;
|
|
CString strHashOfActual;//group ID number +"\" + id + first + last + tech + active
|
|
int x;
|
|
bool bData;
|
|
long lData;
|
|
bool bIsManager=false;
|
|
strData=m_cbUsers.GetCurrentRowID();
|
|
if(strData=="1")
|
|
bIsManager=true;
|
|
strHashOfActual="\\"+strData;
|
|
q.Format("SELECT users.* FROM users WHERE (((users.id)=%s));",strData);
|
|
rs->Query(q);
|
|
if(!rs->IsEmpty())
|
|
{
|
|
rs->FetchField("defzone",&lData);
|
|
m_cbZone.Select(lData);
|
|
|
|
rs->FetchField("first",&strData);
|
|
m_edFirst.SetWindowText(strData);
|
|
strHashOfActual=strHashOfActual+strData;
|
|
|
|
rs->FetchField("last",&strData);
|
|
m_edLast.SetWindowText(strData);
|
|
strHashOfActual=strHashOfActual+strData;
|
|
|
|
rs->FetchField("initials",&strData);
|
|
m_edInitials.SetWindowText(strData);
|
|
|
|
|
|
//added sept 6th 2001 for 1720 email notification
|
|
rs->FetchField("email",&strData);
|
|
m_edEmail.SetWindowText(strData);
|
|
|
|
rs->FetchField("emailnotify",&bData);
|
|
m_ckEmailNotify.SetCheck(bData ? TRUE:FALSE);
|
|
//----------------------------------------
|
|
|
|
|
|
|
|
rs->FetchField("login",&strData);
|
|
m_strLoginName=strData;
|
|
|
|
rs->FetchField("pass",&strData);
|
|
m_strPW=strData;
|
|
|
|
rs->FetchField("tech",&bData);
|
|
m_ckTech.SetCheck(TRUE);
|
|
strData="TRUE";
|
|
|
|
if(!bIsManager)
|
|
{
|
|
m_cbZone.EnableWindow(TRUE);
|
|
m_edEmail.EnableWindow(TRUE);
|
|
m_ckEmailNotify.EnableWindow(TRUE);
|
|
}
|
|
|
|
if(bData==false)
|
|
{
|
|
m_ckTech.SetCheck(FALSE);
|
|
strData="FALSE";
|
|
|
|
m_cbZone.EnableWindow(FALSE);
|
|
m_edEmail.EnableWindow(FALSE);
|
|
m_ckEmailNotify.EnableWindow(FALSE);
|
|
|
|
}
|
|
|
|
strHashOfActual=strHashOfActual+strData;
|
|
|
|
rs->FetchField("active",&bData);
|
|
m_ckActive.SetCheck(TRUE);
|
|
strData="TRUE";
|
|
if(bData==false)
|
|
{
|
|
m_ckActive.SetCheck(FALSE);
|
|
strData="FALSE";
|
|
}
|
|
strHashOfActual=strHashOfActual+strData;
|
|
|
|
|
|
|
|
rs->FetchField("a",&strData);
|
|
rs->FetchField("b",&strHashFromDataBase);//hash of a
|
|
strHashOfData=strData;
|
|
k->GZDecrypt(&strHashOfData,false);
|
|
k->GZHash(&strHashOfData);
|
|
|
|
k->GZDecrypt(&strData,false);
|
|
|
|
x=strData.Find('\\');
|
|
CString strID=strData.Left(x);
|
|
|
|
strHashOfActual=strID+strHashOfActual;
|
|
k->GZHash(&strHashOfActual);
|
|
|
|
//check hash in table against group data in table
|
|
//check group data in table against fields in table that
|
|
//make up group data.
|
|
if(strHashFromDataBase.Compare(strHashOfData)!=0 || strHashOfData.Compare(strHashOfActual)!=0)
|
|
{
|
|
AfxMessageBox("Security violation!"
|
|
"\r\nThis user record has been modified outside of this program."
|
|
"\r\n\r\nThis user was automatically locked out to protect your security"
|
|
"\r\nYou will need to make a change to this record so that it will be cleared"
|
|
"\r\n(e.g. click on Active user checkbox twice to force an update)"
|
|
"\r\nOnce the record has been updated the user will be able to log in again."
|
|
"\r\n\r\nIf users attempt to modify records from outside this program your"
|
|
"\r\ndata could become corrupted and unrepairable other than restoring from a backup."
|
|
"\r\n\r\nIf someone was attempting to enable more tehnicians than"
|
|
"\r\nyou are registered for, this is a violation of your license agreement"
|
|
"\r\nand puts the integrity of your data at risk!");
|
|
|
|
}
|
|
else
|
|
{
|
|
//select group in group combo.
|
|
m_cbGroup.Select(strID);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//save current selection so that updates and changes
|
|
//will still show what was last selected
|
|
// m_strSelectedGroup=m_cbGroup.GetCurrentRowID();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//********************************************
|
|
bool CUsersDlg::SaveFields(bool UpdateOnly)
|
|
{//true only updating, false adding new record
|
|
CString strData,a,b,strID,strFirst,strLast,q,strHashed;
|
|
bool bData;
|
|
long c,lZone;
|
|
COleDateTime dtData;
|
|
|
|
//don't try to save record if its during an add
|
|
|
|
if(m_bAddMode==true && UpdateOnly==true)
|
|
return false;
|
|
//eval can't save except for email and notify
|
|
if(m_bEval)
|
|
{
|
|
//here separately to give people chance to mod email
|
|
//address for testing but nothing else
|
|
//added sept 6th 2001 for 1720 email notification
|
|
m_edEmail.GetWindowText(strData);
|
|
rs->UpdateField("email",&strData);
|
|
|
|
bData=m_ckEmailNotify.GetCheck() ? true:false;
|
|
rs->UpdateField("emailnotify",&bData);
|
|
rs->SaveRecord();
|
|
//----------------------------------------
|
|
return false;
|
|
}
|
|
|
|
//validate first
|
|
|
|
|
|
m_edFirst.GetWindowText(strFirst);
|
|
if(strFirst.IsEmpty())
|
|
{ AfxMessageBox("First name is mandatory"); return false;}
|
|
|
|
m_edLast.GetWindowText(strLast);
|
|
if(strLast.IsEmpty())
|
|
{ AfxMessageBox("Last name is mandatory"); return false;}
|
|
|
|
if(!UpdateOnly)
|
|
{
|
|
q.Format("SELECT users.first, users.last FROM users WHERE (((users.first)=\"%s\") AND ((users.last)=\"%s\"));",strFirst,strLast);
|
|
rs->Query(q);
|
|
if(!rs->IsEmpty())
|
|
{
|
|
AfxMessageBox("That name is already in use");
|
|
return false;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
m_edInitials.GetWindowText(strData);
|
|
if(strData.IsEmpty())
|
|
{
|
|
AfxMessageBox("Initials are mandatory"
|
|
"\r\nThey are used to uniquely identify workorders"
|
|
"\r\nand other records.");
|
|
return false;
|
|
}
|
|
|
|
if(!UpdateOnly)
|
|
{
|
|
q.Format("SELECT users.initials FROM users WHERE (((users.initials)=\"%s\"));",strData);
|
|
rs->Query(q);
|
|
if(!rs->IsEmpty())
|
|
{
|
|
AfxMessageBox("Those initials are already in use.");
|
|
return false;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if(m_strLoginName.IsEmpty())
|
|
{
|
|
AfxMessageBox("A login user name is mandatory\r\nEven if you don't have a password"); return false;
|
|
}
|
|
|
|
//GET THE ZONE SINCE IT'S USED EITHER WAY
|
|
lZone=atol(m_cbZone.GetCurrentRowID());
|
|
|
|
//POST VALIDATION< NOW SAVING
|
|
|
|
if(UpdateOnly)
|
|
{
|
|
//save all fields, generate hash and group fields
|
|
|
|
//bugbug: possible that first update
|
|
//will cause duplicate before lastname
|
|
//update causing index violation error?
|
|
|
|
a="\\"+m_cbUsers.GetCurrentRowID();
|
|
|
|
m_edFirst.GetWindowText(strData);
|
|
rs->UpdateField("first",&strData);
|
|
a=a+strData;
|
|
|
|
m_edLast.GetWindowText(strData);
|
|
rs->UpdateField("last",&strData);
|
|
a=a+strData;
|
|
|
|
m_edInitials.GetWindowText(strData);
|
|
rs->UpdateField("initials",&strData);
|
|
|
|
rs->UpdateField("defzone",&lZone);
|
|
|
|
|
|
rs->UpdateField("login",&m_strLoginName);
|
|
|
|
|
|
rs->UpdateField("pass",&m_strPW);
|
|
|
|
|
|
m_ckTech.GetCheck() ? bData=true : bData=false;
|
|
bData ? a = a + "TRUE" : a = a + "FALSE";
|
|
rs->UpdateField("tech",&bData);
|
|
|
|
m_ckActive.GetCheck() ? bData=true : bData=false;
|
|
bData ? a = a + "TRUE" : a = a + "FALSE";
|
|
rs->UpdateField("active",&bData);
|
|
|
|
strID=m_cbGroup.GetCurrentRowID();
|
|
a=strID+a;
|
|
|
|
//easy access group number field
|
|
c=atol(strID);
|
|
rs->UpdateField("c",&c);
|
|
|
|
b=a;
|
|
k->GZHash(&b);
|
|
k->GZEncrypt(&a,false);
|
|
//now have encrypted a, hashed b and c is done
|
|
//so save a and b
|
|
rs->UpdateField("a",&a);
|
|
rs->UpdateField("b",&b);
|
|
|
|
//a=encrypted string consisting of groupid\useridFirstnameLastNameTECHACTIVE
|
|
//where TECH and ACTIVE are replaced by TRUE or FALSE each depending upon state
|
|
|
|
//b=hash of unencrypted a
|
|
|
|
//added sept 6th 2001 for 1720 email notification
|
|
m_edEmail.GetWindowText(strData);
|
|
rs->UpdateField("email",&strData);
|
|
|
|
bData=m_ckEmailNotify.GetCheck() ? true:false;
|
|
rs->UpdateField("emailnotify",&bData);
|
|
//----------------------------------------
|
|
|
|
//save changes
|
|
|
|
}
|
|
else
|
|
{
|
|
rs->Query("SELECT * FROM users;");
|
|
rs->AddNewRecord();
|
|
|
|
//added sept 6th 2001 for 1720 email notification
|
|
m_edEmail.GetWindowText(strData);
|
|
rs->UpdateField("email",&strData);
|
|
|
|
bData=m_ckEmailNotify.GetCheck() ? true:false;
|
|
rs->UpdateField("emailnotify",&bData);
|
|
//----------------------------------------
|
|
|
|
m_edFirst.GetWindowText(strData);
|
|
rs->UpdateField("first",&strData);
|
|
a=strData;
|
|
|
|
m_edLast.GetWindowText(strData);
|
|
rs->UpdateField("last",&strData);
|
|
a=a+strData;
|
|
|
|
m_edInitials.GetWindowText(strData);
|
|
rs->UpdateField("initials",&strData);
|
|
|
|
rs->UpdateField("defzone",&lZone);
|
|
|
|
rs->UpdateField("login",&m_strLoginName);
|
|
|
|
|
|
rs->UpdateField("pass",&m_strPW);
|
|
|
|
//DEFAULT PREFERENCES:
|
|
|
|
//MAIL READER SCREEN
|
|
//THIS is obsolete as it's set as a record default
|
|
//value in the database now.
|
|
|
|
//strData="(4,4) 28 175 373 152 0 3 2 1";
|
|
//rs->UpdateField("mailprofile",&strData);
|
|
|
|
//WORKORDER STATUS / DISPATCH SCREEN
|
|
//strData="";
|
|
//rs->UpdateField("wostatprofile",&strData);
|
|
|
|
|
|
|
|
|
|
|
|
m_ckTech.GetCheck() ? bData=true : bData=false;
|
|
bData ? a = a + "TRUE" : a = a + "FALSE";
|
|
rs->UpdateField("tech",&bData);
|
|
|
|
m_ckActive.GetCheck() ? bData=true : bData=false;
|
|
bData ? a = a + "TRUE" : a = a + "FALSE";
|
|
rs->UpdateField("active",&bData);
|
|
|
|
strID=m_cbGroup.GetCurrentRowID();
|
|
|
|
|
|
//easy access group number field
|
|
c=atol(strID);
|
|
rs->UpdateField("c",&c);
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
rs->UpdateField("creator",&m_pApp->m_lusrID);
|
|
COleDateTime dtData;
|
|
dtData=COleDateTime::GetCurrentTime();
|
|
rs->UpdateField("created",&dtData);
|
|
rs->SaveRecord();
|
|
|
|
|
|
|
|
|
|
|
|
b=a;
|
|
k->GZHash(&b);
|
|
|
|
|
|
|
|
//now get the autonumber id assigned to this record
|
|
q.Format("SELECT users.* FROM users WHERE (((users.first)=\"%s\") AND ((users.last)=\"%s\"));",strFirst,strLast);
|
|
rs->Query(q);
|
|
rs->FetchField("id",&c);
|
|
b.Format("%u",c);
|
|
a=strID+"\\"+b+a;
|
|
//ensure this user is the current record when
|
|
//done adding
|
|
m_strSelectedUser=b;
|
|
b=a;
|
|
k->GZHash(&b);
|
|
rs->UpdateField("b",&b);
|
|
k->GZEncrypt(&a,false);
|
|
rs->UpdateField("a",&a);
|
|
if(rs->SaveRecord()==false)
|
|
{
|
|
AfxMessageBox("If you just received an error about duplicate entries\r\n"
|
|
"It's because your trying to use the same first and last name twice\r\n"
|
|
"or more likely the same initials. Change the duplicate field or press cancel");
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
//updates modified by and modified on fields
|
|
rs->UpdateField("modifier",&m_pApp->m_lusrID);
|
|
dtData=COleDateTime::GetCurrentTime();
|
|
rs->UpdateField("modified",&dtData);
|
|
if(rs->SaveRecord()==false)
|
|
{
|
|
AfxMessageBox("If you just received an error about duplicate entries\r\n"
|
|
"It's because your trying to use the same first and last name twice\r\n"
|
|
"or the same initials for two different users.\r\n"
|
|
"Change the duplicate field or press Done to exit without saving");
|
|
return false;
|
|
}
|
|
|
|
FillUserList();
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
//************************************************************
|
|
void CUsersDlg::FillUserList()
|
|
{
|
|
|
|
|
|
CString strData;
|
|
CString strIndex;
|
|
long lData;
|
|
bool bData;
|
|
m_cbUsers.Clear();
|
|
|
|
rs->Query("SELECT users.tech, users.id, [last] & \", \" & [first] AS fullname FROM users ORDER BY users.last;");
|
|
if(!rs->IsEmpty())
|
|
{
|
|
//fill combo box with available zones
|
|
rs->MoveFirst();
|
|
rs->FetchField("fullname",&strData);
|
|
rs->FetchField("tech",&bData);
|
|
rs->FetchField("id",&lData);
|
|
strIndex.Format("%u",lData);
|
|
if(bData) strData+=" (tech.)";
|
|
m_cbUsers.AddRow(strData,strIndex);
|
|
while(rs->MoveForward())
|
|
{
|
|
rs->FetchField("fullname",&strData);
|
|
rs->FetchField("id",&lData);
|
|
strIndex.Format("%u",lData);
|
|
rs->FetchField("tech",&bData);
|
|
if(bData) strData+=" (tech.)";
|
|
|
|
m_cbUsers.AddRow(strData,strIndex);
|
|
}
|
|
|
|
}
|
|
|
|
//pretend user has selected so that other fields get filled in
|
|
if(m_strSelectedUser.IsEmpty()) //first time in
|
|
{
|
|
m_cbUsers.SetCurSel(0);
|
|
m_strSelectedUser=m_cbUsers.GetCurrentRowID();
|
|
}
|
|
else//something valid was selected before so stick with it
|
|
m_cbUsers.Select(m_strSelectedUser);
|
|
|
|
//make sure manager account is not modified
|
|
if(m_strSelectedUser=="1")
|
|
EnableFields(false);
|
|
else
|
|
{
|
|
|
|
if(!m_bEval)
|
|
EnableFields(true);
|
|
else
|
|
EnableFields(false);
|
|
}
|
|
FillFields();
|
|
return ;
|
|
|
|
}
|
|
|
|
void CUsersDlg::OnActive()
|
|
{
|
|
//if it's an inactive tech then check
|
|
if(m_ckActive.GetCheck() && m_ckTech.GetCheck())
|
|
{
|
|
tcrs->Query(k->InLineDecrypt("XpylqTv5lEq+juZqFsgPyAVSmUOGVLDsocm9oZgee2/rmtusjM4c0ac2ft9sKF+YwWxv31Wh"
|
|
"chfLDqupFJnACCEm9uQtvxwdYgDUExMhOav4AcbDNku3TR16BAwj95EIk37jZiZRnv65fWjw"
|
|
"7Z/gog"));
|
|
/*SELECT Count(users.id) AS techcount
|
|
FROM users
|
|
WHERE (((users.tech)=True) AND ((users.active)=True));*/
|
|
long tc;
|
|
tcrs->FetchField(k->InLineDecrypt("Yz02r2k2ZHlf2ywDwrlqsA"),&tc);//techcount
|
|
if(tc==m_pApp->m_lRegLicCount)//at the edge
|
|
{
|
|
//can't do it
|
|
k->gzMsgBox("u0TwBRR48aBBiPKKD+/oG8clJuOBCS2dhRJyS4HtLSyxU9rTHpygT6QZG9vXZwwbxxHK7yRO"
|
|
"eyiUn22/xxG7uAPo/j+4e0vW5T8j5oa+2LM0kZnFE8/S7QM4qd9q6DdZdxWXZD6TtacEB2n7"
|
|
"Q9v1yx+iyH8xzAVCBIskOXGXkneR+GLRejpi6mv/u3qzBjZwDN9HUm81Ft8YY1ShdIgNrQdr"
|
|
"PoMmohZbraolJTBM5PyMtfM47qNxp9DE4TQWjJ48EmLcKTXNa2Fxlorpg1QFEfClgvdrFDEY"
|
|
"aD9uvL51N/s4m2O//fqe3XoQdDBe5FnFBCu61m1VpvFg8is0d9xrlb6XXs9LRomptUmNoohx"
|
|
"sLtN7dRs92a00XgbTAD8TfqShQWYdKWek+O89tD8FwX45ByewThIEEB8vnk63Lwad5Pq2M4s"
|
|
"bKV0vcjRostbar8BbVAVRtF5Lc9qtNcDN9LV7cRqvtQi1Y9dOKDTHaD4k0GJJX827VYTLzs+"
|
|
"H5aeXRau",167);
|
|
/* You can't activate another technician.
|
|
|
|
You have reached your licensed limit
|
|
or are using a trial version of the program.
|
|
|
|
You have two options at this point:
|
|
|
|
1) Set an existing tech to inactive which will free up a license.
|
|
|
|
2) Purchase additional licenses: you can add one or more licenses at any time.
|
|
|
|
See our website at www.ayanova.com to purchase licenses
|
|
now.
|
|
*/
|
|
|
|
//uncheck
|
|
m_ckActive.SetCheck(FALSE);
|
|
return;
|
|
}
|
|
}
|
|
SaveFields(true);
|
|
}
|
|
|
|
|
|
|
|
|
|
//**************************************************************
|
|
void CUsersDlg::OnBtndelete()
|
|
{
|
|
if(m_bEval)
|
|
{
|
|
k->gzMsgBox("56+boENSNE6ZF0XbSNazEC/2PNbalqKYfXjsqBReayt1BFoT8N1cOsjyVHum4oNB26ADutd2"
|
|
"7itQ4De04c2fQZE1jFG0vY3L/nVmUvdFRJ9vMHUKoz+Am4SLSXPWgMrWJ1ZEeNIqGHmsG4u7"
|
|
"YW5P/w",154);
|
|
|
|
return;
|
|
}
|
|
|
|
if(m_bAddMode)//this is the cancel button
|
|
{
|
|
|
|
m_lblMSG.ShowWindow(FALSE);
|
|
m_btnPW.ShowWindow(TRUE);
|
|
m_cbUsers.ShowWindow(TRUE);
|
|
m_lblUserList.ShowWindow(TRUE);
|
|
m_btnDelete.SetWindowText("Delete");
|
|
m_btnSave.SetWindowText("Add");
|
|
m_btnDone.ShowWindow(TRUE);
|
|
m_bAddMode=false;
|
|
FillUserList();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
CString q,strData,strID,strErr;
|
|
|
|
bool OkToDelete=true;
|
|
//check to see if the user exists in any records
|
|
strErr="DATA INTEGRITY PROTECTION:\r\nYou can not delete this user because:\r\n\r\n";
|
|
strID=m_cbUsers.GetCurrentRowID();
|
|
|
|
//Clients:
|
|
q.Format("SELECT clients.company FROM clients "
|
|
"WHERE (((clients.prefertech)=%s));",strID);
|
|
rs->Query(q);
|
|
|
|
if(!rs->IsEmpty())
|
|
{
|
|
OkToDelete=false;
|
|
strErr=strErr+"This user is one or more clients preferred technician\r\n";
|
|
}
|
|
|
|
|
|
|
|
//contacts with clients
|
|
q.Format("SELECT contacts.id FROM contacts "
|
|
"WHERE (((contacts.staff)=%s));",strID);
|
|
rs->Query(q);
|
|
|
|
if(!rs->IsEmpty())
|
|
{
|
|
OkToDelete=false;
|
|
strErr=strErr+"This user has one or more contact with client records\r\n";
|
|
}
|
|
|
|
|
|
|
|
//labour records?
|
|
//v1.9.4.4 HUGE BUG HERE FIXED. previously was labor.tech=1 not %s, must have been copied from
|
|
//test query and not fully modified.
|
|
q.Format("SELECT labor.link FROM labor "
|
|
"WHERE (((labor.tech)=%s));",strID);
|
|
rs->Query(q);
|
|
|
|
if(!rs->IsEmpty())
|
|
{
|
|
OkToDelete=false;
|
|
strErr=strErr+"This user has one or more labor records on workorders\r\n";
|
|
}
|
|
|
|
//MAIL MESSAGES?
|
|
//BUGBUG:SCAN FOR MAIL MESSAGES AS WELL.
|
|
//leaving out for now as will likely set mail reader
|
|
//to display <deleted> as the user name instead.
|
|
//mail just isn't important enough to prevent deleting a user
|
|
//afaik
|
|
|
|
if(!OkToDelete)
|
|
{
|
|
|
|
AfxMessageBox(strErr);
|
|
AfxMessageBox(
|
|
"Hint: Rather than deleting a user, just set them to inactive.\r\n"
|
|
"This will free up a technician license and they will not appear in selection boxes\r\n"
|
|
"But their data will still be there for history reports etc.\r\n"
|
|
"You can set them back to active at a later date if needed.");
|
|
FillUserList();
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
q.Format("DELETE users.*, users.id FROM users "
|
|
"WHERE (((users.id)=%s));",strID);
|
|
|
|
|
|
if(AfxMessageBox("Are you sure?",MB_YESNO)==IDYES)
|
|
{
|
|
rs->Ex(q);
|
|
//a deleted zone can't be selected
|
|
m_strSelectedUser="";
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FillUserList();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
void CUsersDlg::OnBtnpw()
|
|
{
|
|
CString q;
|
|
CString initials;
|
|
CString sLogin;
|
|
CString sPW;
|
|
CPWDlg pwd;
|
|
bool done;
|
|
|
|
do{
|
|
done=true;
|
|
if(m_bEval)
|
|
{
|
|
k->gzMsgBox("56+boENSNE6ZF0XbSNazEC/2PNbalqKYfXjsqBReayt1BFoT8N1cOsjyVHum4oNB26ADutd2"
|
|
"7itQ4De04c2fQZE1jFG0vY3L/nVmUvdFRJ9vMHUKoz+Am4SLSXPWgMrWJ1ZEeNIqGHmsG4u7"
|
|
"YW5P/w",154);
|
|
|
|
return;
|
|
}
|
|
pwd.PassPWString(&m_strPW,&m_strLoginName);
|
|
if(pwd.DoModal()==IDCANCEL)//user decided to cancel.
|
|
return;
|
|
|
|
//1.9.3.0 compare login against aras client logins
|
|
sLogin=m_strLoginName;
|
|
q.Format("SELECT clients_aras.loginid FROM clients_aras WHERE "
|
|
"(((clients_aras.loginid)=\"%s\"));",sLogin);
|
|
tcrs->QueryReadOnly(q);
|
|
if(!tcrs->IsEmpty())
|
|
{
|
|
AfxMessageBox(
|
|
"The login name chosen is already in use.\r\n"
|
|
"Select a different login name.",MB_ICONSTOP);
|
|
done=false;
|
|
goto BAIL;
|
|
|
|
}
|
|
|
|
//HASH the user name
|
|
k->GZHash(&m_strLoginName);
|
|
|
|
//if no pass, instead of leaving blank
|
|
//set to something unique to this user
|
|
//so people cant just wipe someones password
|
|
//in the database to gain access to their account.
|
|
if(m_strPW.IsEmpty())
|
|
m_strPW="@" + m_strLoginName + "gz";
|
|
|
|
//HASH OF PASSWORD
|
|
k->GZHash(&m_strPW);
|
|
|
|
//check for duplicate login name
|
|
m_edInitials.GetWindowText(initials);
|
|
q.Format("SELECT users.login, users.initials "
|
|
"FROM users "
|
|
"WHERE (((users.login)=\"%s\") AND ((users.initials)<>\"%s\"));",m_strLoginName,initials);
|
|
|
|
tcrs->QueryReadOnly(q);
|
|
if(!tcrs->IsEmpty())
|
|
{
|
|
AfxMessageBox("The login name chosen is already in use.\r\n"
|
|
"Please choose another.");
|
|
done=false;
|
|
goto BAIL;
|
|
}
|
|
if(!m_bAddMode)//Only save from here if its an update
|
|
SaveFields(true);
|
|
BAIL:
|
|
;
|
|
}while(!done);
|
|
|
|
}
|
|
|
|
void CUsersDlg::OnBtnsave()
|
|
{
|
|
|
|
if(m_bEval)
|
|
{
|
|
k->gzMsgBox("56+boENSNE6ZF0XbSNazEC/2PNbalqKYfXjsqBReayt1BFoT8N1cOsjyVHum4oNB26ADutd2"
|
|
"7itQ4De04c2fQZE1jFG0vY3L/nVmUvdFRJ9vMHUKoz+Am4SLSXPWgMrWJ1ZEeNIqGHmsG4u7"
|
|
"YW5P/w",154);
|
|
|
|
return;
|
|
}
|
|
if(!m_bAddMode)
|
|
{//go to add mode
|
|
EnableFields(true);
|
|
m_cbUsers.ShowWindow(FALSE);
|
|
m_lblUserList.ShowWindow(FALSE);
|
|
m_btnDelete.SetWindowText("CANCEL");
|
|
m_btnSave.SetWindowText("SAVE");
|
|
m_btnDone.ShowWindow(FALSE);
|
|
m_btnPW.ShowWindow(FALSE);
|
|
m_edFirst.SetWindowText("");
|
|
m_edLast.SetWindowText("");
|
|
m_edEmail.SetWindowText("");
|
|
m_ckEmailNotify.SetCheck(FALSE);
|
|
m_edEmail.EnableWindow(FALSE);
|
|
m_ckEmailNotify.EnableWindow(FALSE);
|
|
m_edInitials.SetWindowText("");
|
|
m_lblMSG.ShowWindow(TRUE);
|
|
m_ckActive.SetCheck(TRUE);
|
|
m_ckTech.SetCheck(FALSE);
|
|
m_strPW="";
|
|
m_strLoginName="";
|
|
m_cbGroup.SetCurSel(0);
|
|
m_bAddMode=true;
|
|
m_cbZone.EnableWindow(FALSE);
|
|
m_lblZone.EnableWindow(FALSE);
|
|
}
|
|
else
|
|
{//come from add mode
|
|
//set password and user login name
|
|
OnBtnpw();
|
|
if(SaveFields(false)!=true)
|
|
return;
|
|
m_lblMSG.ShowWindow(FALSE);
|
|
m_btnPW.ShowWindow(TRUE);
|
|
m_cbUsers.ShowWindow(TRUE);
|
|
m_lblUserList.ShowWindow(TRUE);
|
|
m_btnDelete.SetWindowText("Delete");
|
|
m_btnSave.SetWindowText("Add");
|
|
m_btnDone.ShowWindow(TRUE);
|
|
m_bAddMode=false;
|
|
FillUserList();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void CUsersDlg::OnKillfocusFirst()
|
|
{
|
|
SaveFields(true);
|
|
|
|
}
|
|
|
|
void CUsersDlg::OnCloseupGroup()
|
|
{
|
|
|
|
SaveFields(true);
|
|
|
|
}
|
|
|
|
void CUsersDlg::OnKillfocusInitials()
|
|
{
|
|
SaveFields(true);
|
|
|
|
}
|
|
|
|
void CUsersDlg::OnKillfocusLast()
|
|
{
|
|
|
|
SaveFields(true);
|
|
}
|
|
|
|
|
|
void CUsersDlg::OnTech()
|
|
{
|
|
if(m_ckTech.GetCheck())
|
|
{
|
|
m_cbZone.EnableWindow(TRUE);
|
|
m_lblZone.EnableWindow(TRUE);
|
|
m_edEmail.EnableWindow(TRUE);
|
|
m_ckEmailNotify.EnableWindow(TRUE);
|
|
|
|
tcrs->Query(k->InLineDecrypt("XpylqTv5lEq+juZqFsgPyAVSmUOGVLDsocm9oZgee2/rmtusjM4c0ac2ft9sKF+YwWxv31Wh"
|
|
"chfLDqupFJnACCEm9uQtvxwdYgDUExMhOav4AcbDNku3TR16BAwj95EIk37jZiZRnv65fWjw"
|
|
"7Z/gog"));
|
|
/*SELECT Count(users.id) AS techcount
|
|
FROM users
|
|
WHERE (((users.tech)=True) AND ((users.active)=True));*/
|
|
long tc;
|
|
tcrs->FetchField(k->InLineDecrypt("Yz02r2k2ZHlf2ywDwrlqsA"),&tc);
|
|
if(tc==m_pApp->m_lRegLicCount)//at the edge
|
|
{
|
|
//can't do it
|
|
k->gzMsgBox("u0TwBRR48aBBiPKKD+/oG8clJuOBCS2dhRJyS4HtLSyxU9rTHpygT6QZG9vXZwwbxxHK7yRO"
|
|
"eyiUn22/xxG7uAPo/j+4e0vW5T8j5oa+2LM0kZnFE8/S7QM4qd9q6DdZdxWXZD6TtacEB2n7"
|
|
"Q9v1yx+iyH8xzAVCBIskOXGXkneR+GLRejpi6mv/u3qzBjZwDN9HUm81Ft8YY1ShdIgNrQdr"
|
|
"PoMmohZbraolJTBM5PyMtfM47qNxp9DE4TQWjJ48EmLcKTXNa2Fxlorpg1QFEfClgvdrFDEY"
|
|
"aD9uvL51N/s4m2O//fqe3XoQdDBe5FnFBCu61m1VpvFg8is0d9xrlb6XXs9LRomptUmNoohx"
|
|
"sLtN7dRs92a00XgbTAD8TfqShQWYdKWek+O89tD8FwX45ByewThIEEB8vnk63Lwad5Pq2M4s"
|
|
"bKV0vcjRostbar8BbVAVRtF5Lc9qtNcDN9LV7cRqvtQi1Y9dOKDTHaD4k0GJJX827VYTLzs+"
|
|
"H5aeXRau",167);
|
|
/* You can't activate another technician.
|
|
|
|
You have reached your licensed limit
|
|
or are using a trial version of the program.
|
|
|
|
You have two options at this point:
|
|
|
|
1) Set an existing tech to inactive which will free up a license.
|
|
|
|
2) Purchase additional licenses: you can add one or more licenses at any time.
|
|
|
|
See our website at www.ayanova.com to purchase licenses
|
|
now.
|
|
*/
|
|
|
|
//uncheck
|
|
m_ckTech.SetCheck(FALSE);
|
|
m_cbZone.EnableWindow(FALSE);
|
|
m_lblZone.EnableWindow(FALSE);
|
|
m_edEmail.EnableWindow(FALSE);
|
|
m_ckEmailNotify.EnableWindow(FALSE);
|
|
return;
|
|
}
|
|
}
|
|
else//unchecked
|
|
{
|
|
m_cbZone.EnableWindow(FALSE);
|
|
m_lblZone.EnableWindow(FALSE);
|
|
m_edEmail.EnableWindow(FALSE);
|
|
m_ckEmailNotify.EnableWindow(FALSE);
|
|
|
|
}
|
|
SaveFields(true);
|
|
|
|
|
|
//Delay to make it extra annoying to change tech status casually.
|
|
m_pDlgStartUp=new CDlgStartUp;
|
|
m_pDlgStartUp->Create(IDD_DLGSTARTUP);
|
|
m_pDlgStartUp->ShowWindow(SW_SHOW);
|
|
m_pDlgStartUp->m_pc.SetPos(0);
|
|
m_pDlgStartUp->UpdateWindow();
|
|
CWaitCursor cw;
|
|
for(int x=0;x<19;x++)
|
|
{
|
|
m_pApp->Delay(1);
|
|
m_pDlgStartUp->m_pc.SetPos(x);
|
|
m_pDlgStartUp->UpdateWindow();
|
|
cw.Restore();
|
|
|
|
|
|
}
|
|
m_pDlgStartUp->DestroyWindow();
|
|
delete m_pDlgStartUp;
|
|
|
|
|
|
|
|
}
|
|
|
|
void CUsersDlg::OnCloseupUserlist()
|
|
{
|
|
m_strSelectedUser=m_cbUsers.GetCurrentRowID();
|
|
FillFields();
|
|
//make sure manager account is not modified
|
|
if(m_strSelectedUser=="1")
|
|
EnableFields(false);
|
|
else
|
|
{
|
|
|
|
if(!m_bEval)
|
|
EnableFields(true);
|
|
else
|
|
EnableFields(false);
|
|
}
|
|
}
|
|
|
|
void CUsersDlg::OnOK()
|
|
{
|
|
|
|
SaveFields(true);
|
|
if(m_pstrReturnString!=NULL)
|
|
m_pstrReturnString->Format("%s",m_cbUsers.GetCurrentRowID());
|
|
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
BOOL CUsersDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
|
|
|
|
xclusivers->m_bExclusiveConnection=true;
|
|
|
|
//Attempt to go Exclusive
|
|
if(!m_pApp->rsPool->GoExclusive())
|
|
{
|
|
AfxMessageBox("In order to protect the integrity of your data\r\n"
|
|
"you need exclusive access to the database to access this function.\r\n"
|
|
"\r\nAll other users must exit before proceeding.");
|
|
//xclusivers->Close();
|
|
//back to shared mode
|
|
m_pApp->rsPool->GoShared();
|
|
CDialog::OnCancel();
|
|
}
|
|
else
|
|
xclusivers->Close();
|
|
|
|
//Ok, everyone is out, go shared
|
|
m_pApp->rsPool->GoShared();
|
|
|
|
|
|
|
|
|
|
|
|
m_bAddMode=false;
|
|
FillGroupList();
|
|
FillZoneList();
|
|
FillUserList();
|
|
|
|
if(m_bEval)
|
|
{
|
|
m_lblEval.SetFontBold(TRUE);
|
|
m_lblEval.SetFontSize(14);
|
|
m_lblEval.SetTextColor(RGB(255,0,0));
|
|
m_lblEval.SetWindowText(k->InLineDecrypt("AANE0AREBSmag+mTxYGK25zEpSyotBlK3SRYh2Vxi87CiuANBRKNjxCC6xEui5OaOWscafL4"
|
|
"/N4UuKG3Krz3yQ"));
|
|
/** * Evaluation version: restrictions are in effect * **/
|
|
}
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
|
|
//*****************************
|
|
void CUsersDlg::FillGroupList()
|
|
{
|
|
//fill list box with different groups
|
|
CString strData;
|
|
CString strIndex;
|
|
long lData;
|
|
m_cbGroup.Clear();
|
|
|
|
|
|
|
|
rs->Query("SELECT groups.* FROM groups;");
|
|
if(!rs->IsEmpty())
|
|
{
|
|
//fill combo box with available zones
|
|
rs->MoveFirst();
|
|
rs->FetchField("a",&strData);
|
|
|
|
//decrypt the name
|
|
k->GZDecrypt(&strData,false);
|
|
|
|
rs->FetchField("id",&lData);
|
|
strIndex.Format("%u",lData);
|
|
m_cbGroup.AddRow(strData,strIndex);
|
|
while(rs->MoveForward())
|
|
{
|
|
rs->FetchField("a",&strData);
|
|
//decrypt the name
|
|
k->GZDecrypt(&strData,false);
|
|
rs->FetchField("id",&lData);
|
|
strIndex.Format("%u",lData);
|
|
m_cbGroup.AddRow(strData,strIndex);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void CUsersDlg::FillZoneList()
|
|
{
|
|
CString q, strData,strIndex;
|
|
long lData;
|
|
//fill ZONES
|
|
m_cbZone.Clear();
|
|
m_cbZone.AddRow(" < All Zones >","0");
|
|
q="SELECT zones.id, zones.name FROM zones ORDER BY zones.name;";
|
|
|
|
rs->QueryReadOnly(q);
|
|
if(!rs->IsEmpty())
|
|
{
|
|
do
|
|
{
|
|
rs->FetchField("name",&strData);
|
|
rs->FetchField("id",&lData);
|
|
strIndex.Format("%u",lData);
|
|
m_cbZone.AddRow(strData,strIndex);
|
|
}while(rs->MoveForward());
|
|
m_cbZone.SetCurSel(0);
|
|
}
|
|
}
|
|
|
|
|
|
void CUsersDlg::SetReturnString(CString *ret)
|
|
{
|
|
//we have a string
|
|
m_pstrReturnString=ret;
|
|
}
|
|
|
|
void CUsersDlg::EnableFields(bool bEnable)
|
|
{
|
|
BOOL enable=bEnable ? TRUE : FALSE;
|
|
|
|
m_btnDelete.EnableWindow(enable);
|
|
m_cbGroup.EnableWindow(TRUE);
|
|
if(m_strSelectedUser=="1")
|
|
m_cbGroup.EnableWindow(FALSE);
|
|
|
|
m_ckActive.EnableWindow(enable);
|
|
m_ckTech.EnableWindow(enable);
|
|
m_edFirst.EnableWindow(enable);
|
|
m_edLast.EnableWindow(enable);
|
|
m_edInitials.EnableWindow(enable);
|
|
if(m_bEval)
|
|
{
|
|
m_btnSave.EnableWindow(FALSE);
|
|
m_btnPW.EnableWindow(FALSE);
|
|
|
|
|
|
}
|
|
//m_cbZone.EnableWindow(enable);
|
|
|
|
|
|
}
|
|
|
|
|
|
void CUsersDlg::OnCloseupCbzone()
|
|
{
|
|
SaveFields(true);
|
|
}
|
|
|
|
void CUsersDlg::OnKillfocusTechemail()
|
|
{
|
|
SaveFields(true);
|
|
}
|
|
|
|
void CUsersDlg::OnCkemailnotify()
|
|
{
|
|
SaveFields(true);
|
|
}
|