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

Rental Units (Source Code)

Link to: header | lists directory

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

Comments

CRentalUnit

a rental unit within a property. This used to be handled via a member
table in the Real Estate account, but we now keep them as separate objects
so it's easier to get reports for each unit, etc.

This class manages rental units for the Goldenseal accounting software,
property management software and rental property management software.

SUPERCLASS = DB_DescribedPersistent

Constructor

/*********************************************************************************
default constructor TCS 3/2/03
*********************************************************************************/
CRentalUnit::CRentalUnit()
{
mRealEstateAccount = mPaymentTerms = 0;
mRentAmount = 0;

mSize = 0;
mRoomCount = 0;

mUnitType = rental_Apartment;

mHasKitchen = mHasBath = mHasLaundry = false;
mHasParking = mHasDeck = mHasRentControl = false;
mHasInternet = mAllowSubsidized = false;

mPictureID = 0; // TCS 1/19/04
mExpansionMoney = 0;

mEndSafetyTag = tag_endsafetytag;
}

Source Code

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

CopyFrom TCS 3/2/03

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

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

NeoVersion version = src->GetVersion();

// we don't copy arrays

if (version > 1) // TCS 12/15/03
{
mDetails = src->mDetails;
CCustomFieldOwner::CopyFrom(*(CCustomFieldOwner*)src, id_RentalUnit);

TCS_BlockMove(&src->mRealEstateAccount, &mRealEstateAccount, cCopyFileLength2);
}
else
TCS_BlockMove(&src->mRealEstateAccount, &mRealEstateAccount, cCopyFileLength);
}
/*********************************************************************************

GetFileLength TCS 3/2/03

return the file length used by this object

*********************************************************************************/
NeoSize CRentalUnit::GetFileLength(const CNeoFormat *aFormat) const
{
NeoSize baseLength = THE_SUPERCLASS::GetFileLength(aFormat) +
ARRAY_FILE_SIZE(mLeaseArray) +
ARRAY_FILE_SIZE(mRentalTransactArray);

NeoVersion version = GetVersion();

if (version > 1)
{
return baseLength +
mDetails.LongFileLength(cMaximumTextLen) +
CCustomFieldOwner::GetFileLength(aFormat) +
cFileLength2;
}
else
return baseLength + cFileLength;
}
/*********************************************************************************

GetMemberValue TCS 3/2/03

return the value of the member with the given tag

*********************************************************************************/
Boolean CRentalUnit::GetMemberValue(const NeoTag aTag, const NeoTag aType,
void *aValue) const
{
CMoney value = 0;

switch (aTag)
{
case tag_mainaccount:
return ConvertObjectIDMember(mRealEstateAccount, id_RealEstateAccount, aValue, aType);
break;

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

case tag_picture: // TCS 1/19/04
return ConvertObjectIDMember(mPictureID, id_Picture, aValue, aType);
break;

case tag_type:
return ConvertEnumMember(mUnitType, MENU_RentalUnitTypes, aValue, aType);
break;

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

case tag_size: // TCS 12/15/03
return ConvertMember(&mSize, type_number, aValue, aType);
break;

case tag_roomcount: // TCS 12/15/03
return ConvertMember(&mRoomCount, type_short, aValue, aType);
break;

case tag_details: // TCS 12/15/03
return ConvertMember(&mDetails, type_longcstring, aValue, aType);
break;

case tag_haskitchen: // TCS 12/15/03
return ConvertBitFieldMember(mHasKitchen, aValue, aType);
break;

case tag_hasbath: // TCS 12/15/03
return ConvertBitFieldMember(mHasBath, aValue, aType);
break;

case tag_haslaundry: // TCS 12/15/03
return ConvertBitFieldMember(mHasLaundry, aValue, aType);
break;

case tag_hasparking: // TCS 12/15/03
return ConvertBitFieldMember(mHasParking, aValue, aType);
break;

case tag_hasdeck: // TCS 12/15/03
return ConvertBitFieldMember(mHasDeck, aValue, aType);
break;

case tag_hasrentcontrol: // TCS 12/15/03
return ConvertBitFieldMember(mHasRentControl, aValue, aType);
break;

case tag_hasinternet: // TCS 12/15/03
return ConvertBitFieldMember(mHasInternet, aValue, aType);
break;

case tag_allowsubsidized: // TCS 12/15/03
return ConvertBitFieldMember(mAllowSubsidized, aValue, aType);
break;

case tag_customer: // we fetch this info from the lease
case tag_lease:
case tag_leasestart:
case tag_leaseend:
{
DBid leaseID = GetCurrentLeaseID(CDate::Today());

if (aTag == tag_lease) // TCS 12/15/03
{
return ConvertObjectIDMember(leaseID, id_Lease, aValue, aType);
}

if (leaseID)
{
// if we have a current lease, we can fetch info from it.
CLease *lease = TCS_SAFE_CAST(gDBFile->GetOneObject(id_Lease, leaseID), CLease);

if (lease)
{
DB_ObjectWatcher watcher (lease);
return lease->GetMemberValue(aTag, aType, aValue);
}
}

// return values for empty units (no lease)
if (aTag == tag_customer)
{
return ConvertMember(&leaseID, type_objectid, aValue, aType);
}
else
{
CDate date = CDate::Never();
return ConvertMember(&date, type_date, aValue, aType);
}
}
break;

default: // it may be a custom field? TCS 12/15/03
if (CCustomFieldOwner::GetCustomFieldValue(aTag, aType, aValue, GetDBClassID()))
return true;
else
return THE_SUPERCLASS::GetMemberValue(aTag, aType, aValue);
break;
}
}
/*********************************************************************************
SetMemberValue TCS 3/2/03

set the value of the member with the given tag

*********************************************************************************/
Boolean CRentalUnit::SetMemberValue(const NeoTag aTag, const NeoTag aType,
const void *aValue)
{
switch (aTag)
{
case tag_mainaccount:
return ConvertDataToObjectID(aValue, aType, &mRealEstateAccount, id_RealEstateAccount);
break;

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

case tag_picture: // TCS 1/19/04
return ConvertDataToObjectID(aValue, aType, &mPictureID, id_Picture);
break;

case tag_type:
return ConvertMember(aValue, aType, &mUnitType, type_enum);
break;

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

case tag_size: // TCS 12/15/03
return ConvertMember(aValue, aType, &mSize, type_number);
break;

case tag_roomcount: // TCS 12/15/03
return ConvertMember(aValue, aType, &mRoomCount, type_short);
break;

case tag_details: // TCS 12/15/03
return SafeConvertString(aValue, aType, &mDetails, type_longcstring);
break;

case tag_haskitchen: // TCS 12/15/03
mHasKitchen = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_hasbath: // TCS 12/15/03
mHasBath = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_haslaundry: // TCS 12/15/03
mHasLaundry = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_hasparking: // TCS 12/15/03
mHasParking = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_hasdeck: // TCS 12/15/03
mHasDeck = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_hasrentcontrol: // TCS 12/15/03
mHasRentControl = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_hasinternet: // TCS 12/15/03
mHasInternet = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_allowsubsidized: // TCS 12/15/03
mAllowSubsidized = ConvertDataToBitField(aValue, aType);
return true;
break;

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

default: // TCS 12/15/03
if (CCustomFieldOwner::SetCustomFieldValue(aTag, aType, aValue, GetDBClassID()))
return true;
else
return THE_SUPERCLASS::SetMemberValue(aTag, aType, aValue);
break;
}
}/*********************************************************************************

ReadObject TCS 3/2/03

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

CNeoDebugImport checker(aStream, this, cCheckTooSmall);

THE_SUPERCLASS::ReadObject(aStream, aTag);

if (!IsIOValid())
return;

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

if (version > 1)
{
if (!CCustomFieldOwner::ReadObject(*aStream, this))
{
SetHadIOProblems();
return;
}
}

ReadIDArrayFromStream(aStream, mLeaseArray, cHasSafetyTag);
ReadIDArrayFromStream(aStream, mRentalTransactArray, cHasSafetyTag);

if (version > 1)
ReadLongTextFromStream(aStream, &mDetails);

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

mRealEstateAccount = aStream->ReadID();
mPaymentTerms = aStream->ReadID();
mRentAmount.ReadFromStream(aStream);

if (version > 1) // TCS 12/15/03
{
mSize.ReadFromStream(aStream);
mRoomCount = aStream->ReadShort();
mUnitType = aStream->ReadChar();

*((UInt8*)&mUnitType + sizeof(mUnitType)) = aStream->ReadBits(8); // --Bitfield
}

mPictureID = aStream->ReadID();

mExpansionMoney.ReadFromStream(aStream);
mEndSafetyTag = aStream->ReadEndSafetyTag(this);

if (!IsValidEndTag(mEndSafetyTag))
ReportDamagedObject(GetDBClassID(), GetDBID());
}/*********************************************************************************

WriteObject TCS 3/2/03

write the persistent object's data to a stream
*********************************************************************************/
void CRentalUnit::WriteObject(CNeoStream *aStream, const NeoTag aTag)
{
TCS_FailNILMsg(aStream, TCS_GetErrString(errID_BadStream));

// make sure we have valid data to write
if (!IsValidEndTag(mEndSafetyTag))
{
ReportDamagedObject(GetDBClassID(), GetDBID());
mEndSafetyTag = tag_endsafetytag;
}

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

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

if (version > 1)
{
if (!CCustomFieldOwner::WriteObject(*aStream, this))
{
SetHadIOProblems();
return;
}
}

WriteIDArrayToStream(aStream, mLeaseArray, cHasSafetyTag);
WriteIDArrayToStream(aStream, mRentalTransactArray, cHasSafetyTag);

if (version > 1)
WriteLongTextToStream(aStream, mDetails, cMaximumTextLen);

aStream->WriteID(mRealEstateAccount);
aStream->WriteID(mPaymentTerms);
mRentAmount.WriteToStream(aStream);

if (version > 1) // TCS 12/15/03
{
mSize.WriteToStream(aStream);
aStream->WriteShort(mRoomCount);
aStream->WriteChar(mUnitType);

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

aStream->WriteID(mPictureID);
mExpansionMoney.WriteToStream(aStream);
aStream->WriteEndSafetyTag(mEndSafetyTag, this);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

FinishImportCreate TCS 11/19/01

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

PostRealEstateAccount();
}
/*********************************************************************************

PostNewRecord TCS 3/3/03

post creation of a rental unit. We need to adjust the array in the
real estate account
*********************************************************************************/
void CRentalUnit::PostNewRecord(const UInt8 creationType)
{
PostRealEstateAccount();

PostUseCount(id_RealEstateAccount, mRealEstateAccount); // TCS 11/22/03
PostUseCount(id_RentalPaymentTerm, mPaymentTerms);

THE_SUPERCLASS::PostNewRecord(creationType);
}
/*********************************************************************************

PostDeletion TCS 3/3/03

post deletion of a rental unit. We need to adjust the array in the
real estate account

*********************************************************************************/
void CRentalUnit::PostDeletion(const Boolean postAudit)
{
PostRealEstateAccount(cRemoveItem);

PostUseCount(id_RealEstateAccount, mRealEstateAccount, cRemoveItem);
PostUseCount(id_RentalPaymentTerm, mPaymentTerms, cRemoveItem);

THE_SUPERCLASS::PostDeletion(postAudit);
}
/*********************************************************************************

PostRecordChanging TCS 11/22/03

a record will be changing. Post the change.
*********************************************************************************/
void CRentalUnit::PostRecordChanging(const Boolean accountChanging, const Boolean jobChanging)
{
PostUseCount(id_RealEstateAccount, mRealEstateAccount, cRemoveItem);
PostUseCount(id_RentalPaymentTerm, mPaymentTerms, cRemoveItem);

// let the superclass do any posting
THE_SUPERCLASS::PostRecordChanging(accountChanging, jobChanging);
}
/*********************************************************************************

PostRecordChanged TCS 11/22/03

a record has changed. Post it.
*********************************************************************************/
void CRentalUnit::PostRecordChanged(const CMoney &oldAmount, const Boolean accountChanged,
const Boolean jobChanged)
{
PostUseCount(id_RealEstateAccount, mRealEstateAccount);
PostUseCount(id_RentalPaymentTerm, mPaymentTerms);

// let the superclass do any posting
THE_SUPERCLASS::PostRecordChanged(oldAmount, accountChanged, jobChanged);
}
/*********************************************************************************

PostRealEstateAccount TCS 3/3/03

post deletion of a rental unit. We need to adjust the array in the
real estate account

*********************************************************************************/
void CRentalUnit::PostRealEstateAccount(const Boolean removeItem)
{
CRealEstateAccount *account =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_RealEstateAccount, mRealEstateAccount),
CRealEstateAccount);

