Stephen Smith's Blog

Musings on Machine Learning…

Posts Tagged ‘sdk

Sage 300 Web UI SDK – Adding UI Controls

with 11 comments


In my last posting I showed how to quickly create an empty Sage 300 Web UI by running our two new wizards from Visual Studio. In this article we’ll look at how to add some visual controls to this project and talk a bit about some of the issues with doing this, namely about using our provided HTML helper functions and CSS styling.

We’re basically going to continue on and add the visual elements for the PJC Cost Types setup screen. We won’t write any JavaScript yet, so the only functionality will be that provided by the code generator and the default data binding support. This still give quite a bit as you can navigate, use the finder, delete records and save updates.

The UI Wizard discussed last week produces a simple starting page with the standard heading controls, the key field and the Save and Delete buttons. These are all wired up to Javascript and working. This makes our life much easier when adding the rest of the controls.

The only thing you need to do manually is change the Starting Page to: “/OnPremise/PM/CostType” on the Web tab of the Web project’s properties. Then it will compile and run yielding:


Adding the Parts

ASP.Net MVC Razor Views are a technique to dynamically generate our HTML by embedding C# code in an HTML template. When the HTML needs to go to the browser the C# code is executed and it usually generates more HTML into the template, so that pure dynamically generated HTML is transmitted to the Browser. The Razor View system is very extensible and it allows a lot of extensibility which we do by adding a large set of helper functions.

Below is the screen once we add some more controls. I showed with a record loaded since that part works with the generated code. The dates and bottom combo box aren’t working yet since we need to add some JavaScript code to help them out.


The source code for this screens Razor View (the partial view part) is:

(That didn’t work so well. Apparently WordPress ate all the div’s, I’ll do a bit of research to see if I can fix this, so a bit is missing from the below code. I also added some line breaks so the code doesn’t go off the right of the page).

@* Copyright © 2015 Sage *@
@model Sage.Web.Areas.PM.Models.CostTypeViewModel<Sage.PM.Models.CostType>
@using Sage.PM.Resources.Forms

@using Sage.CA.SBS.ERP.Sage300.Common.Web.AreaConstants
@using Sage.CA.SBS.ERP.Sage300.Common.Resources
@using Sage.CA.SBS.ERP.Sage300.Common.Web.HtmlHelperExtension
@using Sage.CA.SBS.ERP.Sage300.Common.Models.Enums
@using AnnotationsResx = Sage.CA.SBS.ERP.Sage300.Common.Resources.AnnotationsResx

@Html.ConvertToJsVariableUsingNewtonSoft("CostTypeViewModel", Model)

<section class="header-group">
    @Html.SageHeader3Label("CostTypeHeader", CostTypeResx.Entity)
    @if (Model.UserAccess.SecurityType.HasFlag(SecurityType.Modify))
        @Html.KoSageButton("btnNew", null, new { @value = CommonResx.CreateNew, @id = "btnNew",
             @class = "btn-primary" })
    @Html.Partial(Core.Menu, Model.UserAccess)

<section class="required-group">
    @Html.SageLabel(CommonResx.RequiredLegend, new { @class = "required" })

  @Html.SageLabel("CostTypeCode", CostTypeResx.CostTypeCode, new { @class = "required" })
  @Html.KoSageTextBoxFor(model => model.Data.CostTypeCode, new { @sagevalue = "Data.CostTypeCode",
      @valueUpdate = "'input'" }, new { @id = "txtCostTypeCode", @class = "default txt-upper",
      @formatTextbox = "alphaNumeric" })
  @Html.KoSageButton("btnLoadCostTypeCode", null, new { @id = "btnLoad", @class = "icon btn-go",
      @tabindex = "-1" })
  @Html.KoSageButton("btnFinderCostTypeCode", null, new { @class = "icon btn-search",
      @id = "btnFinderCostTypeCode", @tabindex = "-1" })
  @Html.ValidationMessageFor(model => model.Data.CostTypeCode)

@* End of generated header, next is code I wrote. *@

    @Html.SageLabelFor(model => model.Data.Description)
    @Html.KoSageTextBoxFor(model => model.Data.Description, new { @value = "Data.Description",
        @valueUpdate = "'input'" }, new { @id = "tbDescription", @class = "large" })
    @Html.ValidationMessageFor(model => model.Data.Description, null)

   @Html.SageLabelFor(model => model.Data.LastMaintained)
   @Html.KoSageTextBoxFor(model => model.Data.LastMaintained, new {
       @value = "Data.ComputedLastMaintainedDate" }, new { @disabled = "true", @class = "default" })

    @Html.KoSageCheckBox("chkStatus", false, new { @sagechecked = "Data.Status" },
         new { @id = "chkStatus" })
    @Html.SageLabel(CommonResx.InactiveAsOfDate, null, new { @for = "chkStatus", @class = "" })
    @Html.KoSageTextBox("txInactiveDate", new { @value = "Data.ComputedInactiveDate" },
         new { @disabled = true, @class = "default " })

    @Html.SageLabelFor(m => m.Data.CostClass, new { @id = "lblCostClass", @class = "" })
    @Html.KoSageDropDownList("Data_CostClass", new { @options = "CostClass", @sagevalue =
          "Data.CostClass", @optionsText = "'Text'", @optionsValue = "'Value'" },
          new { @class = "w188" })

@* End of my code, next is the generated footer. *@

<section class="footer-group">
   @if (Model.UserAccess.SecurityType.HasFlag(SecurityType.Modify))
      @Html.KoSageButton("btnSave", new { }, new { @value = CommonResx.Save, @id = "btnSave",
            @class = "btn-primary" })
      @Html.KoSageButton("btnDelete", new { }, new { @value = CommonResx.Delete, @id = "btnDelete",
            @class = "btn-primary" })


I put comments around the code I wrote so you can see what is generated by the code generation wizard versus the code you add later. Basically this is a mixture of C# code (each line starts with @) and HTML which is in the angle brackets.

There isn’t much layout in this file because this is handled by the CSS. For simple screens like this one there are sufficient styles in the provided Sage standard CSS file that we don’t need to add any CSS. As a result, the HTML is actually fairly simple and really just used to logically group things.

Notice that we use Sage provided extension functions to create all the controls. This provides us with the hooks to provide quite a bit of standard functionality. For instance, we don’t want any hard coded strings in our HTML, otherwise we would force our translators to produce a different copy of the HTML for each language and then we would have to maintain all these files. Here we just use the helper function and it will look up the correct string from the language resource appropriate for the user’s language setting. This also gives us the ability to change the underlying control without changing all the HTMLs. So we can use a different date picker control for instance by changing the code our helper function emits rather than editing each HTML individually. Basically giving us a lot of global control over the behavior of the product.

