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

Paid Vacations & Holidays (Source Code)

Link to: header | lists directory

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

Comments

CVacationItem

This class manages employee vacations for the Goldenseal accounting software,
time tracking software and payroll software.

Employee sick days, vacations, holidays and other paid time off.
These calculate accrued vacation time in Write Payroll and Payroll Records,
and post to employee accounts via CVacationBreakdownEntry.

SUPERCLASS = DB_DescribedPersistent

Constructor

/*********************************************************************************
default constructor
*********************************************************************************/
CVacationItem::CVacationItem()
{
mVacationAmount = mReduceTo = mStartAfter = 0;
mHolidayHoursPaid = 8;
mHolidayDate.SetToToday();
mVacationType = condition_AddHoliday;
mVacationUnit = time_day;
mReduceUnit = time_day;
mVacationBase = time_year; // rev TCS 6/10/02
mWhenCredited = time_payperiod;
mHolidayType = time_firm;
mFloatingWeek = time_firstweek;
mFloatingDay = time_monday;
mFloatingMonth = time_january;
mReduceTime = time_never;
mStartAfterPeriod = time_day;
mEveryYear = true;

mExpansionMoney = 0; // TCS 3/27/02
mExpansionLong = 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 CVacationItem::CopyFrom(DB_PersistentObject *source, const UInt8 copyFlags)
{
THE_SUPERCLASS::CopyFrom(source, copyFlags);

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

TCS_BlockMove(&src->mVacationAmount, &mVacationAmount, cCopyFileLength);
}
/*********************************************************************************

GetFileLength TCS 8/16/00

return the file length used by this object

*********************************************************************************/
NeoSize CVacationItem::GetFileLength(const CNeoFormat *aFormat) const
{
return THE_SUPERCLASS::GetFileLength(aFormat) +
ARRAY_FILE_SIZE(mUseageArray) +
cFileLength;
}
/*********************************************************************************

GetMemberValue

return the value of the member with the given tag

*********************************************************************************/
Boolean CVacationItem::GetMemberValue(const NeoTag aTag, const NeoTag aType,
void *aValue) const
{
switch (aTag)
{
case tag_vacationtype:
return ConvertEnumMember(mVacationType, MENU_VacationTypes, aValue, aType);
break;

case tag_vacationunit:
return ConvertEnumMember(mVacationUnit, MENU_HourstoDaysTimeUnits, aValue, aType);
break;

case tag_reduceunit:
return ConvertEnumMember(mReduceUnit, MENU_HourstoDaysTimeUnits, aValue, aType);
break;

case tag_vacationbase:
return ConvertEnumMember(mVacationBase, MENU_VacationAccrue, aValue, aType);
break;

case tag_whencredited:
return ConvertEnumMember(mWhenCredited, MENU_VacationReduce, aValue, aType);
break;

case tag_holidaytype:
return ConvertEnumMember(mHolidayType, MENU_VacationHolidayCalc, aValue, aType);
break;

case tag_floatweek:
return ConvertEnumMember(mFloatingWeek, MENU_WeeksofMonth, aValue, aType);
break;

case tag_floatday:
return ConvertEnumMember(mFloatingDay, MENU_DaysofWeek, aValue, aType);
break;

case tag_floatmonth:
return ConvertEnumMember(mFloatingMonth, MENU_MonthsofYear, aValue, aType);
break;

case tag_reducetime:
return ConvertEnumMember(mReduceTime, MENU_VacationReduce, aValue, aType);
break;

case tag_startafterperiod:
return ConvertEnumMember(mStartAfterPeriod, MENU_DaystoYearsTimeUnits, aValue, aType);
break;

case tag_vacationamount:
return ConvertMember(&mVacationAmount, type_number, aValue, aType);
break;

case tag_holidayamount:
return ConvertMember(&mHolidayHoursPaid, type_number, aValue, aType);
break;

case tag_reduceto:
return ConvertMember(&mReduceTo, type_number, aValue, aType);
break;

case tag_startafter:
return ConvertMember(&mStartAfter, type_long, aValue, aType);
break;

case tag_holidaydate:
return ConvertMember(&mHolidayDate, type_date, aValue, aType);
break;

case tag_everyyear:
return ConvertBitFieldMember(mEveryYear, aValue, aType);
break;

case tag_date: // calculated holiday date for the current year
{
CDate holidayDate = GetHolidayDate(CDate::ThisYear());
return ConvertMember(&holidayDate, type_date, aValue, aType);
}
break;

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

SetMemberValue

set the value of the member with the given tag

*********************************************************************************/
Boolean CVacationItem::SetMemberValue(const NeoTag aTag, const NeoTag aType,
const void *aValue)
{
switch (aTag)
{
case tag_vacationtype:
return ConvertMember(aValue, aType, &mVacationType, type_enum);
break;

case tag_vacationunit:
return ConvertMember(aValue, aType, &mVacationUnit, type_enum);
break;

case tag_reduceunit:
return ConvertMember(aValue, aType, &mReduceUnit, type_enum);
break;

case tag_vacationbase:
return ConvertMember(aValue, aType, &mVacationBase, type_enum);
break;

case tag_whencredited:
return ConvertMember(aValue, aType, &mWhenCredited, type_enum);
break;

case tag_holidaytype:
return ConvertMember(aValue, aType, &mHolidayType, type_enum);
break;

case tag_floatweek:
return ConvertMember(aValue, aType, &mFloatingWeek, type_enum);
break;

case tag_floatday:
return ConvertMember(aValue, aType, &mFloatingDay, type_enum);
break;

case tag_floatmonth:
return ConvertMember(aValue, aType, &mFloatingMonth, type_enum);
break;

case tag_reducetime:
return ConvertMember(aValue, aType, &mReduceTime, type_enum);
break;

case tag_startafterperiod:
return ConvertMember(aValue, aType, &mStartAfterPeriod, type_enum);
break;

case tag_vacationamount:
return ConvertMember(aValue, aType, &mVacationAmount, type_number);
break;

case tag_holidayamount:
return ConvertMember(aValue, aType, &mHolidayHoursPaid, type_number);
break;

case tag_reduceto:
return ConvertMember(aValue, aType, &mReduceTo, type_number);
break;

case tag_holidaydate:
return ConvertMember(aValue, aType, &mHolidayDate, type_date);
break;

case tag_startafter:
return ConvertMember(aValue, aType, &mStartAfter, type_long);
break;

case tag_everyyear:
mEveryYear = ConvertDataToBitField(aValue, aType);
return true;
break;

case tag_date: // 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 CVacationItem::ReadObject(CNeoStream *aStream, const NeoTag 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, mUseageArray, cHasSafetyTag); // TCS 8/16/00

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

mVacationAmount.ReadFromStream(aStream); // mfs_sa rev 20feb2k3
mHolidayHoursPaid.ReadFromStream(aStream);
mReduceTo.ReadFromStream(aStream);

mHolidayDate.ReadFromStream(aStream);

mStartAfter = aStream->ReadLong();

mVacationType = aStream->ReadChar();
mVacationUnit = aStream->ReadChar();
mReduceUnit = aStream->ReadChar();
mVacationBase = aStream->ReadChar();
mWhenCredited = aStream->ReadChar();
mHolidayType = aStream->ReadChar();
mFloatingWeek = aStream->ReadChar();
mFloatingDay = aStream->ReadChar();
mFloatingMonth = aStream->ReadChar();
mReduceTime = aStream->ReadChar();
mStartAfterPeriod = aStream->ReadChar();

*((UInt8*)&mStartAfterPeriod + sizeof(mStartAfterPeriod)) = aStream->ReadBits(1); // --Bitfield

mExpansionMoney.ReadFromStream(aStream);

mExpansionLong = aStream->ReadID();

mEndSafetyTag = aStream->ReadEndSafetyTag(this);

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

WriteObject

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

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

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

WriteIDArrayToStream(aStream, mUseageArray, cHasSafetyTag); // TCS 8/16/00

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

mVacationAmount.WriteToStream(aStream); // mfs_sa rev 20feb2k3
mHolidayHoursPaid.WriteToStream(aStream);
mReduceTo.WriteToStream(aStream);

mHolidayDate.WriteToStream(aStream);

aStream->WriteLong(mStartAfter);

aStream->WriteChar(mVacationType);
aStream->WriteChar(mVacationUnit);
aStream->WriteChar(mReduceUnit);
aStream->WriteChar(mVacationBase);
aStream->WriteChar(mWhenCredited);
aStream->WriteChar(mHolidayType);
aStream->WriteChar(mFloatingWeek);
aStream->WriteChar(mFloatingDay);
aStream->WriteChar(mFloatingMonth);
aStream->WriteChar(mReduceTime);
aStream->WriteChar(mStartAfterPeriod);

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

mExpansionMoney.WriteToStream(aStream);

aStream->WriteID(mExpansionLong);

aStream->WriteEndSafetyTag(mEndSafetyTag, this);

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

IsVacationUsed (static) TCS 10/25/02

return whether to reference a labor log for a vacation breakdown of the given
type

*********************************************************************************/
Boolean CVacationItem::IsVacationUsed(const UInt8 vacationType)
{
switch (vacationType)
{
case condition_UseHoliday:
case condition_UseVacation:
case condition_UseSickTime:
case condition_UseOtherVacation:
return true;
break;

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

CalculateVacation TCS 2/25/99 rev TCS 7/17/02

calculate the vacation accrued for the given hours and employee

*********************************************************************************/
CMoney CVacationItem::CalculateVacation(SVacationInfo &vacationInfo,
SEmployeeInfo &employeeInfo)
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));

CMoney calcAmount = 0;

if (vacationInfo.vacationType == condition_AddHoliday)
{
return 0;
}

switch (mVacationBase)
{
case time_year:
calcAmount = mVacationAmount;
calcAmount.AdjustForPeriod(time_year, employeeInfo.payInterval);
break;

case time_hour:
calcAmount = vacationInfo.baseHours * mVacationAmount;
break;

case time_day:
calcAmount = vacationInfo.baseDays * mVacationAmount;
break;

case time_payperiod:
calcAmount = mVacationAmount;
break;

default:
TCS_DebugAlert("Oops, bad case in CVacationItem::CalculateVacation!");
break;
}

calcAmount.AdjustForPeriod(mVacationUnit, time_day); // TCS 7/30/02

return calcAmount;
}
/*********************************************************************************

IncrementBaseAmount TCS 2/25/99

increment the base amount to use for this vacation item.
Was formerly FetchBaseAmount TCS rev 5/9/00

*********************************************************************************/
void CVacationItem::IncrementBaseAmount(const SLaborHoursInfo &hoursInfo, SVacationInfo &vacInfo,
const CMoney &/*timeUsed*/, const SInt32 /*daysInPeriod*/)
{
vacInfo.baseHours += hoursInfo.baseHours;
vacInfo.baseDays += hoursInfo.daysWorked;
}
/*********************************************************************************

IsInPayPeriod TCS 6/10/02

return whether to include this item in the given pay period. We always include
vacations. Holidays apply only if within the period.

*********************************************************************************/
Boolean CVacationItem::IsInPayPeriod(const CDate &startDate, const CDate &endDate,
const CDate &hireDate)
{
CDate startsAccruing = GetAccrualStartDate(hireDate);

if (mVacationType == condition_AddHoliday)
{
CDate holidayDate = GetHolidayDate(startDate.GetYear());

if (holidayDate.IsAfter(startsAccruing))
return holidayDate.IsBetween(startDate, endDate);
else
return false;
}
else
return endDate.IsAfter(startsAccruing);
}
/*********************************************************************************

GetAccrualStartDate TCS 7/31/01

return the date when a vacation benefit starts to accrue

*********************************************************************************/
CDate CVacationItem::GetAccrualStartDate(const CDate &hireDate) const
{
CDate outDate = hireDate;

switch (mStartAfterPeriod)
{
case time_day:
outDate.AddDays(mStartAfter);
break;

case time_week:
outDate.AddDays(mStartAfter * 7);
break;

case time_month:
outDate.AddSafeMonths(mStartAfter);
break;

case time_quarter:
outDate.AddSafeMonths(mStartAfter * 3);
break;

case time_year:
outDate.AddSafeYears(mStartAfter);
break;

default:
TCS_DebugAlert("Oops, bad case in CVacationItem::GetAccrualStartDate!");
break;
}

return outDate;
}
/*********************************************************************************

GetHolidayDate TCS 5/24/02

return the date of a holiday in the given year

*********************************************************************************/
CDate CVacationItem::GetHolidayDate(const SInt32 inYear) const
{
if (mVacationType != condition_AddHoliday ||
!mEveryYear && mHolidayDate.GetYear() != inYear)
return CDate::Never();

CDate outDate = mHolidayDate;
outDate.SetYear(inYear);

if (mHolidayType == time_firm)
{
// all set
}
else if (mHolidayType == time_floating)
{
outDate = outDate.GetFloatingHolidayDate(mFloatingDay, mFloatingWeek, mFloatingMonth);
}
else
{
outDate = outDate.GetHolidayDate(mHolidayType);
}

return outDate;
}
/*********************************************************************************

IsHoliday TCS 5/24/02

return whether the given date is a holiday

*********************************************************************************/
Boolean CVacationItem::IsHoliday(const CDate inDate)
{
CDate holidayDate = GetHolidayDate(inDate.GetYear());

if (holidayDate.IsNever())
return false;
else
return inDate.IsSameDateAs(holidayDate);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************

FillDataReport TCS 9/7/02

fill in a diagnostic table that shows data field values.

*********************************************************************************/
void CVacationItem::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, "mUseageArray", mUseageArray);

FillFieldTagRow(table, stream, tag_vacationamount, cMoneySize, mVacationAmount.GetNumberString());
FillFieldTagRow(table, stream, tag_holidayamount, cMoneySize, mHolidayHoursPaid.GetNumberString());
FillFieldTagRow(table, stream, tag_reduceto, cMoneySize, mReduceTo.GetNumberString());

FillFieldTagRow(table, stream, tag_holidaydate, cDateSize, mHolidayDate.GetCString());

FillFieldTagRow(table, stream, tag_startafter, cLongSize, mStartAfter);

FillFieldEnumRow(table, stream, tag_vacationtype, mVacationType, MENU_VacationTypes);
FillFieldEnumRow(table, stream, tag_vacationunit, mVacationUnit, MENU_HourstoDaysTimeUnits);
FillFieldEnumRow(table, stream, tag_reduceunit, mReduceUnit, MENU_HourstoDaysTimeUnits);
FillFieldEnumRow(table, stream, tag_vacationbase, mVacationBase, MENU_VacationAccrue);
FillFieldEnumRow(table, stream, tag_whencredited, mWhenCredited, MENU_VacationReduce);
FillFieldEnumRow(table, stream, tag_holidaytype, mHolidayType, MENU_VacationHolidayCalc);
FillFieldEnumRow(table, stream, tag_floatweek, mFloatingWeek, MENU_WeeksofMonth);
FillFieldEnumRow(table, stream, tag_floatday, mFloatingDay, MENU_DaysofWeek);
FillFieldEnumRow(table, stream, tag_floatmonth, mFloatingMonth, MENU_MonthsofYear);
FillFieldEnumRow(table, stream, tag_reducetime, mReduceTime, MENU_VacationReduce);
FillFieldEnumRow(table, stream, tag_startafterperiod, mStartAfterPeriod, MENU_DaystoYearsTimeUnits);

FillFieldBitRow(table, stream, "mEveryYear", mEveryYear, true);
FillFieldStockRow(table, stream, stockID_Padding, -7, SInt32(filler));

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

FillEndSafetyTag(table, stream, mEndSafetyTag);
}