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

Leases (Source Code)

Link to: header | transactions directory

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

Comments

CLease

This class manages property rental leases in the Goldenseal accounting software,
property management software, and rental property software.

Each lease stores rental information for one tenant. This is the basic source
for rental billing, which means that it sometimes acts sort of like an
account.

Leases are the beginning transaction for the Goldenseal property management
software. They generate Rental Transactions for each rent period via the Rental
Billing command.

SUPERCLASS = CMeeting

Constructor

/*********************************************************************************
default constructor
*********************************************************************************/
CLease::CLease()
{
mMainAccountClass = id_CustomerAccount;
mPropertyType = id_RealEstateAccount;
mMainAccount = 0;
mProperty = mPaymentTerm = mRentalUnit = 0;
mLeaseStart.SetToToday();
mLeaseStart.SetToNextFirstOfMonth();
mLeaseEnd = mLeaseStart;
mLeaseEnd.AddSafeYears(1);
mLeaseEnd.AddDays(-1); // rev TCS 4/20/99

mStatus = status_Active; // TCS 10/16/03
mAmount = 0;

mDepositType = mLastMonthPrepaidType = deposit_monthsrent;
mDamageDeposit = mKeyDeposit = mLastMonthPrepaid = 0;
mFirstMonthAmount = mLastMonthAmount = 0;
mEscrowAccount = 0;
mSalesRep = mCommissionID = 0;
mContractPackage = 0;

mCurrBalance = mCommissionPaid = 0;

mMonthToMonth = false;
mFirstMonthPartial = mLastMonthPartial = false;

mLeaseFiller = 0; // TCS 12/12/02
mLeasePadding = 0;
mExpansionLong = 0;
mExpansionMoney = 0;

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

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

NeoVersion version = GetVersion();

if (version > 2)
TCS_BlockMove(&src->mProperty, &mProperty, cFileLength3);
else
TCS_BlockMove(&src->mProperty, &mProperty, cFileLength);

mName = src->mName; // TCS 1/15/03

if (mName.Length())
mName.AppendCopyString(); // TCS 8/5/03

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

GetFileLength

return the file length used by this object

*********************************************************************************/
NeoSize CLease::GetFileLength(const CNeoFormat *aFormat) const
{
NeoSize baseLength = THE_SUPERCLASS::GetFileLength(aFormat) +
ARRAY_FILE_SIZE(mRentalTransactionArray) +
ARRAY_FILE_SIZE(mUnpaidRentArray) +
ARRAY_FILE_SIZE(mUnpaidBillingRecordArray);

NeoVersion version = GetVersion();

if (version == 1) // TCS 1/15/03
{
return baseLength + cFileLength;
}
else if (version == 2)
{
return baseLength +
mName.FileLength(cMenuTextLen) +
cFileLength;
}
else
{
return baseLength +
mName.FileLength(cMenuTextLen) +
cFileLength3;
}
}/*********************************************************************************

GetMemberValue

return the value of the member with the given tag

*********************************************************************************/
Boolean CLease::GetMemberValue(const TagType aTag, const TagType aType,
void *aValue) const
{
CTextString outText;

switch (aTag)
{
case tag_property:
return ConvertObjectIDMember(mProperty, id_RealEstateAccount, aValue, aType);
break;

case tag_paymentterm:
return ConvertObjectIDMember(mPaymentTerm, id_RentalPaymentTerm, aValue, aType);
break;

case tag_escrowaccount:
return ConvertObjectIDMember(mEscrowAccount, id_EscrowAccount, aValue, aType);
break;

case tag_salesrep: // TCS 6/5/02
return ConvertObjectIDMember(mSalesRep, id_EmployeeAccount, aValue, aType);
break;

case tag_commission: // TCS 6/7/02
return ConvertObjectIDMember(mCommissionID, id_Commission, aValue, aType);
break;

case tag_rentalunit: // TCS rev 3/3/03
return ConvertObjectIDMember(mRentalUnit, id_RentalUnit, aValue, aType);
break;

case tag_contractpackage: // TCS rev 11/13/03
return ConvertObjectIDMember(mContractPackage, id_ContractPackage, aValue, aType);
break;

case tag_customer: // TCS 3/3/03
return ConvertObjectIDMember(mMainAccount, id_CustomerAccount, aValue, aType);
break;

case tag_propertytype:
return ConvertEnumMember(mPropertyType, MENU_LeasePropertyTypes, aValue, aType);
break;

case tag_deposittype:
return ConvertEnumMember(mDepositType, MENU_DamageDepositTypes, aValue, aType);
break;

case tag_lastmonthprepaidtype:
return ConvertEnumMember(mLastMonthPrepaidType, MENU_DamageDepositTypes, aValue, aType);
break;

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

case tag_leasestart:
return ConvertMember(&mLeaseStart, type_date, aValue, aType);
break;

case tag_leaseend:
return ConvertMember(&mLeaseEnd, type_date, aValue, aType);
break;

case tag_currbalance:
return ConvertMember(&mCurrBalance, type_money, aValue, aType);
break;

case tag_amount:
return ConvertMember(&mAmount, type_money, aValue, aType);
break;

case tag_damagedeposit:
return ConvertMember(&mDamageDeposit, type_money, aValue, aType);
break;

case tag_lastmonthprepaid:
return ConvertMember(&mLastMonthPrepaid, type_money, aValue, aType);
break;

case tag_firstmonthamount: // TCS 11/13/03
return ConvertMember(&mFirstMonthAmount, type_money, aValue, aType);
break;

case tag_lastmonthamount: // TCS 11/13/03
return ConvertMember(&mLastMonthAmount, type_money, aValue, aType);
break;

case tag_keydeposit:
return ConvertMember(&mKeyDeposit, type_money, aValue, aType);
break;

case tag_commissionpaid: // TCS 9/2/02
return ConvertMember(&mCommissionPaid, type_money, aValue, aType);
break;

case tag_monthtomonth: // TCS 8/30/02
return ConvertBitFieldMember(mMonthToMonth, aValue, aType);
break;

case tag_firstmonthpartial: // TCS 11/13/03
return ConvertBitFieldMember(mFirstMonthPartial, aValue, aType);
break;

case tag_lastmonthpartial: // TCS 11/13/03
return ConvertBitFieldMember(mLastMonthPartial, aValue, aType);
break;

case tag_name: // TCS 1/15/03
case tag_menuname:
if (mName.Length()) // TCS 10/1/03
return ConvertMember(&mName, type_cstring, aValue, aType);
else
{
outText = GetTenantName();
return ConvertMember(&outText, type_cstring, aValue, aType);
}
break;

case tag_paymenttermtext: // TCS 11/13/00
{
outText = GetPaymentTermText(id_RentalPaymentTerm, mPaymentTerm);
return ConvertMember(&outText, type_cstring, aValue, aType);
}
break;

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

SetMemberValue

set the value of the member with the given tag

*********************************************************************************/
Boolean CLease::SetMemberValue(const TagType aTag, const TagType aType,
const void *aValue)
{
switch (aTag)
{
case tag_property:
return ConvertDataToObjectID(aValue, aType, &mProperty, id_RealEstateAccount);
break;

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

case tag_escrowaccount:
return ConvertDataToObjectID(aValue, aType, &mEscrowAccount, id_EscrowAccount);
break;

case tag_salesrep: // TCS 6/5/02
return ConvertDataToObjectID(aValue, aType, &mSalesRep, id_EmployeeAccount);
break;

case tag_commission: // TCS 6/7/02
return ConvertDataToObjectID(aValue, aType, &mCommissionID, id_Commission);
break;

case tag_contractpackage: // TCS rev 11/13/03
return ConvertDataToObjectID(aValue, aType, &mContractPackage, id_ContractPackage);
break;

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

case tag_deposittype:
return ConvertMember(aValue, aType, &mDepositType, type_enum);
break;

case tag_propertytype:
return ConvertMember(aValue, aType, &mPropertyType, type_enum);
break;

case tag_lastmonthprepaidtype:
return ConvertMember(aValue, aType, &mLastMonthPrepaidType, type_enum);
break;

case tag_rentalunit:
return ConvertMember(aValue, aType, &mRentalUnit, type_long);
break;

case tag_currbalance: // TCS 11/15/00
return ConvertMember(aValue, aType, &mCurrBalance, type_money);
break;
case tag_amount:
return ConvertMember(aValue, aType, &mAmount, type_money);
break;

case tag_lastmonthprepaid:
return ConvertMember(aValue, aType, &mLastMonthPrepaid, type_money);
break;

case tag_firstmonthamount: // TCS 11/13/03
return ConvertMember(aValue, aType, &mFirstMonthAmount, type_money);
break;

case tag_lastmonthamount: // TCS 11/13/03
return ConvertMember(aValue, aType, &mLastMonthAmount, type_money);
break;

case tag_damagedeposit:
return ConvertMember(aValue, aType, &mDamageDeposit, type_money);
break;

case tag_keydeposit:
return ConvertMember(aValue, aType, &mKeyDeposit, type_money);
break;

case tag_commissionpaid: // TCS 6/5/02
return ConvertMember(aValue, aType, &mCommissionPaid, type_money);
break;

case tag_leasestart:
return ConvertMember(aValue, aType, &mLeaseStart, type_date);
break;

case tag_leaseend:
return ConvertMember(aValue, aType, &mLeaseEnd, type_date);
break;

case tag_name: // TCS 1/15/03
return SafeConvertString(aValue, aType, &mName);
break;

case tag_monthtomonth: // TCS 12/12/02
mMonthToMonth = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_firstmonthpartial: // TCS 11/13/03
mFirstMonthPartial = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_lastmonthpartial: // TCS 11/13/03
mLastMonthPartial = ConvertDataToBitField(aValue, aType);
return true;
break;

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

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

ReadObject

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

ReadIDArrayFromStream(aStream, mRentalTransactionArray, cHasSafetyTag);
ReadIDArrayFromStream(aStream, mUnpaidRentArray, cHasSafetyTag);
ReadIDArrayFromStream(aStream, mUnpaidBillingRecordArray, cHasSafetyTag);

NeoVersion version = GetVersion();

if (version > 1)
ReadTextFromStream(aStream, &mName);

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

mProperty = aStream->ReadID(); // mfs_sa rev 20feb2k3
mRentalUnit = aStream->ReadID();
mPaymentTerm = aStream->ReadID();
mEscrowAccount = aStream->ReadID();
mSalesRep = aStream->ReadID();
mCommissionID = aStream->ReadID();

mLeaseStart.ReadFromStream(aStream);
mLeaseEnd.ReadFromStream(aStream);

mAmount.ReadFromStream(aStream);
mKeyDeposit.ReadFromStream(aStream);
mLastMonthPrepaid.ReadFromStream(aStream);
mDamageDeposit.ReadFromStream(aStream);

mPropertyType = aStream->ReadChar();
mStatus = aStream->ReadChar();
mDepositType = aStream->ReadChar();
mLastMonthPrepaidType = aStream->ReadChar();

*((UInt8*)&mLastMonthPrepaidType + sizeof(mLastMonthPrepaidType)) = aStream->ReadBits(3); // --Bitfield

mLeasePadding = aStream->ReadChar();

mExpansionMoney.ReadFromStream(aStream);

mExpansionLong = aStream->ReadID();

if (version > 2) // TCS 11/13/03
{
mContractPackage = aStream->ReadID();
mFirstMonthAmount.ReadFromStream(aStream);
mLastMonthAmount.ReadFromStream(aStream);
}

mCurrBalance.ReadFromStream(aStream);
mCommissionPaid.ReadFromStream(aStream);

mEndSafetyTag = aStream->ReadEndSafetyTag(this);

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

WriteObject

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

NeoVersion version = GetVersion();

CNeoDebugExport checker(aStream, this, cCheckTooSmall);
THE_SUPERCLASS::WriteObject(aStream, aTag);

WriteIDArrayToStream(aStream, mRentalTransactionArray, cHasSafetyTag);
WriteIDArrayToStream(aStream, mUnpaidRentArray, cHasSafetyTag);
WriteIDArrayToStream(aStream, mUnpaidBillingRecordArray, cHasSafetyTag);

if (version > 1)
WriteTextToStream(aStream, mName, cMenuTextLen);

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

aStream->WriteID(mProperty); // mfs_sa rev 20feb2k3
aStream->WriteID(mRentalUnit);
aStream->WriteID(mPaymentTerm);
aStream->WriteID(mEscrowAccount);
aStream->WriteID(mSalesRep);
aStream->WriteID(mCommissionID);

mLeaseStart.WriteToStream(aStream);
mLeaseEnd.WriteToStream(aStream);

mAmount.WriteToStream(aStream);
mKeyDeposit.WriteToStream(aStream);
mLastMonthPrepaid.WriteToStream(aStream);
mDamageDeposit.WriteToStream(aStream);

aStream->WriteChar(mPropertyType);
aStream->WriteChar(mStatus);
aStream->WriteChar(mDepositType);
aStream->WriteChar(mLastMonthPrepaidType);

aStream->WriteChar(*((UInt8*)&mLastMonthPrepaidType + sizeof(mLastMonthPrepaidType))); // --Bitfield

aStream->WriteChar(mLeasePadding);

mExpansionMoney.WriteToStream(aStream);

aStream->WriteID(mExpansionLong);

if (version > 2) // TCS 11/13/03
{
aStream->WriteID(mContractPackage);
mFirstMonthAmount.WriteToStream(aStream);
mLastMonthAmount.WriteToStream(aStream);
}

mCurrBalance.WriteToStream(aStream);
mCommissionPaid.WriteToStream(aStream);

aStream->WriteEndSafetyTag(mEndSafetyTag, this);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

PostNewRecord TCS 11/21/03

post info for a new record
*********************************************************************************/
void CLease::PostNewRecord(const UInt8 creationType)
{
PostUseCount(id_ContractPackage, mContractPackage);
PostUseCount(mPropertyType, mProperty);
PostUseCount(id_RentalUnit, mRentalUnit);
PostUseCount(id_RentalPaymentTerm, mPaymentTerm);
PostUseCount(id_EscrowAccount, mEscrowAccount);
PostUseCount(id_EmployeeAccount, mSalesRep);
PostUseCount(id_Commission, mCommissionID);

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

PostDeletion TCS 11/21/03

post info from a deleted record
*********************************************************************************/
void CLease::PostDeletion(const Boolean postAudit)
{
PostUseCount(id_ContractPackage, mContractPackage, cRemoveItem);
PostUseCount(mPropertyType, mProperty, cRemoveItem);
PostUseCount(id_RentalUnit, mRentalUnit, cRemoveItem);
PostUseCount(id_RentalPaymentTerm, mPaymentTerm, cRemoveItem);
PostUseCount(id_EscrowAccount, mEscrowAccount, cRemoveItem);
PostUseCount(id_EmployeeAccount, mSalesRep, cRemoveItem);
PostUseCount(id_Commission, mCommissionID, cRemoveItem);

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

PostRecordActivated TCS 6/5/02

post info from a newly created or activated transaction
*********************************************************************************/
void CLease::PostRecordActivated(const UInt8 creationType)
{
// update the paid amount
PostCommission();
PostLease();

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

PostRecordCancelled TCS 6/5/02

post info from a deleted or voided transaction
*********************************************************************************/
void CLease::PostRecordCancelled(const UInt8 cancelType)
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
// post removal
PostCommission(cRemoveItem);
PostLease(cRemoveItem);

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

PostRecordChanging TCS 6/5/02

a record will be changing. Post the change.
*********************************************************************************/
void CLease::PostRecordChanging(const Boolean accountChanging, const Boolean jobChanging)
{
// we do a full posting removal since pmt method may have changed bill status,
PostCommission(cRemoveItem);
PostLease(cRemoveItem);

PostUseCount(id_ContractPackage, mContractPackage, cRemoveItem); // TCS 11/21/03
PostUseCount(mPropertyType, mProperty, cRemoveItem);
PostUseCount(id_RentalUnit, mRentalUnit, cRemoveItem);
PostUseCount(id_RentalPaymentTerm, mPaymentTerm, cRemoveItem);
PostUseCount(id_EscrowAccount, mEscrowAccount, cRemoveItem);
PostUseCount(id_EmployeeAccount, mSalesRep, cRemoveItem);
PostUseCount(id_Commission, mCommissionID, cRemoveItem);

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

PostRecordChanged TCS 6/5/02

a record has changed. Post it.
*********************************************************************************/
void CLease::PostRecordChanged(const CMoney &oldAmount, const Boolean accountChanged,
const Boolean jobChanged)
{
// we do a full reposting since pmt method may have changed bill status
PostCommission();
PostLease();

PostUseCount(id_ContractPackage, mContractPackage); // TCS 11/21/03
PostUseCount(mPropertyType, mProperty);
PostUseCount(id_RentalUnit, mRentalUnit);
PostUseCount(id_RentalPaymentTerm, mPaymentTerm);
PostUseCount(id_EscrowAccount, mEscrowAccount);
PostUseCount(id_EmployeeAccount, mSalesRep);
PostUseCount(id_Commission, mCommissionID);

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

PostCommission TCS 6/5/02

post a sales commission
*********************************************************************************/
void CLease::PostCommission(const Boolean removeItem)
{
if (HasVoidStatus())
return;

gDBFile->UpdateEarlyLateDates(mLeaseStart); // TCS 1/3/03
gDBFile->UpdateEarlyLateDates(mLeaseEnd);

CEmployeeAccount *employee = TCS_SAFE_CAST(gDBFile->GetOneObject(id_EmployeeAccount, mSalesRep),
CEmployeeAccount);

if (employee)
{
DB_ObjectWatcher watcher (employee);

employee->AddToCommissionArray(id_Lease, GetDBID(), removeItem);

if (mCommissionPaid.IsPositive() || removeItem)
employee->AddToUnpaidCommissionArray(id_Lease, GetDBID(), false);
else
employee->AddToUnpaidCommissionArray(id_Lease, GetDBID());
}
}
/*********************************************************************************

PostLease TCS 3/3/03

post a lease creation, change or deletion
*********************************************************************************/
void CLease::PostLease(const Boolean removeItem)
{
if (mRentalUnit)
{
DB_PersistentObject *rentalUnit = gDBFile->GetOneObject(id_RentalUnit, mRentalUnit);

if (rentalUnit)
{
DB_ObjectWatcher watcher (rentalUnit);
rentalUnit->AddToLeaseArray(GetDBID(), removeItem);
}
}

if (mProperty)
{
DB_PersistentObject *property = gDBFile->GetOneObject(id_RealEstateAccount, mProperty);

if (property)
{
DB_ObjectWatcher watcher (property);
property->AddToLeaseArray(GetDBID(), removeItem);
}
}
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

GetTenantName TCS 10/12/99 rev 11/19/99

fetch the name of the tenant for this lease
*********************************************************************************/
CTextString CLease::GetTenantName() const
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
CTextString tenantName;

if (mMainAccount)
{
DB_PersistentObject *tenant =
gDBFile->GetOneObject(id_CustomerAccount, mMainAccount);
if (tenant)
{
DB_ObjectWatcher watcher(tenant);
tenantName = tenant->GetName();
}
}
return tenantName;
}
/*********************************************************************************

GetPropertyName TCS 3/25/02

fetch the name of the real estate account for this lease
*********************************************************************************/
CTextString CLease::GetPropertyName() const
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
CTextString propertyName;

if (mProperty)
{
DB_PersistentObject *property =
gDBFile->GetOneObject(id_RealEstateAccount, mProperty);
if (property)
{
DB_ObjectWatcher watcher(property);
propertyName = property->GetName();
}
}
return propertyName;
}
/*********************************************************************************

GetUnitName TCS 3/25/02

fetch the name of the rental unit for this lease
*********************************************************************************/
CTextString CLease::GetUnitName() const
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
CTextString unitName;

if (mRentalUnit)
{
unitName = gDBFile->GetObjectName(id_RentalUnit, mRentalUnit); // TCS rev 3/3/03
}
return unitName;
}
/*********************************************************************************

GetCustomerName TCS 8/18/03

return the name of the customer

*********************************************************************************/
CTextString CLease::GetCustomerName() const
{
return GetTenantName();
}
/*********************************************************************************

GetDeposit TCS 3/13/00

return the amount of the deposit
*********************************************************************************/
CMoney CLease::GetDeposit() const
{
switch (mDepositType)
{
case deposit_monthsrent: // bugfix TCS 12/22/00
return mDamageDeposit * mAmount;
break;

case deposit_lumpsum:
return mDamageDeposit;
break;

default:
TCS_DebugAlert("Oops, bad case in CLease::GetDeposit()!");
return 0;
break;
}
}
/*********************************************************************************

GetStartingAmount TCS 3/26/02 rev 11/13/03

return the amount of the first rent payment, which may be partial
*********************************************************************************/
CMoney CLease::GetStartingAmount() const
{
if (mFirstMonthPartial)
return mFirstMonthAmount;
else
return mAmount;
}
/*********************************************************************************

GetClosingAmount TCS 3/26/02 rev 11/13/03

return the amount of the final rent payment, which may be partial
*********************************************************************************/
CMoney CLease::GetClosingAmount() const
{
if (mLastMonthPartial)
return mLastMonthAmount;
else
return mAmount;
}
/*********************************************************************************

GetLastMonthPrepaidRent TCS 3/13/00

return the last month's prepaid rent amount
*********************************************************************************/
CMoney CLease::GetLastMonthPrepaidRent() const
{
switch (mLastMonthPrepaidType)
{
case deposit_monthsrent: // bugfix TCS 3/7/02
return mLastMonthPrepaid * mAmount;
break;

case deposit_lumpsum:
return mLastMonthPrepaid;
break;

default:
TCS_DebugAlert("Oops, bad case in CLease::GetLastMonthRent()!");
return 0;
break;
}
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

GetTransactionCount TCS 3/28/02 rev 7/4/02

return the number of transactions for this lease
*********************************************************************************/
SInt32 CLease::GetTransactionCount() const
{
return mRentalTransactionArray.GetCount();
}
/*********************************************************************************

HasLockedStatus TCS 1/15/03

we override because completed leases should still not be locked.

*********************************************************************************/
Boolean CLease::HasLockedStatus() const
{
if (GetStatus() == status_Completed)
return false;
else return THE_SUPERCLASS::HasLockedStatus();
}
#if CAN_USE_MARK
#pragma mark -
#endif/*********************************************************************************

HandlePaymentReceived TCS 6/24/00

handle a payment received on this lease. We also pass it along to the tenant
*********************************************************************************/
void CLease::HandlePaymentReceived(const CMoney &inAmount, const UInt8 sourceClass,
const DBid sourceID, const UInt8 transactionType,
const Boolean removeItem, const Boolean fromDeposit,
const Boolean /*fromBillRecord*/)
{
// the superclass doesn't do anything now but let's be polite
THE_SUPERCLASS::HandlePaymentReceived(inAmount, sourceClass, sourceID, transactionType, removeItem, fromDeposit);

// pass the payment along to the tenant account
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
DB_Account *account =
TCS_SAFE_CAST(gDBFile->GetOneObject(mMainAccountClass, mMainAccount), DB_Account);

if (account)
{
DB_ObjectWatcher watcher(account);
account->AdjustBalance(-inAmount);
//account->AddToIncomeArray(sourceClass, sourceID, condition_PaymentReceived, removeItem); // removed TCS 5/4/01
//account->HandlePaymentReceived(inAmount, sourceClass, sourceID, removeItem, fromDeposit);
}
}
/*********************************************************************************
HandleCommissionPaid TCS 7/11/02

a commission has been paid on this item. Mark it off
*********************************************************************************/
void CLease::HandleCommissionPaid(const CMoney &amount, const Boolean removeItem)
{
if (removeItem)
mCommissionPaid -= amount;
else
mCommissionPaid += amount;

if (mCommissionPaid.IsZero()) // TCS 7/29/02
{
if (mStatus == status_CommishPaid)
SetToStarterStatus();
}
else
{
if (mStatus == status_Pending || mStatus == status_Active)
SetStatus(status_CommishPaid);
}

MakeDirty();
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

InitializeRentalInfo BD 3/20/02

initialize some values in rent info struct

*********************************************************************************/
void CLease::InitializeRentalInfo(SRentalInfo &rentInfo)
{
// initialize rent info values
rentInfo.rentPeriodStart.SetToNever();
rentInfo.rentPeriodEnd.SetToNever();
rentInfo.amount = 0;
rentInfo.previousPaidAmount = 0; // TCS 3/29/02
rentInfo.overdueAmount = 0;
rentInfo.adjustAmount = 0;
rentInfo.totalDueAmount = 0;
rentInfo.rentPeriod = 0; // TCS 3/30/02
rentInfo.type = condition_BasicRent;
rentInfo.bill = cDontPayNow;
}/*********************************************************************************

InitializeLeaseInfo BD 3/13/02

initialize some values in lease info struct

WARNING- this method creates a rental item array on the heap. The caller should
be sure to bracket with a TRY/CATCH block, and dispose of the array when
it is finished with the SLeaseInfo struct.

*********************************************************************************/
void CLease::InitializeLeaseInfo(SLeaseInfo &leaseInfo)
{
// initialize lease info values
leaseInfo.leaseID = 0;
leaseInfo.currentAmount = 0;
leaseInfo.overdueAmount = 0;
leaseInfo.adjustAmount = 0;
leaseInfo.totalDueAmount = 0;
leaseInfo.bill = false;

leaseInfo.rentArray = NEW TRentalInfoArray;
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

FillDepositInfo TCS 10/12/99

fill in information about deposits for billed rentals for this lease.
*********************************************************************************/
Boolean CLease::FillDepositInfo(SDepositInfo &depositInfo)
{
if (mStatus != status_Active && mStatus != status_CommishPaid) // TCS 1/29/04
return false;

Boolean success = false;

depositInfo.accountID = GetDBID();
depositInfo.accountClassID = id_Lease;
depositInfo.transactionClassID = id_RentalTransaction;
TCS_BufferFromText(depositInfo.itemName, GetTenantName());

CSalesBranch::InitializeDepositInfo(depositInfo);
TCS_FailNILMsg(depositInfo.itemArray, TCS_GetErrString(errID_BadArray));


// do we have any rental transactions? TCS rev 11/13/02
if (mRentalTransactionArray.GetCount() > 0)
{
// sanity check
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));

// set up an item struct
SDepositItem item;
CSalesBranch::InitializeDepositItemInfo(item, id_RentalTransaction);
item.accountClassID = depositInfo.accountClassID;
item.accountID = depositInfo.accountID;

// basic prep
CRentalTransaction *rentalTransact = nil;
DBid rentalID;
UInt8 paymentType;

// prepare to iterate thru array items
TObjectIDArrayIterator iterator(mRentalTransactionArray);

while (iterator.Next(rentalID))
{
rentalTransact =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_RentalTransaction, rentalID),
CRentalTransaction);

if (rentalTransact)
{
DB_ObjectWatcher watcher(rentalTransact);

item.dueAmount = rentalTransact->GetAmount();

// do we have a valid status? bugfix TCS 7/24/01, TCS rev 11/13/02
if (!rentalTransact->HasBeenDeposited() && item.dueAmount.IsNonZero())
{
item.paymentMethod = rentalTransact->GetBillPaymentMethod();
paymentType = CPaymentMethod::GetPaymentType(item.paymentMethod);

depositInfo.dueAmount += item.dueAmount;
item.transactionID = rentalID;

// initial status is based on whether pmt has been received rev TCS 11/13/02
if (rentalTransact->GetPaymentType() != method_billed)
{
item.paidAmount = item.dueAmount; // we'll probably deposit it now
item.deposit = true;
}
else
{
item.paidAmount = 0; // not yet received
item.deposit = false;
}

if (item.paidAmount.IsPositive())
{
switch (paymentType) // TCS rev 10/12/99
{
case method_cash:
depositInfo.cashAmount += item.paidAmount;
break;

case method_check:
depositInfo.checkAmount += item.paidAmount;
break;

case method_creditcard:
depositInfo.creditCardAmount += item.paidAmount;
break;

default:
depositInfo.otherAmount += item.paidAmount;
break;
}

depositInfo.paidAmount += item.paidAmount;
}
else if (item.paidAmount.IsNegative()) // TCS 9/13/01
depositInfo.creditAmount -= item.paidAmount;

// add to the array
depositInfo.itemArray->Append(item);
success = true;
}
}
else
{
// if an item is missing, report the problem and remove it
ReportMissingObject(id_RentalTransaction, rentalID); // TCS 6/26/03
AddToObjectIDArray(mRentalTransactionArray, rentalID, cRemoveItem);
}
}
}

if (!success) // if no items, we'll delete the array
{
TCS_Forget(depositInfo.itemArray);
}
return success;
}
/*********************************************************************************

FillDepositArray rev TCS 1/15/03

fill in details of rental transactions for this lease. This fills data
into a deposit that's not handled via Deposit Funds

*********************************************************************************/
void CLease::FillDepositArray(SPaymentInfo &paymentInfo) const
{
// initialize
CCursorSpinner spinner;

// initialize payment info values
paymentInfo.id = GetDBID();
paymentInfo.dueAmount = 0;
paymentInfo.paymentAmount = 0;

// initialize an item info struct
SPaymentItemInfo itemInfo;
itemInfo.dueAmount = 0;
itemInfo.paymentAmount = 0;
itemInfo.received = true;

// initialize the item array. Note that if there is
// already an array, we don't create one. If you don't
// initialize the itemArray to nil when you first create the
// paymentInfo struct, it will crash horribly later on. rev TCS 10/9/00
if (!paymentInfo.itemArray)
paymentInfo.itemArray = NEW TPaymentItemArray;

// check for rent transactions
if (mRentalTransactionArray.GetCount() > 0)
{
++spinner;
// let's prepare to loop thru the rent transactions and check info for each
DBid recordID = 0;
UInt8 status = 0;
TObjectIDArrayIterator iterator(mRentalTransactionArray);
CRentalTransaction *transaction = nil;

// start loooping
while (iterator.Next(recordID))
{
transaction = TCS_SAFE_CAST(gDBFile->GetOneObject(id_RentalTransaction, recordID),
CRentalTransaction);
++spinner;
if (transaction)
{
DB_ObjectWatcher watcher(transaction);
// fetch values from the rental transaction
status = transaction->GetStatus();

if (transaction->HasOpenStatus())
{
itemInfo.dueAmount = transaction->GetAmountDue(); // bugfix TCS 2/5/03
itemInfo.paymentAmount = itemInfo.dueAmount;

itemInfo.itemID = recordID;
itemInfo.classID = transaction->GetDBClassID();

// add to totals
paymentInfo.dueAmount += itemInfo.dueAmount;

// add it to the array
paymentInfo.itemArray->Append(itemInfo);
}
}
}
}
}
/*********************************************************************************

FillRentalInfo BD 3/13/02

fill in a lease info struct with the rents that are currently unpaid

WARNING- this method creates a rental item array on the heap. The caller should
be sure to bracket with a TRY/CATCH block, and dispose of the array when
it is finished with the SLeaseInfo struct.

*********************************************************************************/
Boolean CLease::FillRentalInfo(SLeaseInfo &leaseInfo, const CDate cutoffDate,
const Boolean /*inViewer*/)
{
Boolean success = false;

if (mStatus != status_Active && mStatus != status_CommishPaid)
return false;

CCursorSpinner spinner;

InitializeLeaseInfo(leaseInfo);
TCS_FailNILMsg(leaseInfo.rentArray, TCS_GetErrString(errID_BadArray));

leaseInfo.leaseID = GetDBID();

TCS_TRY
{
success = FillAllRentsDue(leaseInfo, cutoffDate);

// we have rental items, so check any existing rental transactions
// and mark off any items that are already billed for
if (success)
{
SRentalInfo rentInfo;

TObjectIDArrayIterator iterator(mRentalTransactionArray);
CRentalTransaction *rentalTrans = nil;
DBid rentID = 0;
CDate today = CDate::Today();
CDate billingDate, discountDate, dueDate;
CDate rentPeriodStart, rentPeriodEnd;

// loop though all rents for this lease
while (iterator.Next(rentID))
{
rentalTrans = TCS_SAFE_CAST(gDBFile->GetOneObject(id_RentalTransaction, rentID),
CRentalTransaction);
++spinner;
if (rentalTrans)
{
DB_ObjectWatcher watcher(rentalTrans);

rentalTrans->UpdateLeaseInfo(leaseInfo, cutoffDate);
}
else
ReportMissingObject(id_RentalTransaction, rentID);
}

// fill in payments 'on account'
}

if (leaseInfo.currentAmount.IsPositive())
{
leaseInfo.totalDueAmount = leaseInfo.currentAmount;
leaseInfo.bill = true;
}
else
leaseInfo.bill = false;
}
TCS_CATCH {}

if (!success)
TCS_Forget(leaseInfo.rentArray);

return success;
}
/*********************************************************************************
FillAllRentsDue 3/25/02

fill in all rent items. We start with all deposits, last month and rent for
each period.

*********************************************************************************/
Boolean CLease::FillAllRentsDue(SLeaseInfo &leaseInfo, const CDate cutoffDate)
{
TCS_FailNILMsg(leaseInfo.rentArray, TCS_GetErrString(errID_BadArray));
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));

if (mStatus != status_Active) // TCS 3/25/04
return false;

if (!mLeaseStart.IsValidDate(false, false)) // TCS 3/25/04
return false;

Boolean success = false;

// is this a month-to-month lease? We consider it that if
// the checkbox is on, or if there is no lease end date
Boolean isMonthToMonth = mMonthToMonth;

if (!mLeaseEnd.IsValidDate(false, false))
isMonthToMonth = true;

SRentalInfo rentInfo;
InitializeRentalInfo(rentInfo);
rentInfo.rentPeriodStart = mLeaseStart;
rentInfo.bill = cPayNow;

CMoney lastMonthPrepaidRent = GetLastMonthPrepaidRent();
CMoney deposit = GetDeposit();
CMoney keyDeposit = GetKeyDeposit();

// is there a damage deposit ?
if (deposit.IsPositive())
{
rentInfo.type = condition_Deposit;
rentInfo.amount = deposit;
rentInfo.totalDueAmount = rentInfo.amount;
leaseInfo.rentArray->Append(rentInfo);
leaseInfo.currentAmount += rentInfo.amount;
success = true;
}
// is there a key deposit ?
if (keyDeposit.IsPositive())
{
rentInfo.type = condition_KeyDeposit;
rentInfo.amount = keyDeposit;
rentInfo.totalDueAmount = rentInfo.amount;

leaseInfo.rentArray->Append(rentInfo);
leaseInfo.currentAmount += rentInfo.amount;
success = true;
}
// is there last month prepaid rent ?
if (lastMonthPrepaidRent.IsPositive())
{
rentInfo.type = condition_LastPayment;
rentInfo.amount = lastMonthPrepaidRent;
rentInfo.totalDueAmount = rentInfo.amount;

leaseInfo.rentArray->Append(rentInfo);
leaseInfo.currentAmount += rentInfo.amount;
success = true;
}

// if there are rental terms, they can fill in basic rent items
CRentalPaymentTerm *terms =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_RentalPaymentTerm, mPaymentTerm),
CRentalPaymentTerm);

if (terms)
{
DB_ObjectWatcher watcher (terms);
if (terms->FillBasicRents(leaseInfo, mAmount, mLeaseStart, mLeaseEnd, cutoffDate,
GetStartingAmount(), GetClosingAmount(), isMonthToMonth))
success = true;
}
else
{
// if no payment terms, fill in monthly rents for the lease term
if (FillMonthlyRents(leaseInfo, cutoffDate, isMonthToMonth))
success = true;
}

rentInfo.rentPeriodStart.SetToNever();
rentInfo.rentPeriodEnd = mLeaseEnd;

if (mLeaseEnd.IsBefore(cutoffDate))
rentInfo.bill = cPayNow;
else
rentInfo.bill = cDontPayNow;

// use up the last month rent
if (lastMonthPrepaidRent.IsPositive())
{
rentInfo.type = condition_LastPaymentUsed;
rentInfo.amount = -lastMonthPrepaidRent;

if (rentInfo.bill == cPayNow)
{
rentInfo.totalDueAmount = rentInfo.amount;
leaseInfo.currentAmount += rentInfo.amount;
}
else
rentInfo.totalDueAmount = 0;

leaseInfo.rentArray->Append(rentInfo);
}

// return the damage deposit ?
if (deposit.IsPositive())
{
rentInfo.type = condition_DepositRefund;
rentInfo.amount = -deposit;

if (rentInfo.bill == cPayNow)
{
rentInfo.totalDueAmount = rentInfo.amount;
leaseInfo.currentAmount += rentInfo.amount;
}
else
rentInfo.totalDueAmount = 0;

leaseInfo.rentArray->Append(rentInfo);
}
// return the key deposit ?
if (keyDeposit.IsPositive())
{
rentInfo.type = condition_KeyRefund;
rentInfo.amount = -keyDeposit;

if (rentInfo.bill == cPayNow)
{
rentInfo.totalDueAmount = rentInfo.amount;
leaseInfo.currentAmount += rentInfo.amount;
}
else
rentInfo.totalDueAmount = 0;

leaseInfo.rentArray->Append(rentInfo);
}

return success;
}
/*********************************************************************************
FillMonthlyRents 3/26/02

fill in monthly rental periods, when there are no payment terms

*********************************************************************************/
Boolean CLease::FillMonthlyRents(SLeaseInfo &leaseInfo, const CDate cutoffDate,
const Boolean isMonthToMonth)
{
TCS_FailNILMsg(leaseInfo.rentArray, TCS_GetErrString(errID_BadArray));

Boolean success = false;
SRentalInfo rentInfo;
InitializeRentalInfo(rentInfo);

rentInfo.rentPeriodStart = mLeaseStart;
rentInfo.rentPeriodEnd = mLeaseStart;
rentInfo.rentPeriodEnd.AddSafeMonths(1);
rentInfo.rentPeriodEnd.AddDays(-1);
rentInfo.type = condition_BasicRent;
rentInfo.amount = mAmount;

// fill in basic rent periods
while (rentInfo.rentPeriodEnd.IsBefore(mLeaseEnd))
{
rentInfo.rentPeriod++;

if (rentInfo.rentPeriodStart.IsBefore(cutoffDate))
{
rentInfo.bill = cPayNow;
rentInfo.totalDueAmount = rentInfo.amount;
leaseInfo.currentAmount += rentInfo.amount;
}
else
{
rentInfo.bill = cDontPayNow;
rentInfo.totalDueAmount = 0;
}

// append the rent to the array
leaseInfo.rentArray->Append(rentInfo);
success = true;

// move ahead by one month
rentInfo.rentPeriodStart.AddSafeMonths(1); // rev TCS 3/30/02
rentInfo.rentPeriodEnd = rentInfo.rentPeriodStart;
rentInfo.rentPeriodEnd.AddSafeMonths(1);
rentInfo.rentPeriodEnd.AddDays(-1);

// if it's month to month, should we stop? TCS 3/25/04
if (isMonthToMonth && rentInfo.rentPeriodStart > cutoffDate)
break;
}

// do we have a partial month at the end?
if (rentInfo.rentPeriodStart.IsBefore(mLeaseEnd) &&
rentInfo.rentPeriodEnd.IsAfter(mLeaseEnd))
{

if (rentInfo.rentPeriodStart.IsBefore(cutoffDate))
{
rentInfo.bill = cPayNow;
rentInfo.totalDueAmount = rentInfo.amount;
leaseInfo.currentAmount += rentInfo.amount;
}
else
{
rentInfo.bill = cDontPayNow;
rentInfo.totalDueAmount = 0;
}

rentInfo.rentPeriod++;
rentInfo.rentPeriodEnd = mLeaseEnd;
rentInfo.type = condition_ClosingRent;

leaseInfo.rentArray->Append(rentInfo);
success = true;
}

return success;
}
/*********************************************************************************

FillCommissionInfo TCS 6/6/02

fill in the commission that is due for this lease
*********************************************************************************/
Boolean CLease::FillCommissionInfo(SCommissionInfo &commishInfo, const DBid commissionID) const
{
CCommission *commission = TCS_SAFE_CAST(gDBFile->GetOneObject(id_Commission, mCommissionID),
CCommission);
if (!commission)
commission = TCS_SAFE_CAST(gDBFile->GetOneObject(id_Commission, commissionID),
CCommission);
TCS_FailNILMsg(commission, TCS_GetErrString(errID_BadObject));
DB_ObjectWatcher watcher (commission);

CMoney rate = commission->GetBaseWage();
UInt8 calcMethod = commission->GetCommissionType(),
whenPaid = commission->GetWhenPaid();

// is the commish ready to be paid?
if (HasVoidStatus() || mStatus == status_Pending)
return false;

// calculate the base amount
CMoney baseAmount = 0, commishAmount = 0;

if (calcMethod == commish_dollarpersale)
{
baseAmount = rate;
commishAmount = rate;
}
else if (calcMethod == commish_dollarperunit)
{
baseAmount = GetQuantity();
commishAmount = baseAmount * rate;
}
else switch (whenPaid)
{
case commish_whencompleted:
case commish_whensold:
case commish_whenbilled:
case commish_whenpaid:
baseAmount = mAmount;
commishAmount = baseAmount * rate.GetPercentDecimal();
break;

default:
TCS_DebugAlert("Oops, bad case in CSale::FillCommissionInfo!");
break;
}

if (commishAmount > mCommissionPaid)
{
// fill in the struct
commishInfo.id = GetDBID();
commishInfo.commissionID = commission->GetDBID();
commishInfo.classID = id_Lease;
commishInfo.baseAmount = baseAmount;
commishInfo.percentage = rate;
commishInfo.prevPaidAmount = mCommissionPaid;
commishInfo.commissionAmount = commishAmount;
commishInfo.totalDueAmount = commishAmount;
return true;
}
else
return false;
}
/*********************************************************************************

FillDataReport TCS 9/6/02

fill in a diagnostic table that shows data field values.

*********************************************************************************/
void CLease::FillDataReport(CTCS_Table *table, CNeoStream *stream) const
{
TCS_FailNILMsg(table, TCS_GetErrString(errID_BadTable));
TCS_FailNILMsg(stream, TCS_GetErrString(errID_BadStream));

THE_SUPERCLASS::FillDataReport(table, stream);

FillFieldArrayRow(table, stream, "mRentalTransactionArray", mRentalTransactionArray);
FillFieldArrayRow(table, stream, "mUnpaidRentArray", mUnpaidRentArray);
FillFieldArrayRow(table, stream, "mUnpaidBillingRecordArray", mUnpaidBillingRecordArray);

NeoVersion version = GetVersion(); // TCS 1/15/03

if (version > 1)
FillFieldStringRow(table, stream, tag_name, mName);

FillFieldObjectIDRow(table, stream, tag_property, mProperty, id_RealEstateAccount);
FillFieldTagRow(table, stream, tag_rentalunit, cLongSize, mRentalUnit);
FillFieldObjectIDRow(table, stream, tag_paymentterm, mPaymentTerm, id_RentalPaymentTerm);
FillFieldObjectIDRow(table, stream, tag_escrowaccount, mEscrowAccount, id_EscrowAccount);
FillFieldObjectIDRow(table, stream, tag_salesrep, mSalesRep, id_EmployeeAccount);
FillFieldObjectIDRow(table, stream, tag_commission, mCommissionID, id_Commission);

FillFieldTagRow(table, stream, tag_leasestart, cDateSize, mLeaseStart.GetCString());
FillFieldTagRow(table, stream, tag_leaseend, cDateSize, mLeaseEnd.GetCString());

FillFieldTagRow(table, stream, tag_amount, cMoneySize, mAmount.GetCurrencyString());
FillFieldTagRow(table, stream, tag_keydeposit, cMoneySize, mKeyDeposit.GetCurrencyString());

if (mLastMonthPrepaidType == deposit_monthsrent)
FillFieldTagRow(table, stream, tag_lastmonthprepaid, cMoneySize, mLastMonthPrepaid.GetNumberString());
else
FillFieldTagRow(table, stream, tag_lastmonthprepaid, cMoneySize, mLastMonthPrepaid.GetCurrencyString());

if (mDepositType == deposit_monthsrent)
FillFieldTagRow(table, stream, tag_damagedeposit, cMoneySize, mDamageDeposit.GetNumberString());
else
FillFieldTagRow(table, stream, tag_damagedeposit, cMoneySize, mDamageDeposit.GetCurrencyString());

FillFieldEnumRow(table, stream, tag_property, mPropertyType, MENU_LeasePropertyTypes);
FillFieldEnumRow(table, stream, tag_status, mStatus, MENU_LeaseStatus);
FillFieldEnumRow(table, stream, tag_deposittype, mDepositType, MENU_DamageDepositTypes);
FillFieldEnumRow(table, stream, tag_lastmonthprepaidtype, mLastMonthPrepaidType, MENU_DamageDepositTypes);

FillFieldBitRow(table, stream, tag_monthtomonth, mMonthToMonth, true);
FillFieldStockRow(table, stream, stockID_Padding, -7, SInt32(mLeaseFiller));
FillFieldStockRow(table, stream, stockID_Padding, cCharSize, SInt32(mLeasePadding));

FillFieldStockRow(table, stream, stockID_Expansion, cMoneySize, mExpansionMoney.GetCurrencyString());
FillFieldStockRow(table, stream, stockID_Expansion, cLongSize, mExpansionLong);

if (version > 2)
{
FillFieldObjectIDRow(table, stream, tag_contractpackage, mContractPackage, id_ContractPackage);
FillFieldTagRow(table, stream, tag_firstmonthamount, cMoneySize, mFirstMonthAmount.GetCurrencyString());
FillFieldTagRow(table, stream, tag_lastmonthamount, cMoneySize, mLastMonthAmount.GetCurrencyString());
}

FillFieldTagRow(table, stream, tag_currbalance, cMoneySize, mCurrBalance.GetCurrencyString());
FillFieldTagRow(table, stream, tag_commissionpaid, cMoneySize, mCommissionPaid.GetCurrencyString());

FillEndSafetyTag(table, stream, mEndSafetyTag);
}