sage crm developers course using the.net api (2)

49
Sage CRM Developers Course Using the .NET API (2)

Upload: roland-obrien

Post on 24-Dec-2015

234 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Sage CRM Developers Course Using the.NET API (2)

Sage CRM Developers Course

Using the .NET API (2)

Page 2: Sage CRM Developers Course Using the.NET API (2)

Looking ahead to the classes

DP01: Introduction to the Development Partner Program

DP02: Entities and the Data Model (Part 1 of 2)

DP03: Entities and the Data Model (Part 2 of 2)

DP04: Implementing Screen Based Rules (Part 1 of 2)

DP05: Implementing Screen Based Rules (Part 2 of 2)

DP06: Screen and User Independent Business Rules

DP07: Workflow (Part 1 of 2)

DP08: Workflow (Part 2 of 2)

DP09: Using the API Objects in ASP Pages (Part 1 of 2)

DP10 : Using the API Objects in ASP Pages (Part 2 of 2)

DP11: Using the Component Manager

DP12: Programming for the Advanced Email Manager

DP13: Using the Web Services API

DP14: Using the Web Services API (Part 2 of 2)

DP15: Coding the Web Self Service COM API (Part 1 of 2)

DP16: Coding the Web Self Service COM API (Part 2 of 2)

DP17: Using the .NET API (Part 1 of 2)

DP18: Using the .NET API (Part 2 of 2)

Page 3: Sage CRM Developers Course Using the.NET API (2)

Agenda

The Specialised ClassesListPageDataPageDataPageEditDataPageDeleteDataPageNewSearchPage

Workflow using the .Net APICustomizing the Specialised Classes

Programmatic Control of Screens

Building Complex PagesControlling Screen Positioning

Page 4: Sage CRM Developers Course Using the.NET API (2)

The Specialised Classes

Page 5: Sage CRM Developers Course Using the.NET API (2)

ListPage

Page 6: Sage CRM Developers Course Using the.NET API (2)

ListPage

using System;using System.Collections.Generic;using System.Text;using Sage.CRM.WebObject;

namespace crm72a{public class OppoListPage : ListPage{public OppoListPage(): base("opportunity", "opportunitylist", "opportunityfilterbox"){FilterByField = "oppo_assigneduserID";FilterByContextId = (int)Sage.KeyList.UserId;}

}

}

Page 7: Sage CRM Developers Course Using the.NET API (2)

DataPage

Page 8: Sage CRM Developers Course Using the.NET API (2)

DataPage

using System.Collections.Generic;using System.Text;using Sage.CRM.WebObject;using Sage.CRM.Data;

namespace crm72a{public class myDataPage : DataPage{public myDataPage(): base("company", "comp_companyid", "companyboxshort"){this.UseEntityTabs = true;this.UseWorkflow = true;

this.EditMethod = "RunDataPageEdit";this.ContinueMethod = "RunListPage";}

}}

Allows complex screens to be built using simple DataPage class

Page 9: Sage CRM Developers Course Using the.NET API (2)

DataPageEdit

Page 10: Sage CRM Developers Course Using the.NET API (2)

DataPageEdit

using System.Collections.Generic;

using System.Text;

using Sage.CRM.WebObject;

namespace myProject{ public class myClass : DataPageEdit { /* Constructor needs EntityName, IdField and ScreenName

*/ public myClass()

: base("xxxxTableName", "xxxx_fieldname", "xxxxScreenName") { this.UseEntityTabs = true; this.UseWorkflow = true;

this.CancelMethod = "RunListPage"; this.DeleteMethod = "RunDataPageDelete"; this.SaveMethod = "RunDataPage"; } }}

Page 11: Sage CRM Developers Course Using the.NET API (2)

DataPageDelete

Page 12: Sage CRM Developers Course Using the.NET API (2)

DataPageDelete

using System.Collections.Generic;

using System.Text;

using Sage.CRM.WebObject;

namespace myProject

{

public class myClass : DataPageDelete

{

/* If inherited from DataPageDelete then just need to set the EntityName, IdField and ScreenName

*/

public myClass()

: base("xxxxTableName", "xxxx_fieldname", "xxxxScreenName")

{

this.CancelMethod = "RunListPage";

this.DeleteMethod = "RunDataPage";

}

}

}

Page 13: Sage CRM Developers Course Using the.NET API (2)

