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

Job Cost Transactions (Source Code)

Link to: header | transactions directory

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

Comments

CJobCostTransaction

This class manages job cost transactions in the Goldenseal accounting software,
job costing software, and project management software.

It's the parent transaction class for expenses, bids and purchase/work orders.
This class includes job cost information (job, job class, category and
cost location). The subclasses of this class implement job costing
functions in Goldenseal accounting software. We store job cost members
here but don't do any posting, since subclasses have different styles
of handling costs.

SUPERCLASS = CBreakdownTransaction

Constructor

/*********************************************************************************
constructor
*********************************************************************************/
CJobCostTransaction::CJobCostTransaction()
{
mJob = 0;
mLocation = 0;
mCategory = mSubcat = 0;
mJobClass = id_ProjectAccount;
mJobCostPadding = 0;
}

Source Code

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

GetFileLength

return the file length to reserve for this object

*********************************************************************************/
NeoSize CJobCostTransaction::GetFileLength(const CNeoFormat *aFormat) const
{
return THE_SUPERCLASS::GetFileLength(aFormat) +
mName.FileLength(cMenuTextLen) + // rev 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 CJobCostTransaction::CopyFrom(DB_PersistentObject *source, const UInt8 copyFlags)
{
THE_SUPERCLASS::CopyFrom(source, copyFlags);

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

// copy the string and add 'copy' to the name TCS rev 9/18/01
mName = src->mName;
mName.AppendCopyString();

TCS_BlockMove(&src->mJob, &mJob, cCopyFileLength);
}/*********************************************************************************

GetMemberValue

return the value of the member with the given tag

*********************************************************************************/
Boolean CJobCostTransaction::GetMemberValue(const TagType aTag, const TagType aType,
void *aValue) const
{
DBid catSystemID, jobType;

switch (aTag)
{
case tag_location:
return ConvertObjectIDMember(mLocation, id_Location, aValue, aType);
break;

case tag_jobclass:
return ConvertEnumMember(mJobClass, MENU_ExpenseJobTypes, aValue, aType);
break;

case tag_job: // mJobClass is the type of account
return ConvertObjectIDMember(mJob, mJobClass, aValue, aType);
break;

case tag_category:
return ConvertObjectIDMember(mCategory, id_Category, aValue, aType);
break;

case tag_subcategory:
return ConvertObjectIDMember(mSubcat, id_Category, aValue, aType);
break;

case tag_catsystem: // we override since cat system is based on the job
catSystemID = DB_Account::GetJobCatSystem(mJobClass, mJob);
return DB_PersistentObject::ConvertObjectIDMember(catSystemID,
id_CategorySystem, aValue, aType);
break;

case tag_categorycode: // TCS 3/28/01
{
catSystemID = DB_Account::GetJobCatSystem(mJobClass, mJob);
CTextString catCode;

if (catSystemID)
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
CCategorySystem *catSystem =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_CategorySystem, catSystemID),
CCategorySystem);

if (catSystem)
{
DB_ObjectWatcher watcher(catSystem);
catCode = catSystem->GetCategoryCode(mCategory);
}
}
return ConvertMember(&catCode, type_cstring, aValue, aType);
}
break;

case tag_categoryclass: // TCS 3/28/01
{
catSystemID = DB_Account::GetJobCatSystem(mJobClass, mJob);
DBid classID = 0;

if (catSystemID)
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
CCategorySystem *catSystem =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_CategorySystem, catSystemID),
CCategorySystem);

if (catSystem)
{
DB_ObjectWatcher watcher(catSystem);
classID = catSystem->GetCategoryClass(mCategory);
}
}
return ConvertObjectIDMember(classID, id_CategoryClass, aValue, aType);
}
break;

case tag_jobtype: // we override since job type is based on the job
jobType = DB_Account::GetJobAccountType(mJobClass, mJob);
return DB_PersistentObject::ConvertObjectIDMember(jobType,
id_JobType, aValue, aType);
break;

case tag_name: // TCS 9/13/98
case tag_costitem: // TCS 7/10/02 -- for reports
return ConvertMember(&mName, type_cstring, aValue, aType);
break;

case tag_menuname: // for menus, we make sure to return a valid name
{
if (mName.Length())
return ConvertMember(&mName, type_cstring, aValue, aType);
else // if no name, the superclass will build one
return THE_SUPERCLASS::GetMemberValue(aTag, aType, aValue);
}
break;