These helper functions also can setup databinding. Any helper that start with ko will bind the data to the model (more precisely the viewmodel). We used ko since we use knockout.js for databinding which perhaps isn’t the best choice of function naming since again we can change the mechanism in the background without effecting the application code.

Notice there is a partial view called _Localization.cshtml that is included. This provides any localized strings that are needed by JavaScript. So anything referenced in here will be generated in the correct language when the page is loaded.

There is a strange call to “ConvertToJsVariableUsingNewtonSoft” near the top of the file. This is to load a copy of the model into JavaScript during page loading. This means we don’t need to do an initialization RPC call to get the model (Sage 300 View) meta data. Basically the usual empty screen then has the default data and meta data as a starting point.


This was a quick look at the Razor View part of our Web UIs. This is where the controls and layout are specified. Layout is handled by CSS and data binding is provided to greatly reduce required coding. Next we’ll start to look at the JavaScript that runs behind the scenes in the Browser.


Written by smist08

December 5, 2015 at 12:11 am

Introducing the SDK for the Sage 300 Web UIs

with 13 comments


Sage 300 has always provided an SDK to allow ISVs to create accounting applications in the same way that we create our own applications like General Ledger or Order Entry. In the past our internal application developers have usually only had the SDK installed for doing their own work.

Further these ISVs can install their applications into a working Sage 300 installation by just copying a specific set of folders. We then will see these folders and allow that module to be activated and used.

The new Web Screens will have the same ability to create custom accounting applications and to easily add them to one of our installations.

We will be starting the beta program for this SDK shortly, so this should start to give people a preview of what is coming.

This overview assumes you have an existing SDK program. That you have Sage 300 Views and VB UIs. That you have an activation UI and can activate your module, making it known to Sage 300. This is just how to create the actual Web UI components.

The Module Creation Wizard

We are first going to create a Visual Studio solution for your Accounting module. Then we will use another wizard to add the screens to this solution. The solution will contain several projects that correspond to the parts of a UI screen. This is different than each screen having its own project. This stays in tune with how the ASP.Net MVC tools create solutions and allows us to leverage everything built into Visual Studio.

Create a Visual Studio project. We provide a project wizard to create your solution. Let’s pretend we are going to create the Project and Job Costing module:


The wizard will then ask you some questions about your module.


And then create a solution with the correct project structure for your application.


This solution now has the correct structure to add screens to, plus it has all the module level compents and references. This will compile, but there isn’t anything to run yet.

The UI Wizard

Now you create your separate UIs by running our Code Generation Wizard. You get this by right clicking on the solution and choosing it from the context menu.


This then brings up a wizard that you can step through.


Depending on what you choose for the Code Type, you will get a relevant screen for the details. If you choose Flat you will get the following:


The View ID will be used to generate the model and business repository for this screen. Basically it will use the View meta-data to generate C# classes that will provide most of the functionality to perform standard CRUD type operations.

Next you get a screen to specify which resource file to use for your stirngs:


Like all our previous SDKs there is full support for producing a multi-language product. Of course as in the past its up to you whether you leverage this or not.

Now you get to select some options of features to include:


With in the Sage accounting modules the I/C, O/E and P/O Views contain more functionality for determining if a fields is editable or not than do the G/L, A/R or A/P screens. The “Generate Dynamic Enablement” indicates whether all the checking editbable is done by your UIs or by your Views.

Now its time to confirm to generate the code:


And finally you get the list of files that it generated for you:


The wizard has used the meta-data from the Sage 300 Business Logic View, in this case the PJC Cost Types view to generate the code for a Business Reposity to use and an empty HTML screen.

Real Work

Running these wizards is quite quick and hopefully they give you a good start. The solution will compile and run, but all you get is a blank screen, since the generated Razor View just contains a TODO to add some controls. Now the real work begins adding controls to your Razor Views, adding custom processing logic and generally wiring things up.

You can now use the code-debug-fix cycle within Visual Studio and hopefully find it a productive way to create your Sage 300 screens.

In future articles I’ll talk about creating the Razor Views, using the extension functions we supply to help make this process easier and the CSS that is used to give the screens a standard look and feel. Then we will need to go into how to wire up finders, perform custom processing and all the other things required to make a Sage 300 screen.


This was a very quick look at the SDK for our Web Screens. We haven’t covered any coding yet, but we will. All the functionality used is built into the DLLs installed with Sage 300, so the actual SDK component is quite small. Besides the wizard, there is a lot of framework support to help you with common components and abstractions to hide some of the details.

Written by smist08

November 27, 2015 at 6:19 pm

Skills for Developing for Sage 300c

with 6 comments


With the Web UIs in Sage 300c rolling out in a couple of weeks, there is a lot of interest in the SDK and how to develop for this platform. We are still putting together the SDK, but in the meantime you can learn the technologies that are involved in developing our new Web UIs. Generally we’ve used off the shelf components both commercial and open source to develop our new UI framework. The good thing about this is that there are lots of resources available to learn the various technologies involved, including books, web sites, samples, videos, courses, etc.


We’ve generally tried to use all these tools in very standard ways. For instance we don’t add large amount of code to custom controls to change their behavior, we’ve kept it standard and only changed their appearance using CSS. We use the ASP.Net MVC framework in a natural way, so what you learn from the various standard resources is all applicable.

Due to the nature of programming, you can often do quite a few creative things. There is nothing to stop you using other libraries or tools than mentioned here. However one of the points of listing these is to let you know which we use, which means if you ask DPP support, these are the tools and libraries that we know about and can help answer questions about. You are welcome to use other tools, but we may not be able to provide much help on them.


C#: All server side programming above the Sage 300 .Net API is written in C#. This is a very powerful object oriented extension to C which is quite similar to Java. It has an extensive standard class library. The tools and environments that support C# are really powerful and productive.

JavaScript: All client/browser programming is in JavaScript. We support newer browsers which all now support fairly standard implementations. The main pitfall of JavaScript is that it’s an interpreted language that will process almost anything, often with surprising results.


ASP.Net MVC: Do not confuse this with ASP.Net (no MVC). This is a completely different framework which is much more powerful and gives a really solid framework for web development.


HTML: HTML controls the general layout of web pages in the browser, however it isn’t as important as it used to be. Our HTML is generated from Microsoft Razor Views, so a good portion of the HTML is actually represented as C# code. Then layout is largely controlled by CSS and not by HTML elements.

CSS: Cascading Style Sheets (CSS) control the layout and look of all the elements on the HTML page. We provide a global stylesheet which has most of what you need. However many screens need to define custom elements for their own fine grained control. We will provide a style catalog and samples of all the main UI elements.


