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

Subcontractor Log (Source Code)

Link to: header | transactions directory

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

Comments

CSubcontractorLog

This class manages subcontractor time tracking and time billing in the Goldenseal accounting software,
time tracking software, time billing software and job costing software.

Each record handles one set of subcontractor hours or subcontractor invoices. These are used for job costing
and time billing for subcontracted work (whether hourly or a fixed charge).
Goldenseal posts these to accounts payable, job costs and project billing.

SUPERCLASS = CTimeLog

Constructor

/*********************************************************************************
constructor
*********************************************************************************/
CSubcontractorLog::CSubcontractorLog()
{
mPaymentTerm = mTaxRate = mChargeRate = 0;
mWithholdingRate = 0;
mTMBillingRate = mJobCostRate = 0;

mBillingDate.SetToToday();

mGrossAmount = mBillingAmount = mTaxAmount = 0;
mWithholdingAmount = mRetainageAmount = 0;

mStatus = status_Entered; // rev TCS 4/24/00
mMainAccountClass = id_SubcontractorAccount;
//mJobCosted = mTMBilled = mPartTMBilled = false;
mPaymentMethod = method_billed;

mTimeUnit = time_straightbill;

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

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

// copy the string
mInvoiceNum = src->mInvoiceNum;

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

if (HasLockedStatus()) // new TCS 2/2/99
mStatus = GetStarterStatus(); // rev TCS 3/8/00
}/*********************************************************************************

GetFileLength

return the file length to reserve for this object

*********************************************************************************/
NeoSize CSubcontractorLog::GetFileLength(const CNeoFormat *aFormat) const
{
return THE_SUPERCLASS::GetFileLength(aFormat) +
mInvoiceNum.FileLength(cMenuTextLen) + // TCS 3/14/00
cFileLength;
}/*********************************************************************************

GetMemberValue

return the value of the member with the given tag

*********************************************************************************/
Boolean CSubcontractorLog::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_paymentterm:
return ConvertObjectIDMember(mPaymentTerm, id_VendorPaymentTerm, aValue, aType);
break;

case tag_timeunit:
return ConvertEnumMember(mTimeUnit, MENU_SubcontractorTimeUnits, aValue, aType);
break;

case tag_paymentmethod:
return ConvertEnumMember(mPaymentMethod, MENU_PurchasePaymentMethods, aValue, aType);
break;

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

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

case tag_breakdown:
return ConvertEnumMember(mBreakdownType, MENU_TimeCatItemBreakdown, aValue, aType);
break;

case tag_wagerate:
return ConvertObjectIDMember(mChargeRate, id_SubChargeRate, aValue, aType);
break;

case tag_billingrate:
return ConvertObjectIDMember(mTMBillingRate, id_SubBillingRate, aValue, aType);
break;

case tag_withholdingrate: // TCS 7/24/02
return ConvertObjectIDMember(mWithholdingRate, id_VendorWithholding, aValue, aType);
break;

case tag_taxamount: // 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_actualsubs: // for job cost item reports TCS 4/15/02
return ConvertMember(&mJobCostAmount, type_money, aValue, aType);
break;

case tag_billingamount:
return ConvertMember(&mBillingAmount, type_money, aValue, aType);
break;

case tag_withholdingamount: // TCS 7/24/02
return ConvertMember(&mWithholdingAmount, type_money, aValue, aType);
break;

case tag_retainage: // TCS 9/25/02
return ConvertMember(&mRetainageAmount, type_money, aValue, aType);
break;

case tag_billingdate:
return ConvertMember(&mBillingDate, type_date, aValue, aType);
break;

case tag_jobcostrate:
return ConvertObjectIDMember(mJobCostRate, id_SubBillingRate,
aValue, aType);
break;

case tag_invoicenum: // new TCS 11/24/97
return ConvertMember(&mInvoiceNum, type_cstring, aValue, aType);
break;

case tag_liabdeduct:
case tag_wcdeduct:
{
CSubcontractorAccount *account =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_SubcontractorAccount, mMainAccount),
CSubcontractorAccount);
if (account)
{
DB_ObjectWatcher watcher(account);
CMoney deduction = 0;
if (aTag == tag_liabdeduct)
deduction = account->GetLiabilityDeduction(mAmount, mDate);
else
deduction = account->GetWCDeduction(mAmount, mDate);
return ConvertMember(&deduction, type_money, aValue, aType);
}
else
return false;
}
break;

