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

Inventory Used (Source Code)

Link to: header | transactions directory

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

Comments

CInventoryUsed

This class manages inventory used in the Goldenseal accounting software,
inventory tracking software, inventory management software and
inventory control software.

a cost transaction for materials taken from inventory and used for a job.
It's an expense that we use for job costing on the project, and also for
time and materials billing. It also reduces the inventory count for the
inventory management software and inventory control software.

This class is similar to a material purchase, but it doesn't involve any
money. So we make it the parent so we can combine the job costing code.

SUPERCLASS = CMaterialPurchase

Constructor

/*********************************************************************************
constructor
*********************************************************************************/
CInventoryUsed::CInventoryUsed()
{
mMainAccountClass = id_InventoryAccount;

mStatus = status_Entered;
mConditions = condition_None;

mAmountPaid.SetToZero();
mTaxRate = 0; // TCS bugfix 9/6/01
mGrossAmount = mTaxAmount = 0;
mCheckbookNumber = 0;

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

Source Code

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

GetFileLength

return the file length to reserve for this object

*********************************************************************************/
NeoSize CInventoryUsed::GetFileLength(const CNeoFormat *aFormat) const
{
NeoSize baseSize = THE_SUPERCLASS::GetFileLength(aFormat);

// subclasses do not include the end validation tag
if (GetDBClassID() == id_InventoryUsed)
return baseSize + cFileLength;
else
return baseSize + cParentFileLength;
}
/*********************************************************************************

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

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

// copy the basic data
TCS_BlockMove(&src->mStatus, &mStatus, cCopyFileLength);

if (HasLockedStatus()) // TCS 2/2/99
mStatus = GetStarterStatus(); // rev TCS 3/8/00
// we sometimes need to clear the trans ref field TCS 2/23/04
if (mConditions == condition_EquipmentPurchase ||
mConditions == condition_RealEstatePurchase)
{
mTransactionRef = 0;
}
}/*********************************************************************************

GetMemberValue

return the value of the member with the given tag

*********************************************************************************/
Boolean CInventoryUsed::GetMemberValue(const TagType aTag,
const TagType aType,
void *aValue) const
{
switch (aTag)
{
case tag_taxrate:
return ConvertObjectIDMember(mTaxRate, id_VendorSalesTax, aValue, aType);
break;

case tag_breakdown: // TCS 4/3/00
return ConvertEnumMember(mBreakdownType, MENU_CostCatItemBreakdown, aValue, aType);
break;

case tag_conditions:
return ConvertEnumMember(mConditions, MENU_PurchaseConditions, aValue, aType);
break;

case tag_status:
return ConvertEnumMember(mStatus, MENU_EquipmentLogStatus, aValue, aType);
break;

case tag_taxamount: // TCS 2/22/99 rev TCS 1/12/00
return ConvertMember(&mTaxAmount, type_money, aValue, aType);
break;

case tag_grossprice:
return ConvertMember(&mGrossAmount, type_money, aValue, aType);
break;

case tag_amountbilled:
return ConvertMember(&mAmountBilled, type_money, aValue, aType);
break;

case tag_amountpaid:
return ConvertMember(&mAmountPaid, type_money, aValue, aType);
break;

case tag_actualmaterials: // for job cost item reports TCS 4/15/02
case tag_jobcostamount: // TCS 11/26/02
return ConvertMember(&mAmount, type_money, aValue, aType);
break;

case tag_billingdate: // TCS 9/30/02
{
CDate outDate;
outDate.SetToNever();
return ConvertMember(&outDate, type_date, aValue, aType);
}
break;

case tag_amountdue:
{
CMoney dueAmount = mAmountBilled - mAmountPaid;
return ConvertMember(&dueAmount, type_money, aValue, aType);
}
break;

case tag_billingamount: // TCS 1/27/00
return ConvertMember(&mAmount, type_money, aValue, aType);
break;

case tag_costarea: // calculated-- for reports // TCS 7/10/02
return ConvertEnumMember(costtype_material, MENU_EstimateItemCostTypes, aValue, aType);
break;

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

SetMemberValue

set the value of the member with the given tag

*********************************************************************************/
Boolean CInventoryUsed::SetMemberValue(const TagType aTag,
const TagType aType,
const void *aValue)
{
switch (aTag)
{
case tag_taxrate:
return ConvertDataToObjectID(aValue, aType, &mTaxRate, id_VendorSalesTax);
break;

case tag_status:
return ConvertMember(aValue, aType, &mStatus, type_enum);
break;

case tag_conditions: // TCS moved 9/29/02
return ConvertMember(aValue, aType, &mConditions, type_enum);
break;

case tag_taxamount:
return ConvertMember(aValue, aType, &mTaxAmount, type_money);
break;

case tag_grossprice:
return ConvertMember(aValue, aType, &mGrossAmount, type_money);
break;

case tag_amountbilled:
return ConvertMember(aValue, aType, &mAmountBilled, type_money);
break;

case tag_amountpaid:
return ConvertMember(aValue, aType, &mAmountPaid, type_money);
break;

case tag_vendor: // we don't ever need to set these
case tag_amountdue:
case tag_billingamount:
case tag_billingdate:
case tag_jobcostamount:
return true;
break;

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

ReadObject

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

Boolean isInventory = (GetDBClassID() == id_InventoryUsed);

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

THE_SUPERCLASS::ReadObject(aStream, aTag);

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

mStatus = aStream->ReadChar(); // mfs_sa 20feb2k3
mConditions = aStream->ReadChar();

mGrossAmount.ReadFromStream(aStream);
mTaxAmount.ReadFromStream(aStream);

mTaxRate = aStream->ReadID();

// subclasses don't read safety tag
if (isInventory)
mIUEndSafetyTag = aStream->ReadEndSafetyTag(this);

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

WriteObject

write the persistent object's data to a stream
*********************************************************************************/
void CInventoryUsed::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(mIUEndSafetyTag))
{
ReportDamagedObject(GetDBClassID(), GetDBID());
mIUEndSafetyTag = tag_endsafetytag; // TCS 11/26/02
}

Boolean isInventory = (GetDBClassID() == id_InventoryUsed);

CNeoDebugExport checker(aStream, this, isInventory);

THE_SUPERCLASS::WriteObject(aStream, aTag);

aStream->WriteChar(mStatus); // mfs_sa 20feb2k3
aStream->WriteChar(mConditions);

mGrossAmount.WriteToStream(aStream);
mTaxAmount.WriteToStream(aStream);

aStream->WriteID(mTaxRate);

// subclasses don't write safety tag
if (isInventory)
aStream->WriteEndSafetyTag(mIUEndSafetyTag, this);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

PostNewRecord TCS 11/20/03

post info for a new record
*********************************************************************************/
void CInventoryUsed::PostNewRecord(const UInt8 creationType)
{
PostUseCount(id_VendorSalesTax, mTaxRate);

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

PostDeletion TCS 11/20/03

post info from a deleted record
*********************************************************************************/
void CInventoryUsed::PostDeletion(const Boolean postAudit)
{
PostUseCount(id_VendorSalesTax, mTaxRate, cRemoveItem);

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

PostRecordActivated 10/31/01

post a newly created or activated transaction

*********************************************************************************/
void CInventoryUsed::PostRecordActivated(const UInt8 creationType)
{
PostInventoryChange();

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

PostRecordCancelled 10/31/01

post a deleted or voided transaction

*********************************************************************************/
void CInventoryUsed::PostRecordCancelled(const UInt8 cancelType)
{
PostInventoryChange(cRemoveItem);

// let the superclass do any posting
THE_SUPERCLASS::PostRecordCancelled(cancelType);
}
/*********************************************************************************

PostRecordChanging TCS 10/31/01

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

PostUseCount(id_VendorSalesTax, mTaxRate, cRemoveItem); // TCS 11/20/03
// let the superclass have a crack
THE_SUPERCLASS::PostRecordChanging(accountChanging, jobChanging);
}
/*********************************************************************************

PostRecordChanged TCS 10/31/01

a record has changed. Post it. If the amount has changed, we need to update any
estimates that use this bid.
*********************************************************************************/
void CInventoryUsed::PostRecordChanged(const CMoney &oldAmount, const Boolean accountChanged,
const Boolean jobChanged)
{
PostInventoryChange(); // TCS 11/20/03

PostUseCount(id_VendorSalesTax, mTaxRate);

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

PostInventoryChange TCS 10/31/01

post inventory changes to the inventory account. For this class, we reduce
inventory, but for subclasses (purchases and other costs) we increase it.
*********************************************************************************/
void CInventoryUsed::PostInventoryChange(const Boolean removeItem)
{
Boolean isPurchase = (GetDBClassID() != id_InventoryUsed); // TCS 1/10/02

if (HasVoidStatus())
return;

// we only act on purchases for an inventory account
if (isPurchase && mJobClass != id_InventoryAccount) // TCS 1/10/02
return;

if (GetBreakdownType() == breakdown_costitem)
{
// if we have item breakdowns, the cost items handle updating TCS 1/9/02
TObjectIDArrayIterator iterator(mBreakdownArray);
DBid id;

while (iterator.Next(id))
{
CCostItemBreakdownEntry *entry =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_CostItemBreakdownEntry, id),
CCostItemBreakdownEntry);

if (entry)
{
DB_ObjectWatcher watcher (entry);

if (isPurchase) // TCS 1/10/02
entry->HandleInventoryChange(inventory_purchase, mJob, mDate, removeItem);
else
entry->HandleInventoryChange(inventory_used, mMainAccount, mDate, removeItem);
}
}
}
else
{
// if no item breakdowns, we adjust the inventory balance directly
CInventoryAccount *account = nil;

if (isPurchase) // TCS 1/10/02
account = TCS_SAFE_CAST(gDBFile->GetOneObject(id_InventoryAccount, mJob),
CInventoryAccount);
else
account = TCS_SAFE_CAST(gDBFile->GetOneObject(id_InventoryAccount, mMainAccount),
CInventoryAccount);


if (account)
{
DB_ObjectWatcher watcher(account);

if ((isPurchase && !removeItem) || (!isPurchase && removeItem))
{
account->AdjustBalance(mAmount); // bugfix TCS 12/28/01
account->AdjustNonItemizedAmount(mAmount); // TCS 1/9/02
}
else
{
account->AdjustBalance(-mAmount);
account->AdjustNonItemizedAmount(-mAmount);
}
}
else if (gIsServer)
{
// records may not have an account during the first posting TCS 4/24/03
// when created by a client
}
else
ReportMissingObject(id_InventoryAccount, mMainAccount);
}
}
/*********************************************************************************

GetTandMAmount TCS 10/22/01

return the amount to use for T&M billing. What we include depends on
the incoming parameters, which come from the checkboxes in the project
payment terms.

Note that this also applies to material purchases and other cost
transactions, since they both inherit from this class.
*********************************************************************************/
CMoney CInventoryUsed::GetTandMAmount(const Boolean includeTax,
const Boolean includeAdjustments) const
{
CMoney amount = mGrossAmount;

if (includeTax)
amount += mTaxAmount;

if (includeAdjustments)
amount += mAdjustmentAmount;

return amount;
}
/*********************************************************************************

GetSalesTaxPercent TCS 1/22/03

get the percentage of sales tax

*********************************************************************************/
CMoney CInventoryUsed::GetSalesTaxPercent() const
{
CVendorSalesTax *taxRate =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_VendorSalesTax, mTaxRate),
CVendorSalesTax);

if (taxRate)
{
DB_ObjectWatcher watcher (taxRate);
return taxRate->GetTaxPercent();
}
else
return 0;
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

FillDataReport TCS 9/6/02

fill in a diagnostic table that shows data field values.

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

FillFieldEnumRow(table, stream, tag_status, mStatus, MENU_PurchaseStatus);
FillFieldEnumRow(table, stream, tag_conditions, mConditions, MENU_PurchaseConditions);

FillFieldTagRow(table, stream, tag_grossprice, cMoneySize, mGrossAmount.GetCurrencyString());
FillFieldTagRow(table, stream, tag_taxamount, cMoneySize, mTaxAmount.GetCurrencyString());

FillFieldObjectIDRow(table, stream, tag_taxrate, mTaxRate, id_VendorSalesTax);

if (GetDBClassID() == id_InventoryUsed)
{
FillEndSafetyTag(table, stream, mIUEndSafetyTag);
}
}