Visual Studio 2013: This is the main IDE where we develop and debug our code. This is a very powerful and productive environment to write, build and debug code. Chances are we will be on to VS 2015 by the time the SDK ships, but for now this is what we developed our 2016 release in. We use the premium edition because that is what comes with our particular MSDN subscription, but any edition will probably be fine.

ReSharper: This is an optional tool that we’ve licensed for all our developers. We’ve found it very helpful to improve the quality of our code and to help with refactoring.

GitHub: Although using a source code control system is optional, you should be using one. Using any of Git, Subversion, TFS, etc. is fine, but you should really be using one. We use GitHub because it is very fast and reliable. The real benefit is that it’s fast for everyone when you have large internationally dispersed teams.

TeamCity: This is another optional component. You can just build out of Visual Studio. We use TeamCity, but you can also use other automated build systems like Jenkins. Its generally a good practice to have a continuous build/integration system that is always building things as they are developed, deploying them and running automated tests to ensure that things aren’t broken.


Kendo UI: This is the library of UI widgets that we use like the editable grid and date control. When we started this project this was strictly a commercial product. However half way through they created the open source Kendo UI Core which has all the controls we use for creating Accounting Screens except the editable grid control. For the grid control and the graphical controls in the KPIs,  you will need to purchase a license for the professional edition.

KnockoutJS: We use knockout for data binding between the UI controls and the MVC models. When we started the project the data binding in Kendo UI didn’t meet our needs so we evaluated alternatives. We found knockout and it did everything we needed so we’ve continued to use it. In the meantime Kendo has improved and AngularJS has become popular, but we’ve stuck with Knockout (which is popular again).

JQuery: Most modern web apps use JQuery. Although its main use of insulating people from browser differences isn’t as important and most browsers have natively implemented its main features, it is still an important library and we use it extensively.

.Net Framework 4.5.1: Since all our server components are written in C# and using the ASP.Net MVC framework, of course we are using the .Net framework. For the 2016 release we are at version 4.5.1. However by the time the SDK ships this will probably be at a higher version.

Sage 300 .Net API: To integrate to the standard Sage 300 Business Logic, we use Sage 300’s .Net API. So when writing code in the MVC models to perform Sage 300 processing, you are writing code to this API.

Crystal Web Viewer: We provide a complete framework for handling Crystal Reports, so you don’t need to directly interact with Crystal. We generate reports using the same code as the desktop version, but then display the result in Crystal’s HTML viewer rather than the ActiveX one.

Unity: This is a library for doing dependency injection in .Net. You probably don’t need to use this directly, but it’s useful to understand how your DLLs are being loaded and why the startup process works like it does.


This was a quick list of the various tools and technologies we used to create our new Web UIs. Hopefully it gives you a starting point of things to start learning about, if you are interested in Sage 300c development.

Written by smist08

September 19, 2015 at 4:33 pm

Using the Sage 300 ERP View Protocols with .Net

with 35 comments


Last week we looked at opening and composing groups of Views that will work together to accomplish a task. Now we will start to look at how to use the View API via .Net to accomplish common tasks. For Views that work alone this is fairly straight forwards and is just a matter of knowing which methods to call and in which order. For using multiple Views together it is a bit more complicated, but follows a standard pattern and once you get the hang of the pattern it is fairly straight forward also.

This article is just looking at the general algorithms rather than the details. We do provide one concrete example in the sample code. In future articles we will be using these protocols extensively so you will see more concrete examples. Some terms like read and browse/fetch are a bit vague and generally in the API there are several ways to do these which we will look at in future articles. Also some of the mentioned methods have parameters that we will look into in later articles as well.

You can skip any step marked as optional, and sometimes you can skip some steps in simpler situations, it isn’t only till you get to more complicated situations when the need for these steps become more evident. Part of using these algorithms or protocols is to ensure good multi-user throughput, so although another order of steps might work, it might lead to poor performance. So these tend to be a combinations of best practices along with some absolutely required parts.

If you’ve worked with Sage 300 ERP for any length of time, you might know we have an Init method which used to do the work of RecordCreate and RecordClear. We’ve deprecated this method and I’ve tried to use all the new up to date ways of doing things in this article. But if you do see an error in any of these articles, just leave a comment and I’ll fix it.

View Classes

Basically there are six classes of Views where all the Views in the same class use the same protocol for their basic operations. Here we will go through each class quickly with quick algorithms of how to accomplish various standard CRUD operations.

The classes of views are:

  • Flat
  • Ordered header/detail
  • Sequenced header/detail
  • Batch/header/detail
  • Processing
  • Detail

Flat Views

Flat Views are Views that do not need to be composed with any other Views. The key for a flat view may have multiple segments. Most setup Views are flat. Most master Views can be used as flat Views if you aren’t changing the details. Generally you will use these protocols quite a lot.

Insertion protocol

  1. RecordClear the view to initialize the record.
  2. Set values to the fields, including the key fields.
  3. Insert the record.
  4. If there are more records to insert, go to step 1.

Deletion protocol

  1. Set key values to the key fields.
  2. Read or Browse/Fetch the record.
  3. Delete the record.
  4. If there are more records to delete, go to step 1 to Read another record, or go to step 2 to Fetch the next record to delete. (Optional.)

Update protocol

  1. Set key values to the key fields.
  2. Read or Browse/Fetch the record.
  3. Set values to the fields to be changed.
  4. Update the record.
  5. If there are more records to update, go to step 1 or 2 depending on whether Read or Browse/Fetch is used. (Optional.)

Ordered Header/Detail Views

This is the protocol for two Views composed together where one is the header and the other is the detail. The details are kept in key order (as opposed to position order). You won’t see that many Views of this type, typically these are the header/detail Views used in setup forms.

The detail View’s primary key always starts with the primary key of the header View and then adds its own key segments. This then establishes which details belong to the header. Whenever a key field in the header is set, it is automatically also set in the detail View. When you Browse/Fetch through the detail records, you only get the details for the current header View.

Insertion protocol

  1. RecordClear header to initialize the fields.
  2. Set the fields in the header.
  3. RecordClear detail to initialize the fields.
  4. Set the fields in the detail.
  5. Insert detail.
  6. Go to step 3 if there are more details.
  7. Insert header. (This will Post the details)

Update protocol (Include deleting details)

  1. Set header key into header view.
  2. Read or Browse/Fetch the header view to get to the header.
  3. Set the fields to be updated in the header view. (Optional.)
  4. Set detail key into the detail view.
  5. Read or Browse/Fetch the detail view to get to the detail.

The first n segments (where n is the number of segments in the header key) of the detail key will have been Put by the header because of the composition.

  1. Set the fields to be updated in the detail view. (Optional.)
  2. Update or Delete the detail.
  3. Go to step 4 to update another detail.
  4. Update header. (This will Post the details)

