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);
}
}
}
}
}
|