case tag_costarea: // calculated-- for reports // TCS 7/10/02
return ConvertEnumMember(costtype_subcontractor, 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 CSubcontractorLog::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_wagerate:
return ConvertDataToObjectID(aValue, aType, &mChargeRate, id_SubChargeRate);
break;

case tag_billingrate:
return ConvertDataToObjectID(aValue, aType, &mTMBillingRate, id_SubBillingRate);
break;

case tag_jobcostrate:
return ConvertDataToObjectID(aValue, aType, &mJobCostRate, id_SubBillingRate);
break;

case tag_paymentterm:
return ConvertDataToObjectID(aValue, aType, &mPaymentTerm, id_VendorPaymentTerm);
break;

case tag_withholdingrate: // TCS 7/24/02
return ConvertDataToObjectID(aValue, aType, &mWithholdingRate, id_VendorWithholding);
break;

case tag_paymentmethod:
return ConvertMember(aValue, aType, &mPaymentMethod, type_enum);
break;

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

case tag_conditions:
return ConvertMember(aValue, aType, &mConditions, type_enum);
break;

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

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

case tag_billingamount:
return ConvertMember(aValue, aType, &mBillingAmount, type_money);
break;

case tag_withholdingamount: // TCS 7/24/02
return ConvertMember(aValue, aType, &mWithholdingAmount, type_money);
break;

case tag_retainage: // TCS 9/25/02
return ConvertMember(aValue, aType, &mRetainageAmount, type_money);
break;

case tag_billingdate:
return ConvertMember(aValue, aType, &mBillingDate, type_date);
break;

case tag_invoicenum:
return SafeConvertString(aValue, aType, &mInvoiceNum);
break;

case tag_liabdeduct: // calculated, no need to set
case tag_wcdeduct:
return true;
break;

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

ReadObject

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

ReadTextFromStream(aStream, &mInvoiceNum);

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

mPaymentTerm = aStream->ReadID(); // mfs_sa rev 20feb2k3
mTaxRate = aStream->ReadID();
mChargeRate = aStream->ReadID();
mWithholdingRate = aStream->ReadID();
mTMBillingRate = aStream->ReadID();
mJobCostRate = aStream->ReadID();

mBillingDate.ReadFromStream(aStream);

mBillingAmount.ReadFromStream(aStream);
mGrossAmount.ReadFromStream(aStream);
mTaxAmount.ReadFromStream(aStream);
mWithholdingAmount.ReadFromStream(aStream);
mRetainageAmount.ReadFromStream(aStream);

mStatus = aStream->ReadChar();
mPaymentMethod = aStream->ReadChar();

mEndSafetyTag = aStream->ReadEndSafetyTag(this);

// validate the object end marker TCS 9/8/02
if (!IsValidEndTag(mEndSafetyTag))
ReportDamagedObject(GetDBClassID(), GetDBID());
}/*********************************************************************************

WriteObject

write the persistent object's data to a stream
*********************************************************************************/
void CSubcontractorLog::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);

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

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

aStream->WriteID(mPaymentTerm); // mfs_sa rev 20feb2k3
aStream->WriteID(mTaxRate);
aStream->WriteID(mChargeRate);
aStream->WriteID(mWithholdingRate);
aStream->WriteID(mTMBillingRate);
aStream->WriteID(mJobCostRate);

mBillingDate.WriteToStream(aStream);

mBillingAmount.WriteToStream(aStream);
mGrossAmount.WriteToStream(aStream);
mTaxAmount.WriteToStream(aStream);
mWithholdingAmount.WriteToStream(aStream);
mRetainageAmount.WriteToStream(aStream);

aStream->WriteChar(mStatus);
aStream->WriteChar(mPaymentMethod);

aStream->WriteEndSafetyTag(mEndSafetyTag, this);

}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

IsValidBreakdown

