This post will provide some steps on using the MBF Result Viewer API to pass data to the Dynamics GP Web Services. The specific example shows how you can remove a line item from a Sales Order using the UpdateSalesOrder method. The sales order number, line sequence number, and item number can be pulled off the Rich List Result Viewer web part and passed to the web services.
The Result Viewer API is discussed in the BPIntegrationGuide.pdf file on the Business Portal 3.0 CD and also available on MSDN. The first step is to use a handwritten htm file that will render the Rich List result viewer in a Page Viewer web part. The htm file will also include a button in the task area of the web part. The button event will open a custom ASPX page and provides the sales order line item data using QueryString parameters.
The following is a screen shot of the finished web part and the code in the htm file:
<%@ page language="C#" autoeventwireup="true" inherits="LineItems, App_Web_zymlzqk_" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html XMLNS:RL> <head runat =server> <?IMPORT namespace="RL" implementation="/BusinessPortal/UI/ResultViewer/Scripts/Rich.htc"/> <title>Rich List</title> <script> function OnRichList16Ready() { //Add a stylesheet. RichList16.AddStyleSheet("/BusinessPortal/UI/ResultViewer/Stylesheets/RichList.css"); //Add a button var button = RichList16.ActionButtons.AddButton(); button.ButtonValue = "Remove Line"; button.ButtonTitle = "Click to remove selected line item."; button.OnAction = RemoveLineItem;
} function RemoveLineItem() { if (RichList16.API.SelectedRow == -1) { alert("A sales document must be selected."); } else { var sFeatures = "scrollbars=yes,resizable=yes,height=600px,width=800px,status=yes"; var theWindow = window.open('/BusinessPortal/Applications/SalesDocIntegration/UpdateSalesDoc.aspx?SalesDocumentID=' + RichList16.API.Key(RichList16.API.SelectedRow, 0) + '&LineSeqNumber=' + RichList16.API.Key(RichList16.API.SelectedRow, 2) + '&ItemNumber=' + RichList16.API.GetValue(RichList16.API.SelectedRow, 1), null, sFeatures); RichList16.API.Refresh(); } } </script> </head> <body style="margin:0"> <RL:Rich id="RichList16" SupportsAutoRefresh="true" EventNameSpace="Microsoft.Dynamics.SalesOrder.Transaction.SalesDocument" AutoRefresh="1" SupportsPageSize="true" PageSize="25" HasFind="true" HasHeader="true" HasActionButtons="true" QueryServiceURL="/BusinessPortal/QueryWebService.asmx?WSDL" InitialQuery="/DataViewer/Sales Document Integration/Line Items Per Sales Document" UseLegacySubscribe="true" OnReady="OnRichList16Ready()" /> </body></html>
In the window.open method, a URL to the UpdateSalesDoc.aspx page is passed along with the SalesDocumentID, LineSeqNumber, and ItemNumber parameters. To retrieve these data values from the selected row in the web part, there is one property and two methods of the Result Viewer API that are used that I will further explain below.
The SelectedRow property returns the zero-based index of the currently selected row of the web part. So if you are on the third row of the web part it will return a 2. The first row would return a 0.
The Key method takes a int value that represents the row and another int value that represents the segment of the key. It returns the value of the key segment in the query specified by the zero-based row and key index. In the code example, the query is using the Sales Document entity. The Sales Document entity key is made up of the Document Number for the first segment and Document Type for the second segment. Additionally, the Sales Document Line details are being pulled in the query so the third segment of the key is the Line Sequence Number.
The GetValue method takes a int value that represents the row and another int value that represents the column. It returns the value of the cell in the grid specified by the zero-based row and column. In the code example, I am passing a 1 for the column value since the Item Number is the second column in the query.
I will move on to using the Web Services for Dynamics GP to update the Sales Order where the selected line item is removed. It is important to follow the white paper steps for the building and configuration of the .Net application in Business Portal and to leverage session information like the current company I am logged into in Business Portal. I will provide the code below that takes the document number, line sequence number, and item number values from the query string to the UpdateSalesOrder method call:
using System;using System.Collections;using System.Configuration;using System.Data;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.HtmlControls;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;
using DynamicsGPService;using System.Web.Services.Protocols;using Microsoft.BusinessFramework;using Microsoft.BusinessFramework.Entity;
public partial class UpdateSalesDoc : System.Web.UI.Page{
protected void Page_Load(object sender, EventArgs e) { this.docNumberLabel.Text = Request.QueryString["SalesDocumentID"]; this.lineSeqLabel.Text = Request.QueryString["LineSeqNumber"]; this.segmentsLabel.Text = Request.QueryString["KeySegments"]; this.itemLabel.Text = Request.QueryString["ItemNumber"]; } protected void Button1_Click(object sender, EventArgs e) { Response.Write("<script>window.close()</script>"); } protected void deleteButton_Click(object sender, EventArgs e) { CompanyKey companyKey; Context context; SalesDocumentKey salesOrderKey; SalesOrder salesOrder; SalesOrderLine salesOrderLine; Policy salesOrderUpdatePolicy;
// Create an instance of the web service DynamicsGP wsDynamicsGP = new DynamicsGP();
// Be sure the default credentials are used wsDynamicsGP.UseDefaultCredentials = true;
// Create a context with which to call the web service context = new Context();
// Specify which company to use (sample company) companyKey = new CompanyKey(); companyKey.Id = this.GetDBID();
// Set up the context object context.OrganizationKey = (OrganizationKey)companyKey; context.CultureName = "en-US";
// Create a sales document key salesOrderKey = new SalesDocumentKey(); salesOrderKey.Id = this.docNumberLabel.Text;
try {
// Retrieve the sales order salesOrder = wsDynamicsGP.GetSalesOrderByKey(salesOrderKey, context);
// Create the line ItemKey
ItemKey itemKey = new ItemKey(); itemKey.Id = this.itemLabel.Text;
// Create the line for removal salesOrderLine = new SalesOrderLine(); salesOrderLine.Key = new SalesLineKey(); salesOrderLine.Key.LineSequenceNumber = Convert.ToInt32(this.lineSeqLabel.Text); salesOrderLine.Key.SalesDocumentKey = salesOrderKey; salesOrderLine.DeleteOnUpdate = true; salesOrderLine.ItemKey = itemKey;
// Create an array of sales order lines // Initialize the array with the sales order line object SalesOrderLine[] lineToRemove = { salesOrderLine };
// Add the sales order line array to the sales line object salesOrder.Lines = lineToRemove;
// Retrieve the update policy for sales orders salesOrderUpdatePolicy = wsDynamicsGP.GetPolicyByOperation("UpdateSalesOrder", context);
// Update the sales order object wsDynamicsGP.UpdateSalesOrder(salesOrder, context, salesOrderUpdatePolicy);
statusLabel.Text = "Line removed successfully!";
}
catch (SoapException se) { statusLabel.Text = se.Message + se.StackTrace;
catch (Exception ex1) { statusLabel.Text = ex1.Message + ex1.StackTrace;
public int GetDBID() { int dbID; EntityKey eK; eK = (Microsoft.Dynamics.Common.Company.Company.Key)EnterpriseSession.DefaultParentKey; Microsoft.Dynamics.Common.Company.Company company = (Microsoft.Dynamics.Common.Company.Company)eK.GetEntity(); dbID = company.ID; return dbID; }}
// Copyright © Microsoft Corporation. All Rights Reserved.// This code released under the terms of the // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
At Developing for Dynamics GP, Chris Roehrich of Microsoft has some great information on passing data
Posting from the Dynamics GP Blogster
http://dynamicsgpblogster.blogspot.com/2009/01/developing-for-dynamics-gp-weekly_24.html
PLEASE READ BEFORE POSTING
Please only post comments relating to the topic of this page.
If you wish to ask a technical question, please use the links in the links section (scroll down, on right hand side) to ask on the Newsgroups or Forums. If you ask on the Newsgroups or Forums, others in the community can respond and the answers are available for everyone in the future.