case tag_customer: // TCS 6/14/00 rev TCS 10/9/00
if (aType == type_cstring)
{
CTextString customerName = GetCustomerName();
return ConvertMember(&customerName, type_cstring, aValue, aType);
}
else
return ConvertObjectIDMember(mJob, mJobClass, aValue, aType);
break;

case tag_vendor: // we fetch the vendor name from the vendor object
{
CTextString vendorName;
if (mMainAccount && mMainAccountClass)
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
DB_PersistentObject *vendor =
gDBFile->GetOneObject(mMainAccountClass, mMainAccount);
if (vendor)
{
DB_ObjectWatcher watcher(vendor);
vendorName = vendor->GetName();
}
}
return ConvertMember(&vendorName, type_cstring, aValue, aType);
}
break;

case tag_jobfullname: // TCS 10/31/02
case tag_jobaddress:
case tag_jobphone:
case tag_jobemail:
return true;
break;
{
CTextString outString;

if (IS_TURTLE_CLASS_ID(mJobClass))
{
DB_PersistentObject *account = gDBFile->GetOneObject(mJobClass, mJob);

if (account)
{
DB_ObjectWatcher watcher(account);

if (aTag == tag_jobfullname)
outString = account->GetFullName();
else if (aTag == tag_jobaddress)
account->GetMemberValue(tag_address, type_cstring, &outString);
else if (aTag == tag_jobphone)
account->GetMemberValue(tag_telephone, type_cstring, &outString);
else if (aTag == tag_jobemail)
account->GetMemberValue(tag_email, type_cstring, &outString);
}
}

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

default:
break;
}
return THE_SUPERCLASS::GetMemberValue(aTag, aType, aValue);
}/*********************************************************************************

SetMemberValue

set the value of the member with the given tag

*********************************************************************************/
Boolean CJobCostTransaction::SetMemberValue(const TagType aTag, const TagType aType,
const void *aValue)
{
switch (aTag)
{
case tag_job:
return ConvertDataToObjectID(aValue, aType, &mJob, mJobClass);
break;

case tag_location:
return ConvertMember(aValue, aType, &mLocation, type_long);
break;

case tag_jobclass:
return ConvertMember(aValue, aType, &mJobClass, type_objclass);
break;

case tag_category:
return ConvertMember(aValue, aType, &mCategory, type_long);
break;

case tag_subcategory:
return ConvertMember(aValue, aType, &mSubcat, type_long);
break;

case tag_name:
return SafeConvertString(aValue, aType, &mName);
break;

case tag_catsystem: // calculated, no need to set
case tag_categorycode:
case tag_categoryclass:
return true;
break;

default:
return THE_SUPERCLASS::SetMemberValue(aTag, aType, aValue);
break;
}
}
/*********************************************************************************

ReadObject

read the persistent object's data in from a stream
*********************************************************************************/
void CJobCostTransaction::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;

ReadTextFromStream(aStream, &mName);

/// aStream->ReadChunk(&mJob, cFileLength);

mJob = aStream->ReadID(); // mfs_sa rev 20feb2k3
mLocation = aStream->ReadID();
mCategory = aStream->ReadID();
mSubcat = aStream->ReadID();