return whether the passed breakdown type is valid
*********************************************************************************/
/*Boolean CSubcontractorLog::IsValidBreakdown(const UInt8 breakdownType)
{
switch (breakdownType)
{
case breakdown_none:
case breakdown_item:
case breakdown_category:
case breakdown_powo:
return true;
break;

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

FinishNonViewerCreate

fill in values after creation from an AFW drag
*********************************************************************************/
void CSubcontractorLog::FinishNonViewerCreate()
{
// let the superclass do its stuff TCS moved 11/20/99
THE_SUPERCLASS::FinishNonViewerCreate();

DB_Account *account =
TCS_SAFE_CAST(gDBFile->GetOneObject(mMainAccountClass, mMainAccount), DB_Account);
if (account)
{ // there is an account, so we can proceed
DB_ObjectWatcher watcher(account);

// update the charge rate field
if (!mChargeRate)
account->GetMemberValue(tag_wagerate, type_objectid, &mChargeRate);

// fetch payment term from the account
if (!mPaymentTerm)
account->GetMemberValue(tag_paymentterm, type_objectid, &mPaymentTerm);

// fetch tax rate from the account
if (!mTaxRate)
account->GetMemberValue(tag_taxrate, type_objectid, &mTaxRate);

// update the billing rate field moved TCS 9/29/02
if (!mTMBillingRate)
{
account->GetMemberValue(tag_billingrate, type_objectid, &mTMBillingRate);
}

// update the job cost rate field
if (!mJobCostRate)
{
account->GetMemberValue(tag_jobcostrate, type_objectid, &mJobCostRate);
}
}
}
/*********************************************************************************

FinishImportCreate TCS 8/11/99

fill in values after creation from an import
*********************************************************************************/
void CSubcontractorLog::FinishImportCreate()
{
// let the superclass do its stuff
THE_SUPERCLASS::FinishImportCreate();

// we used to recalc the wage amount and billing amount, but that causes
// problems if rate has changed. TCS removed 11/29/01
}
/*********************************************************************************

FinishBreakdownUpdate TCS 4/17/01 rev 2/22/02 rev 1/25/03 removed 6/10/03 rev 2/18/04

If there is no cost area column, we fill in the cost type
*********************************************************************************/
void CSubcontractorLog::FinishBreakdownUpdate(CBreakdownEntry *breakdown, CBreakdownTable *table)
{
TCS_FailNILMsg(breakdown, TCS_GetErrString(errID_BadBreakdown));
TCS_FailNILMsg(table, TCS_GetErrString(errID_BadTable));

if (!table->HasColumn(tag_costarea))
{
UInt8 costArea = costtype_subcontractor;
breakdown->SetMemberValue(tag_costarea, type_enum, &costArea);
}
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

ShouldBePaid rev TCS 5/5/00 rev TCS 5/19/00

return whether this invoice should be included in lists of bills to pay
*********************************************************************************/
Boolean CSubcontractorLog::ShouldBePaid() const
{
return HasOpenStatus() || mStatus == status_TandMBilled;
}
/*********************************************************************************

GetAccountingAmount TCS 10/4/02

for taxes, use the vendor withholding amount

*********************************************************************************/
CMoney CSubcontractorLog::GetAccountingAmount(const Boolean removeIt, const UInt8 type) const
{
if (type == virtual_unpaidtax)
{
if (removeIt)
return -GetWithholdingAmount();
else
return GetWithholdingAmount();
}
else
{
if (removeIt)
return -GetAmount();
else
return GetAmount();
}
}
/*********************************************************************************

GetAmountUnpaid TCS 10/9/02

return the amount unpaid
*********************************************************************************/
CMoney CSubcontractorLog::GetAmountUnpaid() const
{
if (GetPaymentMethod() == method_billed)
return GetAmountDue();
else
return 0;
}
/*********************************************************************************

GetSalesTaxPercent TCS 1/22/03

get the percentage of sales tax

*********************************************************************************/
CMoney CSubcontractorLog::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;
}
/*********************************************************************************

GetWithholdingDeduction TCS 9/16/03

get the amount of vendor withholding to deduct from the amount due to this
subcontractor.

For the gross withholding amount, use GetWithholdingAmount.

*********************************************************************************/
CMoney CSubcontractorLog::GetWithholdingDeduction() const
{
CVendorWithholding *withholding =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_VendorWithholding, mWithholdingRate),
CVendorWithholding);

