Accounting Software
Small Business Software Estimating Software
Time Tracking SoftwareTime Management SoftwareTime Billing SoftwareContact Management SoftwareCustomer Management SoftwareProject Management SoftwareBusiness Management Software

Cost Breakdown Tables (Source Code)

Link to: header | source 1 | source 3 | tables directory

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

Source Code

This class manages cost breakdown tables for the Goldenseal accounting software,
small business management software, construction project management software and
construction accounting software.

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

GetLaborTotal TCS 11/8/02

get the sum of labor costs from this table

*********************************************************************************/
CMoney CCostBreakdownTable::GetLaborTotal()
{
CMoney theSum = 0;
TableIndexT amountCol = GetMemberCol(tag_amount);
TableIndexT costTypeCol = GetMemberCol(tag_costarea);
TableIndexT itemCol = GetMemberCol(tag_costitem);
TableIndexT quantityCol = GetMemberCol(tag_quantity);
UInt8 costArea = 0;

// if invalid columns, return zero
if (!amountCol || !costTypeCol)
return theSum;

// if we have a valid column, fetch the total
for ( TableIndexT row = 1 ; row <= GetNumRows() ; row++ )
{
costArea = GetCellValue(row, costTypeCol);

switch (costArea)
{
case costtype_labor: // we include these costs
case costtype_unlistedlabor:
theSum += GetCellMoneyValue(row, amountCol);
break;

case costtype_assembly:
case costtype_assmlabor:
{
// for assemblies, we need to fetch labor subtotal
DBid assemblyID = GetCellValue(row, itemCol);
CAssembly *assembly =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_Assembly, assemblyID),
CAssembly);
if (assembly)
{
DB_ObjectWatcher watcher(assembly);

CMoney laborCost = assembly->GetJobCostAmount(costtype_labor);
CMoney quantity = GetCellMoneyValue(row, quantityCol);
laborCost *= quantity;

theSum += laborCost;
}
}
break;

default:
break;
}
}
return theSum;
}
/*********************************************************************************

GetMaterialTotal TCS 11/8/02

get the sum of material costs from this table

*********************************************************************************/
CMoney CCostBreakdownTable::GetMaterialTotal()
{
CMoney theSum = 0;
TableIndexT amountCol = GetMemberCol(tag_amount);
SInt32 costTypeCol = GetMemberCol(tag_costarea);
TableIndexT itemCol = GetMemberCol(tag_costitem);
TableIndexT quantityCol = GetMemberCol(tag_quantity);
UInt8 costArea = 0;

// if invalid columns, return zero
if (!amountCol || !costTypeCol)
return theSum;

// if we have a valid column, fetch the total
for ( TableIndexT row = 1 ; row <= GetNumRows() ; row++ )
{
costArea = GetCellValue(row, costTypeCol);

switch (costArea)
{
case costtype_material: // we include these costs
case costtype_unlistedmaterial:
theSum += GetCellMoneyValue(row, amountCol);
break;

case costtype_assembly:
case costtype_assmmaterial:
{
// for assemblies, we need to fetch material subtotal
DBid assemblyID = GetCellValue(row, itemCol);
CAssembly *assembly =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_Assembly, assemblyID),
CAssembly);
if (assembly)
{
DB_ObjectWatcher watcher(assembly);

CMoney materialCost = assembly->GetJobCostAmount(costtype_material);
CMoney quantity = GetCellMoneyValue(row, quantityCol);
materialCost *= quantity;

theSum += materialCost;
}
}
break;

default:
break;
}
}
return theSum;
}
/*********************************************************************************

GetSubcontractorTotal TCS 1/23/04

get the sum of subcontractor costs from this table

*********************************************************************************/
CMoney CCostBreakdownTable::GetSubcontractorTotal()
{
CMoney theSum = 0;
TableIndexT amountCol = GetMemberCol(tag_amount);
SInt32 costTypeCol = GetMemberCol(tag_costarea);
TableIndexT itemCol = GetMemberCol(tag_costitem);
TableIndexT quantityCol = GetMemberCol(tag_quantity);
UInt8 costArea = 0;

// if invalid columns, return zero
if (!amountCol || !costTypeCol)
return theSum;

// if we have a valid column, fetch the total
for ( TableIndexT row = 1 ; row <= GetNumRows() ; row++ )
{
costArea = GetCellValue(row, costTypeCol);

switch (costArea)
{
case costtype_subcontractor: // we include these costs
case costtype_unlistedsub:
case costtype_bid:
theSum += GetCellMoneyValue(row, amountCol);
break;

case costtype_assembly:
{
// for assemblies, we need to fetch subcontractor subtotal
DBid assemblyID = GetCellValue(row, itemCol);
CAssembly *assembly =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_Assembly, assemblyID),
CAssembly);
if (assembly)
{
DB_ObjectWatcher watcher(assembly);

CMoney subCost = assembly->GetJobCostAmount(costtype_subcontractor);
CMoney quantity = GetCellMoneyValue(row, quantityCol);
subCost *= quantity;

theSum += subCost;
}
}
break;

default:
break;
}
}
return theSum;
}
/*********************************************************************************

GetTaxableAmount TCS 8/14/01

get the taxable amount

*********************************************************************************/
CMoney CCostBreakdownTable::GetTaxableAmount()
{
CMoney total = 0,
rowAmount;

TableIndexT taxableCol = GetMemberCol(tag_taxable),
amountCol = GetMemberCol(tag_amount);

if (amountCol)
{
for ( TableIndexT row = 1 ; row <= GetNumRows() ; row++ )
{
rowAmount = GetCellMoneyValue(row, amountCol);

if (taxableCol)
{
if (IsChecked(row, taxableCol))
total += rowAmount;
}
else
total += rowAmount;
}
}

return total;
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

IsMixedCV TCS 3/13/99

return whether the given cell is currently a cv field

*********************************************************************************/
Boolean CCostBreakdownTable::IsMixedCV(const TableIndexT row,
const TableIndexT col) const
{
if (GetColTag(col) == tag_costitem)
{
return RowUsesObjectID(row);
}
// if we got this far, we must not be a mixed cv
return false;
}
/*********************************************************************************

HasCostItem TCS 8/7/01

return whether the given cost type refers to a cost item or assembly

*********************************************************************************/
Boolean CCostBreakdownTable::HasCostItem(const UInt8 costArea) const
{
return costArea == costtype_material || costArea == costtype_labor ||
costArea == costtype_subcontractor || costArea == costtype_other ||
costArea == costtype_equipment || costArea == costtype_assembly ||
costArea == costtype_assmlabor || costArea == costtype_assmmaterial;
}
/*********************************************************************************

RowUsesPercent TCS 11/5/02

return whether the given row displays a percent value

*********************************************************************************/
Boolean CCostBreakdownTable::RowUsesPercent(const TableIndexT row) const
{
UInt8 costArea = GetCostArea(row);

if (CCostBreakdownEntry::CostItemIsPercent(costArea))
return true;
else
return false;
}
/*********************************************************************************

CostItemIsUnitCost TCS 11/8/01

return whether the given row uses a standard unit cost (assembly or cost item).
Category breakdown tables don't ever show them. Item breakdown tables override
this to check the cost area.

*********************************************************************************/
Boolean CCostBreakdownTable::CostItemIsUnitCost(const TableIndexT /*row*/) const
{
return false;
}
/*********************************************************************************

CostItemIsSoftCost TCS 7/3/00 rev 4/29/02

return whether the given row is a soft cost item

*********************************************************************************/
Boolean CCostBreakdownTable::CostItemIsSoftCost(const TableIndexT row) const
{
UInt8 costArea = GetCostArea(row);

if (costArea)
{
return CCostBreakdownEntry::CostItemIsSoftCost(costArea);
}
else
return true;
}
/*********************************************************************************

CostItemIsUnlisted TCS 7/4/00 rev 4/29/02

return whether the given row is a soft cost item

*********************************************************************************/
Boolean CCostBreakdownTable::CostItemIsUnlisted(const TableIndexT row) const
{
UInt8 costArea = GetCostArea(row);

if (costArea)
{
return CCostBreakdownEntry::CostItemIsUnlisted(costArea);
}
else
return true;
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

UpdateItemDetails moved TCS 9/27/99

a cost item has changed, so change the data that comes from it.

*********************************************************************************/
void CCostBreakdownTable::UpdateItemDetails(const TableIndexT row)
{
// we only update if there's a cv field TCS 9/27/99
if (!RowUsesObjectID(row))
return;

CTextString cstring;
Boolean isTaxable = false;
TableIndexT sizeCol = GetMemberCol(tag_unitsize);
UInt8 colType;
CMoney zeroValue = 0, amount;

// fetch ID's for the cost item.
SInt32 costArea = GetMemberColValue(row, tag_costarea);
UInt8 costAreaClass = DB_ClassDescriptor::GetCostAreaClass(costArea);
DBid costItemID = GetMemberColValue(row, tag_costitem);

// which field should we use for the price?
TagType priceTag = CCostBreakdownEntry::GetPriceTag(costArea, GetOwnerClass(), IsOnSale());

// now fetch the cost item itself
DB_PersistentObject *costItem = nil;
if (costAreaClass && priceTag) // rev TCS 1/18/02
{
costItem = gDBFile->GetOneObject(costAreaClass, costItemID);
}

// if there's no cost item, we clear some fields
if (costItem == nil)
{ // rev TCS 9/26/01, 9/27/01
if (sizeCol) // TCS 1/5/03
{
colType = GetColType(row, sizeCol);
if (colType == coltype_cv || colType == coltype_lookup)
SetMemberCV(row, tag_unitsize, 0);
}

if (mOwnerClass != id_LaborHours && mOwnerClass != id_EquipmentHours)
SetMemberColMoney(row, tag_unitcost, zeroValue);

return;
}

// there is a cost item, so let's fill in the fields
// with info from the cost item
DB_ObjectWatcher watcher(costItem);

// fill in unit size, if it's visible rev TCS 9/26/01
if (sizeCol) // rev TCS 1/5/03
{
DBid unitSizeID;
costItem->GetMemberValue(tag_unitsize, type_objectid, &unitSizeID);

colType = GetColType(row, sizeCol); // TCS bugfix 11/8/01
if (colType == coltype_cv || colType == coltype_lookup)
SetMemberCV(row, tag_unitsize, unitSizeID);
}

// fill in unit cost
if (costArea == costtype_assmlabor)
{
amount = costItem->GetLaborPrice();

if (mAdjustPercent.IsNonZero()) // TCS 1/22/04
amount.Multiply(mAdjustPercent.GetPercentMultiplier());

SetMemberColString(row, tag_unitcost, amount.GetCurrencyString());
}
else if (costArea == costtype_assmmaterial)
{
amount = costItem->GetMaterialPrice();

if (mAdjustPercent.IsNonZero()) // TCS 1/22/04
amount.Multiply(mAdjustPercent.GetPercentMultiplier());

SetMemberColString(row, tag_unitcost, amount.GetCurrencyString());
}
else
{
TCS_ASSERTMsg(costItem->GetMemberValue(priceTag, type_money, &amount),
TCS_GetValueErrString(priceTag));

if (mAdjustPercent.IsNonZero()) // TCS 1/22/04
amount.Multiply(mAdjustPercent.GetPercentMultiplier());

if (mOwnerClass != id_LaborHours && mOwnerClass != id_EquipmentHours)
SetMemberColString(row, tag_unitcost, amount.GetCurrencyString());
}

// fill in suggested quantity TCS 7/5/01
CMoney quantity = FillSuggestedQuantity(row, costItem);

// fill in discount percentage TCS 1/5/03
if (mOwnerClass == id_Sale) // TCS 6/10/03
{
CMoney discount = costItem->GetDiscountForCustomer(mCustDiscount);
SetMemberColString(row, tag_discount, discount.GetPercentString());
}

// fill in taxable columns TCS 7/23/01
isTaxable = costItem->IsTaxable(mOwnerClass);

if (isTaxable)
{ // fill in taxable column
SetMemberColString(row, tag_taxable, cCheckMarkString);
}
else
{ // erase taxable column
SetMemberColString(row, tag_taxable, cEmptyString);
}

// fill in labor hours TCS 5/16/02
CMoney laborHours = costItem->GetLaborHours();
SetMemberColNumber(row, tag_unithours, laborHours);
SetMemberColNumber(row, tag_laborhours, laborHours * quantity);

// fill in crew size
SetMemberColNumber(row, tag_crewsize, costItem->GetCrewSize());

// store variable costing info TCS 4/18/03
SetRowUsesVariableCost(row, costItem->AllowVariablePrices());
}
/*********************************************************************************

ResetCostItem TCS 3/13/99

erase the cost item. We override since the cell may be cv or text

*********************************************************************************/
void CCostBreakdownTable::ResetCostItem(const TableIndexT row, const SInt32 oldValue,
const SInt32 newValue)
{
// we only change if there's a cv field TCS 9/27/99
if (!RowUsesObjectID(row))
return;

if ((oldValue == costtype_assembly || oldValue == costtype_assmlabor || oldValue == costtype_assmmaterial) &&
(newValue == costtype_assembly || newValue == costtype_assmlabor || newValue == costtype_assmmaterial))
{
return; // TCS 4/4/04
}

TableIndexT col = GetMemberCol(tag_costitem);
if (col)
{
if (IsMixedCV(row, col))
ClearCVCell(row, col);
else
SetCellText(row, col, "");
}
}