Accounting Software
Small Business Software Estimating Software
Unit Cost SoftwareConstruction Estimating SoftwareProject Estimating SoftwareCost Estimation SoftwareCost Estimating SoftwareConstruction Management SoftwareBusiness Management Software

Estimating Dimensions (Source Code)

Link to: header | unit cost directory

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

Comments

CDimension

This class manages estimating dimensions in the Goldenseal accounting software,
estimating software, unit cost software, job costing software and construction estimating software.

a dimensional measurement, used for unit price estimating.

SUPERCLASS = DB_DescribedPersistent

Constructor

/*********************************************************************************
default constructor
*********************************************************************************/
CDimension::CDimension()
{
mSuggestAmount = 0;
mDimensionType = dimension_number;
mUnitSize = 0;
mLayoutID = 0;

mExpansionLong = 0; // TCS 9/9/02
mExpansionShort = 0;
mExpansionMoney = 0;

mCalcDirty = true; // TCS 6/7/01

mEndSafetyTag = tag_endsafetytag; // TCS 9/8/02
}

Source Code

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

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 CDimension::CopyFrom(DB_PersistentObject *source, const UInt8 copyFlags)
{
THE_SUPERCLASS::CopyFrom(source, copyFlags);

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

TCS_BlockMove(&src->mSuggestAmount, &mSuggestAmount, cCopyFileLength);

mDependentArray = src->mDependentArray;
mChoiceList = src->mChoiceList;
}
/*********************************************************************************

GetFileLength

return the file length used by this object

*********************************************************************************/
NeoSize CDimension::GetFileLength(const CNeoFormat *aFormat) const
{
return THE_SUPERCLASS::GetFileLength(aFormat) +
ARRAY_FILE_SIZE(mDependentArray) +
mChoiceList.FileLength(cStandardTextLen) + cFileLength;
}/*********************************************************************************

GetMemberValue

return the value of the member with the given tag

*********************************************************************************/
Boolean CDimension::GetMemberValue(const NeoTag aTag, const NeoTag aType,
void *aValue) const
{
switch (aTag)
{
case tag_unitsize: // TCS 3/5/01
return ConvertObjectIDMember(mUnitSize, id_UnitSize, aValue, aType);
break;

case tag_type:
return ConvertEnumMember(mDimensionType, MENU_DimensionTypes, aValue, aType);
break;

case tag_amount: // suggested value
return ConvertMember(&mSuggestAmount, type_number, aValue, aType);
break;

case tag_listitems: // TCS 3/15/01
return ConvertMember(&mChoiceList, type_cstring, aValue, aType);
break;

case tag_layoutid: // TCS 8/29/02
return ConvertMember(&mLayoutID, type_long, aValue, aType);
break;

case tag_layoutname: // TCS 8/29/02
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
CTextString outString;
if (mLayoutID)
outString = DB_Layout::GetLayoutName(mLayoutID, id_DimensionLayout);
return ConvertMember(&outString, type_cstring, aValue, aType);
}
break;

case tag_usedby: // TCS 9/2/02
if (mDependentArray.GetCount() > 0)
{
SObjectInfo info;
mDependentArray.FetchItemAt(1, info);
return ConvertObjectIDMember(info.itemID, info.classID, aValue, aType);
}
else if (aType == type_cstring)
{
CTextString outString;
return ConvertMember(&outString, type_cstring, aValue, aType);
}
else
{
DBid id = 0;
return ConvertMember(&id, type_objectid, aValue, aType);
}
break;

case tag_usedbyclass: // TCS 9/2/02
if (mDependentArray.GetCount() > 0)
{
SObjectInfo info;
mDependentArray.FetchItemAt(1, info);
return ConvertMember(&info.classID, type_objclass, aValue, aType);
}
else
{
DBClass id = 0;
return ConvertMember(&id, type_objclass, aValue, aType);
}
break;

case tag_usedbycount: // TCS 9/3/02
{
SInt32 count = mDependentArray.GetCount();
return ConvertMember(&count, type_long, aValue, aType);
}
break;

case tag_allownegative: // TCS 3/25/02
return ConvertBitFieldMember(mAllowNegatives, aValue, aType);
break;

/*case tag_location:
return ConvertBitFieldMember(mUseInLocations, aValue, aType);
break;*/

case tag_layouttag: // TCS 4/30/01 rev TCS 1/1/02
{
CTextString outString = CCalculatorList::GetCalculatorTagString(GetDBClassID(), GetDBID());
return ConvertMember(&outString, type_cstring, aValue, aType);
}
break;

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

SetMemberValue

set the value of the member with the given tag

*********************************************************************************/
Boolean CDimension::SetMemberValue(const NeoTag aTag, const NeoTag aType,
const void *aValue)
{
switch (aTag)
{
case tag_unitsize: // TCS 3/5/01
return ConvertDataToObjectID(aValue, aType, &mUnitSize, id_UnitSize);
break;

case tag_type:
return ConvertMember(aValue, aType, &mDimensionType, type_enum);
break;

case tag_layoutid: // TCS 8/29/02
return ConvertMember(aValue, aType, &mLayoutID, type_long);
break;

case tag_amount:
return ConvertMember(aValue, aType, &mSuggestAmount, type_number);
break;

case tag_listitems: // TCS 3/15/01 rev 6/12/01
return SafeConvertString(aValue, aType, &mChoiceList);
break;

case tag_allownegative: // TCS 3/25/02
mAllowNegatives = ConvertDataToBitField(aValue, aType);
return true;
break;

/*case tag_location: // TCS 3/16/01
mUseInLocations = ConvertDataToBitField(aValue, aType);
return true;
break;*/

case tag_layouttag: // calculated, no need to set TCS 4/30/01
case tag_layoutname: // TCS 8/29/02
case tag_usedby: // TCS 9/2/02
return true;
break;

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

ReadObject

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

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

THE_SUPERCLASS::ReadObject(aStream, aTag);

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

ReadInfoArrayFromStream(aStream, mDependentArray, cHasSafetyTag);

ReadTextFromStream(aStream, &mChoiceList);

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

mSuggestAmount.ReadFromStream(aStream); // mfs_sa rev 20feb2k3

mExpansionLong = aStream->ReadID();

mExpansionShort = aStream->ReadUShort();

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

mUnitSize = aStream->ReadID();
mLayoutID = aStream->ReadID();

mExpansionMoney.ReadFromStream(aStream);

mEndSafetyTag = aStream->ReadEndSafetyTag(this);

if (!IsValidEndTag(mEndSafetyTag)) // TCS 9/8/02
ReportDamagedObject(GetDBClassID(), GetDBID());
}
/*********************************************************************************

WriteObject

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

// make sure we have valid data to write TCS 9/8/02
if (!IsValidEndTag(mEndSafetyTag))
{
ReportDamagedObject(GetDBClassID(), GetDBID());
mEndSafetyTag = tag_endsafetytag; // TCS 11/26/02
}

CNeoDebugExport checker(aStream, this, cCheckTooSmall);

THE_SUPERCLASS::WriteObject(aStream, aTag);

WriteInfoArrayToStream(aStream, mDependentArray, cHasSafetyTag);

WriteTextToStream(aStream, mChoiceList, cStandardTextLen);

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

mSuggestAmount.WriteToStream(aStream); // mfs_sa rev 20feb2k3

aStream->WriteID(mExpansionLong);

aStream->WriteUShort(mExpansionShort);

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

aStream->WriteID(mUnitSize);
aStream->WriteID(mLayoutID);

mExpansionMoney.WriteToStream(aStream);

aStream->WriteEndSafetyTag(mEndSafetyTag, this);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

PostNewRecord TCS 11/22/03

post info for a new record
*********************************************************************************/
void CDimension::PostNewRecord(const UInt8 creationType)
{
PostUseCount(id_UnitSize, mUnitSize);

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

PostDeletion TCS 11/22/03

post info from a deleted record
*********************************************************************************/
void CDimension::PostDeletion(const Boolean postAudit)
{
PostUseCount(id_UnitSize, mUnitSize, cRemoveItem);

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

PostRecordChanging TCS 11/22/03

a record will be changing. Post the change.
*********************************************************************************/
void CDimension::PostRecordChanging(const Boolean accountChanging, const Boolean jobChanging)
{
PostUseCount(id_UnitSize, mUnitSize, cRemoveItem);

// let the superclass do any posting
THE_SUPERCLASS::PostRecordChanging(accountChanging, jobChanging);
}
/*********************************************************************************

PostRecordChanged TCS 11/22/03

a record has changed. Post it.
*********************************************************************************/
void CDimension::PostRecordChanged(const CMoney &oldAmount, const Boolean accountChanged,
const Boolean jobChanged)
{
PostUseCount(id_UnitSize, mUnitSize);

// let the superclass do any posting
THE_SUPERCLASS::PostRecordChanged(oldAmount, accountChanged, jobChanged);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

CanBeDeleted TCS 9/2/02

can this item be deleted? If it is included in any calculated dimensions,
it can't be.
*********************************************************************************/
Boolean CDimension::CanBeDeleted(const Boolean giveMessage) const
{
if (mDependentArray.GetCount() > 0) // we have dependents
{
if (giveMessage)
{
TCS_ErrorAlert(TCS_GetMsgString(msgID_CantDeleteItem));
}
return false;
}
else // pass it along for judgement
return THE_SUPERCLASS::CanBeDeleted(giveMessage);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

GetSuggestedAmount (static) TCS 2/1/01 rev 6/6/01

return the suggested amount for the dimension with the given tag
*********************************************************************************/
CMoney CDimension::GetSuggestedAmount(const TagType tag)
{
DBClass classID = CCalculatorList::GetCalculatorClassID(tag);
DBid itemID = CCalculatorList::GetCalculatorItemID(tag);

if (classID == id_Dimension || classID == id_LocationDimension)
{
CDimension *dimension =
TCS_SAFE_CAST(gDBFile->GetOneObject(classID, itemID),
CDimension);

if (dimension)
{
DB_ObjectWatcher watcher(dimension);
return dimension->GetSuggestedAmount();
}
else if (GetPrefsBoolean(id_InterfacePrefs, tag_warnmissingcalc)) // TCS 10/28/02
ReportMissingObject(classID, itemID);
}
else if (classID == id_CalcDimension || classID == id_CalcLocation)
{
CCalcLocation *calcDimension =
TCS_SAFE_CAST(gDBFile->GetOneObject(classID, itemID),
CCalcLocation);

if (calcDimension)
{
DB_ObjectWatcher watcher(calcDimension);
return calcDimension->GetSuggestedAmount();
}
else if (GetPrefsBoolean(id_InterfacePrefs, tag_warnmissingcalc)) // TCS 10/28/02
ReportMissingObject(classID, itemID);
}
else
{
TCS_DebugAlert("Oops, bad class in CDimension::GetSuggestedAmount!");
}

return 0;
}
/*********************************************************************************

GetSuggestedAmount TCS 1/2/02

return the suggested amount for this dimension
*********************************************************************************/
CMoney CDimension::GetSuggestedAmount() const
{

if (mDimensionType == dimension_list)
return 1; // for lists, the default is 1 (the first item)
else if (mDimensionType == dimension_checkbox)
return 0; // for checkboxes, the default is 0 (false)
else
return mSuggestAmount;
}
/*********************************************************************************

GetFieldTypeForTag (static) TCS 5/22/01 renamed 4/30/02

return the field type for the dimension with the given tag
*********************************************************************************/
UInt8 CDimension::GetFieldTypeForTag(const TagType tag)
{
DBClass classID = CCalculatorList::GetCalculatorClassID(tag);
DBid itemID = CCalculatorList::GetCalculatorItemID(tag);
return GetFieldTypeForDimension(classID, itemID);
}
/*********************************************************************************

GetFieldTypeForDimension (static) TCS 5/22/01 renamed 4/30/02

return the field type for the dimension with the given class and id
*********************************************************************************/
UInt8 CDimension::GetFieldTypeForDimension(const DBClass classID, const DBid itemID)
{
if (classID == id_Dimension || classID == id_LocationDimension)
{
CDimension *dimension =
TCS_SAFE_CAST(gDBFile->GetOneObject(classID, itemID),
CDimension);

if (dimension)
{
DB_ObjectWatcher watcher(dimension);
return dimension->GetFieldType();
}
else if (GetPrefsBoolean(id_InterfacePrefs, tag_warnmissingcalc)) // TCS 10/28/02
ReportMissingObject(classID, itemID);
}
else if (classID == id_CalcDimension || classID == id_CalcLocation)
{
CCalcLocation *calcDimension =
TCS_SAFE_CAST(gDBFile->GetOneObject(classID, itemID),
CCalcLocation);

if (calcDimension)
{
DB_ObjectWatcher watcher(calcDimension);
return calcDimension->GetFieldType();
}
else if (GetPrefsBoolean(id_InterfacePrefs, tag_warnmissingcalc)) // TCS 10/28/02
ReportMissingObject(classID, itemID);
}
else
{
TCS_DebugAlert("Oops, bad class in CDimension::GetFieldTypes!");
}

return 0;
}
/*********************************************************************************

GetCalcDimensionValue TCS 10/18/01

get the calculated value of this dimension

NOTE- this method can't be const, since some forms store the value

*********************************************************************************/
CMoney CDimension::GetCalcDimensionValue(TDimensionArray &dimensionArray,
TDimensionArray &/*locDimensionArray*/)
{
TagType thisTag = CCalculatorList::GetCalculatorTag(GetDBClassID(), GetDBID());
return CEstimate::GetDimensionValue(thisTag, dimensionArray);
}
/*********************************************************************************

GetCalcLocationValue TCS 10/18/01

get the calculated value of this dimension

NOTE- this method can't be const, since some forms store the value

*********************************************************************************/
CMoney CDimension::GetCalcLocationValue(TDimensionArray &/*dimensionArray*/,
TDimensionArray &locDimensionArray,
const SInt32 locationID)
{
TagType thisTag = CCalculatorList::GetCalculatorTag(GetDBClassID(), GetDBID());
return CEstimate::GetLocationDimensionValue(thisTag, locDimensionArray, locationID);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

FillMenuHandle TCS 5/22/01

fill the menu handle for a popup menu of list items
*********************************************************************************/
void CDimension::FillMenuHandle(TCS_MenuHandle menuH)
{
TCS_FailNILMsg(menuH, TCS_GetErrString(errID_BadMenu));

// we need to parse menu items from the list text
if (mDimensionType == dimension_list)
{
CTextString menuText;

for (UInt8 counter = 1; counter <= cMaxDimensionList; counter++)
{
menuText = mChoiceList.GetNthLine(counter);

if (menuText.Length())
TCS_AppendMenuText(menuH, menuText); // rev TCS 12/8/01
}
}
}
/*********************************************************************************

FillCalculationReport TCS 12/19/02

fill in a report of calculations and dependencies. A dimension is the end
of the road, so just fill in this item.
*********************************************************************************/
void CDimension::FillCalculationReport(CTextOutputStream &stream, CEstimate *estimate,
const UInt8 level, SInt32 &counter, const UInt8 calcType)
{
CCursorSpinner spinner;
++spinner;

counter++; // TCS 1/8/03
if (counter > cRecursionLimit)
return;

// fill in the estimate value TCS 1/2/03
CMoney calcValue = 0;

if (estimate)
{
TagType tag = CCalculatorList::GetCalculatorTag(GetDBClassID(), GetDBID());
calcValue = estimate->GetDimensionValue(tag);
}

stream.WriteString(calcValue.GetNumberString());

// indent tabs
stream.WriteTabs(level);

// calculation type
CTextString outName;
if (calcType)
{
TCS_GetEnumItemName(MENU_CalcDimensionMathTypes, calcType, &outName);
}
else
outName = TCS_GetStockString(stockID_StartWith);

outName.Append(cDashChar);
outName.Append(cSpaceChar);

// name of this item
outName.Append(GetName());
outName.AppendCVExportString(GetDBID());
stream.WriteString(outName);

// done with this line
stream.WriteEndOfLine();
}
/*********************************************************************************

FillUseReport TCS 1/8/03

fill in a report of items dependent on this one.
*********************************************************************************/
void CDimension::FillUseReport(CTextOutputStream &stream, CEstimate *estimate,
const UInt8 level, SInt32 &counter)
{
CCursorSpinner spinner;
++spinner;

counter++;
if (counter > cRecursionLimit)
return;

// fill in the estimate value TCS 1/2/03
CMoney calcValue = 0;

if (estimate)
{
TagType tag = CCalculatorList::GetCalculatorTag(GetDBClassID(), GetDBID());
calcValue = estimate->GetDimensionValue(tag);
}

stream.WriteString(calcValue.GetNumberString());

// indent tabs
stream.WriteTabs(level);

CTextString outName = GetName();
outName.AppendCVExportString(GetDBID());
stream.WriteString(outName);

// done with this line
stream.WriteEndOfLine();

// go thru the dependent array and include them too
TObjectInfoArrayIterator iterator (mDependentArray);
SObjectInfo info;
DB_PersistentObject *calculator;

while (iterator.Next(info))
{
calculator = gDBFile->GetOneObject(info.classID, info.itemID);

if (calculator)
{
DB_ObjectWatcher watcher (calculator);
calculator->FillUseReport(stream, estimate, level + 1, counter);
}
else
{
stream.WriteTabs(level + 1);
stream.WriteString(TCS_GetStockString(stockID_MissingItem));
stream.WriteEndOfLine();
}
}
}
/*********************************************************************************

FillDataReport TCS 9/7/02

fill in a diagnostic table that shows data field values.

*********************************************************************************/
void CDimension::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);

FillFieldArrayRow(table, stream, "mDependentArray", mDependentArray);

FillFieldStringRow(table, stream, tag_listitems, mChoiceList);

FillFieldTagRow(table, stream, tag_amount, cMoneySize, mSuggestAmount.GetNumberString());

FillFieldStockRow(table, stream, stockID_Expansion, cLongSize, mExpansionLong);
FillFieldStockRow(table, stream, stockID_Expansion, cShortSize, SInt32(mExpansionShort));

FillFieldTagRow(table, stream, tag_type, cCharSize, SInt32(mDimensionType));
FillFieldBitRow(table, stream, "mCalcDirty", mCalcDirty, true);
FillFieldBitRow(table, stream, tag_allownegative, mAllowNegatives);
FillFieldStockRow(table, stream, stockID_Padding, -6, SInt32(mSpareByte));

FillFieldObjectIDRow(table, stream, tag_unitsize, mUnitSize, id_UnitSize);
FillFieldTagRow(table, stream, tag_layoutid, cLongSize, mLayoutID);

FillFieldStockRow(table, stream, stockID_Expansion, cMoneySize, mExpansionMoney.GetCurrencyString());

FillEndSafetyTag(table, stream, mEndSafetyTag);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

UpdateDependentDimensions TCS 6/6/01 major rev 8/24/01 total rewrite 10/18/01

update dimensions in an estimate's dimension array. We don't need to do any
calculating here, but we must pass it along to any dependent calculators

*********************************************************************************/
void CDimension::UpdateDependentDimensions(TDimensionArray &dimensionArray,
TDimensionArray &locDimensionArray)
{
if (mDependentArray.GetCount() > 0)
{
TObjectInfoArrayIterator iterator(mDependentArray);
SObjectInfo info;
DB_PersistentObject *calculator = nil;

while (iterator.Next(info))
{
// we skip unit costs TCS 9/3/02
if (info.classID == id_CostItem || info.classID == id_Assembly)
continue;

calculator = gDBFile->GetOneObject(info.classID, info.itemID);

if (calculator)
{
DB_ObjectWatcher watcher(calculator);
calculator->UpdateDependentDimensions(dimensionArray, locDimensionArray);
}
}
}
}
/*********************************************************************************

UpdateDependentLocations TCS 11/5/01

update location dimensions in an estimate's dimension array. We don't need to do any
calculating here, but we must pass it along to any dependent calculators

*********************************************************************************/
void CDimension::UpdateDependentLocations(TDimensionArray &dimensionArray,
TDimensionArray &locDimensionArray,
const SInt32 locationID)
{
if (mDependentArray.GetCount() > 0)
{
TObjectInfoArrayIterator iterator(mDependentArray);
SObjectInfo info;
DB_PersistentObject *calculator = nil;

while (iterator.Next(info))
{
// we skip unit costs TCS 9/3/02
if (info.classID == id_CostItem || info.classID == id_Assembly)
continue;

calculator = gDBFile->GetOneObject(info.classID, info.itemID);

if (calculator)
{
DB_ObjectWatcher watcher(calculator);

if (info.classID == id_CalcLocation)
{
calculator->UpdateDependentLocations(dimensionArray, locDimensionArray,
locationID);
}
else // rev TCS 1/2/02
{
calculator->UpdateDependentDimensions(dimensionArray, locDimensionArray);
}
}
}
}
}