Accounting Software
Small Business Software Estimating Software
Inventory SoftwareInventory Tracking SoftwareInventory Control SoftwareInventory Management SoftwareConstruction Management SoftwareProject Management SoftwareBusiness Management Software

Transactions (Source Code)

Link to: header | source 2 | source 3 | source 4 | transactions directory

Copyright Turtle Creek Software 1996-2006. All Rights Reserved.

Comments

CTransaction

This class manages basic accounting transactions in the Goldenseal accounting software,
estimating software, project management software and cost accounting software.

This is the base class for a transaction. All accounting transactions descend from this class.

Transactions cover all sorts of financial items-- bank checks, sales, billing
records, purchases. They also handle non-financial events such as appointments,
contact records and project events.

Transactions also include some tangible items like cost items (items purchased
and sold), assemblies (unit costs) and prospect records.

SUPERCLASS = DB_BaseTransaction

Constructor

/*********************************************************************************
constructor
*********************************************************************************/
CTransaction::CTransaction()
:THE_SUPERCLASS()
{
mMainAccountClass = id_CustomerAccount; //subclasses can override this

mMainAccount = 0;

mDate.SetToNow();

mReferenceNum = 0;

mFlagged = false;
mUseShortForm = false;
mUsedAsTemplate = false;
mUsedAsRecurring = false;
mIncludeInStarterFile = false;
mTransactionBit = false; // TCS 8/30/02
mTransactionBit2 = false;
mNeedsAttention = false;
mTransCopiedPadding = 0;

mTransFiller = 0;
mPrintFlagged = true;
mSalesTaxPaid = mBeenOverpaid = false;
transCalcFiller = 0;

mTransPadding = 0;

mIsPosting = false;
mTempPadding = 0;
}

Source Code