Protocol for deleting header

  1. Set the header key in the header view.
  2. Read or Browse/Fetch the header. This causes the audit stamp to be read.
  3. Delete the header. (This will cause all details in the header to be deleted.)

Protocol for browsing

  1. Set the header key in the header view.
  2. Read or Browse/Fetch the header.
  3. Get fields from the header view.
  4. Browse/Fetch the detail view. (Browse/Fetch will not go beyond the header key.)

Sequenced Header/Detail Views

This class of Views is the most common for document entry in the operations modules. The detail View has all the key segments from the header View and then adds one numeric type field to act as the sequence number. The last segment of the header key is also numeric and contains the header number. Note that these numbers can be stored in string type fields, in which case they are masked to only contain the decimal digits ‘0’ to ‘9’. Often you can either set the header key or you can get the header to generate a key which means it allocates the next header number. The header key segments are always automatically set in the detail view and when you browse through the detail records you only get the records for the current header.

Insertion protocol

  1. If the next header number is generated by the view, Use RecordCreate to generate the next available header number. If the header number is specified by the caller, use RecordClear to initialize the fields of the header, then Set the header number in the header view.
  2. Set the fields in the header.
  3. RecordClear detail to initialize the fields.
  4. Set zero into the detail number field to insert from the start.
  5. Set values in the other detail fields.
  6. Insert detail.
  7. Go to step 5 until no more detail.
  8. Insert the header. (This will do a Post of the details.)

Note that an insert of the details does an “insert after”. So because we don’t reset the sequence number in the detail each insert will be after the previous one. If we want to insert after a specific record then put that sequence number into the key field. A common bug is to set the key field to 0 each time which then causes the records to be inserted in reverse order since each new one is inserted at the beginning.

Protocol for update (Include deleting details)

  1. Set header key into header view.
  2. Read or Browse/Fetch the header view to get to the header.
  3. Set the fields to be updated in the header view. (Optional.)
  4. Set detail key into the detail view.
  5. Read or Browse/Fetch the detail view to get to the detail. The header number in the detail view will have been set by the header.
  6. Set the fields to be updated in the detail view. (Optional.)
  7. Update or delete the detail.
  8. Go to step 4 to process another detail.
  9. Update the header. (This will do a Post of the details.)

Protocol for deleting header

  1. Set the header key in the header view.
  2. Read or Browse/Fetch the header. This causes the audit stamp to be read.
  3. Delete the header. (This causes all details in the header to be deleted.)

Protocol for browsing

  1. Set the header key in the header view.
  2. Read or Browse/Fetch the header.
  3. Get fields from the header view.
  4. Browse/Fetch the detail view. (This will not go beyond the header key.)

Batch/Header/Detail Views

This class of Views contain a batch View, header View and detail View. These are used for document entry in the Financial Modules. The header/detail part is just the sequenced header/detail class indicated above and works pretty much the same way. In a similar manner the Batch View has some key segments, one of which is the batch number which is a numeric type (or string where only ‘0’ through ‘9’ are allowed). Then the header shares the batch number and adds its header number and then the detail shares the header’s keys adding its detail sequence number. The batch number is usually generated and rarely can be specified for a new batch. Again the key fields from a higher level View are automatically set to the lower level Views so when you browser headers, you only see the headers for the current batch and when you browse details you only see details for the current header.

Insertion protocol

  1. RecordCreate batch to get the next available key for the batch.
  2. Set the fields in the batch.
  3. Update batch. (The batch record is already inserted by the RecordCreate call, in step 1.)
  4. RecordCreate header to get the next available key for the header. The key for the batch in the header view is assumed to be set already.
  5. Set the fields in the header.
  6. RecordCreate detail to initialize the fields.
  7. Set zero (or last detail number) into the detail key field to insert from the start.
  8. Set values in the other detail fields.
  9. Insert detail.
  10. Go to step 6 until no more detail.
  11. Insert header. (This will do a Post of the details.)
  12. Go back to step 4 to add another header.

Protocol for update (Include deleting details)

  1. Set batch key into the batch view.
  2. Read the batch record.
  3. Set the fields to be updated in the batch view. (Optional.)
  4. Update batch view. (Optional.)
  5. Set header key into header view.
  6. Read or Browse/Fetch the header view to get to the header. The key for the batch in the header view is assumed to be set already.
  7. Set the fields to be updated in the header view. (Optional.)
  8. Set detail key into the detail view.
  9. Read or Browse/Fetch the detail view to get to the detail. The key for the batch and the header in the detail view are assumed to be set already.
  10. Put the fields to be updated in the detail view. (Optional.)
  11. Update or Delete the detail.
  12. Go to step 8 to update another detail.
  13. Update the header. (This will do a Post of the details.)
  14. Go to step 5 to update another header.

Protocol for deleting batch

  1. Set the batch key in the batch view.
  2. Read or Browse/Fetch the batch. This causes the audit stamp to be read.
  3. Delete the batch. (This causes all headers and details in that batch to be deleted.)

Protocol for deleting header

  1. Set the batch key in the batch view.
  2. Read or Browse/Fetch the batch.
  3. Set the header key in the header view.
  4. Read or Browse/Fetch the header. This causes the audit stamp to be read.
  5. Delete the header. (The details will be deleted.)

Protocol for browsing

  1. Set the batch key in the batch view.
  2. Read or Browse/Fetch the batch.
  3. Get fields from the batch view.
  4. Browse/Fetch the header view. (This will not go beyond the batch key in the batch view.)
  5. Get fields from the header view.
  6. Browse/Fetch the details. (This will not go beyond thebatch and the header keys.)

Process Views (SuperViews)

This class of views is mainly used to implement procedures that do not involve editing data. Examples are consolidation, year-end procedures, and posting a batch.

Typically you set some fields in the View and the call Process to do the operation. These tend to be the simplest Views to use and yet often do the most processing.

What Class is my View?

OK, but now I want to program some set of Views, but what class are they? One way to find out is to look in the application’s xx.ini file. For instance for say A/R 6.1A, look in “Sage 300 Program Files”\ar61a\ar.ini and at the top is an [Objects] section that lists all the View classes for A/R. This is here so standards system components know what protocol to use on a given set of Views. Further you can check how to make the calls by doing a macro recording of the UI doing the operations you are interested in.

Sample Program

The sample program ARInvEntryWinForms (located here) has been updated to exactly follow the insert protocol for a batch/header/detail View with all the steps from above added as comments.

// 1. RecordCreate batch to get the next available key for the batch.

// 2. Set the fields in the batch.
arInvoiceBatch.Fields.FieldByName("BTCHDESC").SetValue("My new batch", false);