DataPageNew

Page 14: Sage CRM Developers Course Using the.NET API (2)

DataPageNew

using System.Collections.Generic;using System.Text;using Sage.CRM.WebObject;using Sage.CRM.Controls;using Sage.CRM.Data;

namespace myProject{ public class myClass : DataPageNew { public myClass() : base("xxxxTableName", "xxxx_fieldname", "xxxxScreenName") { this.SaveMethod = "RunDataPage"; this.UseWorkflow = true; this.WorkflowName = "Entity Workflow"; this.WorkflowState = "NewRecord"; } public override void AfterSave(EntryGroup screen) { /*Record recNewOppo = screen.getRecord; *recNewOppo.SetField("xxxxx_companyid", int.Parse(GetContextInfo("company", "comp_companyid"))); *recNewOppo.SetField("xxxxx_personid", int.Parse(GetContextInfo("company", "comp_primarypersonid"))); *recNewOppo.SaveChanges(); */ base.AfterSave(screen); } }}

Page 15: Sage CRM Developers Course Using the.NET API (2)

SearchPage

Page 16: Sage CRM Developers Course Using the.NET API (2)

SearchPage

using System.Collections.Generic;using System.Text;using Sage.CRM.WebObject;

namespace myProject{ public class myClass : SearchPage {

/*if descended from SearchPage then you just need to set the * appropriate ListName and SearchBoxName */ public myClass() : base("xxxxSearchBoxName", "xxxxListName") { this.SavedSearch = true;

/* ************* * Other objects available include: * * SearchScreen * ResultsGrid */ } }}

Page 17: Sage CRM Developers Course Using the.NET API (2)

Search Screen Additional Components

Saved Search available

Keyword Search available

Clear Button automatic in class

Create New GroupRequires additional custom coding by developer

ActionsRequires additional custom coding by developer

Page 18: Sage CRM Developers Course Using the.NET API (2)

Workflow using the .Net API

Page 19: Sage CRM Developers Course Using the.NET API (2)

Workflow in DataPages

Controlled by properties of Specialised Classes

DataPageBase

UseWorkflow

DataPage

isWorkflowPostBack

DataPageEdit

WorkflowScreen

DataPageNew

WorkflowName

WorkflowState

Page 20: Sage CRM Developers Course Using the.NET API (2)

Calling Custom ASP and .NET Workflow Behaviour

ASP pages and .NET assemblies may only be called by user driven rules (Primary, Transitional, Global) and may not be invoked by Escalation rules.

Can either call ASP page or .NET assembly

Workflow actions would be ignored

Jscript conditions maybe used to control availability of rule

Page 21: Sage CRM Developers Course Using the.NET API (2)

Customizing the Specialised Classes

Page 22: Sage CRM Developers Course Using the.NET API (2)

Programmatic Control of Screens

Adding Conditional Behaviour to a screenControlling the display of data elements

Adding and removing default buttons

Adding Custom controls to screens– Buttons and Hyperlinks (Save, Cancel, Help, Clear etc)

Adding/Removing Fields from screens and lists

Interacting with existing CRM information (TopContent and (recent) menus)

Page 23: Sage CRM Developers Course Using the.NET API (2)

Sage.CRM.Controls

The Sage.CRM.Controls namespace provides access to screen components to allow programmatic update of propertiesEntry– Fields within a Meta Data defined screen

EntryGroup– Control of HTML returned and interaction with component Fields (Entry)

GridCol– Columns within a Meta Data defined list

List– Control of the HTML returned and interaction with component Columns (GridCol)

Page 24: Sage CRM Developers Course Using the.NET API (2)

Interacting with the Screens

When you call AddEntryGroup (c.f. DataPage) it stores up all the names of the entry groups that you have added in the array called EntryGroups Contains EntryGroup objects for each screen.

Can reference EntryGroups array in BuildContents

In ListPage can access

ResultsGrid

Screen Fields

EntryGroup mygroup = EntryGroups[1];Entry newE = mygroup.CreateEntry("oppo_createddate");base.BuildContents();

List Columns

for (int i = 0; i < ResultsGrid.Count; i++) { if (ResultsGrid[i].Name == "oppo_stage") { ResultsGrid[i].ShowHeading = false; break; } }

Page 25: Sage CRM Developers Course Using the.NET API (2)