if (withholding)
{
DB_ObjectWatcher watcher (withholding);

if (withholding->IsDeducted())
return mWithholdingAmount;
else
return 0;
}
else if (mWithholdingRate)
ReportMissingObject(id_VendorWithholding, mWithholdingRate);

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

PostNewRecord TCS 11/21/03

post info for a new record
*********************************************************************************/
void CSubcontractorLog::PostNewRecord(const UInt8 creationType)
{
PostUseCount(id_VendorPaymentTerm, mPaymentTerm);
PostUseCount(id_VendorSalesTax, mTaxRate);
PostUseCount(id_SubChargeRate, mChargeRate);
PostUseCount(id_VendorWithholding, mWithholdingRate);
PostUseCount(id_SubBillingRate, mTMBillingRate);
PostUseCount(id_SubBillingRate, mJobCostRate);

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

PostDeletion TCS 11/21/03

post info from a deleted record
*********************************************************************************/
void CSubcontractorLog::PostDeletion(const Boolean postAudit)
{
PostUseCount(id_VendorPaymentTerm, mPaymentTerm, cRemoveItem);
PostUseCount(id_VendorSalesTax, mTaxRate, cRemoveItem);
PostUseCount(id_SubChargeRate, mChargeRate, cRemoveItem);
PostUseCount(id_VendorWithholding, mWithholdingRate, cRemoveItem);
PostUseCount(id_SubBillingRate, mTMBillingRate, cRemoveItem);
PostUseCount(id_SubBillingRate, mJobCostRate, cRemoveItem);

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

PostRecordActivated TCS 10/17/99

post info from a transaction that is new or activated. We may need to create
a bank payment for the purchase
*********************************************************************************/
void CSubcontractorLog::PostRecordActivated(const UInt8 creationType)
{
// let the superclass do any posting first TCS changed order 1/23/01
THE_SUPERCLASS::PostRecordActivated(creationType);

// we may need to create an instant payment transaction
if (NeedsPurchaseOffset(mPaymentMethod)) // rev TCS 11/30/99, 10/25/00, 2/14/01
{
SetIsInstantPayment(true); // TCS rev 2/9/01

if (!WasJustImported())
CreateOffsetTransaction();
}

PostVendorWithholding(); // TCS 10/4/02
PostRetainage(); // TCS 10/9/02
}
/*********************************************************************************

PostRecordCancelled TCS 10/17/99

post info from a voided or deleted transaction
*********************************************************************************/
void CSubcontractorLog::PostRecordCancelled(const UInt8 cancelType)
{
PostVendorWithholding(cRemoveItem); // TCS 10/4/02
PostRetainage(cRemoveItem); // TCS 10/9/02

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

PostRecordChanging TCS 10/17/99

a record will be changing. Post the change.
*********************************************************************************/
void CSubcontractorLog::PostRecordChanging(const Boolean accountChanging, const Boolean jobChanging)
{
PostVendorWithholding(cRemoveItem); // TCS 10/4/02
PostRetainage(cRemoveItem); // TCS 10/9/02

PostUseCount(id_VendorPaymentTerm, mPaymentTerm, cRemoveItem); // TCS 11/21/03
PostUseCount(id_VendorSalesTax, mTaxRate, cRemoveItem);
PostUseCount(id_SubChargeRate, mChargeRate, cRemoveItem);
PostUseCount(id_VendorWithholding, mWithholdingRate, cRemoveItem);
PostUseCount(id_SubBillingRate, mTMBillingRate, cRemoveItem);
PostUseCount(id_SubBillingRate, mJobCostRate, cRemoveItem);

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

PostRecordChanged TCS 10/17/99

a record has changed. Post it.
*********************************************************************************/
void CSubcontractorLog::PostRecordChanged(const CMoney &oldAmount, const Boolean accountChanged,
const Boolean jobChanged)
{
if (NeedsPurchaseOffset(mPaymentMethod) && !WasJustImported()) // rev TCS 10/25/00, 2/14/01
{
SetIsInstantPayment(true); // TCS rev 2/14/01

CreateOffsetTransaction();
}

PostVendorWithholding(); // TCS 10/4/02
PostRetainage(); // TCS 10/9/02

gDBFile->UpdateEarlyLateDates(mBillingDate); // TCS 7/15/03

PostUseCount(id_VendorPaymentTerm, mPaymentTerm); // TCS 11/21/03
PostUseCount(id_VendorSalesTax, mTaxRate);
PostUseCount(id_SubChargeRate, mChargeRate);
PostUseCount(id_VendorWithholding, mWithholdingRate);
PostUseCount(id_SubBillingRate, mTMBillingRate);
PostUseCount(id_SubBillingRate, mJobCostRate);

THE_SUPERCLASS::PostRecordChanged(oldAmount, accountChanged, jobChanged);
}
/*********************************************************************************

PostRecordChangedRemotely TCS 7/15/03

a record has changed from a remote update. Post it. We don't do purchase
offsets
*********************************************************************************/
void CSubcontractorLog::PostRecordChangedRemotely(const CMoney &oldAmount, const Boolean accountChanged,
const Boolean jobChanged)
{
PostVendorWithholding();
PostRetainage();

gDBFile->UpdateEarlyLateDates(mBillingDate);

THE_SUPERCLASS::PostRecordChanged(oldAmount, accountChanged, jobChanged);
}
/*********************************************************************************

PostVendorWithholding TCS 10/4/02

post vendor withholding
*********************************************************************************/
void CSubcontractorLog::PostVendorWithholding(const Boolean removeItem)
{

DBClass paytoClass = id_OtherCostAccount;
DBid payToID = 0, taxAccountID = account_UnpaidVendorWithholding;

if (mWithholdingRate) // rev TCS 1/19/01
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));

CVendorWithholding *withholdRate =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_VendorWithholding, mWithholdingRate),
CVendorWithholding);
if (withholdRate)
{
DB_ObjectWatcher watcher(withholdRate);
paytoClass = withholdRate->GetPaidToClass(); // rev TCS 10/4/02
payToID = withholdRate->GetPaidToAccount();
taxAccountID = withholdRate->GetExpenseAccount();

// check the validity
if (!CUtilityAccount::IsValidAccount(taxAccountID, virtual_unpaidtax))
{
taxAccountID = account_UnpaidVendorWithholding;
withholdRate->SetUtilityAccount(taxAccountID);
withholdRate->MakeDirty();
}
}
else
ReportMissingObject(id_VendorWithholding, mWithholdingRate);
}