// 3. Update batch. (The batch record is already inserted by the RecordGenerate call, in step 1.)

// 4. RecordCreate header to get the next available key for the header.
//    The key for the batch in the header view is assumed to be set already.

// 5. Set the fields in the header.
arInvoiceHeader.Fields.FieldByName("IDCUST").SetValue(custNumber.Text, false);

// 6. RecordCreate detail to initialize the fields.

// 7. Set zero (or last detail number) into the detail key field to insert from the start.
arInvoiceDetail.Fields.FieldByName("CNTLINE").SetValue(0, false);

// 8. Set values in the other detail fields.
arInvoiceDetail.Fields.FieldByName("IDITEM").SetValue("CA-78", false);

// 9. Insert detail.
arInvoiceDetail.Insert();   // Insert the detail line (only in memory at this point).

// 11. Insert header. (This will do a Post of the details.)


This was a quick introduction to the View Protocols on how to do basic CRUD operations on the various classes of Views. These are all one level descriptions, but can be generalized to more complicated cases like header-detail-detail views where the middle detail acts as a header to the second detail. Generally the ideas of these protocols will be used extensively in all future articles.

Written by smist08

November 2, 2013 at 6:22 pm

Composing Views in the Sage 300 ERP .Net API

with 23 comments


In the past couple of weeks we’ve had a look at opening sessions with the Sage 300 ERP .Net API and then opening a View and doing some simple View operations. This week we are going to start looking at the more complicated case of document entry which involves “header/detail” type Views as well as composing multiple Views together. I talked a bit about these concepts in this article on entering O/E Orders via the COM API.

Composing Views

Composing Views is a topic that usually confuses people that are new to using the Sage 300 API. It is a basic mechanism to allow multiple Views to work together with each other as well as to work with the person calling the Views via the API. Roughly for data Views, each View corresponds to a database table. But when we are doing document entry like A/R Invoices or O/E Orders, multiple Views must be used together to build up the document. Further we want to write the document in a single database transaction (we wouldn’t want some tables updated and others not). We also want to ensure that the various Views are used in such a way to avoid multi-user problems like deadlocks.

View composition is the basic mechanism that enables this functionality. It is really a way of sharing View objects, so that everyone is using the same copy rather than opening their own copies. So who is everyone? There is only me the programmer. Well not only do you call Views via the API, but Views call each other all the time. We will look at why they do this in the next section.

Our convention is that the person using the API is responsible for opening all the Views that will be shared. This is just via regular OpenView method calls from a DBLink object. Then we give a reference to all these Views to everyone else via the View’s compose method.

Let’s look at an example for opening and composing the Views required to enter A/R Invoices:

// Open the A/R Invoice Entry Views
arInvoiceBatch = mDBLinkCmpRW.OpenView("AR0031");
arInvoiceHeader = mDBLinkCmpRW.OpenView("AR0032");
arInvoiceDetail = mDBLinkCmpRW.OpenView("AR0033");
arInvoicePaymentSchedules = mDBLinkCmpRW.OpenView("AR0034");
arInvoiceHeaderOptFields = mDBLinkCmpRW.OpenView("AR0402");
arInvoiceDetailOptFields = mDBLinkCmpRW.OpenView("AR0401");

// Compose the Batch, Header and Detail views together.
arInvoiceBatch.Compose(new ACCPAC.Advantage.View[] { arInvoiceHeader });
arInvoiceHeader.Compose(new ACCPAC.Advantage.View[] { arInvoiceBatch, arInvoiceDetail,
      arInvoicePaymentSchedules, arInvoiceHeaderOptFields });
arInvoiceDetail.Compose(new ACCPAC.Advantage.View[] { arInvoiceHeader,
      arInvoiceBatch, arInvoiceDetailOptFields });
arInvoicePaymentSchedules.Compose(new ACCPAC.Advantage.View[] {
      arInvoiceHeader });
arInvoiceHeaderOptFields.Compose(new ACCPAC.Advantage.View[] { arInvoiceHeader });
arInvoiceDetailOptFields.Compose(new ACCPAC.Advantage.View[] { arInvoiceDetail });

To work with A/R Invoices requires using six Views which we open first. Now we as the caller of the API have a View object for each of these. So we can go ahead and make method calls to all these Views. However, these Views need to know about each other so they can work together. There may be fields in the header that the details need to update as they are updated, deleted or inserted, like totals for each invoice. When we save the invoice, it must be able to start a database transaction and save all the other Views as well as itself to work correctly. So basically the compose calls are giving the Views the ability to use the other Views they need that we opened. For instance the first Compose call is the batch.Compose which gives the A/R Invoice Batch View access to the A/R Invoice Header View that we opened. Now the batch View can call the same instance of the header View that we opened and if we look at the fields in the header View we will see the values set by the batch View before things are saved to the disk.

But the code above does seem rather magic. How did I know which Views to open and how did I know which Views to compose? It is very important that you compose the correct Views and the order the Views appear in the array passed into the Compose call is very important. The way I create these, is to run macro recording on the regular UI that uses the document I am programming. Then I get all the correct open and compose calls in VBA syntax which is quite easy to translate into C# and then I have something I know will work. Sometimes you can leave out composite views that aren’t used in a situation, but I find that leads to more problems than its worth, so I generally just include them all. Similarly the ViewDoc and the Application Object Model list all the Views a View will compose with, but I find translating this information into code more tedious.


Within the Sage 300 system, most accounting documents use a header/detail structure. This means that we have a single header record for the document (like an Invoice) and then multiple detail lines, one for each of the line item detail lines. This gets more complicated since details can have sub-details and so on, but the basic concept is the same. We often are using View composition to get header and detail Views to work together to correctly insert, delete and edit accounting documents.

As an example of header/detail we have the Order Header and then its detail lines. The Order header has information that there is one of for the order. The details then contain data that there are many of. The Order Header contains information like the customer id and the ship-to address. Then each detail line contains an I/C Item number and quantity. So for an order you can order as many items as you like.

The Order Header also stores information like various totals. So as each detail line is added, updated or deleted these header totals have to be updated to keep them correct. Details are always associated with their header by having their primary key start with the header’s primary key, then just adding an uniquifier or counter. This is show in the diagram below:


Sample Program

The sample code for this article is the ARInvEntryWinForms sample on the GDrive here. This sample opens and composes the A/R Invoice Views, then it goes a bit further to create a batch with a single entry for the customer number you enter on the form and then inserts one detail line with a fixed item number (the quantity is defaulted to 1 by the detail View). There is a bit of error handling. In future articles we will talk in detail about the protocol for entering header/detail documents, we will also talk a lot about exception handling and debugging in a future article. But just describing the View composing and header/detail concepts has already lead to a full article. But I did want to include a bit more code than just opening and composing the Views, so it would really do something. You need to go into A/R Invoice Entry to see the invoices created.


