Beruflich Dokumente
Kultur Dokumente
Date: February 2012 www.microsoft.com/dynamics/ax Patrick Nelson, Solution Architect Send suggestions and comments about this document to adocs@microsoft.com. Please include the title with your feedback.
Table of Contents
Introduction ................................................................................................ 3 Data complexity in Microsoft Dynamics AX 2012......................................... 3 Options for importing data into Microsoft Dynamics AX 2012 ..................... 4
Microsoft Dynamics AX import ................................................................................................ 4 Microsoft Excel Add-in for Microsoft Dynamics AX ..................................................................... 5 Using document services with the Excel Add-in to import data................................................. 5 Using the Excel Add-in to import tables ................................................................................ 5 RapidStart Services ............................................................................................................... 7 AIF, document services, and custom code ................................................................................ 9 Examples of using AIF to import global address bookrelated data .............................................10 Customer import .............................................................................................................. 10 Vendor import .................................................................................................................. 15 HCMWorker (employee or worker) import ............................................................................ 16 Product-item data management services ............................................................................. 19
Recommended import methods for specific tables and entities................. 26 Performance considerations...................................................................... 28
Introduction
Microsoft Dynamics AX 2012 must be populated with configuration and master data records before an organization can start using it. To minimize data duplication and enable change tracking in Microsoft Dynamics AX, the underlying database schema is quite complex. This complexity can present challenges to system integrators and developers who are migrating data from other systems into Microsoft Dynamics AX. Data is likely to be imported many times during the life cycle of a system; for example, when you migrate from another system, set up a new test or demonstration environment, or add new master data. This document is only intended to describe how to perform the initial data load into a new system. The following table describes the types of data that can be imported or set up in the system. Type of data
System configuration data
Description
Data used to set up the Microsoft Dynamics AX environment. This data is not considered part of data migration, but part of your initial setup and configuration. Microsoft Dynamics ERP RapidStart Services can be used to set the system configuration data. Data specific to each module in the environment. This data is typically migrated from a test or staging environment into a production environment. It is not imported from another ERP system. Entities that describe the parties, locations, products, and activities that are referenced by entities that document and record business events. Examples of this type of data are customers, vendors, products, ZIP Codes/postal codes, payment methods, and delivery methods. Entities that document business events and record their economic value. Examples of this type of data are ledger transactions, customer transactions, and inventory transactions.
Parameter data
Master data
Transactional data
Impact
Table inheritance is a concept that recognizes and represents generalized and specialized relationships between data entities. In Microsoft Dynamics AX 2012, tables can inherit, or extend, from the tables that are situated above them in a hierarchy. A base table contains fields that are common to all tables that are derived from it. A derived table inherits these fields but also contains fields that are unique to its purpose. Each table contains the SupportInheritance and Extends properties, which can be used to control table inheritance. When you import a table that inherits from a base table, you must also import the base table. This is most easily accomplished through code.
Core concept
Date effectivity
Impact
Valid time state tables can be used to store and track an objects history over its lifetime in Microsoft Dynamics AX 2012. Valid time state tables are often used to track changes to an entity, which requires that some of the data about an entity be stored in a separate table. It is important that you not access valid time state tables directly, but instead use a service abstraction. A view can be thought of as either a virtual table or a stored query. The data accessible through a view is not stored in the database as a distinct object. What is stored in the database is a SELECT statement. The result set of the SELECT statement forms the virtual table returned by the view. Views are used extensively in Microsoft Dynamics AX to access highly normalized data. Views are employed by services that reference these constructs to help simplify the programming model and data access patterns.
One-to-many relationships
Many Microsoft Dynamics AX entities allow for one-to-many relationships. For example, the global address book allows an unlimited number of addresses and an unlimited amount of contact information to be associated with each party. One-to-many relationships can make it challenging to present information in a tabular format such as a worksheet, where all contact information for a particular party (customer or vendor) is frequently typed on a single line. A financial dimension is a data classifier created from the parties, locations, products, and activities in an organization. The master entities, such as customers, vendors, and workers, contain default financial dimensions that help populate default transaction information. The underlying storage for dimensions and the associated rules and combinations is complex, and the logic to properly associate dimension attributes with a master entity must be done by calling the correct APIs rather than populating data directly into tables.
Financial dimensions
Most tables in Microsoft Dynamics AX have a surrogate key, usually the record ID (RecId) of the table, which is used as the primary key. Tables related to the original (parent) table usually have the surrogate key of the parent as a foreign key. RecIdThis provides the benefit of being able to rename items and show friendly names in the user interface while maintaining the data integrity of the stored information. Because RecIds are allocated by the system as data is inserted, maintaining primary key/foreign key relationships without using a service abstraction or APIs is quite difficult and prone to error.
It is often helpful, before you import data into Microsoft Dynamics AX, to review E/R diagrams of the data structures that you will be working with. We recommend that you use either the Application Analysis Tool that is available on InformationSource or the Reverse Engineering tool.
For more information, see the following resources: Import initial setup data Create definition groups for import and export
Because of these constraints, the Excel Add-in can be used only with the following document services to update, create, and delete data: BudgetTransaction EMSMeterReading EMSSubstanceFlow GeneralJournal ProductionPickingList ProjectHourJournals SysImportBusSector VendGroup VendRequestSignup
Valid references All relations in the relations collection for the table that refer to other tables via RecId must be related to tables that have a replacement key specified.
You can import data into the following Microsoft Dynamics AX 2012 tables by using the Excel Addin. Table name
BANKCENTRALBANKPURPOSE BANKGROUP BANKTRANSACTIONTYPEGROUPHEADER BANKTRANSTYPE BANKTRANSTYPEGROUPDETAILS CURRENCYLEDGERGAINLOSSACCOUNT CUSTBANKACCOUNT CUSTCOLLECTIONLETTERLINE CUSTCOLLECTIONLETTERTABLE CUSTINTERESTWAIVELIMIT CUSTLEDGER CUSTTABLE DIRADDRESSBOOK DIRADDRESSBOOKPARTY DIRORGANIZATIONBASE DIRPARTYTABLE DIRPERSON DLVTERM ECORESCATEGORYHIERARCHYROLE ECORESCATEGORYHIERARCHYTRANSLATION ECORESSTORAGEDIMENSIONGROUP EXCHANGERATE EXCHANGERATECURRENCYPAIR EXCHANGERATETYPE FORECASTMODEL INVENTBATCH INVENTDIMSETUPGRID INVENTITEMGROUP INVENTLOCATION INVENTMODELGROUP INVENTSITE JOURNALIZINGDEFINITION KANBANQUANTITYPOLICY KANBANQUANTITYPOLICYDEMANDPERIOD LEANPRODUCTIONFLOWMODEL
Table name
LEDGERALLOCATEKEY LEDGERALLOCATIONBASISRULE LEDGERALLOCATIONBASISRULESOURCE LEDGERALLOCATIONRULE LEDGERALLOCATIONRULEDESTINATION LEDGERALLOCATIONRULESOURCE LEDGERBALANCECONTROL LEDGERIMPORTMODE LEDGERJOURNALTXT LEDGERSYSTEMACCOUNTS MAINACCOUNTCATEGORY MAINACCOUNTTEMPLATE OMOPERATINGUNIT PAYMDAY PAYMDAYLINE PAYMSCHEDLINE PAYMTERM PRICEDISCADMNAME PRICEDISCGROUP PRODUNITTABLE PROJCATEGORY REASONTABLE RETURNACTIONDEFAULTS RETURNREASONCODEGROUP ROUTEGROUP ROUTEOPRTABLE SALESQUOTATIONTYPEGROUP SMMCAMPAIGNSELECTION SMMENCYCLOPEDIAITEMS SMMSALESUNIT SMMTMCALLLISTTABLE STATREPINTERVAL VENDBANKACCOUNT VENDGROUP WRKCTRCAPABILITY
RapidStart Services
RapidStart Services can be used to populate basic configuration data records in a new environment, and also some master data (customers and vendors). RapidStart Services cannot be used to import transaction data. Although you can use RapidStart Services to manage customers and vendors, the templates for customers and vendors are quite large. If the volume of customer and vendor data to be imported is small, you may be able to use the customer and vendor templates in RapidStart Services. However, if you have large lists of customers or vendors, you should consider using Application Integration Framework (AIF). For more information, see InformationSource. The following functional areas can be set up by using RapidStart Services: Applicability Model Bank Account Management Base Information (Organization, Ledger Currency) Customer and Price Discount General Ledger Setup Manage Collections Manage Customers Manage Fixed Assets Manage Inventory Manage Product Categories Manage Vendors Organization Information Process Customer Invoices Process Customer Payments Process Vendor Invoices Process Vendor payments Purchase Order Management Purchase Quotation Management Sales Order Management Sales Quote Management Tax Vendor Price and Discount
At the time of writing, the following are the supported tables in RapidStart Services that correspond to the preceding functional areas. Table name
AddressCountryRegionGroupBLWI AssetAcquisitionMethod AssetActivityCode AssetBonus AssetBookTable AssetBookTableDerived
Table name
InventModelGroup InventParameters InventPosting InventSite Ledger LedgerAllocateKey
Table name
AssetCondition AssetDepBookTable AssetDepBookTableDerived AssetDepreciationProfile AssetGroup AssetGroupBookSetup AssetGroupDepBookSetup AssetGroupDepBookSetupBonus AssetLedger AssetLedgerAccounts AssetLocation AssetMajorType AssetParameters AssetPropertyGroup AssetTable BankCentralBankPurpose BankParameters BankTransactionTypeGroupHeader BankTransType BankTransTypeGroupDetails CashDisc CurrencyLedgerGainLossAccount CustCollectionLetterLine CustCollectionLetterTable CustFormletterParameters CustGroup CustInterest CustInterestFee CustInterestVersion CustInterestVersionDetail CustInterestWaiveLimit CustLedger CustLedgerAccounts CustParameters CustPaymModeTable CustTable DirPartyTable DlvMode DlvTerm EcoResCategory
Table name
LedgerAllocateTrans LedgerAllocationBasisRule LedgerAllocationBasisRuleSource LedgerAllocationRule LedgerAllocationRuleDestination LedgerAllocationRuleSource LedgerBalanceControl LedgerGainLossAccount LedgerJournalTxt LedgerParameters LedgerSystemAccounts LineOfBusiness LogisticsLocation MainAccount MainAccountCategory MainAccountTemplate PaymDay PaymDayLine PaymSched PaymSchedLine PaymTerm PriceDiscAdmName PriceDiscGroup PriceParameters PurchParameters PurchRFQParameters ReasonTable ReturnActionDefaults ReturnReasonCode ReturnReasonCodeGroup SalesParameters SalesQuotationTypeGroup StatRepInterval StatRepIntervalLine TaxAuthorityAddress TaxData TaxExemptCodeTable TaxGroupData TaxGroupHeading TaxItemGroupHeading
Table name
EcoResCategoryHierarchy EcoResCategoryHierarchyRole EcoResCategoryHierarchyTranslation EcoResProductDimensionGroup EcoResProductDimensionGroupFldSetup EcoResStorageDimensionGroup EcoResStorageDimensionGroupFldSetup EcoResTrackingDimensionGroup EcoResTrackingDimensionGroupFldSetup ExchangeRate ExchangeRateCurrencyPair ExchangeRateType InventDimSetupGrid InventItemGroup InventLocation
Table name
TaxLedgerAccountGroup TaxOnItem TaxParameters TaxPeriodHead TaxReportPeriod TaxTable VendExceptionGroup VendGroup VendLedger VendLedgerAccounts VendParameters VendPaymModeTable VendTable WMSJournalName WMSParameters
As previously discussed, many of these concepts require that the underlying tables be highly normalized, and therefore make it quite difficult to directly update tables. Core concept
Table inheritance
Impact
The party model uses a single party and the corresponding subtypes, such as organizations, teams, departments, and people. Because parties can play many roles, the information for the party, such as the organization, is often split across several tables in the underlying storage layer. These separate tables are managed by the kernel to keep them synchronized. Date effectivity is used to track the active version of the name of an organization or person as it changes over time. This requires that the name information be stored outside the actual party tables. Again, the kernel ensures the proper closure and creation of new date effective entries, guaranteeing that they do not overlap. To ensure data integrity, the model for storing names, city references, address components, and their roles with respect to the party is highly normalized in the database. Views are used to pull the information together. The global address book allows an unlimited number of addresses and an unlimited amount of contact information to be associated with each party.
Date effectivity
Because of the complex data model required for the global address book, we recommend that you import data related to it by using the services layer and APIs. There are many approaches that can be used to call service layer APIs. In this paper, we describe how to read a flat file, such as a comma-separated value (.csv) file, and call a service by using C# code.
Customer import
In this example, we demonstrate how to import customer data by using the CustomerService service.
6. In the Inbound ports form, click Activate. You can now access the service externally by using the WSDL URI.
Sample code to import customers from a .csv file by using a Visual Studio service reference
This section provides a sample that shows the correct order of operations when using the customer service to create a new customer in Microsoft Dynamics AX 2012.
//Index locations of the data columns in the .csv file. //How you choose to manage the index locations may vary depending on your implementation and structures used internal static int NameIndex = 0; internal static int KnownAsIndex = 1; 11 DATA MIGRATION FOR MICROSOFT DYNAMICS AX 2012
internal static int PhoneticNameIndex = 2; internal static int OrganizationNameIndex = 3; internal static int NameAliasIndex = 4; internal static int CustGroupIndex = 5; internal static int SalesGroupIndex = 6; internal static int DlvModeIndex = 7; internal static int InvoiceAddressTypeIndex = 8; internal static int PostalLocationNameIndex = 9; internal static int PostalstreetIndex = 10; internal static int PostalBuildingComplimentIndex = 11; internal static int PostalPOBoxIndex = 12; internal static int PostalCityIndex = 13; internal static int PostalStateIndex = 14; internal static int PostalZipIndex = 15; internal static int PostalCountryIndex = 16; internal static int PostalRolesIndex = 17; internal static int IsPostalPrimaryIndex = 18; internal static int ContactLocationNameIndex = 19; internal static int LocatorIndex = 20; internal static int ContactTypeIndex = 21; internal static int ContactRolesIndex = 22; internal static int IsContactPrimaryIndex = 23; //Create a new Instance of the Customer Service client CustomerServiceClient custSvcClient = new CustomerServiceClient(); //Read in your .csv file however you want to //This is just provided as a reference List<string[]> CustData = ParseCSVFile("C:\\CustomerImport.csv", true); //Create a customer for each row in the .csv file foreach (string[] customer in CustData) { AxdCustomer axdCustomer = new AxdCustomer(); AxdEntity_DirParty_DirPartyTable dirPartyTable = new AxdEntity_DirParty_DirPartyTable(); AxdEntity_CustTable custTable = new AxdEntity_CustTable(); AxdEntity_CustTable[] customerList = new AxdEntity_CustTable[1]; EntityKey[] entityKey; //Create the base organization that the customer will belong AxdEntity_DirParty_DirOrganization org = new AxdEntity_DirParty_DirOrganization() { KnownAs = customer[KnownAsIndex], PhoneticName = customer[PhoneticNameIndex], OrganizationName = new AxdEntity_OrganizationName[1], NameAlias = customer[NameAliasIndex], Name = customer[NameIndex] }; // Create the Organization name for the Customer AxdEntity_OrganizationName orgName = new AxdEntity_OrganizationName() { Name = customer[OrganizationNameIndex] };
//Assign organization name to the base organization. org.OrganizationName[0] = orgName; //Add an address to the org. You can add a loop and add as many address and types you want to here AxdEntity_DirPartyPostalAddressView[] postalAddView = new AxdEntity_DirPartyPostalAddressView[1]; postalAddView[0] = new AxdEntity_DirPartyPostalAddressView() { LocationName = customer[PostalLocationNameIndex], BuildingCompliment = customer[PostalBuildingComplimentIndex], City = customer[PostalCityIndex], State = customer.[PostalStateIndex], ZipCode = customer[PostalZipIndex], Street = customer[PostalstreetIndex], CountryRegionId = customer[PostalCountryIndex], //Valid Values come from the Typed column logisticsLocationRole where //IsPostalAddress = true Roles = customer[PostalRolesIndex], IsPrimary = (AxdExtType_LogisticsIsPrimaryAddress)Enum.Parse(typeof(AxdExtType_Logi sticsIsPrimaryAddress),customer[IsPostalPrimaryIndex]) }; //Add the party Address to the Organization org.DirPartyPostalAddressView = postalAddView; //Add a contact to the organization. You can add a loop and add as many address //and types you want to here AxdEntity_DirPartyContactInfoView[] contactList = new AxdEntity_DirPartyContactInfoView[1]; contactList[0] = new AxdEntity_DirPartyContactInfoView() { LocationName = customer[ContactLocationNameIndex], //Value of locator will vary by type. Locator = customer[LocatorIndex], IsPrimarySpecified = true, IsPrimary = (AxdEnum_NoYes)Enum.Parse(typeof(AxdEnum_NoYes), customer[IsContactPrimaryIndex]), TypeSpecified = true, Type = (AxdEnum_LogisticsElectronicAddressMethodType)Enum.Parse(typeof(AxdEnum _LogisticsElectronicAddressMethodType), customer[ContactTypeIndex]), //Valid Values come from the Typed column logisticsLocationRole where //IsContactInfo = true Roles = customer[ContactRolesIndex] }; //Add the contacts to the organization org.DirPartyContactInfoView = contactList; //Set the customer specific information on the CustTable custTable.CustGroup = customer[CustGroupIndex]; custTable.InvoiceAddress = (AxdExtType_CustInvoiceAddress)Enum.Parse(typeof(AxdExtType_CustInvoiceAddress) ,customer[InvoiceAddressTypeIndex]); 13 DATA MIGRATION FOR MICROSOFT DYNAMICS AX 2012
custTable.InvoiceAddressSpecified = true; custTable.DlvMode = customer[DlvModeIndex]; custTable.SalesGroup = customer[SalesGroupIndex]; //Assign the organization to the customer custTable.DirParty = new AxdEntity_DirParty_DirPartyTable[1]; custTable.DirParty[0] = org; //Add the specific customer to the list customerList[0] = custTable; axdCustomer.CustTable = customerList; //Set the header fields axdCustomer.DocPurpose = AxdEnum_XMLDocPurpose.Original; axdCustomer.DocPurposeSpecified = true; //Create the customer entityKey = custSvcClient.create(null, axdCustomer); } } //Simple .csv parser without any robust error handling. Please implement your //own logic to parse your csv file or use existing parsing libraries. //This code is provided only as a sample. public static List<string[]> ParseCSVFile(string path, Boolean hasHeaders) { List<string[]> CSVRows = new List<string[]>(); int rowNumber = 0; using (StreamReader inputFile = new StreamReader(path)) { string line; string[] columns; while ((line = inputFile.ReadLine()) != null) { columns = line.Split(','); if (hasHeaders != true || rowNumber != 0) { CSVRows.Add(columns); } rowNumber++; } } return CSVRows; }
Header field
Name KnownAs PhoneticName OrganizationName NameAlias CustGroup SalesGroup DlvMode InvoiceAddressType PostalLocationName Postalstreet PostalBuildingCompliment PostalPOBox PostalCity PostalState PostalZip PostalCountry PostalRoles IsPostalPrimary ContactLocationName Locator ContactType ContactRoles IsContactPrimary
Values row 1
Customer One cust1 Customer1 Customer One cust1 10 10 1 InvoiceAccount Primary 11111 Sample Lane
Values row 2
Customer Two cust2 Customer2 Customer Two cust2 10 20 10 InvoiceAccount Primary 22222 Sample Lane Building 1
Redmond WA 98052 USA Delivery;Invoice;Business Yes Primary Phone 111-222-333-4444 Phone Business Yes
Redmond WA 98052 USA Delivery;Invoice;Business Yes Primary Phone 111-222-333-4444 Phone Business Yes
Vendor import
In this example, we demonstrate how to import vendor data by using the vendVendTableService service.
Sample code to import a vendor from a .csv file by using a Visual Studio service reference
The sample code for a vendor import follows the same pattern as the sample for a customer import, except that the axdCustomer and CustTable objects in the code should be replaced with the AxdVendor and VendTable objects.
Modify the customer or vendor import sample to bind to DirPerson instead of DirOrganization
If you intend to bind the customer or vendor to a person rather than an organization, the code needs to be modified to create a DirPerson rather than a DirOrganization. This section provides a sample that shows how to create a DirOrganization. The rest of the code functions the same for address and contacts, but you should attach the address to the DirPerson rather than the DirOrganization.
AxdEntity_DirParty_DirPerson person = new AxdEntity_DirParty_DirPerson() { KnownAs = "KnownAs", NameAlias = "NameAlias", Name = "NameAlias", NameSequence = "NameSequence", }; // Create and assign the person name person.PersonName = new AxdEntity_PersonName[1]; AxdEntity_PersonName personName = new AxdEntity_PersonName() { FirstName = "FirstName", MiddleName = "MiddleName", LastName = "LastName" }; person.PersonName[0] = personName;
5. Select the HCMWorkerImportService operations, move them to the Selected operations pane, and then click Close. 6. In the Inbound ports form, click Activate. You can now access the service externally by using the WSDL URI.
//Create a contact for the person. You can add a loop and add as many address and //types you want to here AxdEntity_DirPartyContactInfoView[] contactList = new AxdEntity_DirPartyContactInfoView[1]; contactList[0] = new AxdEntity_DirPartyContactInfoView() { LocationName = "Employee email", //Value of locator will vary by type. Locator = "empimport@contoso.com", IsPrimarySpecified = true, IsPrimary = AxdEnum_NoYes.Yes, TypeSpecified = true, Type = AxdEnum_LogisticsElectronicAddressMethodType.Email, //Valid Values come from the Type column in logisticsLocationRole table where //IsContactInfo = true Roles = "Business" }; //Add the contacts to the person person.DirPartyContactInfoView = contactList; //Assign property values to the personName object personName.LastName = "SampleLast1"; personName.FirstName = "SampleFirst1"; personName.MiddleName = "SampleMiddle1"; //Assign PersonName to DirPersonName person.DirPersonName = personName; //Assign person deatils properties personDetails.MaritalStatus = AxdEnum_HcmPersonMaritalStatus.Married; personDetails.MaritalStatusSpecified = true; //Assign person Details to the person person.HcmPersonDetails = personDetails; personPrivateDetails.BirthDate = new DateTime(1983, 2, 18); personPrivateDetails.BirthDateSpecified = true; personPrivateDetails.Gender = AxdEnum_HcmPersonGender.Male; personPrivateDetails.GenderSpecified = true; //Assign person private Details to the person person.HcmPersonPrivateDetails = personPrivateDetails; //Assign the person to the worker worker.DirPerson = person; //Create the employment array for the worker AxdEntity_HcmEmployment[] employmentList = new AxdEntity_HcmEmployment[1]; //Set the employment ValidTo and ValidFrom Fields AxdExtType_HcmEmploymentValidFrom employmentValidFrom = new AxdExtType_HcmEmploymentValidFrom(); employmentValidFrom.Value = DateTime.UtcNow.AddYears(-5); 18 DATA MIGRATION FOR MICROSOFT DYNAMICS AX 2012
AxdExtType_HcmEmploymentValidTo employmentValidTo = new AxdExtType_HcmEmploymentValidTo(); employmentValidTo.Value = DateTime.UtcNow.AddYears(10); //Set the properties to the employment object employment.ValidFrom = employmentValidFrom; employment.ValidTo = employmentValidTo; employment.LegalEntity = "CEU"; employment.EmploymentType = AxdEnum_HcmEmploymentType.Employee; //Create an employment Detail object and set the start date AxdExtType_HcmEmploymentStartDateTime employmentStartDate = new AxdExtType_HcmEmploymentStartDateTime(); employmentStartDate.Value = DateTime.UtcNow.AddDays(7); employmentDetail.WorkerStartDate = employmentStartDate; //Assign the Detail to the employment object employment.HcmEmploymentDetail = employmentDetail; //Assign the employment object to the employment list employmentList[0] = employment; worker.HcmEmployment = employmentList; //Assign values to the worker title object AxdExtType_HcmEmploymentSeniorityDateTime seniorityDateEDT = new AxdExtType_HcmEmploymentSeniorityDateTime(); seniorityDateEDT.Value = DateTime.UtcNow.AddYears(1); workerTitle.SeniorityDate = seniorityDateEDT; workerTitle.OfficeLocation = "Room101"; //Assign worker Title to Worker worker.HcmWorkerTitle = workerTitle; //Set the Personnel number. This must be unique for each worker record. worker.PersonnelNumber = "ImportSVCNum1"; //Create the worker element in the document workerDocument.HcmWorker = new AxdEntity_HcmWorker[1]; //assign the worker to the document workerDocument.HcmWorker[0] = worker; workerDocument.DocPurpose = AxdEnum_XMLDocPurpose.Original; workerDocument.DocPurposeSpecified = true; //Call the create on the service with the worker document EntityKey[] ek = hcmSvcClient.create(null, workerDocument);
Purpose
Create products (all three types). The service can also be used to retrieve data that has already been created. 19 DATA MIGRATION FOR MICROSOFT DYNAMICS AX 2012
Service
EcoResProductMasterDimValueService
Purpose
Specify values of product dimensions for a product master. These values become available for the creation of product variants. The service can also be used to retrieve data that has already been created. Release distinct products and product masters. The service can also be used to retrieve data that has already been created. Release product variants. The service can also be used to retrieve data that has already been created.
ItemService InventDimCombinationService
All types of products are created by using the EcoResProductService service. However, the methods to create a distinct product, a product master, and a product variant are different, so each method is described separately.
5. Select the Product and Item operations, move them to the Selected operations pane, and then click Close.
6. In the Inbound ports form, click Activate. You can now access the service externally by using the WSDL URI.
{ LanguageId = "en-us", Name = "Transparent Bulb 60W" }; distinctProduct.Identifier = new AxdEntity_Identifier[1]; distinctProduct.Identifier[0] = new AxdEntity_Identifier() { ProductNumber = "Bulb60W" }; distinctProduct.StorageDimGroup = new AxdEntity_StorageDimGroup[1]; distinctProduct.StorageDimGroup[0] = new AxdEntity_StorageDimGroup() { Product = "Bulb60W", StorageDimensionGroup = "Std-Dim" }; distinctProduct.TrackingDimGroup = new AxdEntity_TrackingDimGroup[1]; distinctProduct.TrackingDimGroup[0] = new AxdEntity_TrackingDimGroup() { Product = "Bulb60W", TrackingDimensionGroup = "Std-Dim" }; AxdEcoResProduct axdProduct = new AxdEcoResProduct() { Product = new AxdEntity_Product_EcoResProduct[1] { distinctProduct } }; CallContext ctx = new CallContext(); EcoResProductServiceClient service = new EcoResProductServiceClient(); try { service.create(ctx, axdProduct); } catch (Exception e) { System.Console.WriteLine(e.Message); System.Console.ReadKey(); } }
The create operation accepts an array of products, so it is possible to create multiple products in one call to the service.
{ Product = "RunningShoe", ProductDimensionGroup = "Size-Dim" }; productMaster.VariantConfigurationTechnology = AxdEnum_EcoResVariantConfigurationTechnologyType.PredefinedVariants; AxdEcoResProduct axdProduct = new AxdEcoResProduct() { Product = new AxdEntity_Product_EcoResProduct[1] { productMaster } }; CallContext ctx = new CallContext(); EcoResProductServiceClient productService = new EcoResProductServiceClient(); try { productService.create(ctx, axdProduct); } catch (Exception e) { System.Console.WriteLine(e.Message); System.Console.ReadKey(); } }
When the product master is created, associate two size dimension values with the product master (sizes L and M).
static void createMasterDimensions() { //master dimensions definition (two sizes, L and M) AxdEntity_MasterDim_EcoResProductMasterSize sizeDimensionL = new AxdEntity_MasterDim_EcoResProductMasterSize() { SizeProductMaster = "RunningShoe", Size = "L", EcoResSize = new AxdEntity_EcoResSize[1] { new AxdEntity_EcoResSize() { Name = "L" } } }; AxdEntity_MasterDim_EcoResProductMasterSize sizeDimensionM = new AxdEntity_MasterDim_EcoResProductMasterSize() { SizeProductMaster = "RunningShoe", Size = "M", EcoResSize = new AxdEntity_EcoResSize[1] { new AxdEntity_EcoResSize() { Name = "M" } } }; AxdEcoResProductMasterDimValue axdDimValue = new AxdEcoResProductMasterDimValue() { MasterDim = new AxdEntity_MasterDim_EcoResProductMasterDimensionValue[2] { sizeDimensionL, sizeDimensionM } }; CallContext ctx = new CallContext(); EcoResProductMasterDimValueServiceClient masterDimensionService = new EcoResProductMasterDimValueServiceClient(); try { masterDimensionService.create(ctx, axdDimValue); } catch (Exception e) { System.Console.WriteLine(e.Message); System.Console.ReadKey(); } }
Create a product variant with the size L for the product master. One thing that may not be apparent from the sample is the value that is required for the ProductDimensionAttribute field of the
23 DATA MIGRATION FOR MICROSOFT DYNAMICS AX 2012
AxdEntity_VariantDimValue_EcoResProductVariantConfiguration, AxdEntity_VariantDimValue_EcoResProductVariantSize, and AxdEntity_VariantDimValue_EcoResProductVariant entities. The value must correspond to the IDs of the EcoResConfiguration, the EcoResSize, and the EcoResColor tables, respectively.
static void createVariant() { //product variant definition AxdEntity_Product_EcoResDistinctProductVariant productVariant = new AxdEntity_Product_EcoResDistinctProductVariant() { DisplayProductNumber = "RunningShoeL", ProductType = AxdEnum_EcoResProductType.Item, SearchName = "RunningShoeL", ProductMaster = "RunningShoe" }; productVariant.Translation = new AxdEntity_Translation[1]; productVariant.Translation[0] = new AxdEntity_Translation() { LanguageId = "en-us", Name = "Comfortable running shoe L size" }; productVariant.VariantDimValue = new AxdEntity_VariantDimValue_EcoResProductVariantDimensionValue[1]; productVariant.VariantDimValue[0] = new AxdEntity_VariantDimValue_EcoResProductVariantSize() { DistinctProductVariant = "RunningShoeL", ProductDimensionAttribute = 3173,//The ID of the EcoResSize table Size = "L", EcoResSize = new AxdEntity_EcoResSize1[1] { new AxdEntity_EcoResSize1() { Name = "L" } } }; AxdEcoResProduct axdProduct = new AxdEcoResProduct() { Product = new AxdEntity_Product_EcoResProduct[1] { productVariant } }; CallContext ctx = new CallContext(); EcoResProductServiceClient productService = new EcoResProductServiceClient(); try { productService.create(ctx, axdProduct); } catch (Exception e) { System.Console.WriteLine(e.Message); System.Console.ReadKey(); } }
Release products
A product must be released to a company before it can be used in that company. The ItemService and InventDimCombinationService services serve this purpose. The former can be used to release distinct products and product masters. The latter can be used to release product variants. A product master must be released before any of its product variants can be released.
{ ItemId = "Bulb60W", Product = "Bulb60W", Invent = new AxdEntity_Invent[1] { new AxdEntity_Invent() { ItemId = "Bulb60W", UnitId = "Box" } }, Purch = new AxdEntity_Purch[1] { new AxdEntity_Purch() { ItemId = "Bulb60W", UnitId = "Box" } }, Sales = new AxdEntity_Sales[1] { new AxdEntity_Sales() { ItemId = "Bulb60W", UnitId = "Pcs" } } }; AxdItem item = new AxdItem() { InventTable = new AxdEntity_InventTable[1] { inventTable } }; CallContext ctx = new CallContext() { Company = "DMO" }; ItemServiceClient itemService = new ItemServiceClient(); try { itemService.create(ctx, item); } catch (Exception e) { System.Console.WriteLine(e.Message); System.Console.ReadKey(); } }
For details, see the following examples. Use the product number of the product variant (DistinctProductVariant)
private static void releaseProductVariants() { AxdEntity_InventDimCombination releasedVariant = new AxdEntity_InventDimCombination() { DistinctProductVariant = "RunningShoeL", ItemId = "" }; AxdInventDimCombination inventDimCombination = new AxdInventDimCombination() { InventDimCombination = new AxdEntity_InventDimCombination[1] { releasedVariantL } }; CallContext ctx = new CallContext() { Company = "DMO" }; 25 DATA MIGRATION FOR MICROSOFT DYNAMICS AX 2012
InventDimCombinationServiceClient inventDimCombinationService = new InventDimCombinationServiceClient(); try { inventDimCombinationService.create(ctx, inventDimCombination); } catch (Exception e) { System.Console.WriteLine(e.Message); System.Console.ReadKey(); } }
Performance considerations
As the volume of data being imported increases, the use of a single-threaded service may not meet your performance needs. Each record in a synchronous service call is processed serially and does not take advantage of parallelism. The services stack has built-in support to run requests in parallel. However, you must use the Fie System Adapter rather than NetTcp. To do this, you will need to create the requests as .xml files, and leverage the BatchId and CoversationID in the .xml file. This process is documented in the MSDN topic Processing batched messages in AIF.
Microsoft Dynamics is a line of integrated, adaptable business management solutions that enables you and your people to make business decisions with greater confidence. Microsoft Dynamics works like and with familiar Microsoft software, automating and streamlining financial, customer relationship and supply chain processes in a way that helps you drive business success. U.S. and Canada Toll Free 1-888-477-7989 Worldwide +1-701-281-6500 www.microsoft.com/dynamics
This document is provided as-is. Information and views expressed in this document, including URL and other Internet Web site references, may change without notice. You bear the risk of using it. Some examples depicted herein are provided for illustration only and are fictitious. No real association or connection is intended or should be inferred. This document does not provide you with any legal rights to any intellectual property in any Microsoft product. You may copy and use this document for your internal, reference purposes. You may modify this document for your internal, reference purposes. 2012 Microsoft Corporation. All rights reserved.