Troubleshooting Inplace Upgrade Script updateDirDartyRelationshipXDSLegalEntity()

You might recieve the following message when  running the upgrade script Classes\ReleaseUpdateDB62_GABMinor\updateDirDartyRelationshipXDSLegalEntity() during  an inplace upgrade from MS Dynamics AX 2012 R2 to R3:

“Cannot create a record in Party relationships (DirPartyRelationship). Invalid value specified for ‘Expiration:’. It cannot be greater than or equal to the ‘Expiration:’ of the first record.”

One possible background could be unsufficient customer data quality in terms of partly missing data in the field “PartyID”
The following script is a slightly modified version of the standard script updateDirDartyRelationshipXDSLegalEntity(). It loops through the records sequentially instead of block wise and will list records where a PartyID might be missing:

“Microsoft provides programming examples for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability or fitness for a particular purpose. This blog post  assumes that you are familiar with the X++ programming language that is being demonstrated . Always test the script in test environments first in detail! ”

<<<<<<<
static void UpdateDirPartyRelationship_Test(Args _args)
{
#DirParty
HcmWorker worker;
HcmEmployment employment;
CompanyInfo companyInfo;
DirPartyRelationship partyRelationship;
DirRelationshipTypeId workerTypeId, applicantTypeId, partyInLETypeId;
utcdatetime validFrom = DateTimeUtil::minValue(), validTo = DateTimeUtil::maxValue();
DirDataAreaId systemDataAreaId = #SystemDataAreaId;

workerTypeId = DirRelationshipTypeTable::findBySystemType(DirSystemRelationshipType::Worker).RelationshipTypeId;
applicantTypeId = DirRelationshipTypeTable::findBySystemType(DirSystemRelationshipType::Applicant).RelationshipTypeId;
partyInLETypeId = DirRelationshipTypeTable::findBySystemType(DirSystemRelationshipType::PartyInLE).RelationshipTypeId;

partyRelationship.skipDatabaseLog(true);
partyRelationship.skipEvents(true);
partyRelationship.skipDataMethods(true);

info(strFmt(“systemDataAreaId: “, systemDataAreaId));
info(strFmt(“workerTypeId: “, workerTypeId));
info(strFmt(“applicantTypeId: “, applicantTypeId));
info(strFmt(“partyInLETypeId: “, partyInLETypeId));

ttsbegin;

// Delete all worker and applicant relationships
delete_from partyRelationship
where partyRelationship.RelationshipTypeId == workerTypeId ||
partyRelationship.RelationshipTypeId == applicantTypeId;

info(“Finish deleting record in partyRelationship table”);

// Insert worker relationships with employment record
/*insert_recordset
partyRelationship (RelationshipTypeId, ChildParty, ValidFrom, ValidTo, LegalEntityDataAreaId)
select workerTypeId, Person from worker
join ValidFrom, ValidTo from employment where employment.Worker == worker.RecId
join DataArea from companyInfo where companyInfo.RecId == employment.LegalEntity;*/

while select Person from worker
join ValidFrom, ValidTo from employment where employment.Worker == worker.RecId
join DataArea from companyInfo where companyInfo.RecId == employment.LegalEntity
{
  partyRelationship.clear();
  partyRelationship.RelationshipTypeId = workerTypeId;
  partyRelationship.ChildParty = worker.Person;
  partyRelationship.ValidFrom = employment.ValidFrom;
  partyRelationship.ValidTo = employment.ValidTo;
  partyRelationship.LegalEntityDataAreaId = companyInfo.DataArea;
try
{
partyRelationship.insert();
}
catch(Exception::DuplicateKeyException)
{
  error(strFmt(“Duplicated key error on inserting HcmWorker record with recId %1 and relationship type %2 with Child Party %3”,
  worker.RecId, workerTypeId, worker.Person));
}
  catch(Exception::UpdateConflict)
{
  error(strFmt(“Update conflict error on inserting HcmWorker record with recId %1 and relationship type %2 with Child Party %3”,
  worker.RecId, workerTypeId, worker.Person));
}
catch(Exception::Error)
{
  error(strFmt(“Error on inserting HcmWorker record with recId %1 and relationship type %2 with Child Party %3”,
  worker.RecId, workerTypeId, worker.Person));
}
}

info(“Finish inserting worker relationships with employment record”);

// Insert workers without employment records that does not existing party relationship
/*insert_recordset
partyRelationship (RelationshipTypeId, ChildParty, ValidFrom, ValidTo, LegalEntityDataAreaId)
select partyInLETypeId, Person, validFrom, validTo, systemDataAreaId from worker
notexists join employment
where employment.Worker == worker.RecId
notexists join partyRelationship
where partyRelationship.ChildParty == worker.Person &&
partyRelationship.LegalEntityDataAreaId == systemDataAreaId;*/

while select Person from worker
notexists join employment
where employment.Worker == worker.RecId
notexists join partyRelationship
where partyRelationship.ChildParty == worker.Person &&
partyRelationship.LegalEntityDataAreaId == systemDataAreaId
{
  partyRelationship.clear();
  partyRelationship.RelationshipTypeId = partyInLETypeId;
  partyRelationship.ChildParty = worker.Person;
  partyRelationship.ValidFrom = validFrom;
  partyRelationship.ValidTo = validTo;
  partyRelationship.LegalEntityDataAreaId = systemDataAreaId;
try
{
  partyRelationship.insert();
}
catch(Exception::DuplicateKeyException)
{
  error(strFmt(“Duplicated key error on inserting HcmWorker record with recId %1 and relationship type %2 with Child Party %3”,
  worker.RecId, partyInLETypeId, worker.Person));
}
catch(Exception::UpdateConflict)
{
  error(strFmt(“Update conflict error on inserting HcmWorker record with recId %1 and relationship type %2 with Child Party %3”,
  worker.RecId, partyInLETypeId, worker.Person));
}
  catch(Exception::Error)
{
  error(strFmt(“Error on inserting HcmWorker record with recId %1 and relationship type %2 with Child Party %3”,
  worker.RecId, partyInLETypeId, worker.Person));
}
}

info(“Finish workers without employment records that does not existing party relationship”);

ttsabort;

info(“The script finishes without error!”);
}
>>>>>>>