This article covered the basic concepts of View composition and of header/detail relationships. We will start to use these frequently in future articles. These are an important building block to much more sophisticated programs.

Written by smist08

October 27, 2013 at 3:31 am

The Argos SDK Part 2

with one comment


Last week I introduced a sample of how to develop mobile apps for Sage 300 ERP using the Argos SDK. In that article I covered where to get the sample and how to get it working. This week, we’ll start to look at how it is put together and how it works.

Sign On

The first thing you need to do is sign-on or authenticate. There is a standard method of authentication built into SData which is explained on the SData website here. Usually you would want to create a sign-on dialog and then feed the results into the SData access layer. This is all done in the sample application.

Basically the file src\Application.js is responsible for orchestrating the running of the application. When it starts running, it calls handleAuthentication() which usually calls navigateToLoginView() to run the login screen. This is done in src\views\login.js. This file displays the UI and gets the data entered. We’ll talk more about how UIs work next. It basically sets up the credentials data structure, calls authenticateuser to save these for the SData layer and then navigates to the initial screen.

Anatomy of a View

For Sage 300 ERP developers this is going to be confusing, because in the Sage 300 ERP world, business logic objects are called Views. But here in the Argos SDK world, Views are UI screens. Basically you provide a data structure (JavaScript object described in JSON notation) with all the fields you want and an HTML template on how you want them displayed, and then Argos has base classes to display these. The Argos SDK uses object oriented JavaScript, so it’s often worth going into the SDK and browsing the base classes to see what things are derived from. This gives you a good idea of what is done for you and what behavior you can override.

The most basic such View is src\views\VendorGroups. This is used as a finder when adding new Vendors. The code is:

