Understanding Address Framework Technically
LogisticsPostalAddress (Address): This table stores the actual physical postal
address.
Postal Address have 2 important
fields ValidFrom, ValidTo. This means that there could be multiple entries.
LogisticsElectronicAddress (Contact): This table stores all the
contacts. Contacts are of 2 types
·
Contacts linked
directly to Customer/Vendor.
·
Contacts linked to a
Postal Address.
In Microsoft Dynamics AX, you
add postal and electronic address information to entities such as customer,
vendor, or contact person by using the DirPartyPostalAddressView and DirPartyContactInfoView views.
Table
|
Description
|
DirPartyTable
|
Global address book. This will
contain entries for all people and organizations
|
you deal with, including customers,
suppliers, employees, etc.
|
|
This information is maintained
across the entire organization. NB the table structure often refers to
address book entries as 'parties'. Generally other records (like customer,
supplier, etc) will reference a record in this table by a field named Party.
|
|
LogisticsLocation
|
This is a single 'location' that
can be attached to one or more address book entries. This is similar in
principle to the old 'Address' table from Ax2009, that no longer exists - The
main difference now being that the location header always points to an
address book entry, whereas in 2009 the Address table could point to anything.
|
|
|
Note that this is not an address -
Physical address details are stored in
|
|
LogisticsPostalAddress
|
|
LogisticsPostalAddress
|
A postal address, linked to a LogisticsLocation record
via field Location.
|
LogisticsElectronicAddress
|
'Electronic' address details, such
as email, phone, web address etc.
|
|
|
Each different type of address is
represented as a separate record, delineated by 'Type'. This links to
the location record.
|
|
DirPartyLocation
|
This table links entries in
the LogisticsLocation table to an address book entry (DirPartyTable).
|
LogisticsLocationRole
|
This defines types of roles that an
address are classified as, such as "Delivery",
"Invoice", etc.
|
DirPartyLocationRole
|
Links a location role type (LogisticsLocationRole)
and an address book entry (DirPartyTable)
|
DirPartyPostalAddressView (view)
|
This is a view that collates
address book entries with their linked postal adresses
|
Simple
job to understand the relation between DirPartyLocation and DirPartyTable. Creation
of postal address and contact info is shown below:
static
void AddressJob(Args _args) // X++
job.
{
// Declare variables: views.
DirPartyContactInfoView contactInfo;
DirPartyPostalAddressView postalAddress;
// Declare variables: tables.
ContactPerson contactperson;
DirPartyTable partyTable = DirPartyTable::findByName("Contoso",
DirPartyType::Organization);
LogisticsPostalAddress
logisticsPostalAddressInfo;
// Declare variables: classes.
ContactPersonEntity contactPersonEntity;
LogisticsLocationEntity entity;
// Declare variables: extended data
types.
Phone phone;
// Declare variables: primitives.
str firstName;
str middleName;
str lastName;
// Create and populate the contact
person.
contactPersonEntity =
ContactPersonEntity::construct(contactPerson);
contactPersonEntity.parmFirstName('Contact');
contactPersonEntity.parmMiddleName('M.');
contactPersonEntity.parmLastName('Person');
contactPersonEntity.parmAssistantName('AssistantName');
contactPersonEntity.parmBillingInformation('Billing
info');
contactPersonEntity.parmCharacter('Character description');
contactPersonEntity.parmComputerNetworkName('Computer network name');
contactPersonEntity.parmContactForParty(partyTable.RecId);
contactPersonEntity.parmContactMemo('Memo');
contactPersonEntity.parmContactPersonId('CP61');
contactPersonEntity.parmLoyalty('Loyalty');
contactPersonEntity.parmMileage('Mileage');
contactPersonEntity.parmOfficeLocation('Office location');
contactPersonEntity.parmOutlookCategories('Outlook
categories');
contactPersonEntity.parmProfession('Profession');
contactPersonEntity.parmSensitivity(smmSensitivity::Personal);
contactPersonEntity.parmSpouse('Spouse');
contactPersonEntity.parmTimeAvailableFrom(1000);
contactPersonEntity.parmTimeAvailableTo(2000);
contactPersonEntity.write();
// Populate the postal address
information by using the view.
postalAddress.Street = 'One Microsoft
Way';
postalAddress.City = 'Redmond';
postalAddress.State = 'WA';
postalAddress.ZipCode = '98052';
postalAddress.CountryRegionId = 'US';
// Update the postal address information.
contactPersonEntity.createOrUpdatePostalAddress(postalAddress);
// Populate the contact information by
using the view.
contactInfo.Locator = '555-555-5555';
contactInfo.Type =
LogisticsElectronicAddressMethodType::Phone;
contactInfo.IsPrimary = true;
// Update the contact information.
contactPersonEntity.createOrUpdateContactInfo(contactInfo);
// Verify that the data was stored
correctly.
firstName =
contactPersonEntity.parmFirstName();
middleName =
contactPersonEntity.parmMiddleName();
lastName =
contactPersonEntity.parmLastName();
logisticsPostalAddressInfo =
entity.getPostalAddress();
phone =
contactPersonEntity.getPrimaryElectronicAddressLocation().getPhone();
info(firstName + " " +
middleName + " " + LastName +
" is located at " +
logisticsPostalAddressInfo.StreetNumber +
" " +
logisticsPostalAddressInfo.Street + ", " +
logisticsPostalAddressInfo.City +
", " +
logisticsPostalAddressInfo.State +
" " +
logisticsPostalAddressInfo.ZipCode +
". They can be contacted at
" + phone + ".");
}
|
Note:
Ø LogisticsPostalAddressView consists of LogisticsPostalAddress and LogisticsLocation.
Ø DirPartyPostalAddressView consists of LogisticsPostalAddressView and DirPartyLocation.
Ø DirPartyLocation consists of Party and Location.
Retrieve Customer/Vendor address:
static void CustomerAddressBook
(Args _args)
{
CustTable custTable;
DirPartyTable dirPartyTable;
DirPartyLocation partyLocation;
LogisticsLocation logisticsLocation;
LogisticsPostalAddress postalAddress;
;
custTable = custTable::find('Test1001'); //
Customer account id
dirPartyTable = dirPartyTable::findRec(custTable.Party);
while select partyLocation
where partyLocation.Party == dirPartyTable.RecId
{
logisticsLocation =
logisticsLocation::find(partyLocation.Location);
if(logisticsLocation.IsPostalAddress)
{
postalAddress =
LogisticsPostalAddress::findByLocation(logisticsLocation.RecId);
info(strFmt("%1 - %2",
logisticsLocation.Description,
postalAddress.CountryRegionId));
}
}
}
|
Get Email address:
static void CustomerEmailAddresses(Args
_args)
{
CustTable custTable;
DirPartyTable dirPartyTable;
DirPartyLocation partyLocation;
LogisticsLocation logisticsLocation;
LogisticsElectronicAddress electronicAddress;
;
custTable = custTable::find('Test1001'); //
Customer account id
dirPartyTable = dirPartyTable::findRec(custTable.Party);
while select partyLocation
where partyLocation.Party == dirPartyTable.RecId
{
logisticsLocation =
logisticsLocation::find(partyLocation.Location);
while select electronicAddress
where electronicAddress.Location == logisticsLocation.RecId
&& electronicAddress.Type ==
LogisticsElectronicAddressMethodType::Email
{
info(strFmt("%1",electronicAddress.Locator));
}
}
}
|
Get Phone number from warehouses:
static void PhoneNumbersAttachedToWarehouse(Args
_args)
{
InventLocation inventLocation;
LogisticsEntityPostalAddressView postalAddressView;
LogisticsElectronicAddress elecAddress;
LogisticsLocation contactLocation;
inventLocation = inventLocation::find('NB');
if(inventLocation)
{
while select postalAddressView
where postalAddressView.Entity == inventLocation.RecId
&& postalAddressView.EntityType ==
LogisticsLocationEntityType::Warehouse
{
while select elecAddress
where elecAddress.Type ==
LogisticsElectronicAddressMethodType::Phone
join contactLocation
where contactLocation.ParentLocation == postalAddressView.Location
&& contactLocation.RecId == elecAddress.Location
{
info(elecAddress.Locator);
}
}
}
}
|
Here is
the static method which I've written to make the life easier for the developer,
to find the already existing combination of street, city, zip code, state,
country etc.
If it
finds the existing data in the tables then it will return the ‘LogisticsPostalAddress’ buffer else it creates the new record in the LogisticsPostalAddress table using the below logic.
public static
LogisticsPostalAddress retrieveMatchingPostalAddress(
Description _locationName,
LogisticsAddressStreet _street,
LogisticsAddressCity _city,
LogisticsAddressCountyId _county,
LogisticsAddressZipCodeId _zipCode,
LogisticsAddressStateId _state,
LogisticsAddressCountryRegionId
_countryRegionId,
LogisticsPostalAddressRecId _originalPostalAddress = 0
)
{
LogisticsPostalAddress ret;
LogisticsPostalAddressEntity postalAddressEntity = new LogisticsPostalAddressEntity();
LogisticsPostalAddressView postalAddressView;
LogisticsPostalAddress originalPostalAddress;
LogisticsLocation originalLocation;
boolean createAddress = false;
if
(_originalPostalAddress != 0)
{
originalPostalAddress =
LogisticsPostalAddress::findRecId(_originalPostalAddress);
originalLocation =
LogisticsLocation::find(originalPostalAddress.Location);
if (originalLocation.Description == _locationName
&&
originalPostalAddress.Street
== _street
&& originalPostalAddress.City == _city
&&
originalPostalAddress.ZipCode
== _zipCode
&&
originalPostalAddress.State
== _state
&&
originalPostalAddress.County
== _county
&& originalPostalAddress.CountryRegionId == _countryRegionId)
{
ret = originalPostalAddress;
}
else
{
createAddress = true;
}
}
else
{
createAddress = true;
}
if
(createAddress)
{
postalAddressView.LocationName = _locationName;
postalAddressView.Street = _street;
postalAddressView.City = _city;
postalAddressView.ZipCode = _zipCode;
postalAddressView.State = _state;
postalAddressView.County = _county;
postalAddressView.CountryRegionId
= _countryRegionId;
ret =
postalAddressEntity.createPostalAddress(postalAddressView);
}
return
ret;
}
|
Hello :) Thank you so much for providing such useful tutorial about understanding Address Framework in the technical aspect. It will help me a lot, because I'm just a beginner in the field of Microsoft Dynamics AX and have to learn alot :)
ReplyDeleteThank you :)
Deletethis is probably the best explanation that I've found regarding AX6 and Addresses. Thank you
ReplyDeleteThanks Cheri :) Keep daxing!!
DeleteThis comment has been removed by the author.
ReplyDeleteThanks so much for this . But i need one thing on How to update the Address Purpose( Invoice,Delivery,Business( etc .) of customer or vendor . Actaully It inserts into dirPartyLocationRole where you will get the location from logisticsLocationRole.
ReplyDeleteCan you please check i just need to update AddressType/Purpose
Very informative,useful ,thanks alot
ReplyDeleteThanks for your wonderful blog, today i was helped by your writing. Thanks
ReplyDeleteHow can you update a contact person?
ReplyDelete