Linking GridCols to ASP and .NET

To link to an ASP page

GridCol colOppoStatus = this.ResultsGrid[0]; colOppoStatus.JumpAction = 430; colOppoStatus.CustomActionFile = "CRMtest.asp"; colOppoStatus.CustomIdField = "oppo_opportunityid";

To call a CustomDotNet dll

GridCol colOppoStatus = this.ResultsGrid[0]; colOppoStatus.JumpAction = 432; colOppoStatus.CustomActionFile = "CRMtest&dotnetfunc=RunOppoSummary"; colOppoStatus.CustomIdField = "oppo_opportunityid";

Page 26: Sage CRM Developers Course Using the.NET API (2)

User Screen TopContent

Custom EntityGetCustomEntityTopFrame("Project");

User Screen control HTMLString strFieldText = new HTMLString("<span class=TOPCAPTION>Custom Entity Information</span>");

VerticalPanel panelFields = new VerticalPanel();

panelFields.Add(strFieldText);

ImageObject myEntityImage = new ImageObject(CurrentUser.VirtualImgPath() + "Icons/company.png");

this.AddTopContent(new HorizontalPanel(myEntityImage, panelFields));

Page 27: Sage CRM Developers Course Using the.NET API (2)

Admin Screen TopContent

//change the breadcrumb trail as needed;

string strCrumbTrail = "<A CLASS=TOPBC TARGET = EWARE_MID HREF=" + Url("1650") + "&MenuName=Admin&BC=Admin,Admin>Administration</A> ->";

strCrumbTrail += "&nbsp;<A CLASS=TOPBC TARGET = EWARE_MID HREF=" + Url("1650") + "&MenuName=AdminSystem&BC=Admin,Admin,AdminSystem,System>System</A> ->";

strCrumbTrail += "&nbsp;<A CLASS=TOPBC TARGET = EWARE_MID HREF=" + UrlDotNet(ThisDotNetDll, ThisDotNetFunction) + "&MenuName=Admin&BC=Admin,Admin,AdminSystem>My Admin</A> ->";

HTMLString strFieldText = new HTMLString(strCrumbTrail);

VerticalPanel panelFields = new VerticalPanel();

panelFields.Add(strFieldText);

ImageObject myEntityImage = new ImageObject(CurrentUser.VirtualImgPath() + "Icons/admin.png");

this.AddTopContent(new HorizontalPanel(myEntityImage, panelFields));

Page 28: Sage CRM Developers Course Using the.NET API (2)

Button Types

Main Default ButtonsAddEditButtonAddHelpButtonAddDeleteButtonAddContinueButtonAddSaveButtonAddCancelButton

Custom ButtonsAddConfirmButton("CaptionCode","Image.gif","Question");AddConfirmButton("CaptionCode","Image.gif","Question","fieldname","fieldvalue");

AddSubmitButton("CaptionCode","Image.gif","javascript")AddSubmitButton("CaptionCode","Image.gif","fieldname","fieldvalue");

AddUrlButton("CaptionCode","Image.gif","URL");

string test = "/Main Menu/wwhelp/wwhimpl/js/html/wwhelp.htm?href=AddingInformation.html";AddHelpButton(test);

Page 29: Sage CRM Developers Course Using the.NET API (2)

Special Help Method

Add the help button

AddHelpButton("help.htm");

In CRM - turn on inline translation mode and go to your dot net dll page with the help button on it.

Click the help button and the list of available help files will be displayed.

Select the desired help file and save.

Turn off inline translation mode and your help button on your .net dll page will launch the help file you selected previously.

Page 30: Sage CRM Developers Course Using the.NET API (2)

Overriding Button Behaviour

ExamplesAddEditButton public override void AddEditButton(){string sUrl = UrlDotNet(ThisDotNetDll, "RunEditOpportunity"); AddUrlButton("Edit", "Edit.gif", sUrl);}