define('Mobile/Sage300/Views/VendorGroup/List', [
 ], function(
 ) {
     dojo.declare('Mobile.Sage300.Views.VendorGroup.List', [List], {
         itemTemplate: new Simplate([
             '<h3>{%: $.DESCRIPTN %}</h3>',
             '<h4>{%: "Code: " + $.GROUPID + " Active: " + $.ACTIVESW %}</h4>'
         titleText: 'Vendor Groups',
        //View Properties
         icon: 'content/images/Accounts_24x24.gif',
         id: 'vendorgroup_list',
         security: 'Entities/VendorGroup/View',
         queryOrderBy: 'GROUPID',
         querySelect: [
         resourceKind: 'apVendorGroupsFinder',

         onRequestDataFailure: function(response, o) { 
               alert( Mobile.Sage300.Environment.parseErrors(response.responseText) );
               Sage.Platform.Mobile.ErrorManager.addError(response, o, this.options,
               dojo.removeClass(this.domNode, 'list-loading');
         formatSearchQuery: function(query) {
             return dojo.string.substitute('upper(DESCRIPTN) like "%${0}%"',

This is basically the JSON definition for this View object. This one fairly simple and bare bones, the main points are to define the SData feed in the resourceKind: property, along with the query fields we need. Notice the simplate which  is used to format and display each entry in the list, these are described in the next section. Then there is an error handler and a function to perform searches. The rest is done in the base class for this View. For more complicated objects, you will need to override more functions and provide more input (like more details about fields for editing).


Simplate is a small templating engine for JavaScript. We use the templates to dynamically combine HTML and data in our views.

The Simplate syntax is a mix of markup, tags and JavaScript code. These are the most common syntax items you’ll see:

  • {%= … %}: Output the result of the inner JavaScript
  • {: … %}: Output the HTML encoded result of the inner JavaScript
  • $: References the data object (in our case, the JSON entry retrieved via Sdata)
  • $$: References the data object container (in our case, the view)

You can check out the code and some examples here:


When developing you run into lots of bugs, so how to solve them? The nice thing about JavaScript is you just update your files, save them and then hit refresh on the browser to run. But since JavaScript is interpreted and not compiled, you only find out about syntax errors when you run. If the syntax error is bad then it can stop the whole program from running (extra or missing brackets are bad for this), simpler errors will just stop the program when it hits that line of code. Also beware that if you misspell variables, JavaScript will just happily keep going using an undefined value, so be careful.

I like to run in both Firefox and Chrome. Firefox (with Firebug) is good at pointing out syntax errors, so they are easy to fix. Chrome has an excellent JavaScript source code debugger built in that is great for setting breakpoints and tracing through code. Another tool I really like is Fiddler which spies on all the SData server calls being made. From here you can look in depth at what is going on with the SData server.

Since the Argos SDK along with any other libraries it uses are all open source JavaScript projects that means you can examine any of the source code in the Argos SDK and debug into it to see what is happening there as well as what is happening in your own code.

Also remember the SalesLogix and Sage 300 sample applications, chances are you can find an example of what you are trying to do in one of these programs.


The Argos SDK is a powerful mobile development platform that combines SData with the Dojo JavaScript framework to give quite a deep method to quickly develop mobile applications for various Sage SData enabled products.

Written by smist08

July 28, 2012 at 5:03 pm

The Argos SDK

with 16 comments


Argos is a framework for creating mobile SData clients using HTML5, JavaScript and CSS. This was originally developed by the Sage SalesLogix group to create the mobile interface for the Sage SalesLogix Mobile product. However since SalesLogix uses SData as its Web Services interface, this library was created entirely on SData. As a consequence it can be used with any product that supports SData.

As part of our Sage 300 ERP 2012 development we tested Argos on our SData feeds and produced a sample mobile application.

Note: that to run this application on your own system, you need at least the Sage 300 ERP 2012 beta.

Argos SDK

The Argos SDK is open source and available on github:

This includes a JavaScript SData client library that you can use standalone independent of the rest of the SDK along with a sample application that shows Argos running on SalesLogix. The SalesLogix sample application also includes the second sample which shows how to customize the first without requiring code changes to it.

Sage 300 Sample Argos Application

Sorry, the Sage 300 team doesn’t have a github account like SalesLogix right now. However I posted the Sage 300 Sample application and the matching Argos SDK on GDrive here:

Generally you would put these as folders under the c:\inetpub\wwwroot folder. Then you can start the app via: http://localhost/sage300/index-dev.html. (Or substitute your own hostname as needed).

In the Sage300 application there is a runtime folder. This needs to be copied to: C:\Program Files (x86)\Common Files\Sage\Sage 300 ERP\Tomcat\portal\sageERP\runtime. These are the definition files for the SData feeds that this sample uses. After you copy this, you need to restart the “Sage 300 ERP Tomcat” service for them to get read.


The last gotcha is that the Argos SDK uses Cross Origin Resource Sharing (CORS). This is a mechanism where the server that is serving the HTML can let the browser know its ok to talk to another server. This way the Web Server that serves up the HTML, CSS and JavaScript files can be different than the SData server. Normally this isn’t allowed as it’s considered a severe security threat since it allows malicious programs to send sensitive data to a third server or to send out things like Spam. CORS is an internet standard that provides a way to let the browser know what is ok and what is bad in a secure manner.

As a result, you have to configure the IIS (or whatever web server you use for the static content) to grant access to the SData server. You still have to do this, even if they are the same, since all SData requests from the Argos SDK are CORS validated. The Wiki attached to the Argos SDK on the main Github site above has complete information on this.

But since I’m not exposed to the outside world and don’t usually worry too much about this, I tend to just let CORS say everything is valid with a simple web.config file (in c:\inetpub\wwwroot):

<?xml version=”1.0″ encoding=”UTF-8″?>
<handlers accessPolicy=”Read, Execute, Script” />
<add name=”Access-Control-Allow-Origin” value=”*” />

Like I said, don’t just specify “*” like I have for a real situation, but if you are on different networks with a laptop, sometimes this is just easier. Similarly in a real environment, you would want to use https rather than http.

Configuring to Connect to Sage 300 SData Feeds

The key to interfacing to Sage 300 is the development.js file in the configuration folder. To work with Sage 300 it needs to look something like this:

define(‘configuration/development’, [‘Mobile/Sage300/ApplicationModule’], function() {
return {
modules: [
new Mobile.Sage300.ApplicationModule()
connections: {
‘crm’: {
isDefault: true,
offline: false,
url: ‘http://localhost/sdata/sageERP/sage300mobiledemo/SAMINC/&#8217;,
virtualDirectory: ‘SDataServlet/sdata’,
json: false
enableUpdateNotification: true

The key parts are the virtualDirectory to form the correct SData URLs for Sage 300. Remember that Sage 300 URLs start SDataServlet/sdata rather than just sdata. This is to avoid conflict when we are installed on the same server as Sage CRM. So notice the url: tag doesn’t include SDataServlet and then the virtualDirectory tag does. This will then cause the correct URLs to be formed. If you are having trouble with URLs then the Fiddler tool is great for debugging what is going on.

Note that to work, at least you need to change localhost to the server name you are using. Localhost will only work when running on the same computer.

Setup Quick List

So to summarize setup:

  1. Unzip the two zip files under the c:\inetpub\wwwroot folder.
  2. Add something to c:\inetpub\wwwroot\web.config for CORS.
  3. Copy the sage300\runtime folder to …\portal\sageerp\runtime.
  4. Restart Tomcat
  5. Edit the development.js file if you need to change the hostname.

Hopefully this will get you going fairly quickly.

Create Your Own App

This blog post is already getting a bit long, so I’ll go into more detail on how this sample program works in a future post. However this should be enough to get you started with the Argos SDK Wiki information and a working sample.

The Argos SDK is written in JavaScript and oriented to JavaScript development, so learning JavaScript is crucial. There are many good books on JavaScript as well as many good free web based resources. I like “Eloquent JavaScript” by Marign Haverbeke since it is fairly short and complete.

The Argos SDK relies heavily on the Dojo JavaScript framework. Along with the Simplate library and iUI library. My experience is that you don’t need to know too much about these to work with Argos, but I imagine if you get deep into it, it doesn’t hurt to know something about these.


One of the goals of SData is to enable the use of common tools across all Sage products. The Argos SDK is an example of this; it is a mobile SDK library for creating mobile applications that use SData to communicate with on-premise Sage applications. Over time you will see more and more of these sort of tools that leverage SData to provide enhanced functionality for a whole range of Sage applications.

Written by smist08

July 21, 2012 at 6:25 pm

To SDK or Not to SDK

with 7 comments

That is the question. With Sage ERP Accpac there is a lot of customization capabilities and programming APIs built in including VBA macros and the Accpac COM API, but then there is the Software Development Kit or SDK ( A common question is: Do I need the SDK to do this or that? In this blog posting we will see what you can do without the SDK and what you require the SDK to do.

The core Accpac System Manager contains many components and tools that are installed as part of the regular product. These are all required for the normal use of Accpac. For instance all our User Interface Forms use our COM API to communicate with the Business Logic, so this interface must be installed with System Manager and as a result if fully usable from any COM aware programming system (like VB) without anything else being required. In the same way, the VBA macro system is installed as part of System Manager.

Although there is an SDK installation that you install and use on your computer, we don’t sell that as a product. What we sell is an ISV program that includes the SDK, along with access to online resources like a Wiki, programming support calls and other programs like discounts for trade show booths. So even if you don’t need the SDK installation part, you might still want to sign up for the ISV program for some of the other benefits. Especially the support, since this is the only way you can get support on programming type problems.

Without the SDK


The Accpac macro language is VBA ( You can use this to automate processes and customize UIs. It is a very powerful feature of the core Accpac System Manager. From VBA you have access to all the Accpac Business Logic.

External APIs

These are APIs that are built into the core Accpac System Manager that allow external programs to connect to Accpac and use the Accpac Business Logic. These APIs include the Accpac COM API (also used by VBA) and the .Net Interface. In the forthcoming Accpac 6.0 there will also be a Java Native Interface (JNI, and the SData RESTful web services interface (

Crystal Reports

Crystal Reports ( is not part of the SDK. If you want to customize reports in Accpac, you need the Crystal Reports Designer (available separately). With this you can open and customize any report in Accpac (except Financial Reports which are done in Excel). When customizing reports, consider putting them in a customization directory (see administrative services) rather than just customizing the report Accpac installed in place, since it might get overwritten by a product update later.


System Manager includes a number of useful tools under the Tools folder of its start menu entry. Many of these like RVSpy are very useful when developing macros or programming the external interfaces. Below is the U.I. Info tool that is included with System Manager.

With the SDK

The goal of the SDK is to let third parties write accounting modules just like Sage writes Accpac accounting modules like Accounts Receivable or Order Entry. In fact our own developers of these products use the same SDK that we make available. Some examples of third party applications developed this way are Technisoft Service Manager (, Norming Asset Management (, Peresoft Cashbooks ( or AutoSimply (

The SDK gives you all the header files and libraries to develop with C/C++. It gives you templates for create Accpac User Interface Forms and Views (Business Logic Objects). It gives you a large set of tools to help you develop with. Many of these tools are added to Accpac as a regular Accpac application see below.

If you look in an accounting application directory such as AR56A you will see a number of small files like roto.dat or eng\grp.dat. The SDK contains command line tools to create these files. Basically it is everything you need to develop a complete Accpac application.

When you create your application with the SDK you get all the functionality of a full Accpac application with very little extra work. For instance your application will:

  • Fully support VBA – you are as customizable as any other Accpac application
  • Your Business Logic will be available through all the external APIs
  • Will use  the standard Accpac Import/Export
  • Your UIs will look, feel and behave like any other Accpac screen – you will use the same controls like Finders, grids and navigation controls
  • Runs from the Sage Accpac desktop, and the Sage Accpac Web-desktop
  • Will participate in data activation, database dump/load and all other Accpac database operations like database transactions


Add-ins are developed in the same manner as full SDK modules. However their goal isn’t to be a standalone application. Their goal is to add to or change the functionality of existing Accpac modules. They can alter the behavior of the business logic, as well as add their own business logic, UIs and reports.

The key feature add-ins are using is that the Accpac business logic can be “subclassed”. That means you can create a new business logic object that sits in front of the Accpac one and process all the calls first. These subclasses are chained, so there could be several add-ins all subclassing the same Accpac business logic object. This is a very powerful form of customization, in that it customizes the behavior for everything that uses the business logic including import/export, macros, external programs as well as UIs. Whereas UI customization only affects the customized UI.

An example of an Add-in is the Accpac SageCRM integration module. This module, once activated has a few UIs, but its main purpose is to subclass a number of Accpac business logic object and when they are called, make corresponding changes in SageCRM. For instance when you update a customer’s information in Accpac, the SageCRM’s subclass Views sees the changes and calls SageCRM’s API to make the corresponding change there.


As you can see, you can develop quite a few powerful customizations and integrations without using the SDK at all. So how do you choose when to use the SDK? Main reasons to use the SDK:

  • Create a full Accpac accounting module
  • Create an add-in with subclass business logic objects
  • Want to get the 12 free developer support calls per year
  • Want the full Accpac SKD documentation to better understand the workings of Accpac

Some of the main things that you don’t need the SDK for:

  • Create a macro to customize a UI
  • Create a macro to import data
  • Create an integration via the COM API or .Net interface to an external program

This is a guide, as with anything in computing there are always exceptions, but hopefully this gives some guidance.

Written by smist08

October 30, 2010 at 9:01 pm

Posted in sage 300

Tagged with ,

Creating a Web Form for Accpac 6

with 12 comments

Sage ERP Accpac 6.0A is just entering beta (lucky Friday 13th August, 2010). With this release you will be able start to run Web based User Interface forms. We’ve covered how this looks in several other blog posts like and But as a developer, how do you create new Web Based forms using the Accpac SDK?

The new Web based forms are written using a number of tools that are integrated into the Eclipse development environment ( Our SDK involves programming with the Sage Web Toolkit (SWT) which is based on the Google Web Toolkit (GWT – With this toolkit you develop your programs in Java and then GWT provides a compiler that will compile these programs into JavaScript, which will run in your browser.

To start with we provide a project wizard integrated into Eclipse. You use this to create a starting Accpac screen project. From the File menu in Eclipse you choose File – New – Project… Then select under “Sage Web Toolkit”, “New SWT UI”. This gives the following dialog that gets the basic information on the UI you want to create:

When you are done and click Finish, our wizard will create a new project in Eclipse. This eclipse has a simple UI form and everything you need to start working on your UI:

This is a completely ready to run minimal UI that is all set for you to add your own logic to. If you don’t do anything and just choose run, then your project will be run in GWT hosted mode, which means it is run as a Java program in a container that simulate browser behavior. This is how you debug your programs. In this mode you can set breakpoints, single step through code, examine variables and do anything else supported by the full Java debugger. When you run it will pull up the sign-on screen:

And then when you sign-on you get the screen with the single table control connected to the A/R customers SData feed that we put on the form. Normally you would delete this control and then add the controls you really want on your form.

Behind the scenes is the development shell that show useful messages on what is going on, especially if something goes wrong. Plus status messages are sent to the Java Console inside the Eclipse IDE.

Once you have debugged the program and have it working then you run the project through the GWT compiler to produce a Web HTML/JavaScript version of the program that you can run directly in the Browser, or which you can add to the Accpac Portal.

When you are writing code for your UI, it can go into one of two places. If can reside on the Browser side of things running as JavaScript or it can run on the server side as an SData service ( or In VB all the UI code was within the VB OCX control and this talked directly to the Accpac Views (Business Logic Objects). In the Web world we have JavaScript running in the Browser (created by compiling Java programs with GWT), that talk to SData services running on the Server. These SData services then talk to the Accpac Views.

When programming the Browser half, you have nearly all the power you had in VB. You can add listeners to any control and get events as things happen. You can add listeners to data sources to get notified as things happen to data. This is very similar to VB event handlers. You can make SData calls that translate directly into View calls, like you called the Accpac COM API in VB. However there are some major differences. Just because you can do something, doesn’t mean it’s a good idea. In the Web world you want as much to happen on the server as possible. Any code you add to the JavaScript side, increases the size of JavaScript that has to be downloaded to the Browser (it will be cached and JavaScript code is very compact). Plus whenever you make an SData call to the Views, this call will happen over the Internet. This means it could be slow. Generally you only want to make 1 SData call to the server to do anything. You don’t want to make a bunch of SData calls to accomplish something. You really only want to make one call. Additionally in the Web world all calls are asynchronous, meaning that other processing continues after you send off the request. When you send the call you set a listener, which will be called when the response comes back from the server. This makes it quite complicated to make multiple calls and we don’t provide any help to do this in our framework (and neither does GWT), because we really want to discourage it.

So how do you do complicated sets of View operations? You create these on the server where we’ve made it easy. We let you create your own SData services or extend the standard services that we put on top of all the Views. So for instance to perform the operation to calculate taxes, you would send all the input fields in a service SData request, the server Java class would do all the viewPuts, viewProcess, etc and return any fields that changed as a result. This way you make 1 SData call from the UI, the SData process on the server makes all the View calls and returns the request. This minimized network time both in latency and bandwidth. On the server we have a generic class that wraps a View, this class is responsible for converting SData requests into View calls. It handles all the standard View protocols. You can extend this class with your own class and add extra logic to it. You can easily add additional fields from other Views or calculated fields. Generally you would like to only interact with one SData source from a UI, so you want to include any side lookups like description fields into the main SData source. You also would rather do calculations on the server for performance reasons, plus then anyone else using your SData service benefits from this code. All these server classes are controlled by a number of XML configuration files that define all the SData sources and configure which server side Java classes process them.

This was a quick overview of how to create a new Accpac Web based UI along with a bit of discussion on conceptually what you do next without any details. Hopefully in future blog posts we can fill in a few more details on how to program both the Browser and server in this new model.

Written by smist08

August 14, 2010 at 4:28 pm

Posted in sage 300

Tagged with , , ,