Link to: header | source
1 | source 3 | transactions
directory
Copyright Turtle Creek Software 1996-2006. All Rights Reserved.
This class manages payroll records for the Goldenseal accounting software,
payroll software and business management software.
Source Code
/*********************************************************************************
HasBreakdowns TCS 6/14/02
return whether this record contains any breakdowns. We override since
there are more arrays to check
*********************************************************************************/
Boolean CPayrollRecord::HasBreakdowns() const
{
if (mBreakdownArray.GetCount() > 0)
return true;
else if (mCommissionArray.GetCount() > 0)
return true;
else if (mDeductionArray.GetCount() > 0)
return true;
else if (mEmployerTaxArray.GetCount() > 0)
return true;
else if (mCategoryItemArray.GetCount() > 0)
return true;
else if (mBenefitArray.GetCount() > 0)
return true;
else if (mVacationArray.GetCount() > 0)
return true;
else
return false;
}
/*********************************************************************************
HasPayrollBreakdown TCS 3/7/99
return whether the given breakdown id is already included in this items' array
*********************************************************************************/
Boolean CPayrollRecord::HasPayrollBreakdown(const DBid breakdownClassID, const DBid breakdownID)
{
switch (breakdownClassID)
{
case id_WagesBreakdownEntry:
return mBreakdownArray.ContainsItem(breakdownID); // tidied TCS 6/14/02
break;
case id_CommishBreakdownEntry:
return mCommissionArray.ContainsItem(breakdownID);
break;
case id_DeductBreakdownEntry:
return mDeductionArray.ContainsItem(breakdownID);
break;
case id_EmpTaxBreakdownEntry:
return mEmployerTaxArray.ContainsItem(breakdownID);
break;
case id_CatTaxBreakdownEntry:
return mCategoryItemArray.ContainsItem(breakdownID);
break;
case id_BennyBreakdownEntry:
return mBenefitArray.ContainsItem(breakdownID);
break;
case id_VacBreakdownEntry:
return mVacationArray.ContainsItem(breakdownID);
break;
default:
TCS_DebugAlert("Oops, bad case in CPayrollRecord::HasBreakdown!");
break;
}
// if we got this far, the breakdown is not there
return false;
}/*********************************************************************************
AddPayrollBreakdown TCS 3/7/99
add a breakdown to the breakdown array.
*********************************************************************************/
void CPayrollRecord::AddPayrollBreakdown(const DBid breakdownClassID, const DBid breakdownID)
{
switch (breakdownClassID)
{
case id_WagesBreakdownEntry:
mBreakdownArray.Append(breakdownID);
break;
case id_CommishBreakdownEntry:
mCommissionArray.Append(breakdownID);
break;
case id_DeductBreakdownEntry:
mDeductionArray.Append(breakdownID);
break;
case id_EmpTaxBreakdownEntry:
mEmployerTaxArray.Append(breakdownID);
break;
case id_CatTaxBreakdownEntry:
mCategoryItemArray.Append(breakdownID);
break;
case id_BennyBreakdownEntry:
mBenefitArray.Append(breakdownID);
break;
case id_VacBreakdownEntry:
mVacationArray.Append(breakdownID);
break;
default:
TCS_DebugAlert("Oops, bad case in CPayrollRecord::HasBreakdown!");
break;
}
}
/*********************************************************************************
HasPayrollData
return whether there is data in the payroll breakdowns
*********************************************************************************/
Boolean CPayrollRecord::HasPayrollData()
{
if (mBreakdownArray.GetCount() > 0) // bugfix TCS 1/3/03
return true;
else if (mCommissionArray.GetCount() > 0)
return true;
else if (mDeductionArray.GetCount() > 0)
return true;
else if (mEmployerTaxArray.GetCount() > 0)
return true;
else if (mCategoryItemArray.GetCount() > 0)
return true;
else if (mBenefitArray.GetCount() > 0)
return true;
else if (mVacationArray.GetCount() > 0)
return true;
else return false;
}
/*********************************************************************************
RemoveAllBreakdownEntries added param TCS 4/20/00
remove all the breakdowns. We override since there are several arrays to clear.
WARNING- because this method changes an object's file length, it should only be
used on an object that has already been removed from the database.
*********************************************************************************/
void CPayrollRecord::RemoveAllBreakdownEntries(const Boolean removeFromDatabase)
{
// sanity check
TCS_ASSERTMsg(!IsInDatabase(), TCS_GetErrString(errID_BadDatabaseChange));
// remove each of our arrays
ClearBreakdownArray(&mBreakdownArray, id_WagesBreakdownEntry, removeFromDatabase); // rev TCS 9/6/99
ClearBreakdownArray(&mCommissionArray, id_CommishBreakdownEntry, removeFromDatabase);
ClearBreakdownArray(&mDeductionArray, id_DeductBreakdownEntry, removeFromDatabase);
ClearBreakdownArray(&mEmployerTaxArray, id_EmpTaxBreakdownEntry, removeFromDatabase);
ClearBreakdownArray(&mCategoryItemArray, id_CatTaxBreakdownEntry, removeFromDatabase);
ClearBreakdownArray(&mBenefitArray, id_BennyBreakdownEntry, removeFromDatabase);
ClearBreakdownArray(&mVacationArray, id_VacBreakdownEntry, removeFromDatabase);
}/*********************************************************************************
UpdateBreakdownsFromTable
read in the breakdowns from the breakdown table. We override since we use
several different arrays
*********************************************************************************/
void CPayrollRecord::UpdateBreakdownsFromTable(CBreakdownTable *table,
const SInt32 breakdownType,
const DBid breakdownClassID,
DB_PersistentObject *owner)
{
switch (breakdownType)
{
case breakdown_wages:
FillBreakdownEntriesFromTable(table, mBreakdownArray, breakdownClassID, owner,
cAllowZeroAmount, cAllowBlankItem, false);
break;
case breakdown_commission: // TCS 12/18/99
FillBreakdownEntriesFromTable(table, mCommissionArray, breakdownClassID, owner,
cAllowZeroAmount, cAllowBlankItem, false);
break;
case breakdown_deduction:
FillBreakdownEntriesFromTable(table, mDeductionArray, breakdownClassID, owner,
cAllowZeroAmount, cAllowBlankItem, cAllowOffCheckmark);
break;
case breakdown_employertax:
FillBreakdownEntriesFromTable(table, mEmployerTaxArray, breakdownClassID, owner,
cAllowZeroAmount, cAllowBlankItem, cAllowOffCheckmark);
break;
case breakdown_categorytax:
FillBreakdownEntriesFromTable(table, mCategoryItemArray, breakdownClassID, owner,
cAllowZeroAmount, cAllowBlankItem, cAllowOffCheckmark);
break;
case breakdown_benefit:
FillBreakdownEntriesFromTable(table, mBenefitArray, breakdownClassID, owner,
cAllowZeroAmount, cAllowBlankItem, cAllowOffCheckmark);
break;
case breakdown_vacation:
FillBreakdownEntriesFromTable(table, mVacationArray, breakdownClassID, owner,
cAllowZeroAmount, cAllowBlankItem, cAllowOffCheckmark);
break;
default:
TCS_DebugAlert("Oops, bad case in CPayrollRecord::UpdateBreakdownsFromTable!");
break;
}
}
/*********************************************************************************
WriteToPrintFormTable TCS 1/3/00
write breakdowns to a report table(in print forms). We override since
the data we use depends on the type of the table
*********************************************************************************/
Boolean CPayrollRecord::WriteToPrintFormTable(CReportTable *table)
{
// sanity check
TCS_FailNILMsg(table, TCS_GetErrString(errID_BadTable));
// if this record has no breakdowns, we don't fill in a table TCS 12/26/01
if (!HasPayrollData())
return false;
// the array we write depends on the table's display class
switch (table->GetReportClassID())
{
case id_WagesBreakdownEntry:
return WriteToReportTable(table, id_WagesBreakdownEntry, mBreakdownArray, this);
break;
case id_CommishBreakdownEntry: // bugfix TCS 7/11/02
return WriteToReportTable(table, id_CommishBreakdownEntry, mCommissionArray, this);
break;
case id_DeductBreakdownEntry:
return WriteToReportTable(table, id_DeductBreakdownEntry, mDeductionArray, this);
break;
case id_CatTaxBreakdownEntry:
return WriteToReportTable(table, id_CatTaxBreakdownEntry, mCategoryItemArray, this);
break;
case id_EmpTaxBreakdownEntry:
return WriteToReportTable(table, id_EmpTaxBreakdownEntry, mEmployerTaxArray, this);
break;
case id_BennyBreakdownEntry:
return WriteToReportTable(table, id_BennyBreakdownEntry, mBenefitArray, this);
break;
case id_VacBreakdownEntry:
return WriteToReportTable(table, id_VacBreakdownEntry, mVacationArray, this);
break;
default:
break;
}
return false;
}
/*********************************************************************************
FillTableFromBreakdowns
write breakdowns to a breakdown table. We override since different arrays
may be used to provide the list of elements
*********************************************************************************/
Boolean CPayrollRecord::FillTableFromBreakdowns(CBreakdownTable *table,
const DBid breakdownClassID)
{
// sanity check
TCS_FailNILMsg(table, TCS_GetErrString(errID_BadTable));
switch (breakdownClassID)
{
case id_WagesBreakdownEntry:
return FillTableFromBreakdownArray(table, mBreakdownArray, breakdownClassID);
break;
case id_CommishBreakdownEntry:
return FillTableFromBreakdownArray(table, mCommissionArray, breakdownClassID);
break;
case id_DeductBreakdownEntry:
return FillTableFromBreakdownArray(table, mDeductionArray, breakdownClassID);
break;
case id_EmpTaxBreakdownEntry:
return FillTableFromBreakdownArray(table, mEmployerTaxArray, breakdownClassID);
break;
case id_CatTaxBreakdownEntry:
return FillTableFromBreakdownArray(table, mCategoryItemArray, breakdownClassID);
break;
case id_BennyBreakdownEntry:
return FillTableFromBreakdownArray(table, mBenefitArray, breakdownClassID);
break;
case id_VacBreakdownEntry:
return FillTableFromBreakdownArray(table, mVacationArray, breakdownClassID);
break;
default:
TCS_DebugAlert("Oops, bad case in CPayrollRecord::FillTableFromBreakdowns!");
return false;
break;
}
}
/*********************************************************************************
ExportBreakdowns TCS 8/21/03
export breakdowns for this item
*********************************************************************************/
void CPayrollRecord::ExportBreakdowns(CTextOutputStream &stream)
{
CDataTranslator::ExportRecordArray(id_WagesBreakdownEntry, mBreakdownArray, stream);
CDataTranslator::ExportRecordArray(id_CommishBreakdownEntry, mCommissionArray, stream);
CDataTranslator::ExportRecordArray(id_DeductBreakdownEntry, mDeductionArray, stream);
CDataTranslator::ExportRecordArray(id_EmpTaxBreakdownEntry, mEmployerTaxArray, stream);
CDataTranslator::ExportRecordArray(id_CatTaxBreakdownEntry, mCategoryItemArray, stream);
CDataTranslator::ExportRecordArray(id_BennyBreakdownEntry, mBenefitArray, stream);
CDataTranslator::ExportRecordArray(id_VacBreakdownEntry, mVacationArray, stream);
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************
FillBreakdownsFromPayStruct TCS 2/5/99
fill breakdowns from an employee info struct. This is used to update from a
payroll record, or when creating a new payroll record with the Write Payroll command
*********************************************************************************/
void CPayrollRecord::FillBreakdownsFromPayStruct(SEmployeeInfo &employeeInfo,
const Boolean isTempRecord)
{
// if no breakdowns, we can skip this TCS 6/2/00
if (GetBreakdownType() == breakdown_none)
return;
// we do each of the components
AddHourBreakdowns(employeeInfo, isTempRecord);
AddCommissionBreakdowns(employeeInfo, isTempRecord);
AddDeductionBreakdowns(employeeInfo, isTempRecord);
AddEmployerTaxBreakdowns(employeeInfo, isTempRecord);
AddCategoryTaxBreakdowns(employeeInfo, isTempRecord);
AddBenefitBreakdowns(employeeInfo, isTempRecord);
AddVacationBreakdowns(employeeInfo, isTempRecord);
// it used to erroneously set mAmount here TCS removed 5/10/00
}
/*********************************************************************************
FillTotalsFromStruct TCS moved 5/10/00
update calculated values from an SEmployeeInfo struct. This is used to update from a
payroll record, or when creating a new payroll record with the Write Payroll command
*********************************************************************************/
void CPayrollRecord::FillTotalsFromStruct(SEmployeeInfo &employeeInfo)
{
if (GetBreakdownType() == breakdown_none) // if no breakdown, erase most calc values TCS 6/2/00
{
mWagesTotal = 0;
mHoursTotal = 0;
mCommissionsTotal = 0;
mDeductionsTotal = 0;
mEmployerTaxTotal = 0;
mEmployeeCatTaxTotal = 0;
mEmployerCatTaxTotal = 0;
mEmployeeBenefitsTotal = 0;
mEmployerBenefitsTotal = 0;
mCompTimeChange = 0;
mVacationChange = 0;
mSickTimeChange = 0;
mOtherVacationChange = 0;
}
else // otherwise fill in calc totals from the struct
{
mWagesTotal = employeeInfo.wageAmount;
mHoursTotal = employeeInfo.hours; // TCS 5/25/00
mCommissionsTotal = employeeInfo.commissionAmount;
mDeductionsTotal = employeeInfo.deductAmount;
mEmployerTaxTotal = employeeInfo.empTaxAmount;
mEmployeeCatTaxTotal = employeeInfo.catEmployeeAmount;
mEmployerCatTaxTotal = employeeInfo.catEmployerAmount;
CMoney benefitAmount = employeeInfo.benefitAddAmount - employeeInfo.benefitSubtractAmount;
mEmployeeBenefitsTotal = benefitAmount;
mEmployerBenefitsTotal = employeeInfo.benefitEmployerAmount;
mCompTimeChange = employeeInfo.compTimeChange;
mVacationChange = employeeInfo.vacationChange;
mSickTimeChange = employeeInfo.sickTimeChange;
mOtherVacationChange = employeeInfo.otherVacationChange;
mAmount = employeeInfo.wageAmount + employeeInfo.commissionAmount -
employeeInfo.deductAmount - employeeInfo.catEmployeeAmount +
benefitAmount;
}
}
/*********************************************************************************
FillYTD TCS 2/22/99
fill in year to date totals for deductions
*********************************************************************************/
void CPayrollRecord::FillYTD(SEmployeeInfo &employeeInfo)
{
TCS_FailNILMsg(gDBFile, TCS_GetErrString(errID_BadFile));
DBid breakdownID, deductionID;
DBid category, subcategory, catSystem;
CMoney amount, baseAmount;
// update year to date in deductions
if (mDeductionArray.GetCount() > 0)
{
TObjectIDArrayIterator iterator(mDeductionArray);
while (iterator.Next(breakdownID))
{
CDeductionBreakdownEntry *entry =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_DeductBreakdownEntry, breakdownID),
CDeductionBreakdownEntry);
if (entry)
{
DB_ObjectWatcher watcher(entry);
TCS_ASSERTMsg(entry->GetMemberValue(tag_transactid, type_objectid, &deductionID),
TCS_GetValueErrString(tag_transactid));
TCS_ASSERTMsg(entry->GetMemberValue(tag_amount, type_money, &amount),
TCS_GetValueErrString(tag_amount));
TCS_ASSERTMsg(entry->GetMemberValue(tag_baseamount, type_money, &baseAmount),
TCS_GetValueErrString(tag_baseamount));
TDeductionArrayIterator deductIterator(*employeeInfo.deductionArray);
SDeductionInfo info;
while (deductIterator.Next(info))
{
if (info.id == deductionID)
{
info.yearToDateAmount += amount;
info.yearToDateBase += baseAmount;
employeeInfo.deductionArray->AssignItemAt(deductIterator.GetCurrentIndex(), info);
break;
}
}
}
}
}
// calculate YTD for employer taxes
if (mEmployerTaxArray.GetCount() > 0)
{
TObjectIDArrayIterator iterator(mEmployerTaxArray);
while (iterator.Next(breakdownID))
{
CEmpTaxBreakdownEntry *entry =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_EmpTaxBreakdownEntry, breakdownID),
CEmpTaxBreakdownEntry);
if (entry)
{
DB_ObjectWatcher watcher(entry);
TCS_ASSERTMsg(entry->GetMemberValue(tag_transactid, type_objectid, &deductionID),
TCS_GetValueErrString(tag_transactid));
TCS_ASSERTMsg(entry->GetMemberValue(tag_amount, type_money, &amount),
TCS_GetValueErrString(tag_amount));
TCS_ASSERTMsg(entry->GetMemberValue(tag_baseamount, type_money, &baseAmount),
TCS_GetValueErrString(tag_baseamount));
TDeductionArrayIterator empTaxIterator(*employeeInfo.employerTaxArray);
SDeductionInfo info;
while (empTaxIterator.Next(info))
{
if (info.id == deductionID)
{
info.yearToDateAmount += amount;
info.yearToDateBase += baseAmount;
employeeInfo.employerTaxArray->AssignItemAt(empTaxIterator.GetCurrentIndex(), info);
break;
}
}
}
}
}
// calculate YTD for category taxes
if (mCategoryItemArray.GetCount() > 0)
{
TObjectIDArrayIterator iterator(mCategoryItemArray);
while (iterator.Next(breakdownID))
{
CCatTaxBreakdownEntry *entry =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_CatTaxBreakdownEntry, breakdownID),
CCatTaxBreakdownEntry);
if (entry)
{
DB_ObjectWatcher watcher(entry);
TCS_ASSERTMsg(entry->GetMemberValue(tag_transactid, type_objectid, &deductionID),
TCS_GetValueErrString(tag_transactid));
TCS_ASSERTMsg(entry->GetMemberValue(tag_amount, type_money, &amount),
TCS_GetValueErrString(tag_amount));
TCS_ASSERTMsg(entry->GetMemberValue(tag_baseamount, type_money, &baseAmount),
TCS_GetValueErrString(tag_baseamount));
TCS_ASSERTMsg(entry->GetMemberValue(tag_category, type_objectid, &category),
TCS_GetValueErrString(tag_category));
TCS_ASSERTMsg(entry->GetMemberValue(tag_subcategory, type_objectid, &subcategory),
TCS_GetValueErrString(tag_subcategory));
TCS_ASSERTMsg(entry->GetMemberValue(tag_catsystem, type_objectid, &catSystem),
TCS_GetValueErrString(tag_catsystem));
TCatTaxItemArrayIterator catTaxIterator(*employeeInfo.categoryItemArray);
SCatTaxItemInfo info;
while (catTaxIterator.Next(info))
{
if (info.id == deductionID && info.catSystem == catSystem &&
info.category == category && info.subcategory == subcategory)
{
info.yearToDateAmount += amount;
info.yearToDateBase += baseAmount;
employeeInfo.categoryItemArray->AssignItemAt(catTaxIterator.GetCurrentIndex(), info);
break;
}
}
}
}
}
// calculate YTD for benefits
if (mBenefitArray.GetCount() > 0) // added TCS 2/6/99
{
CMoney benefitAmount, employerAmount, YTDAmount;
TObjectIDArrayIterator iterator(mBenefitArray);
while (iterator.Next(breakdownID))
{
CBenefitBreakdownEntry *entry =
TCS_SAFE_CAST(gDBFile->GetOneObject(id_BennyBreakdownEntry, breakdownID),
CBenefitBreakdownEntry);
if (entry)
{
DB_ObjectWatcher watcher(entry);
TCS_ASSERTMsg(entry->GetMemberValue(tag_transactid, type_objectid, &deductionID),
TCS_GetValueErrString(tag_transactid));
TCS_ASSERTMsg(entry->GetMemberValue(tag_calcdeduction, type_money, &amount),
TCS_GetValueErrString(tag_calcdeduction));
TCS_ASSERTMsg(entry->GetMemberValue(tag_employeebenefits, type_money, &benefitAmount),
TCS_GetValueErrString(tag_employeebenefits));
TCS_ASSERTMsg(entry->GetMemberValue(tag_employeramount, type_money, &employerAmount),
TCS_GetValueErrString(tag_employeramount));
TCS_ASSERTMsg(entry->GetMemberValue(tag_baseamount, type_money, &baseAmount),
TCS_GetValueErrString(tag_baseamount));
YTDAmount = TCS_MAX(amount, benefitAmount);
YTDAmount = TCS_MAX(YTDAmount, employerAmount);
TBenefitArrayIterator benefitIterator(*employeeInfo.benefitArray);
SBenefitInfo info;
while (benefitIterator.Next(info))
{
if (info.id == deductionID)
{
info.yearToDateAmount += YTDAmount; // rev TCS 6/14/00
info.yearToDateBase += baseAmount;
employeeInfo.benefitArray->AssignItemAt(benefitIterator.GetCurrentIndex(), info);
break;
}
}
}
}
}
}
#if CAN_USE_MARK
#pragma mark -
#endif
/*********************************************************************************
AddHourBreakdowns
add labor hour breakdowns from the given employee info
*********************************************************************************/
void CPayrollRecord::AddHourBreakdowns(const SEmployeeInfo &employeeInfo,
const Boolean /*isTempRecord*/)
{
// sanity check
TCS_FailNILMsg(employeeInfo.hoursArray, TCS_GetErrString(errID_BadArray));
TCS_ASSERTMsg(!IsInDatabase(), TCS_GetErrString(errID_BadDatabaseChange));
// fetch basic info
DBid ownerID = GetDBID();
DBClass ownerClass = GetDBClassID();
DBid breakdownID;
SInt32 breakdownIndex,
breakdownsCompleted = 0;
CMoney oldAmount;
CBreakdownEntry *entry;
Boolean isExisting = false;
// walk through the items in the hours item array
TLaborHoursArrayIterator iterator(*(employeeInfo.hoursArray));
SLaborHoursInfo itemInfo;
while (iterator.Next(itemInfo))
{
// we now include only hours that are checked TCS rev 10/23/01
if (!itemInfo.pay)
continue;
entry = nil; // bugfix TCS 4/27/00
breakdownIndex = iterator.GetCurrentIndex();
if (mBreakdownArray.FetchItemAt(breakdownIndex, breakdownID)) // major rev TCS 4/20/00
{ // fetch an existing breakdown entry
entry = TCS_SAFE_CAST(gDBFile->GetOneObject(id_WagesBreakdownEntry, breakdownID),
CBreakdownEntry);
// we watch this later
if (entry)
isExisting = true;
}
if (!entry)
{
// create a new breakdown entry
entry = TCS_SAFE_CAST(gDBFile->CreateObjectFromID(id_WagesBreakdownEntry,
flag_dontautoname), CBreakdownEntry);
// sanity check.
TCS_FailNILMsg(entry, TCS_GetErrString(errID_BadBreakdown));
entry->SetCreationType(record_new); // TCS 6/25/03
entry->FinishNonViewerCreate(); // TCS 5/5/03
// add to the database. This now happens explicitely TCS 5/1/03
// DO NOT sic a watcher on the entry yet-- that happens later
gDBFile->AddObject(entry);
// add the new entry to the payroll record
AddBreakdown(entry->GetDBID());
}
// increment the counter
breakdownsCompleted++;
// watch the entry so it does not leak
DB_ObjectWatcher entryWatcher(entry);
{
DB_ObjectTempRemover remover (entry, cUpdateServer); // TCS 8/26/03
if (remover.WasRemoved())
{
entry->SetMemberValue(tag_ownerobject, type_objectid, &ownerID);
entry->SetMemberValue(tag_ownerobjectclass, type_objclass, &ownerClass);
entry->SetMemberValue(tag_payday, type_date, &mDate);
entry->SetMemberValue(tag_employee, type_objectid, &mMainAccount);
entry->SetMemberValue(tag_mainaccount, type_objectid, &mMainAccount); // TCS 8/10/01
entry->SetMemberValue(tag_mainaccountclass, type_objclass, &mMainAccountClass);
// make sure amounts are even pennies TCS 8/30/01
// no, we do NOT want to round values here-- people do not want
// line-item rounding for payroll. TCS 2/4/02
// itemInfo.totalDueAmount.RoundPennies();
// now fill in data from the struct
FillHoursFromStruct(entry, itemInfo);
}
}
// we used to post here, but that is now handled elsewhere
}
// remove any excess breakdowns TCS 5/2/00
RemoveExcessBreakdowns(mBreakdownArray, id_WagesBreakdownEntry, breakdownsCompleted);
// also update the total
mWagesTotal = employeeInfo.wageAmount;
}
/*********************************************************************************
AddCommissionBreakdowns
add commission breakdowns from the given employee info
*********************************************************************************/
void CPayrollRecord::AddCommissionBreakdowns(const SEmployeeInfo &employeeInfo,
const Boolean /*isTempRecord*/)
{
// sanity check
TCS_FailNILMsg(employeeInfo.commissionArray, TCS_GetErrString(errID_BadArray));
TCS_ASSERTMsg(!IsInDatabase(), TCS_GetErrString(errID_BadDatabaseChange));
// fetch basic info
DBid ownerID = GetDBID();
DBClass ownerClass = GetDBClassID();
DBid breakdownID;
SInt32 breakdownIndex,
breakdownsCompleted = 0;
CMoney oldAmount;
CBreakdownEntry *entry;
Boolean isExisting = false;
// walk through the items in the commish array
TCommissionArrayIterator iterator(*(employeeInfo.commissionArray));
SCommissionInfo itemInfo;
while (iterator.Next(itemInfo))
{
// we now include only commissions that are checked
if (!itemInfo.pay)
continue;
entry = nil;
breakdownIndex = iterator.GetCurrentIndex();
if (mCommissionArray.FetchItemAt(breakdownIndex, breakdownID))
{ // fetch an existing breakdown entry
entry = TCS_SAFE_CAST(gDBFile->GetOneObject(id_CommishBreakdownEntry, breakdownID),
CBreakdownEntry);
// we watch this later
if (entry)
isExisting = true;
}
if (!entry)
{ // create a new breakdown entry
entry = TCS_SAFE_CAST(gDBFile->CreateObjectFromID(id_CommishBreakdownEntry,
flag_dontautoname), CBreakdownEntry);
TCS_FailNILMsg(entry, TCS_GetErrString(errID_BadBreakdown));
entry->FinishNonViewerCreate(); // TCS 5/5/03
entry->SetCreationType(record_new); // TCS 6/25/03
// add to the database. This now happens explicitly TCS 5/1/03
gDBFile->AddObject(entry);
// add the new entry to the payroll record
AddCommissionBreakdown(entry->GetDBID());
}
// increment the counter
breakdownsCompleted++;
// watch the entry so it does not leak
DB_ObjectWatcher entryWatcher(entry);
{
DB_ObjectTempRemover remover (entry, cUpdateServer);
if (remover.WasRemoved())
{
entry->SetMemberValue(tag_ownerobject, type_objectid, &ownerID);
entry->SetMemberValue(tag_ownerobjectclass, type_objclass, &ownerClass);
entry->SetMemberValue(tag_payday, type_date, &mDate);
entry->SetMemberValue(tag_employee, type_objectid, &mMainAccount);
entry->SetMemberValue(tag_mainaccount, type_objectid, &mMainAccount); // TCS 8/10/01
entry->SetMemberValue(tag_mainaccountclass, type_objclass, &mMainAccountClass);
// make sure amounts are even pennies
itemInfo.totalDueAmount.RoundPennies();
// now fill in data from the struct
FillCommissionFromStruct(entry, itemInfo);
}
}
// we used to post here, but that is now handled elsewhere
}
// remove any excess breakdowns TCS 5/2/00
RemoveExcessBreakdowns(mCommissionArray, id_CommishBreakdownEntry, breakdownsCompleted);
// also update the total
mCommissionsTotal = employeeInfo.commissionAmount;
}
|