AddContinueButtonpublic override void AddContinueButton(){//base.AddContinueButton();//string sUrl = UrlDotNet(ThisDotNetDll, "RunDeleteOpportunity"); string sUrl = Url("184"); ; AddUrlButton("Continue", "Continue.gif", sUrl);}

Tip:Ensure Base.AddCancelButton is commented out to stop default behaviour being implemented

Page 31: Sage CRM Developers Course Using the.NET API (2)

Dealing with Security Policy

For example adding Custom Button to a Screen

Delete, Editif (CurrentUser.IsInRange(Sage.PermissionType.Delete, "EntityName", TerritoryId,AssignedToUserId, AssignedToTeamId, CreatedByUserId))

{

string sUrl = UrlDotNet(ThisDotNetDll, "RunCustomAction");

AddUrlButton("Continue", "Continue.gif", sUrl);

}

New ButtonCurrentUser.HasRights(Sage.PermissionType.Insert, "Entity");

Page 32: Sage CRM Developers Course Using the.NET API (2)

Custom Validation

Can override the Validate method to add your own validationMust always call the base validation method as this checks for required fields.

public override bool Validate(){//Always call the base validation method as it checks for required fieldsBoolean ok = base.Validate();if (ok){//do my validation here! //Check values on screen with Dispatch.ContentField("fieldname");

string name = Dispatch.ContentField("core_name");if (name == "aaa"){ok = false;AddError("The name cannot be aaa");}}return ok;}

Page 33: Sage CRM Developers Course Using the.NET API (2)

Overriding the AfterSave()

public override void AfterSave(EntryGroup screen) { Record recNewOppo = EntryGroups[0].getRecord; recNewOppo.SetField("oppo_primarycompanyid", int.Parse(GetContextInfo("company","comp_companyid"))); recNewOppo.SetField("oppo_primarypersonid", int.Parse(GetContextInfo("company", "comp_primarypersonid")));

recNewOppo.SaveChanges(); base.AfterSave(screen); }

Page 34: Sage CRM Developers Course Using the.NET API (2)

Intercepting the SaveChanges()

Override of the EntryGroups_FillRecordFromContent method

public override void EntryGroups_FillRecordFromContent(Sage.CRM.Data.Record info)

{

base.EntryGroups_FillRecordFromContent(info);

info.SetField("core_name", "Override the core name");

info.SetField("core_Status", "Logged");

}

Page 35: Sage CRM Developers Course Using the.NET API (2)

Building Complex Pages

Page 36: Sage CRM Developers Course Using the.NET API (2)

Typical Web Page Tasks

Building Pages without Reference to Meta Data

Data TasksCloning and copying data– E.g. Copying a Case– Cloning a Report or Group

Custom Complex PagesMulti-Entity Edit or Entry ScreensMultiple Lists on Page Interaction with 3rd Party Apps via COM or web services API including screen scraping from legacy systems

Rebuild of Company Quicklook showing inclusion of custom entity

Demonstration of dll called via workflow e.g. Opportunity Workflow

Rebuild of the Company Summary Screen

Editable grid example e.g. quick editing/entry of contacts in company

Custom Import example e.g. Importing folder contents to create library entries

List with check boxes (to allow batch tasks)

Listing and Notes with a Custom Entity

Compound Entry Screen quick entry of company with oppo/case details

Page 37: Sage CRM Developers Course Using the.NET API (2)

Sage.CRM.Data

Specialised Web Classes referencing Meta Data screens and lists automatically imply Data Interaction

Explicit control of Data Interaction provided by Record and Entity classes within Sage.CRM.Data namespaceRecord– Allows individual records and data sets to be handled for Create, Read and Update and

DeleteEntity– Allows compound entities to be handled in a unified manner

– E.g. Insert of Company together with Person, Address, Phone, Email and intersection table records

Page 38: Sage CRM Developers Course Using the.NET API (2)

Record Handling

FindCurrentRecord(tablename)gets current record FindRecord(tablename, whereclause) gets the record specified by where clause (like the existing COM)

Page 39: Sage CRM Developers Course Using the.NET API (2)

Data Handling Changes