if (payToID)
{
DB_Account *payToAccount =
TCS_SAFE_CAST(gDBFile->GetOneObject(paytoClass, payToID),
DB_Account);
if (payToAccount)
{
DB_ObjectWatcher accountWatcher(payToAccount);
payToAccount->AddToUnpaidVendorWithholdingArray(GetDBClassID(), GetDBID(), removeItem);
}
else
ReportMissingObject(paytoClass, payToID);
}

// also add to the virtual account TCS 11/10/00 rev TCS 11/21/00 rev 12/11/00
CUtilityAccount::AddToBothArrays(taxAccountID, this, removeItem);
}
/*********************************************************************************

PostRetainage TCS 10/9/02

post retainage withheld or paid
*********************************************************************************/
void CSubcontractorLog::PostRetainage(const Boolean removeItem)
{
if (mRetainageAmount.IsZero() && mConditions != condition_Retainage)
return;
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));

DB_PersistentObject *costAccount =
gDBFile->GetOneObject(GetMainAccountClass(), GetMainAccountID());

if (costAccount)
{
DB_ObjectWatcher watcher (costAccount);

if (mConditions == condition_Retainage)
costAccount->HandleRetainage(GetDBClassID(), GetDBID(), -mAmount, removeItem);
else
costAccount->HandleRetainage(GetDBClassID(), GetDBID(), mRetainageAmount, removeItem);
}
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

CalculateWageAmount

calculate the wage amount (which is actually the cost billing amount)

*********************************************************************************/
CMoney CSubcontractorLog::CalculateWageAmount(const CMoney &billedUnits, const DBid accountID,
const UInt8 timeUnit, const DBid wageRateID) const
{
CMoney amount(0,0),
accountRate;

// sanity check
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));