mJobClass = aStream->ReadChar();
mJobCostPadding = aStream->ReadChar();
}/*********************************************************************************

WriteObject

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

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

WriteTextToStream(aStream, mName, cMenuTextLen); // removed -1 TCS 2/28/00

/// aStream->WriteChunk(&mJob, cFileLength);

aStream->WriteID(mJob); // mfs_sa rev 20feb2k3
aStream->WriteID(mLocation);
aStream->WriteID(mCategory);
aStream->WriteID(mSubcat);

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

PostNewRecord TCS 11/20/03

post info for a new record
*********************************************************************************/
void CJobCostTransaction::PostNewRecord(const UInt8 creationType)
{
PostUseCount(mJobClass, mJob);
PostUseCount(id_Location, mLocation);
PostUseCount(id_Category, mCategory);
PostUseCount(id_Category, mSubcat);

// let the superclass do any posting
THE_SUPERCLASS::PostNewRecord(creationType);
}
/*********************************************************************************

PostDeletion TCS 11/20/03

post info from a deleted record
*********************************************************************************/
void CJobCostTransaction::PostDeletion(const Boolean postAudit)
{
PostUseCount(mJobClass, mJob, cRemoveItem);
PostUseCount(id_Location, mLocation, cRemoveItem);
PostUseCount(id_Category, mCategory, cRemoveItem);
PostUseCount(id_Category, mSubcat, cRemoveItem);

// let the superclass do any posting
THE_SUPERCLASS::PostDeletion(postAudit);
}
/*********************************************************************************

PostRecordChanging TCS 11/20/03

a record will be changing. Post the change.
*********************************************************************************/
void CJobCostTransaction::PostRecordChanging(const Boolean accountChanging, const Boolean jobChanging)
{
PostUseCount(mJobClass, mJob, cRemoveItem);
PostUseCount(id_Location, mLocation, cRemoveItem);
PostUseCount(id_Category, mCategory, cRemoveItem);
PostUseCount(id_Category, mSubcat, cRemoveItem);

THE_SUPERCLASS::PostRecordChanging(accountChanging, jobChanging);
}
/*********************************************************************************

PostRecordChanged TCS 11/20/03

a record has changed. Post it.
*********************************************************************************/
void CJobCostTransaction::PostRecordChanged(const CMoney &oldAmount, const Boolean accountChanged,
const Boolean jobChanged)
{
PostUseCount(mJobClass, mJob);
PostUseCount(id_Location, mLocation);
PostUseCount(id_Category, mCategory);
PostUseCount(id_Category, mSubcat);

THE_SUPERCLASS::PostRecordChanged(oldAmount, accountChanged, jobChanged);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

GetJobName TCS 7/29/99

return the name of the job account
*********************************************************************************/
CTextString CJobCostTransaction::GetJobName()
{
if (mJob && mJobClass)
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
DB_PersistentObject *job = gDBFile->GetOneObject(mJobClass, mJob);
if (job)
{
DB_ObjectWatcher watcher(job);
return job->GetName();
}
}
// if we get this far, we don't have a name so just return blank
return cEmptyString;
}
/*********************************************************************************

GetCustomerName TCS 10/30/01

return the name of the customer. We generally use the job name, but for projects
we fetch the project's customer account

*********************************************************************************/
CTextString CJobCostTransaction::GetCustomerName() const
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));

if (IS_TURTLE_CLASS_ID(mJobClass))
{
DB_PersistentObject *account = gDBFile->GetOneObject(mJobClass, mJob);

if (account)
{
DB_ObjectWatcher watcher(account);
return account->GetCustomerName();
}
}

return cEmptyString;
}
/*********************************************************************************

GetCompanyDivision TCS 4/10/04

return the company division. We use the job account if possible, otherwise
the main account's division.

*********************************************************************************/
DBid CJobCostTransaction::GetCompanyDivision() const
{
DBid id = 0;

if (IS_TURTLE_CLASS_ID(mJobClass))
{
DB_PersistentObject *job = gDBFile->GetOneObject(mJobClass, mJob);

if (job)
{
DB_ObjectWatcher watcher(job);
id = job->GetCompanyDivision();
}
}

if (id)
return id;
else
return THE_SUPERCLASS::GetCompanyDivision();
}
/*********************************************************************************

NeedsJobAccountValue TCS 10/24/00

return whether the job account must be filled in. We require it if
prefs say so

*********************************************************************************/
Boolean CJobCostTransaction::NeedsJobAccountValue() const
{
return GetPrefsBoolean(id_DataPrefs, tag_requirejobaccount);
}
/*********************************************************************************

FillDataReport TCS 9/6/02

fill in a diagnostic table that shows data field values.

*********************************************************************************/
void CJobCostTransaction::FillDataReport(CTCS_Table *table, CNeoStream *stream) const
{
TCS_FailNILMsg(table, TCS_GetErrString(errID_BadTable));
TCS_FailNILMsg(stream, TCS_GetErrString(errID_BadStream));

THE_SUPERCLASS::FillDataReport(table, stream);

FillFieldStringRow(table, stream, tag_name, mName);

FillFieldObjectIDRow(table, stream, tag_job, mJob, mJobClass);
FillFieldObjectIDRow(table, stream, tag_location, mLocation, id_Location);
FillFieldObjectIDRow(table, stream, tag_category, mCategory, id_Category);
FillFieldObjectIDRow(table, stream, tag_subcategory, mSubcat, id_Category);

FillFieldEnumRow(table, stream, tag_jobclass, mJobClass, MENU_AccountClasses);
FillFieldStockRow(table, stream, stockID_Padding, cCharSize, SInt32(mJobCostPadding));

}