EntryGroup screenPersonBoxShort = new EntryGroup(“CompanyBoxShort");compGroup.Fill (compRec);

QuerySelect PhonQuery = GetQuery();PhonQuery.SQLCommand=querySQL;PhonQuery.ExecuteReader();//PhonQuery.ExecuteNonQuery();

Page 40: Sage CRM Developers Course Using the.NET API (2)

Usage

Record objectFindCurrentRecord(“Tablename”)FindCurrentEntity(“EntityName”)FindRecord(“TableName”,”WhereClause”)– record set maybe returned

Record NewUserConRec = new Record("UserContacts");

Specialised ClassesCreateAppointment()CreateTask()

Record OppoRecords = FindRecord("opportunity", "oppo_assigneduserid=" + CurrentUser.UserId);

while (!OppoRecords.Eof())

{

AddContent(OppoRecords.GetFieldAsString("oppo_description"));

OppoRecords.GoToNext();

}

Page 41: Sage CRM Developers Course Using the.NET API (2)

Sage.CRM.HTML

Building forms, fields and tables with out reference to meta data

UI control

Page 42: Sage CRM Developers Course Using the.NET API (2)

Creating Lists and Screens

ListList CommList = new List("CommunicationList");

ScreenEntryGroup compGroup = new EntryGroup("companyboxlong");

Page 43: Sage CRM Developers Course Using the.NET API (2)

Filtering of Lists

AddContent(HTML.Form());

AddContent(HTML.StartTable());

GetTabs();

List CommList = new List("CommunicationList");

CommList.RowsPerScreen = 4;

CommList.ShowNavigationButtons = false;

CommList.Filter = "cmli_comm_companyid =" + Dispatch.EitherField("key1");

AddContent(HTML.GridData(CommList.ToHtml()));

AddContent(HTML.EndTable());

Page 44: Sage CRM Developers Course Using the.NET API (2)

Controlling PositioningUsing objects in the Sage.CRM.UI namespace

Page 45: Sage CRM Developers Course Using the.NET API (2)

Use of Vertical Panel

using System;

using System.Collections.Generic;

using System.Text;

using Sage.CRM.WebObject;

using Sage.CRM.UI;

using Sage.CRM.Data;

using Sage.CRM.Controls;

namespace CRM62a

{

class OpportunityQuotes : Web

{

public override void BuildContents()

{

GetTabs();

VerticalPanel vp = new VerticalPanel();

vp.AddAttribute("width", "100%");

Record oppRecord = FindCurrentRecord("Opportunity");

EntryGroup oppScreen = new EntryGroup("OpportunityDetailBox");

oppScreen.Title = "Opportunity Detail";

oppScreen.Fill(oppRecord);

vp.Add(oppScreen);

List quotesGrid = new List("QuotesGrid");

quotesGrid.SelectSql = "Select * From quotes";

quotesGrid.Filter = "Quot_Opportunityid = " + oppRecord.GetFieldAsString("Oppo_OpportunityId");

vp.Add(quotesGrid);

AddContent(vp);

}

}

}

Page 46: Sage CRM Developers Course Using the.NET API (2)

Compounding Pages

When using Panels must convert to UI objectHorizontalPanelVerticalPanel

VerticalPanel myPipeandList = new VerticalPanel();HTMLString myPipeLine = new HTMLString();myPipeLine.Html = myPipe.Execute();myPipeandList.Add(myPipeLine);

HorizontalPanel myListandFilter = new HorizontalPanel();EntryGroup oppoFilter = new EntryGroup("OpportunityFilterBox");HTMLString FilterBoxHTML = new HTMLString();FilterBoxHTML.Html = oppoFilter.GetHtmlInEditMode();myListandFilter.Add(FilterBoxHTML);

Page 47: Sage CRM Developers Course Using the.NET API (2)

Q&AQ&A

Page 48: Sage CRM Developers Course Using the.NET API (2)

Looking ahead to the classes

DP01: Introduction to the Development Partner Program

DP02: Entities and the Data Model (Part 1 of 2)

DP03: Entities and the Data Model (Part 2 of 2)

DP04: Implementing Screen Based Rules (Part 1 of 2)

DP05: Implementing Screen Based Rules (Part 2 of 2)

DP06: Screen and User Independent Business Rules

DP07: Workflow (Part 1 of 2)

DP08: Workflow (Part 2 of 2)

DP09: Using the API Objects in ASP Pages (Part 1 of 2)

DP10 : Using the API Objects in ASP Pages (Part 2 of 2)

DP11: Using the Component Manager

DP12: Programming for the Advanced Email Manager

DP13: Using the Web Services API

DP14: Using the Web Services API (Part 2 of 2)

DP15: Coding the Web Self Service COM API (Part 1 of 2)

DP16: Coding the Web Self Service COM API (Part 2 of 2)

DP17: Using the .NET API (Part 1 of 2)

DP18: Using the .NET API (Part 2 of 2)

Page 49: Sage CRM Developers Course Using the.NET API (2)