Link to: header
| source
2 | source 3 | transactions
directory
Copyright Turtle Creek Software 1996-2006. All Rights Reserved.
Comments
CBankTransaction
This class manages bank transactions for the Goldenseal accounting software,
small business management software, construction
project management software and
construction
accounting software.
Base class for transactions in banking accounts-- parent for cash, checking,
savings, investment, credit card, loan and escrow transactions.
Most of the financial management code is concentrated here, since the various
subclasses don't really have much different behaviour.
SUPERCLASS = CBreakdownTransaction
********************
Related classes: CBankTransViewer handles display of 'interior' data.
CBankTransEditor does the basic 'outer' window- bank account, reconcile, running
total, etc.
Note that between 7/1/98 and 6/9/00 we handled bank transactions with two different
object classes- CBankTransaction (and subclasses) handled only the data in the editor,
and CBankTransDetail (and subclasses) handled the data from the viewer.
There was a lot of code to link them. TCS merged them 6/10/00, which has made things
much simpler.
Constructor
/*********************************************************************************
constructor
*********************************************************************************/
CBankTransaction::CBankTransaction()
{
mReconcilePeriod = 0;
mBankAccount = 0;
mJob = mCategory = mTaxRate = 0;
mGrossAmount = mTaxAmount = 0;
mMainAccountClass = id_MaterialAccount; // TCS 6/12/00
mTransactionType = 0; // rev TCS 6/26/00. We need init of zero so we
// can tell if trans type has been set, when importing
mStatus = status_Entered;
mJobClass = id_ProjectAccount; // TCS 6/21/00
mConditions = condition_None;
mPriorRunningTotal = 0;
mTransactionRef = 0;
mTransactionRefClass = condition_OnAccount; // TCS 6/21/00
mUseOneTimeName = false;
mIsAutoTransfer = false;
mHasAutoTransfer = false;
mBankTransPadding = 0;
mCashUtilityAccount = 0;
mPaidOnAccount = 0;
mMessage = 0; // TCS 5/7/04
mExpansionMoney = 0; // TCS 9/29/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 CBankTransaction::CopyFrom(DB_PersistentObject *source, const UInt8 copyFlags)
{
THE_SUPERCLASS::CopyFrom(source, copyFlags);
CBankTransaction *src = TCS_SAFE_CAST(source, CBankTransaction);
TCS_FailNILMsg(src, TCS_GetErrString(errID_BadRecord));
mOneTimePayeeName = src->mOneTimePayeeName; // TCS 10/26/00 CSale
TCS_BlockMove(&src->mReconcilePeriod, &mReconcilePeriod, cCopyFileLength);
// don't copy the reconcile period TCS 4/18/03
mReconcilePeriod = 0;
// only copy the transaction ref if it's a safe type TCS 11/13/03
if (src->mTransactionRefClass == condition_DirectExpense ||
src->mTransactionRefClass == condition_Gift)
{
mTransactionRefClass = src->mTransactionRefClass;
}
mMessage = src->mMessage;
// start it as entered TCS bugfix 9/4/03
SetToStarterStatus();
}
/*********************************************************************************
GetFileLength TCS moved 8/17/00
return the file length used by this object
*********************************************************************************/
NeoSize CBankTransaction::GetFileLength(const CNeoFormat *aFormat) const
{
return THE_SUPERCLASS::GetFileLength(aFormat) +
mOneTimePayeeName.FileLength(cFullNameTextLen)
+ cFileLength;
}
/*********************************************************************************
GetMemberValue
return the value of the member with the given tag
*********************************************************************************/
Boolean CBankTransaction::GetMemberValue(const TagType aTag, const TagType aType,
void *aValue) const
{
CMoney amount = 0;
switch (aTag)
{
// subclasses handle tag_bankaccountclass(calculated)
case tag_mainaccount: // some classes are not valid accounts rev TCS 3/13/00
case tag_owner: // TCS 6/12/00
if (DB_ClassDescriptor::IsAccount(mMainAccountClass, cIncludeOwner))
return ConvertObjectIDMember(mMainAccount, mMainAccountClass, aValue, aType);
else
{
DBid zeroValue = 0;
return ConvertMember(&zeroValue, type_objectid, aValue, aType);
}
break;
case tag_reconcileperiod:
return ConvertObjectIDMember(mReconcilePeriod, id_ReconcilePeriod, aValue, aType);
break;
case tag_bankaccount:
{
DBClass classID = GetBankAccountClass();
return ConvertObjectIDMember(mBankAccount, classID, aValue, aType);
}
break;
case tag_transactionref: // TCS 5/23/00 rev TCS 12/27/01
return ConvertObjectIDMember(mTransactionRef, mTransactionRefClass, aValue, aType);
break;
case tag_catsystem:
// for transfers, we fetch this from the job account TCS 8/18/00
if (mTransactionType == id_BankTransferOut || mTransactionType == id_BankTransferIn)
{
DBid catSystemID = DB_Account::GetJobCatSystem(mJobClass, mJob);
return ConvertObjectIDMember(catSystemID, id_CategorySystem, aValue, aType);
}
break;
case tag_category:
return ConvertObjectIDMember(mCategory, id_Category, aValue, aType);
break;
case tag_taxrate:
return ConvertObjectIDMember(mTaxRate, id_VendorSalesTax, aValue, aType);
break;
case tag_job: // mJobClass is the type of account
return ConvertObjectIDMember(mJob, mJobClass, aValue, aType);
break;
case tag_cashaccount: // TCS 12/12/00
return ConvertObjectIDMember(mCashUtilityAccount, id_UtilityAccount, aValue, aType);
break;
case tag_message: // TCS 5/7/04
return ConvertObjectIDMember(mMessage, id_Message, aValue, aType);
break;
case tag_messagetext: // TCS 5/7/04
{
CTextString messageText = GetMessageText(mMessage);
return ConvertMember(&messageText, type_cstring, aValue, aType);
}
break;
case tag_transactiontype:
return ConvertEnumMember(mTransactionType, MENU_CheckingTransactionTypes, aValue, aType);
break;
case tag_breakdown:
return ConvertEnumMember(mBreakdownType, MENU_BankTransBreakdown, aValue, aType);
break;
case tag_status:
return ConvertEnumMember(mStatus, MENU_BankTransStatus, aValue, aType);
break;
case tag_bankaccountclass: // this has no display but menu converts text
{
UInt8 accountClass = GetBankAccountClass();
return ConvertEnumMember(accountClass, MENU_AccountClasses, aValue, aType);
}
break;
case tag_jobclass:
return ConvertEnumMember(mJobClass, MENU_ExpenseJobTypes, aValue, aType);
break;
case tag_mainaccountclass:
switch (mTransactionType) // sometimes this is a non-account
{
case id_BankCheck:
case id_BankPayment:
return ConvertEnumMember(mMainAccountClass, MENU_BankCheckAccountTypes, aValue, aType);
break;
case id_BankDeposit:
return ConvertEnumMember(mMainAccountClass, MENU_BankDepositAccountTypes, aValue, aType);
break;
case id_BankTransferOut:
return ConvertEnumMember(mMainAccountClass, MENU_BankTransferOutAccountTypes, aValue, aType);
break;
case id_BankTransferIn:
return ConvertEnumMember(mMainAccountClass, MENU_BankTransferInAccountTypes, aValue, aType);
break;
default:
return false;
break;
}
break;
case tag_transactionrefclass: // rev TCS 5/23/00
switch (mTransactionType)
{
case id_BankCheck:
case id_BankPayment:
return ConvertEnumMember(mTransactionRefClass, MENU_BankPaymentTransTypes, aValue, aType);
break;
case id_BankDeposit:
return ConvertEnumMember(mTransactionRefClass, MENU_BankDepositTransTypes, aValue, aType);
break;
case id_BankTransferOut:
case id_BankTransferIn: // rev TCS 6/21/00
return ConvertEnumMember(mTransactionRefClass, MENU_BankTransferTransTypes, aValue, aType);
break;
default:
return false;
break;
}
break;
case tag_conditions:
return ConvertEnumMember(mConditions, MENU_BankTransConditions, aValue, aType);
break;
case tag_grossprice:
return ConvertMember(&mGrossAmount, type_money, aValue, aType);
break;
case tag_taxamount: // TCS 1/12/00
return ConvertMember(&mTaxAmount, type_money, aValue, aType);
break;
case tag_onetimeitem: // TCS 8/17/00
return ConvertBitFieldMember(mUseOneTimeName, aValue, aType);
break;
case tag_onetimename: // TCS 8/17/00
case tag_secondname: // TCS 1/29/01
if (mUseOneTimeName)
return ConvertMember(&mOneTimePayeeName, type_cstring, aValue, aType);
else if (mMainAccount && mMainAccountClass)
{ // rev TCS 1/23/01
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
DB_PersistentObject *source = gDBFile->GetOneObject(mMainAccountClass, mMainAccount);
CTextString itemName;
if (source)
{
DB_ObjectWatcher watcher(source);
itemName = source->GetFullName();
if (!itemName.Length())
itemName = source->GetName();
}
return ConvertMember(&itemName, type_cstring, aValue, aType);
}
else
return true; // TCS 10/27/00
break;
case tag_runningtotal: // rev TCS 12/15/99
{
amount = GetRunningTotal();
return ConvertMember(&amount, type_money, aValue, aType);
}
break;
case tag_transferamount: // TCS 12/16/03
{
amount = GetTransferAmount();
return ConvertMember(&amount, type_money, aValue, aType);
}
break;
case tag_miscincome:
switch (mTransactionType)
{
case id_BankCheck: // always zero TCS 7/27/99
case id_BankPayment:
case id_BankTransferOut:
return ConvertMember(&amount, type_money, aValue, aType);
break;
case id_BankDeposit:
/*if (mMainAccountClass == condition_Interest || mMainAccountClass == condition_OtherCredit)
amount = mAmount;*/
return ConvertMember(&amount, type_money, aValue, aType);
break;
case id_BankTransferIn:
if (mMainAccountClass == condition_InterestIn || mMainAccountClass == condition_OtherCredit)
amount = mAmount;
return ConvertMember(&amount, type_money, aValue, aType);
break;
default:
return false;
break;
}
break;
case tag_miscexpense:
switch (mTransactionType)
{
case id_BankCheck:
case id_BankPayment:
/*if (mMainAccountClass == condition_Interest || mMainAccountClass == condition_OtherCredit)
amount = mAmount;*/
return ConvertMember(&amount, type_money, aValue, aType);
break;
case id_BankDeposit:
case id_BankTransferIn: // always zero TCS 7/27/99
return ConvertMember(&amount, type_money, aValue, aType);
break;
case id_BankTransferOut:
if (mMainAccountClass == condition_InterestOut || mMainAccountClass == condition_OtherCharge)
amount = mAmount;
return ConvertMember(&amount, type_money, aValue, aType);
break;
default:
return false;
break;
}
break;
case tag_spellout:
{
CTextString cstring = mAmount.GetSpelledMoney(true);
return ConvertMember(&cstring, type_cstring, aValue, aType);
}
break;
case tag_address: // we get these from the payee account
case tag_taxid: // TCS 4/8/04
case tag_telephone:
case tag_eveningtel:
case tag_faxtel:
case tag_email:
{
CTextString outString;
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
if (DB_ClassDescriptor::IsAccount(mMainAccountClass))
{
DB_PersistentObject *account = gDBFile->GetOneObject(mMainAccountClass, mMainAccount);
if (account)
{
DB_ObjectWatcher watcher(account);
account->GetMemberValue(aTag, type_cstring, &outString);
}
}
return ConvertMember(&outString, type_cstring, aValue, aType);
}
break;
case tag_refnumstring: // we override since checks don't show numbering additions TCS 4/1/03
if (mTransactionType == id_BankCheck)
{
return ConvertMember(&mReferenceNum, type_long, aValue, aType);
}
else
{
CTextString refNumString =
CNumbering::RefNumberToString(GetDBClassID(), mReferenceNum);
return ConvertMember(&refNumString, type_cstring, aValue, aType);
}
break;
case tag_incometaxclass: // TCS 10/21/02
if (aType == type_long)
{
SInt32 taxID = GetIncomeTaxID(mMainAccountClass, mMainAccount, mTransactionType, mStatus);
return ConvertMember(&taxID, type_long, aValue, aType);
}
else
{
CTextString taxString = GetIncomeTaxClass(mMainAccountClass, mMainAccount, mTransactionType, mStatus);
return ConvertMember(&taxString, type_cstring, aValue, aType);
}
break;
case tag_wagestotal: // added TCS 1/23/00
case tag_hourstotal:
case tag_commissionstotal:
case tag_deductionstotal:
case tag_employeebenefits:
case tag_employerbenefits:
case tag_employercattax:
case tag_employeecattax:
case tag_employertax:
case tag_alldeductionstotal:
case tag_allemployertaxtotal:
case tag_periodstart:
case tag_periodend:
if ((mTransactionType == id_BankCheck || mTransactionType == id_BankPayment) &&
mTransactionRefClass == id_PayrollRecord && mTransactionRef)
{ // used on paychecks only
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
CPayrollRecord *record =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_PayrollRecord, mTransactionRef),
CPayrollRecord);
if (record)
{ // fetch a value from the payroll record
DB_ObjectWatcher watcher(record);
if (aTag == tag_periodstart || aTag == tag_periodend) // TCS 7/2/03
{
CDate outDate;
record->GetMemberValue(aTag, type_date, &outDate);
return ConvertMember(&outDate, type_date, aValue, aType);
}
else
record->GetMemberValue(aTag, type_money, &amount);
}
}
return ConvertMember(&amount, type_money, aValue, aType);
break;
case tag_debitamount:
if (HasVoidStatus() || mTransactionType == id_BankDeposit || mTransactionType == id_BankTransferIn)
return ConvertMember(&amount, type_money, aValue, aType); // zero
else
return ConvertMember(&mAmount, type_money, aValue, aType);
break;
case tag_creditamount:
if (HasVoidStatus() || (mTransactionType != id_BankDeposit && mTransactionType != id_BankTransferIn))
return ConvertMember(&amount, type_money, aValue, aType); // zero
else
return ConvertMember(&mAmount, type_money, aValue, aType);
break;
case tag_accountnum: // TCS 2/5/02
case tag_companydivision: // TCS 12/16/03
{
DB_Account *account = TCS_SAFE_CAST(gDBFile->GetOneObject(GetBankAccountClass(), mBankAccount),
DB_Account);
if (account)
{
// we just fetch these from the bank account
DB_ObjectWatcher bankWatcher (account);
return account->GetMemberValue(aTag, aType, aValue);
}
else
return false;
}
break;
case tag_costarea: // calculated-- for reports // TCS 7/10/02
switch (mMainAccountClass)
{
case id_EmployeeAccount:
return ConvertEnumMember(costtype_labor, MENU_EstimateItemCostTypes, aValue, aType);
break;
case id_MaterialAccount:
return ConvertEnumMember(costtype_material, MENU_EstimateItemCostTypes, aValue, aType);
break;
case id_SubcontractorAccount:
return ConvertEnumMember(costtype_subcontractor, MENU_EstimateItemCostTypes, aValue, aType);
break;
case id_OtherCostAccount:
return ConvertEnumMember(costtype_other, MENU_EstimateItemCostTypes, aValue, aType);
break;
default:
return ConvertEnumMember(costtype_overhead, MENU_EstimateItemCostTypes, aValue, aType);
break;
}
break;
case tag_micrtext: // TCS 10/1/03
{
CTextString outString = GetMICRText();
return ConvertMember(&outString, type_cstring, aValue, aType);
}
break;
case tag_cashamount: // these will be calculated from breakdown table
case tag_checkamount:
case tag_creditcardamount:
case tag_otheramount:
return true;
break;
default:
break;
}
return THE_SUPERCLASS::GetMemberValue(aTag, aType, aValue);
}/*********************************************************************************
SetMemberValue
set the value of the member with the given tag
*********************************************************************************/
Boolean CBankTransaction::SetMemberValue(const TagType aTag, const TagType aType,
const void *aValue)
{
switch (aTag)
{
// mMainAccount is handled in subclasses
case tag_bankaccount:
case tag_owner: // TCS 6/12/00
return ConvertDataToObjectID(aValue, aType, &mBankAccount, GetBankAccountClass());
break;
case tag_reconcileperiod:
return ConvertDataToObjectID(aValue, aType, &mReconcilePeriod, id_ReconcilePeriod);
break;
case tag_category:
return ConvertDataToObjectID(aValue, aType, &mCategory, id_Category);
break;
case tag_transactionref:
return ConvertDataToObjectID(aValue, aType, &mTransactionRef, mTransactionRefClass);
break;
case tag_taxrate:
return ConvertDataToObjectID(aValue, aType, &mTaxRate, id_VendorSalesTax);
break;
case tag_job:
return ConvertDataToObjectID(aValue, aType, &mJob, mJobClass);
break;
case tag_cashaccount: // TCS 12/12/00
return ConvertDataToObjectID(aValue, aType, &mCashUtilityAccount, id_UtilityAccount);
break;
case tag_message: // TCS 5/7/04
return ConvertDataToObjectID(aValue, aType, &mMessage, id_Message);
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_transactionrefclass:
return ConvertMember(aValue, aType, &mTransactionRefClass, type_objclass);
break;
case tag_jobclass:
return ConvertMember(aValue, aType, &mJobClass, type_objclass);
break;
case tag_transactiontype:
return ConvertMember(aValue, aType, &mTransactionType, type_objclass);
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_onetimename: // TCS 8/17/00
if (mUseOneTimeName)
return SafeConvertString(aValue, aType, &mOneTimePayeeName);
else
{
if (IsInDatabase()) // TCS 5/31/00
{
TCS_TokenErrorAlert(errID_BadLengthChange, DB_ClassDescriptor::GetClassName(GetDBClassID()));
return false;
}
else
{
mOneTimePayeeName.MakeNull();
return true;
}
}
break;
case tag_onetimeitem: // TCS 8/17/00
mUseOneTimeName = ConvertDataToBitField(aValue, aType);
return true;
break;
case tag_runningtotal: // don't set this directly
case tag_currbalance: // we don't need to set this
case tag_bankaccountclass:
case tag_spellout:
case tag_address: // we don't store these items
case tag_wagestotal: // added TCS 1/23/00
case tag_hourstotal:
case tag_commissionstotal:
case tag_deductionstotal:
case tag_employeebenefits:
case tag_employerbenefits:
case tag_employercattax:
case tag_employeecattax:
case tag_employertax:
case tag_alldeductionstotal:
case tag_allemployertaxtotal:
case tag_secondname: // TCS 1/29/01
case tag_taxid: // TCS 4/8/04
return true;
break;
case tag_cashamount: // calculated, no need to set
case tag_checkamount:
case tag_creditcardamount:
case tag_otheramount:
case tag_accountnum:
case tag_incometaxclass:
case tag_micrtext: // TCS 10/1/03
case tag_companydivision: // TCS 12/16/03
case tag_transferamount:
return true;
break;
default:
break;
}
return THE_SUPERCLASS::SetMemberValue(aTag, aType, aValue);
}
/*********************************************************************************
ReadObject
read the persistent object's data in from a stream. All subclasses now have
members, so we no longer check for too small size here.
*********************************************************************************/
void CBankTransaction::ReadObject(CNeoStream *aStream, const TagType aTag)
{
TCS_FailNILMsg(aStream, TCS_GetErrString(errID_BadStream));
CNeoDebugImport checker(aStream, this); // TCS 2/24/00 rev 5/19/00
THE_SUPERCLASS::ReadObject(aStream, aTag);
if (!IsIOValid()) // TCS 2/5/02
return;
ReadTextFromStream(aStream, &mOneTimePayeeName);
/// aStream->ReadChunk(&mReconcilePeriod, cFileLength);
mReconcilePeriod = aStream->ReadID(); // mfs_sa rev 20feb2k3
mBankAccount = aStream->ReadID();
mJob = aStream->ReadID();
mCategory = aStream->ReadID();
mTaxRate = aStream->ReadID();
mCashUtilityAccount = aStream->ReadID();
mGrossAmount.ReadFromStream(aStream);
mTaxAmount.ReadFromStream(aStream);
mTransactionType = aStream->ReadChar();
mStatus = aStream->ReadChar();
mJobClass = aStream->ReadChar();
mConditions = aStream->ReadChar();
mPriorRunningTotal.ReadFromStream(aStream);
mPaidOnAccount.ReadFromStream(aStream);
mTransactionRef = aStream->ReadID();
mTransactionRefClass = aStream->ReadChar();
*((UInt8*)&mTransactionRefClass + sizeof(mTransactionRefClass)) = aStream->ReadBits(3); // --Bitfield
mMessage = aStream->ReadID();
mExpansionMoney.ReadFromStream(aStream);
}/*********************************************************************************
WriteObject
write the persistent object's data to a stream. All subclasses now have
members, so we no longer check for too small size here.
*********************************************************************************/
void CBankTransaction::WriteObject(CNeoStream *aStream, const TagType aTag)
{
TCS_FailNILMsg(aStream, TCS_GetErrString(errID_BadStream));
CNeoDebugExport checker(aStream, this); // TCS rev 5/19/00, 3/3/01
THE_SUPERCLASS::WriteObject(aStream, aTag);
WriteTextToStream(aStream, mOneTimePayeeName, cFullNameTextLen);
/// aStream->WriteChunk(&mReconcilePeriod, cFileLength);
aStream->WriteID(mReconcilePeriod); // mfs_sa rev 20feb2k3
aStream->WriteID(mBankAccount);
aStream->WriteID(mJob);
aStream->WriteID(mCategory);
aStream->WriteID(mTaxRate);
aStream->WriteID(mCashUtilityAccount);
mGrossAmount.WriteToStream(aStream);
mTaxAmount.WriteToStream(aStream);
aStream->WriteChar(mTransactionType);
aStream->WriteChar(mStatus);
aStream->WriteChar(mJobClass);
aStream->WriteChar(mConditions);
mPriorRunningTotal.WriteToStream(aStream);
mPaidOnAccount.WriteToStream(aStream);
aStream->WriteID(mTransactionRef);
aStream->WriteChar(mTransactionRefClass);
aStream->WriteChar(*((UInt8*)&mTransactionRefClass + sizeof(mTransactionRefClass))); // --Bitfield
aStream->WriteID(mMessage);
mExpansionMoney.WriteToStream(aStream);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************
VerifyImport rev TCS 6/10/00
return whether a record can be imported
*********************************************************************************/
SInt32 CBankTransaction::VerifyImport()
{
// we must have a valid bank account
if (mBankAccount)
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
if (!gDBFile->ObjectExists(GetBankAccountClass(), mBankAccount))
return import_Fatal;
}
else
return import_Fatal;
// we don't need anything else for void transactions TCS 5/1/01
if (HasVoidStatus())
return import_OK;
// check for a valid main account.
// transfers have some other valid main acct classes
if (mTransactionType == id_BankTransferIn && (mMainAccountClass == condition_InterestIn ||
mMainAccountClass == condition_OtherCredit)) // bugfix TCS 4/25/01
{
return import_OK;
}
else if (mTransactionType == id_BankTransferOut && (mMainAccountClass == condition_InterestOut ||
mMainAccountClass == condition_OtherCharge))
{
return import_OK;
}
// deposits have some other valid main acct classes
else if (mTransactionType == id_BankDeposit && (mMainAccountClass == filter_cashsalesbybranch ||
mMainAccountClass == filter_cashsalesbydate ||mMainAccountClass == filter_billedsales ||
mMainAccountClass == filter_billedprojects || mMainAccountClass == filter_rentals ||
mMainAccountClass == filter_paymentsreceived))
{
return import_OK;
}
else if (mMainAccount && IS_TURTLE_CLASS_ID(mMainAccountClass))
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
if (gDBFile->ObjectExists(mMainAccountClass, mMainAccount))
return import_OK;
else
return import_Fatal;
}
else
return import_Fatal;
// ****** DO NOT PASS TO THE SUPERCLASS******** We need to accept main accounts
// that are considered invalid in CTransaction::VerifyImport
}
/*********************************************************************************
FinishViewerCreate
fill in values after creation in a viewer TCS 2/10/99
*********************************************************************************/
void CBankTransaction::FinishViewerCreate()
{
// we need to explicitely set the transaction type, since
// it is now initialized to zero TCS 8/17/00
if (mTransactionType)
{
// value already set e.g. from duplicate. TCS 10/26/00
}
else if (GetDBClassID() == id_CheckingTransaction || GetDBClassID() == id_EscrowTransaction ||
GetDBClassID() == id_LoanTransaction)
{
mTransactionType = id_BankCheck;
}
else
{
mTransactionType = id_BankPayment;
}
// let the superclass do its stuff
THE_SUPERCLASS::FinishViewerCreate();
FinishNewBankTransaction();
}
/*********************************************************************************
FinishClientCreate TCS 5/1/03
fill in values after creation by a client
*********************************************************************************/
void CBankTransaction::FinishClientCreate()
{
THE_SUPERCLASS::FinishClientCreate();
// we need to explicitely set the transaction type, since
// it is now initialized to zero
if (mTransactionType)
{
// value already set e.g. from duplicate.
}
else if (GetDBClassID() == id_CheckingTransaction || GetDBClassID() == id_EscrowTransaction ||
GetDBClassID() == id_LoanTransaction)
{
mTransactionType = id_BankCheck;
}
else
{
mTransactionType = id_BankPayment;
}
// we pass it along for regular non-viewer creation action
THE_SUPERCLASS::FinishNonViewerCreate();
// fill in some details
FinishNewBankTransaction();
}
/*********************************************************************************
FinishNonViewerCreate TCS 2/9/99
fill in values after creation from an AFW drag, process or client creation
*********************************************************************************/
void CBankTransaction::FinishNonViewerCreate()
{
// let the superclass do its stuff
THE_SUPERCLASS::FinishNonViewerCreate();
// fill in some details
FinishNewBankTransaction();
}
/*********************************************************************************
FinishTemplateCreate TCS 8/17/01
fill in values after creation from a template or recurring transaction
*********************************************************************************/
void CBankTransaction::FinishTemplateCreate()
{
// let the superclass do its stuff
THE_SUPERCLASS::FinishTemplateCreate();
// fill in some details
FinishNewBankTransaction();
}
/*********************************************************************************
FinishNewBankTransaction TCS moved 8/17/01
finish up details for a newly created bank transaction
*********************************************************************************/
void CBankTransaction::FinishNewBankTransaction()
{
// fill in the running total.
FetchNewRunningTotal();
// fill in the check number (don't increment it)
if (mTransactionType == id_BankCheck)
FillCheckbookNumber(); // rev TCS 10/13/00
else if (GetDBClassID() == id_CheckingTransaction)
SetRefNum(CNumbering::PeekNextNumber(id_CheckingTransaction));
}
/*********************************************************************************
FinishImportCreate
fill in values after creation from an import TCS 8/11/99
*********************************************************************************/
void CBankTransaction::FinishImportCreate()
{
// let the superclass do its stuff
THE_SUPERCLASS::FinishImportCreate();
// calculate the running total. TCS 6/22/00
FetchNewRunningTotal();
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************
IsRefund (static) TCS 12/14/00
return whether the given combination of account and transaction means this
is a refund
*********************************************************************************/
Boolean CBankTransaction::IsRefund(const DBClass accountClass, const UInt8 transactionType)
{
switch (accountClass)
{
case id_EmployeeAccount:
case id_MaterialAccount:
case id_SubcontractorAccount:
case id_OtherCostAccount:
return transactionType == id_BankDeposit;
break;
case id_CustomerAccount:
case id_ProjectAccount:
case id_Lease:
return (transactionType == id_BankCheck || transactionType == id_BankPayment);
break;
// we don't do owners here, since their deposits and payments
// are posted to separate utility accounts(so both are positive)
default:
return false;
break;
}
}
/*********************************************************************************
IsValidBreakdown
return whether the passed breakdown type is valid. We override, since the
valid breakdown types depends on the type of bank transaction.
*********************************************************************************/
Boolean CBankTransaction::IsValidBreakdown(const UInt8 breakdownType)
{
if (breakdownType == breakdown_none)
return true;
switch (mTransactionType)
{
case id_BankTransferIn:
case id_BankTransferOut:
return false;
break;
case id_BankPayment:
case id_BankCheck:
return (breakdownType == breakdown_purchase ||
breakdownType == breakdown_costcategory ||
breakdownType == breakdown_costitem ||
breakdownType == breakdown_payrollrecord/* ||
breakdownType == breakdown_salestax || // rev TCS 10/7/02
breakdownType == breakdown_payrolltax ||
breakdownType == breakdown_vendorwithholding*/);
break;
case id_BankDeposit:
return (breakdownType == breakdown_payment);
break;
case 0: // importing, and trans type has not yet been set
return (breakdownType == breakdown_purchase ||
breakdownType == breakdown_costcategory ||
breakdownType == breakdown_costitem ||
breakdownType == breakdown_payrollrecord ||
breakdownType == breakdown_payment);
break;
default:
TCS_DebugAlert("Oops, bad case in CBankTransaction::IsValidBreakdown!");
return false;
break;
}
}
/*********************************************************************************
IsValidJobCost TCS 4/19/01
should we display this transaction in a job cost item breakdown? We override
so we'll catch classes that have non-accounts for the main account class
*********************************************************************************/
Boolean CBankTransaction::IsValidJobCost(const UInt8 costType) const
{
if (costType == costtype_other)
{
if (mMainAccountClass == condition_TransferIn ||
mMainAccountClass == condition_OtherCharge)
return true;
}
else if (costType == costtype_income)
{
return (mTransactionType == id_BankDeposit || mTransactionType == id_BankTransferIn);
}
// if we got this far, the superclass can handle it
return THE_SUPERCLASS::IsValidJobCost(costType);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************
PostQuickDeletion TCS 6/2/00
post info from a transaction that has been deleted immediated after creation.
We need to remove it from the bank trans array
*********************************************************************************/
void CBankTransaction::PostQuickDeletion(const Boolean postAudit)
{
// find the bank account and update arrays. We do this first
// so run total update won't think this transaction is still around
if (mBankAccount)
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
DB_Account *bank = TCS_SAFE_CAST(gDBFile->GetOneObject(GetBankAccountClass(),
mBankAccount), DB_Account);
if (bank)
{
DB_ObjectWatcher watcher(bank);
bank->AddToMainTransactionArray(GetDBID(), cRemoveItem);
}
}
// pass it along to the superclass
THE_SUPERCLASS::PostQuickDeletion(postAudit);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************
PostNewRecord TCS 11/20/03
post info for a new record
*********************************************************************************/
void CBankTransaction::PostNewRecord(const UInt8 creationType)
{
PostUseCount(id_ReconcilePeriod, mReconcilePeriod);
PostUseCount(GetBankAccountClass(), mBankAccount);
PostUseCount(mJobClass, mJob);
PostUseCount(id_Category, mCategory);
PostUseCount(id_VendorSalesTax, mTaxRate);
PostUseCount(id_UtilityAccount, mCashUtilityAccount);
// let the superclass do any posting
THE_SUPERCLASS::PostNewRecord(creationType);
}
/*********************************************************************************
PostDeletion TCS 11/20/03
post info from a deleted record
*********************************************************************************/
void CBankTransaction::PostDeletion(const Boolean postAudit)
{
PostUseCount(id_ReconcilePeriod, mReconcilePeriod, cRemoveItem);
PostUseCount(GetBankAccountClass(), mBankAccount, cRemoveItem);
PostUseCount(mJobClass, mJob, cRemoveItem);
PostUseCount(id_Category, mCategory, cRemoveItem);
PostUseCount(id_VendorSalesTax, mTaxRate, cRemoveItem);
PostUseCount(id_UtilityAccount, mCashUtilityAccount, cRemoveItem);
// let the superclass do any posting
THE_SUPERCLASS::PostDeletion(postAudit);
}
/*********************************************************************************
PostRecordActivated
post info from a transaction that has been activated
*********************************************************************************/
void CBankTransaction::PostRecordActivated(const UInt8 creationType)
{
if (mTransactionType == id_BankCheck || mTransactionType == id_BankPayment ||
mTransactionType == id_BankTransferOut)
{
if (DB_ClassDescriptor::IsBankAccount(mMainAccountClass))
{
if (creationType == record_voidtoactive || creationType == record_jobcosttoactive) // TCS 4/30/01
{
UpdateOffsetTransaction(id_BankTransferIn, mAmount, mConditions);
}
else if (creationType != record_fromimport && creationType != record_autotransfer)
{ // it's a transfer, so create an offset transaction
CreateOffsetTransaction(id_BankTransferIn);
}
else
{
// if it's an import we should be importing the other half already.
// if it's an auto-transfer the other half has already been created.
}
}
else if (mTransactionType == id_BankCheck || mTransactionType == id_BankPayment)
{ // it's a regular pmt. Deal with transaction ref
PostBankPayment();
}
else
{ // non bank transfers out are handled as an expense
}
}
else if (mTransactionType == id_BankTransferIn) // TCS bugfix 8/18/00
{
if (DB_ClassDescriptor::IsBankAccount(mMainAccountClass))
{ // it's a transfer, so do an offset transaction
if (creationType == record_voidtoactive || creationType == record_jobcosttoactive) // TCS 4/30/01
{
UpdateOffsetTransaction(id_BankTransferOut, mAmount, mConditions);
}
else if (creationType != record_fromimport && creationType != record_autotransfer)
{ // it's a transfer, so create an offset transaction
CreateOffsetTransaction(id_BankTransferOut);
}
}
}
else if (mTransactionType == id_BankDeposit)
{
PostBankDeposit();
}
// post to the payee account
PostMainAccount();
// post to the bank account
PostBankAccount();
// post to revenue and expense accounts TCS 12/14/00
PostUtilityAccounts();
// post job costs
if (creationType != record_jobcosttoactive) // rev TCS 12/17/99, 12/5/00
AdjustJobCosts(GetJobCostAmount());
// if being reactivated from void status, we'd better recalc // TCS moved 6/22/00
// we need to do this AFTER other posting so we don't double-post
if (creationType == record_voidtoactive || creationType == record_jobcosttoactive)
UpdateRunningTotals(); // param change TCS 2/12/01
// update the stored reference number
if (creationType == record_new || creationType == record_duplicate ||
creationType == record_fromtemplate || creationType == record_fromafw ||
creationType == record_fromprocess || creationType == record_newfromopen)
UpdateBankRefNumber();
// let the superclass do any posting
THE_SUPERCLASS::PostRecordActivated(creationType);
}
|