if (wageRateID)
{
// find the billing rate
CSubChargeRate *rate = TCS_SAFE_CAST(gDBFile->GetOneObject(id_SubChargeRate,
wageRateID), CSubChargeRate);
if (rate)
{
DB_ObjectWatcher watcher(rate);

// we have a wage rate, so it can calculate
if (rate->HasVariableRate())
{ // it's a variable rate, so the account provides the value
accountRate = FetchAccountRate(tag_wageamount, id_SubcontractorAccount, accountID);
amount = rate->ComputeBillingAmount(billedUnits, timeUnit, 0, 0, accountRate);
}
else // it's a simple rate, so the rate can compute things
amount = rate->ComputeBillingAmount(billedUnits, timeUnit, 0, 0);
}
}
// return the computed amount
return amount;
}
/*********************************************************************************
HandlePaymentCancelled TCS 10/25/00, rev 2/9/01

deal with a payment that has been voided. We override to change
the payment method if we've cancelled payment for a non-billed item

This was formerly handled via HandlePaymentMade but that caused problems, since
it was posted during any change, not just payment cancellation or deletion.
*********************************************************************************/
void CSubcontractorLog::HandlePaymentCancelled()
{
UInt8 saveSuccess = PrepareViewerDisplay();

if (GetPaymentMethod() != method_billed)
{
mPaymentMethod = method_billed;

// we also need to fill in payment terms TCS 11/14/00
DB_Account *account = TCS_SAFE_CAST(gDBFile->GetOneObject(GetMainAccountClass(), mMainAccount),
DB_Account);

if (account)
{
DB_ObjectWatcher watcher(account);
mPaymentTerm = account->GetPaymentTerm();
}

if (!mPaymentTerm)
mPaymentTerm = gDBFile->GetFirstObjectID(id_VendorPaymentTerm);
}

UpdateViewerDisplay(saveSuccess);
}
/*********************************************************************************

HandleTaxesPaid TCS 10/7/02

handle payment of sales tax for this item.
*********************************************************************************/
void CSubcontractorLog::HandleTaxesPaid(const DBClass /*sourceClass*/, const DBid /*sourceID*/,
const Boolean removeItem)
{
// We can just use the basic tax posting code, but reversed.
PostVendorWithholding(!removeItem);
}
/*********************************************************************************

FillDataReport TCS 9/6/02

fill in a diagnostic table that shows data field values.

*********************************************************************************/
void CSubcontractorLog::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_invoicenum, mInvoiceNum);

FillFieldObjectIDRow(table, stream, tag_paymentterm, mPaymentTerm, id_VendorPaymentTerm);
FillFieldObjectIDRow(table, stream, tag_taxrate, mTaxRate, id_VendorSalesTax);
FillFieldObjectIDRow(table, stream, tag_wagerate, mChargeRate, id_SubChargeRate);
FillFieldObjectIDRow(table, stream, tag_withholdingrate, mWithholdingRate, id_VendorWithholding);
FillFieldObjectIDRow(table, stream, tag_billingrate, mTMBillingRate, id_SubBillingRate);
FillFieldObjectIDRow(table, stream, tag_jobcostrate, mJobCostRate, id_SubBillingRate);

FillFieldTagRow(table, stream, tag_billingdate, cDateSize, mBillingDate.GetCString());

FillFieldTagRow(table, stream, tag_billingamount, cMoneySize, mBillingAmount.GetCurrencyString());
FillFieldTagRow(table, stream, tag_grossprice, cMoneySize, mGrossAmount.GetCurrencyString());
FillFieldTagRow(table, stream, tag_taxamount, cMoneySize, mTaxAmount.GetCurrencyString());
FillFieldTableRow(table, stream, "mWithholdingAmount", cMoneySize, mWithholdingAmount.GetCurrencyString());
FillFieldTagRow(table, stream, tag_retainage, cMoneySize, mRetainageAmount.GetCurrencyString());

FillFieldEnumRow(table, stream, tag_status, mStatus, MENU_PurchaseStatus);
FillFieldEnumRow(table, stream, tag_paymentmethod, mPaymentMethod, MENU_PurchasePaymentMethods);

FillEndSafetyTag(table, stream, mEndSafetyTag);
}