Create customization to MYOBAdvanced(Acumatica), part 2 сreate page, graph, DAC class extension and xml page for mobile

So, continue the work:). Part 1 is here.

Part 2 сreate page, graph, DAC class extension and xml page for mobile

First of all, In project I create folder "DAC" and add two clasess:

  1. ActivityTypes.cs

This class need to filter types rows from table CRActivity(column name - Type). Client asked display all events for that Business Account of type "Phone Call", "Client Visit" and "Futile Visit" So for this I do next:

This constant types I will use in graph when will select all from table CRActivity.

     2. CRActivityExtension.cs

This class need for correct show "Body"(Comments) from table CRActivity. Some fields include html tags. To show clear text I do next:

public class CRActivityExt : PXCacheExtension<CRActivity>
        public abstract class bodyWithoutHtml : IBqlFieldIBqlOperand
        [PXUIField(DisplayName = "Activity Details")]
        [PXString(IsUnicode = true)]
        public virtual string BodyWithoutHtml { getset; }
        public abstract class usrBodyWithoutHtml : IBqlFieldIBqlOperand
        [PXUIField(DisplayName = "Activity Details Without Html")]
        [PXDBString(IsUnicode = true)]
        public virtual string UsrBodyWithoutHtml { getset; }

Please pay attention that for string - UsrBodyWithoutHtml I use PXDBString atrribute, it`s mean that field will be in database CRActivity. This field is necessary for mobile application. I don't know why, but mobile application weren't able to display field that was created dynamically.

Next step - create graph , .aspx page and mobile site map:

     1. ActivitiesMaint.cs

       #region Selector
       public PXSelect<BAccount,
       public PXSelect<CRActivity,            Where2<Where<CRActivity.bAccountIDEqual<Current<BAccount.bAccountID>>>,                And<Where<CRActivity.typeEqual<ActivityTypes.fType>,                    Or<CRActivity.typeEqual<ActivityTypes.mType>,                       Or<CRActivity.typeEqual<ActivityTypes.pType>>>>>>,        OrderBy<Desc<CRActivity.startDate>>> Activities;        protected IEnumerable activities()        {            var result = new PXSelect<CRActivity,                Where2<Where<CRActivity.bAccountIDEqual<Current<BAccount.bAccountID>>>,                    And<Where<CRActivity.typeEqual<ActivityTypes.fType>,                        Or<CRActivity.typeEqual<ActivityTypes.mType>,                            Or<CRActivity.typeEqual<ActivityTypes.pType>>>>>>,                OrderBy<Desc<CRActivity.startDate>>>(this).Select();                        foreach (PXResult<CRActivity> boxedActivity in result)            {                var activity = boxedActivity.GetItem<CRActivity>();                string cutted = StripTagsCharArray(activity.Body);                PXDatabase.Update<CRActivity>(                    new PXDataFieldRestrict<CRActivity.noteID>(activity.NoteID),                    new PXDataFieldAssign<CRActivityExt.usrBodyWithoutHtml>(cutted)                );            }            var result2 = new PXSelectReadonly<CRActivity,                Where2<Where<CRActivity.bAccountIDEqual<Current<BAccount.bAccountID>>>,                    And<Where<CRActivity.typeEqual<ActivityTypes.fType>,                        Or<CRActivity.typeEqual<ActivityTypes.mType>,                            Or<CRActivity.typeEqual<ActivityTypes.pType>>>>>>,                OrderBy<Desc<CRActivity.startDate>>>(this).Select();            return result2;        } #endregion

#region ClearHtml        public static string StripTagsCharArray(string source)        {            string result2 = "";            if (source == null)            {                source = "";            }            HtmlDocument htmlDoc = new HtmlDocument();            htmlDoc.LoadHtml(source);            if (htmlDoc.ParseErrors != null && htmlDoc.ParseErrors.Count() > 0)            {                // Handle any parse errors as required                result2 = "Text not correct";            }            else            {                if (htmlDoc.DocumentNode != null)                {                    HtmlAgilityPack.HtmlNode bodyNode = htmlDoc.DocumentNode.SelectSingleNode("//body");                    if (bodyNode != null)                    {                        result2 = htmlDoc.DocumentNode.SelectSingleNode("//body").InnerText;                    }                    else                    {                        result2 = source;                    }                }            }            return result2;        }    }    #endregion

Here I use 2 standart PXSelect from tables BAcount and CRActivity, and my IEnumerable method where I change text - strip html tags (StripTagsCharArray), and also use PXDatabase.Update for write text to column "UsrBodyWithoutHtml". 

About this(PXDatabase.Update, PXDataFieldRestrict<>, Where2) and how it work read in my blog.

One more interesting part is Method StripTagsCharArray. That method uses external library HtmlAgilityPack in order to strip html tags from text.

      2. AC601000.aspx page

After I go to web site and in folder Page create new folder "AC". In this folder I copy and paste structure of another .aspx page (becouse .aspx page include .aspx.cs file), rename to "AC601000" (Screenshot 6).

It looks like this:

<%@ Page Language="C#" MasterPageFile="~/MasterPages/FormDetail.master" AutoEventWireup="true" ValidateRequest="false" 
	CodeFile="AC601000.aspx.cs" Inherits="Page_AC601000" Title="Untitled Page" %>
<%@ MasterType VirtualPath="~/MasterPages/FormDetail.master" %>
<asp:Content ID="cont1" ContentPlaceHolderID="phDS" runat="Server">
	 <px:PXDataSource ID="ds" runat="server" Visible="True" SuspendUnloading="False" 
		 TypeName="RayTaylor.Acumatica.ActivitiesMaint" PrimaryView="BAccount">
<asp:Content ID="cont2" ContentPlaceHolderID="phF" Runat="Server">
	<px:PXFormView ID="form" runat="server" Width="100%" Caption="Account Summary"
				   DataMember="BAccount" DataSourceID="ds" NoteIndicator="True" LinkIndicator="True"
				   NotifyIndicator="True" FilesIndicator="True" DefaultControlID="edAcctCD">
			<px:PXLayoutRule ID="PXLayoutRule1" runat="server" StartColumn="True" LabelsWidth="SM"
							 ControlSize="XM" />
			<px:PXSegmentMask ID="edAcctCD" runat="server" DataField="AcctCD" AutoRefresh="True"
							  FilterByAllFields="True" />
			<px:PXTextEdit CommitChanges="True" ID="edAcctName" runat="server" DataField="AcctName" />
<asp:Content ID="cont3" ContentPlaceHolderID="phG" runat="Server">
	<px:PXGrid  ID="gridRT"   runat="server"  Height="600px" Width="100%"   Style="z-index100;"
				AllowPaging="True" AllowSearch="True" AdjustPageSize="Auto" DataSourceID="ds" SkinID="Primary" TabIndex="800" TemporaryFilterCaption="Filter Applied">
			<px:PXGridLevel DataKeyNames="BaccountID" DataMember="Activities">
					<px:PXTextEdit ID="edBodyWithoutHtml" runat="server" AlreadyLocalized="False" DataField="BodyWithoutHtml" DefaultLocale="">
					<px:PXGridColumn DataField="StartDate" Width="100px" AllowFilter="True" Multiline="True">
						<ValueItems MultiSelect="False">
					<px:PXGridColumn DataField="Subject" Width="200px" Multiline="True">
						<ValueItems MultiSelect="False">
					<px:PXGridColumn DataField="UsrBodyWithoutHtml" Width="400px" Multiline ="True">
						<ValueItems MultiSelect="False"  >
		<AutoSize Container="Window" Enabled="True" MinHeight="200" />

Look that in "cont3" in last field I use my "UsrBodyWithoutHtml" from CRActivity class extension. Take note on the following fragment:

Multiline ="True"

of is set to true. It allows to display multiple lines instead of one cutted line.

Now I can launch the web site, go to System - Customization - Site Map, and add new row (Scrennshot 7):

So, if open web site - page AC601000 will be look like this Screenshot 8:

      3. Comments.xml

To create page for mobile device I go to App_Data - Mobile, and create page - "Comments.xml" (Screenshot 9):

Page look like this:

<?xml version="1.0" encoding="UTF-8"?>
<sm:SiteMap xmlns:sm="" xmlns:xsi="">
	<sm:Screen Id="AC601000" Type="SimpleScreen" DisplayName="AccountDetails" Visible="true" Icon="system://NewsPaper" IsDefaultFavorite="true">
		<sm:Container Name="AccountSummary" FieldsToShow="1">
			<sm:Attachments Disabled="true" />
			<sm:Field Name="AccountID" />
			<sm:Field Name="AccountName" />
			<sm:Action Name="Save" Context="Record" Behavior="Save" />
			<sm:Action Name="Cancel" Context="Record" Behavior="Cancel" />
			<sm:Action Name="Insert" Context="Container" Behavior="Create" DisplayName="Add" Icon="system://Plus"/>
		<sm:Container Name="Activities">
			<sm:Attachments Disabled="true" />
			<sm:Field Name="StartDate"/>
			<sm:Field Name="Summary" ForceType="String"/>
			<sm:Field Name="ActivityDetailsWithoutHtml"  ForceType="String"/>
			<sm:Action Name="Save" Context="Record" Behavior="Save" />
			<sm:Action Name="Cancel" Context="Record" Behavior="Cancel" />
			<sm:Action Name="Insert" Context="Container" Behavior="Create" DisplayName="Add" Icon="system://Plus"/>
			<sm:Action Name="Delete" Context="Selection" Behavior="Delete" DisplayName="Delete"/>


As if everything is done and everything works. I can go to next part 3 - create customazation for import and test it.

Add comment