if (account)
{
DB_ObjectWatcher watcher (account);

UInt8 saveType = account->PrepareViewerDisplay(); // bugfix TCS 4/23/03

account->AddToRentalUnitArray(GetDBID(), removeItem);

account->UpdateViewerDisplay(saveType);
}
else if (gIsClient)
{
// clients post a new record earlier than usual, so there
// may not be an account yet TCS 4/24/03
}
else
ReportMissingObject(id_RealEstateAccount, mRealEstateAccount);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

GetTransactionCount TCS 3/2/03

return the raw number of transactions for this unit

*********************************************************************************/
SInt32 CRentalUnit::GetTransactionCount() const
{
return mLeaseArray.GetCount() +
mRentalTransactArray.GetCount() +
THE_SUPERCLASS::GetTransactionCount();
}
/*********************************************************************************

GetCurrentLeaseID TCS 3/3/03

get the id of the lease that is current as of the given date

*********************************************************************************/
DBid CRentalUnit::GetCurrentLeaseID(const CDate matchDate) const
{
TObjectIDArrayIterator iterator(mLeaseArray, iter_from_end);
DBid id;
CLease *lease = nil;

while (iterator.Previous(id))
{
lease = TCS_SAFE_CAST(gDBFile->GetOneObject(id_Lease, id), CLease);

if (lease)
{
DB_ObjectWatcher watcher (lease);

if (matchDate.IsBetween(lease->GetStartDate(), lease->GetEndDate()))
return id;
}
}

return 0;
}
/*********************************************************************************

FillDataReport TCS 3/2/03

fill in a diagnostic table that shows data field values.

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

NeoVersion version = GetVersion();

if (version > 1)
{
const UInt8 numCustomFields = mCustomFieldData.GetCount();
FillFieldStockRow(table, stream, stockID_CustomFieldCount, cCharSize, SInt32(numCustomFields));

// write values of any custom fields
if (numCustomFields)
{
CTextString valueString, fieldName;
CCustomDataHolder *holder = nil;
TCustomDataArrayIterator iterator(mCustomFieldData);
while (iterator.Next(holder))
{
TCS_FailNILMsg(holder, TCS_GetErrString(errID_BadCustomField));
valueString = holder->GetCString();
fieldName = DB_ObjectClassInfo::GetCustomFieldName(GetDBClassID(), iterator.GetCurrentIndex());
fieldName.AppendWithParentheses(TCS_GetStockString(stockID_Custom)); // TCS 12/31/02

FillFieldStringRow(table, stream, fieldName, valueString);
}
}
}

FillFieldArrayRow(table, stream, "TLeaseArray", mLeaseArray);
FillFieldArrayRow(table, stream, "TRentalTransArray", mRentalTransactArray);

if (version > 1)
{
FillFieldStringRow(table, stream, tag_details, mDetails, true);
}

FillFieldObjectIDRow(table, stream, tag_mainaccount, mRealEstateAccount, id_RealEstateAccount);
FillFieldObjectIDRow(table, stream, tag_paymentterm, mPaymentTerms, id_RentalPaymentTerm);

FillFieldTagRow(table, stream, tag_amount, cMoneySize, mRentAmount.GetCurrencyString());

if (version > 1)
{
FillFieldTagRow(table, stream, tag_size, cMoneySize, mSize.GetNumberString());
FillFieldTagRow(table, stream, tag_roomcount, cShortSize, SInt32(mRoomCount));

FillFieldEnumRow(table, stream, tag_type, mUnitType, MENU_RentalUnitTypes);

FillFieldBitRow(table, stream, tag_haskitchen, mHasKitchen, true);
FillFieldBitRow(table, stream, tag_hasbath, mHasBath);
FillFieldBitRow(table, stream, tag_haslaundry, mHasLaundry);
FillFieldBitRow(table, stream, tag_hasparking, mHasParking);
FillFieldBitRow(table, stream, tag_hasdeck, mHasDeck);
FillFieldBitRow(table, stream, tag_hasrentcontrol, mHasRentControl);
FillFieldBitRow(table, stream, tag_hasinternet, mHasInternet);
FillFieldBitRow(table, stream, tag_allowsubsidized, mAllowSubsidized);
}

FillFieldObjectIDRow(table, stream, tag_picture, mPictureID, id_Picture);
FillFieldStockRow(table, stream, stockID_Expansion, cMoneySize, mExpansionMoney.GetCurrencyString());

FillEndSafetyTag(table, stream, mEndSafetyTag);
}