/*********************************************************************************

GetFileLength

return the file length to reserve for this object

*********************************************************************************/
NeoSize CTransaction::GetFileLength(const CNeoFormat *aFormat) const
{
return THE_SUPERCLASS::GetFileLength(aFormat) +
CCustomFieldOwner::GetFileLength(aFormat) +
mDescription.FileLength(cStandardTextLen) + // TCS 3/14/00
cFileLength;
}
/*********************************************************************************

CopyFrom

copy the data members from the passed object. This is used to implement
duplicate. source should be an object of the same class as this object

*********************************************************************************/
void CTransaction::CopyFrom(DB_PersistentObject *source, const UInt8 copyFlags)
{
THE_SUPERCLASS::CopyFrom(source, copyFlags);

CTransaction *src = TCS_SAFE_CAST(source, CTransaction);
TCS_FailNILMsg(src, TCS_GetErrString(errID_BadRecord));

CCustomFieldOwner::CopyFrom(*(CCustomFieldOwner*)src, GetDBClassID());

mDescription = src->mDescription;
TCS_BlockMove(&src->mMainAccount, &mMainAccount, cCopyFileLength); // bugfix 3/6/00

mUsedAsTemplate = false; // TCS 4/24/01
mUsedAsRecurring = false;
}/*********************************************************************************

GetMemberValue

return the value of the member with the given tag

*********************************************************************************/
Boolean CTransaction::GetMemberValue(const TagType aTag, const TagType aType,
void *aValue) const
{
DBClass accountClass;
DBid accountID;

switch (aTag)
{
case tag_mainaccount:
return ConvertObjectIDMember(mMainAccount, mMainAccountClass, aValue, aType);
break;

case tag_mainaccountfullname: // TCS 3/25/02
case tag_mainaccountaddress: // TCS 10/31/02
case tag_mainaccountphone:
case tag_mainaccountemail:
{ // bugfix TCS 1/21/03
CTextString outString;

if (IS_TURTLE_CLASS_ID(mMainAccountClass)) // TCS rev 10/31/02
{
DB_PersistentObject *account = gDBFile->GetOneObject(mMainAccountClass, mMainAccount);

if (account)
{
DB_ObjectWatcher watcher(account);

if (aTag == tag_mainaccountfullname)
outString = account->GetFullName();
else if (aTag == tag_mainaccountaddress)
outString = account->GetAddress();
else if (aTag == tag_mainaccountphone)
account->GetMemberValue(tag_telephone, type_cstring, &outString);
else if (aTag == tag_mainaccountemail)
account->GetMemberValue(tag_email, type_cstring, &outString);
}
}

return ConvertMember(&outString, type_cstring, aValue, aType);
}
break;

case tag_comments:
return ConvertMember(&mDescription, type_cstring, aValue, aType);
break;

case tag_date:
case tag_creationdate:
return ConvertMember(&mDate, type_date, aValue, aType);
break;

case tag_time: // TCS 2/8/01
return ConvertMember(&mDate, type_time, aValue, aType);
break;

case tag_refnum:
return ConvertMember(&mReferenceNum, type_long, aValue, aType);
break;

case tag_refnumstring: // we get the string from refnum and numbering dialog
{
CTextString refNumString =
CNumbering::RefNumberToString(GetDBClassID(), mReferenceNum);
return ConvertMember(&refNumString, type_cstring, aValue, aType);
}
break;

case tag_mainaccountclass:
return ConvertEnumMember(mMainAccountClass, MENU_AccountClasses, aValue, aType);
break;

case tag_catsystem: // there is no direct catsystem member, but we can derive it
// from the main account
{
accountID = DB_Account::GetJobCatSystem(mMainAccountClass, mMainAccount);

return ConvertObjectIDMember(accountID, id_CategorySystem, aValue, aType);
}
break;

case tag_jobtype: // there is no direct jobtype member, but we can derive it
// from the main account TCS 9/3/98
{
accountID = DB_Account::GetJobAccountType(mMainAccountClass, mMainAccount);
return ConvertObjectIDMember(accountID, id_JobType, aValue, aType);
}
break;

case tag_menuname: // rev TCS 9/8/99, rev 1/29/01
{
CTextString menuName = GetMenuName();
if (!menuName.Length())
{
menuName = DB_ClassDescriptor::GetClassName(GetDBClassID());
menuName.AppendNumber(GetDBID());
}

return ConvertMember(&menuName, type_cstring, aValue, aType);
}
break;

case tag_costamount: // TCS 12/16/03
{
CMoney costAmount = GetCostAmount();
return ConvertMember(&costAmount, type_money, aValue, aType);
}
break;

case tag_incomeamount: // TCS 12/16/03
{
CMoney costAmount = GetIncomeAmount();
return ConvertMember(&costAmount, type_money, aValue, aType);
}

case tag_downpayment: // TCS 12/16/02
{
CMoney zero = 0;
return ConvertMember(&zero, type_money, aValue, aType);
}
break;

case tag_flagged:
return ConvertBitFieldMember(mFlagged, aValue, aType);
break;

case tag_printflagged:
return ConvertBitFieldMember(mPrintFlagged, aValue, aType);
break;

case tag_includeinstarter: // TCS 9/2/02
return ConvertBitFieldMember(mIncludeInStarterFile, aValue, aType);
break;

case tag_dayofweek: // TCS 10/1/03
{
UInt8 dayOfWeek = mDate.GetDayOfWeekTag();
return ConvertEnumMember(dayOfWeek, MENU_DaysofWeek, aValue, aType);
}
break;

case tag_dayofmonth: // TCS 10/1/03
{
UInt8 dayOfMonth = mDate.GetDayOfMonthTag();
return ConvertEnumMember(dayOfMonth, MENU_DaysofMonth, aValue, aType);
}
break;

case tag_debitaccount: // these are calculated TCS 11/19/03
accountClass = GetDebitAccountClass();
accountID = GetDebitAccountID();
return ConvertObjectIDMember(accountID, accountClass, aValue, aType);
break;

case tag_creditaccount:
accountClass = GetCreditAccountClass();
accountID = GetCreditAccountID();
return ConvertObjectIDMember(accountID, accountClass, aValue, aType);
break;

case tag_debitaccountclass:
accountClass = GetDebitAccountClass();
return ConvertEnumMember(accountClass, MENU_AccountClasses, aValue, aType);
break;

case tag_creditaccountclass:
accountClass = GetCreditAccountClass();
return ConvertEnumMember(accountClass, MENU_AccountClasses, aValue, aType);
break;

case tag_supplier: // TCS 5/18/04
case tag_suppliercode:
case tag_supplier2code:
case tag_supplier3code:
// these may be called for transactions that don't have a value.
// we don't want to give an error msg, so just ignore the request.
return true;
break;

default:
if (CCustomFieldOwner::GetCustomFieldValue(aTag, aType, aValue, GetDBClassID()))
return true;
else
return (THE_SUPERCLASS::GetMemberValue(aTag, aType, aValue));
break;
}
}/*********************************************************************************

SetMemberValue

set the value of the member with the given tag

*********************************************************************************/
Boolean CTransaction::SetMemberValue(const TagType aTag, const TagType aType,
const void *aValue)
{
switch (aTag)
{
case tag_mainaccount: // rev TCS 3/6/00
return ConvertMember(aValue, aType, &mMainAccount, type_objectid);
break;

case tag_comments:
return SafeConvertString(aValue, aType, &mDescription);
break;

case tag_date:
case tag_creationdate:
return ConvertMember(aValue, aType, &mDate, type_date);
break;

case tag_time: // TCS 2/8/01
{
CDate date;
if (ConvertMember(aValue, aType, &date, type_time))
{
mDate.SetTime(date);
return true;
}
else
return false;
}
break;

case tag_refnum:
return ConvertMember(aValue, aType, &mReferenceNum, type_long);
break;

case tag_refnumstring: // we process the string and store it in ref num
{
CTextString refNumString; // rev TCS 10/20/99, 11/2/99
ConvertMember(aValue, aType, &refNumString, type_cstring);
refNumString.StripNonNumbers(); // bugfix TCS 2/13/01
SInt32 number = refNumString.GetNumberValue(cPositiveOnly);
return ConvertMember(&number, type_long, &mReferenceNum, type_long);
}
break;

case tag_mainaccountclass:
return ConvertMember(aValue, aType, &mMainAccountClass, type_objclass);
break;

case tag_flagged:
mFlagged = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_printflagged:
mPrintFlagged = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_includeinstarter: // TCS 9/3/02
mIncludeInStarterFile = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_mainaccountaddress: // calculated, no need to set
case tag_mainaccountphone: // TCS 10/31/02
case tag_mainaccountemail:
case tag_mainaccountfullname:
case tag_secondaccountfullname:
case tag_secondaccountaddress:
case tag_secondaccountphone:
case tag_secondaccountemail:
case tag_jobfullname:
case tag_jobaddress:
case tag_jobphone:
case tag_jobemail:
case tag_dayofweek: // TCS 10/1/03
case tag_dayofmonth:
case tag_debitaccount: // TCS 11/19/03
case tag_creditaccount:
case tag_debitaccountclass:
case tag_creditaccountclass:

case tag_costamount: // TCS 12/16/03
case tag_incomeamount:
return true;
break;

default:
if (CCustomFieldOwner::SetCustomFieldValue(aTag, aType, aValue, GetDBClassID()))
return true;
else
return THE_SUPERCLASS::SetMemberValue(aTag, aType, aValue);
break;
}
}/*********************************************************************************

ReadObject

read the persistent object's data in from a stream
*********************************************************************************/
void CTransaction::ReadObject(CNeoStream *aStream, const TagType aTag)
{
TCS_FailNILMsg(aStream, TCS_GetErrString(errID_BadStream));

CNeoDebugImport checker(aStream, this); // TCS 2/24/00

THE_SUPERCLASS::ReadObject(aStream, aTag);

if (!IsIOValid()) // TCS 2/5/02
return;

if (!CCustomFieldOwner::ReadObject(*aStream, this))
{
SetHadIOProblems();
return;
}

ReadTextFromStream(aStream, &mDescription);

/// aStream->ReadChunk(&mMainAccount, cFileLength); // bugfix 3/6/00

mMainAccount = aStream->ReadID(); // mfs_sa 20feb2k3

mDate.ReadFromStream(aStream);

mReferenceNum = aStream->ReadLong();
*((UInt8*)&mReferenceNum + sizeof(mReferenceNum)) = aStream->ReadBits(8); // --Bitfield

mTransCopiedPadding = aStream->ReadChar();
*((UInt8*)&mTransCopiedPadding + sizeof(mTransCopiedPadding)) = aStream->ReadBits(7); // --Bitfield

mTransPadding = aStream->ReadChar();
}/*********************************************************************************

WriteObject

write the persistent object's data to a stream
*********************************************************************************/
void CTransaction::WriteObject(CNeoStream *aStream, const TagType aTag)
{
TCS_FailNILMsg(aStream, TCS_GetErrString(errID_BadStream));

CNeoDebugExport checker(aStream, this);
THE_SUPERCLASS::WriteObject(aStream, aTag);

if (!CCustomFieldOwner::WriteObject(*aStream, this)) // TCS rev 9/26/03
{
SetHadIOProblems();
return;
}

WriteTextToStream(aStream, mDescription, cStandardTextLen);

/// aStream->WriteChunk(&mMainAccount, cFileLength); // bugfix 3/6/00

aStream->WriteID(mMainAccount); // mfs_sa 20feb2k3

mDate.WriteToStream(aStream);

aStream->WriteLong(mReferenceNum);
aStream->WriteChar(*((UInt8*)&mReferenceNum + sizeof(mReferenceNum))); // --Bitfield

aStream->WriteChar(mTransCopiedPadding);
aStream->WriteChar(*((UInt8*)&mTransCopiedPadding + sizeof(mTransCopiedPadding))); // --Bitfield

aStream->WriteChar(mTransPadding);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

FinishViewerCreate TCS 4/11/01

fill in values after creation in a viewer. We need to wait on a few
things that rely on the class ID, since that's not accessible yet in
the constructor
*********************************************************************************/
void CTransaction::FinishViewerCreate()
{
// we used to get the next reference number from our stored array of next #'s,
// but that resulted in ref number = object id + 1, since the number is
// incremented during object creation. So we now just use the object ID.
mReferenceNum = GetDBID(); // rev TCS 4/16/01

if (DB_ObjectClassInfo::AutoEntersDate(GetDBClassID())) // TCS 4/11/01
mDate.SetToNow();
else
mDate.SetToNever();
}
/*********************************************************************************

FinishNonViewerCreate TCS 4/11/01

fill in values after creation in an AFW drag or dialog. We need to wait on a few
things that rely on the class ID, since that's not accessible yet in
the constructor
*********************************************************************************/
void CTransaction::FinishNonViewerCreate()
{
// we used to get the next reference number from our stored array of next #'s,
// but that resulted in ref number = object id + 1, since the number is
// already incremented. So we now just use the object ID.
mReferenceNum = GetDBID(); // rev TCS 4/16/01

if (DB_ObjectClassInfo::AutoEntersDate(GetDBClassID())) // TCS 8/15/02
mDate.SetToNow();
else
mDate.SetToNever();
}
/*********************************************************************************

FinishTemplateCreate TCS 8/17/01

fill in values after creation from a template or recurring transaction
*********************************************************************************/
void CTransaction::FinishTemplateCreate()
{
mReferenceNum = GetDBID();

if (DB_ObjectClassInfo::AutoEntersDate(GetDBClassID())) // TCS 8/15/02
mDate.SetToNow();
}
/*********************************************************************************

CopyFromAnotherClass rev TCS 12/31/02

copy over information from the given record. We fetch the main account.
Subclasses can override if they get different info.

*********************************************************************************/
void CTransaction::CopyFromAnotherClass(DB_PersistentObject *source)
{
// file length may change, so this record should
// never be in the database when this is called
TCS_ASSERTMsg(!IsInDatabase(), TCS_GetErrString(errID_BadDatabaseChange));
TCS_FailNILMsg(source, TCS_GetErrString(errID_BadObject));

DBClass sourceClass = source->GetDBClassID();
DBid sourceID = source->GetDBID();
mMainAccountClass = sourceClass;
mMainAccount = sourceID;
}