Stephen Smith's Blog

Musings on Machine Learning…

Posts Tagged ‘web uis

Sage 300c Web Services

with 16 comments

Introduction

Hand in hand with true HTML/JavaScript/CSS Web UI’s you also want to access the same logic from other general programs using RESTful Web Services. This gives a general API to access the application which doesn’t require any Sage 300 components be installed on the client computer and doesn’t require the calling application be on the same computer or even at the same location.

ASP.Net MVC Web screens tend to have quite quickly changing interfaces between the Views, Controllers and Models which makes using then same Web Services as the UI a bit problematic, especially as the screens evolve quickly. You want a stable Web Services interface that preserves compatibility from version to version and provides a wider more general interface. At the same time the developer of an ASP.Net MVC program doesn’t want to do a completely different implementation for exposing Web Services.

The way ASP.Net MVC solves this dilemma is by allowing you to add a Web Services stack on top of your existing models (which in our case means fully leveraging the business repositories and Sage 300 Business Logic as well). But it uses a custom controller to handle the Web Services requests. In the Microsoft stack there are several supported standards for Web Services, but the one we used is OData. This means that using our Web Services you can do all the standard OData queries and supports the standard OData meta-data.

With our Sage 300 2016 Product Update 1 we have included a number of Web Services in the product. These are automatically installed if you select the Web UIs option from the main installation. So if the Web UIs are up and running then you can try playing with the Web Services. In this article we’ll show how to get started using these. Over next couple of releases, we’ll be fleshing these out to support all the Business logic as well as services beyond the basic CRUD operations.

Some Examples

If you type:

https://yourservername/Sage300webapi/sdata/-/SAMLTD/GL/Accounts

into the Chrome browser you will be prompted for your Sage 300 login credentials, which you can enter. Note that from this browser prompt the password is case sensitive, so you need to uppercase your normal Sage 300 password (since our regular login screen normally does this).

webserv1

Then after entering the correct data you will get back a JSON object with all the information in your chart of Accounts (including details like optional fields):

webserv2

Working with the Browser directly, although fun, will soon become tedious. Another easier approach is to install the Chrome add-in PostMan which will remember your Web Services so you can adjust and repeat them. You need to set the Basic Authorization header with your Sage 300 login and password. Below we use the shortened URL to get the list of all the available feeds for SAMLTD with the URL:

https://yourservername/Sage300webapi/sdata/-/SAMLTD

using PostMan:

webserv3

And we get the returned JSON object containing the list of Web Services we support. It by company since not all accounting application may be activated in the database.

Queries

You can do standard OData queries to filter the returned data. For instance:

https://yourservername/Sage300webapi/sdata/-/SAMLTD/GL/Accounts?$filter=UnformattedAccount eq ‘1020’

will result in just this one account being returned:

webserv4

The way we implement queries is via adding LINQ support that will convert the LINQ query to a Browse filter for our Sage 300 View. This means we will support any query as long as we can translated it into a Browse filter. If the filter contains a SQL function we don’t support, then you will get back a not supported error for your query. Note that often people writing code for the regular Web UIs just use our C# LINQ support to browse/fetch rather than calling browse/fetch directly since this lets you leverage other advanced features in C# and .Net.

Other Clauses

You can specify a sort order as long as what you requests matches an index in the Sage 300 database:

https://yourservername/Sage300webapi/sdata/-/SAMLTD/GL/Accounts?$orderby=UnformattedAccount desc

webserv5

You can specify to get the top n records or to skip n records via:

https://yourservername/Sage300webapi/sdata/-/SAMLTD/GL/Accounts?$top=2

https://yourservername/Sage300webapi/sdata/-/SAMLTD/GL/Accounts?$skip=2

which is useful to page data.

Meta Data

You can get meta data for all the feeds using the $metadata tag. For instance:

https://yourservername/Sage300webapi/sdata/-/SAMLTD/$metadata

will return the meta data for all the feeds that are relevant for SAMLTD:

webserv6

(Note that this is quite a large JSON object to process).

Updating/Inserting/Deleting

This initial implementation includes sufficient G/L feeds for supporting financial reporting. Hence these G/L feeds are read only at this point. We do support inserting G/L Batches, O/E Orders and A/R Customers. Many of the non-G/L feeds support updating, inserting and deleting. If the entity supports these then you can delete the record by specifying DELETE as the HTTP verb (which is easy in PostMan), similarly insert if via POST and update if via PUT or PATCH.

Generally, the best way to figure out the format of the payload to include with these is to do a GET and then use that payload as a template to build the JSON object with the data you want to update or insert.

Since these Web APIs are built on the Sage 300 Business Logic all the usual validation will take place and you will get back Sage 300 error messages in the response payload if the request fails.

Troubleshooting

Ideally the responses from the server will include error messages to tell you what went wrong, so always check these. If they aren’t helpful, then on your web server check the Web API trace log which is located at:

Sage300InstallDir/Online/WebApi/Logs/trace.log

This will usually have the raw error when something has gone wrong.

If you don’t see anything in either of these places, perhaps check your IIS log to make sure that the request didn’t get rejected for some other reason. Especially remember to include your basic authorization header.

Security

If you expose your Web Services to the general Internet, ensure that you follow all the security measures in this article. You will need to do this if you are integrating with an external cloud service or other client located outside your network. Generally, you want to keep your Web Service communications private, so they can’t be accessed by hackers or spied on by hackers. Using good practices around enforcing HTTPS is crucial here.

Summary

The set of Web Services included in the Sage 300 2016 Product Update 1 are intended to support Financial Reporting on General Ledger as well as basic e-Commerce functionality like accessing Customers and entering Orders. Part of the intent of this release is to let people play with these and provide feedback as we move to complete out the full set of Web Services for our next version.

Written by smist08

February 15, 2016 at 11:26 pm

Accessing Sage 300c’s Business Logic from the Web UIs

with 5 comments

Introduction

In the Sage 300 VB UIs, a user would do something in the UI (press a button or tab out of a field) and then the VB UI would be notified of this and would possibly execute a number of Sage 300 Business Logic (View) calls and based on their results update various other fields and possibly provide user feedback via a message box.

In the Web UIs we want to do similar processing since we want to re-use the tried and true Sage 300 Business Logic, but we have to be careful since now the Web UI is half running as JavaScript in the Browser and half running as .Net assemblies on the server. We have to be careful of the communication between the Browser and the server since there will be quite a bit of latency in each call over the Internet. Generally, we never want one user action to result in more than one call to the server (and ideally most user actions shouldn’t result in any calls to the server).

This blog post talks about where you put your code to access the Sage 300 Business Logic and how a UI interaction in the Browser flows through the system to execute this business logic.

Architecture

In the new Web UI architecture, we access the Sage 300 Business logic from our Business Repository classes. The base classes for these provide a wrapper of the Sage 300 .Net API to actually access the Views, but hiding the details of things like session and database link management. Then above this layer are the usual ASP.Net MVC Models and Controllers.

cna2arch

The Sage 300c Web UI Architecture

Generally, we want to put all this logic in the Business Repository so it can be used by multiple higher level clients including the Web UIs, our new RESTful WebAPI and services which are available for other applications to utilize.

Some of the layering is in place ready for additional functionality like customization. We need provide the common interfaces that can act as the basis for programmatic customization by inserting custom modules into the processing flow via Unity Interception.

Moving VB Code

In VB we often make lots of Business Logic (View) calls all interspersed with lots of interactions with various UI controls. This code has to be separated where the Business Logic (View) calls will go in the Business Repository which runs on the server and then the part that interacts with the controls has to move to the JavaScript code running in the Browser. The Business Repository has to provide the necessary data in a single payload which the mode/controller will transport to the Browser for processing.

The easiest way for the repository to transfer data is to have the model provide extra fields for this communication. This way no extra layers need to be involved, the business repository just populates these fields and the JavaScript layers pull them out of the returned JSON object and use them.

But you only want to add so much to the model, since you don’t want it to be too cumbersome to move around and you might want more focused calls. For these we usually define special calls in the controller and these go through a services layer to execute the code in the repository. The service call only passes the exact data needed (like parameters to a function) and knows what data to expect back.

Example

Adding extra fields to the model is fairly straight forward, so let’s trace through the logic of making a services call. In this example we’ll look at the simple case of checking a customer’s credit limit in A/R Invoice Entry (which is using a stateful business repository). We’ll start up in the JavaScript code and work our way down through the layers to get an idea of who does what.

So let’s start near the top. In the A/R Invoice Entry UI there are various times when the credit limit needs to be looked up. So the JavaScript code in the InvoiceEntryBehaviour.js file has a routine to initiate this process. Note that server calls are asynchronous so the response is handled in a callback function.

    showCreditLimit: function (result) {
        // Open Credit Check pop up window
        if (result) {
            var jsonResult = JSON.parse(result);
            if (jsonResult.ShowCreditCheck) {
                arInvoiceEntryRepository.getCreditCheck(jsonResult.id,
                    sg.utls.kndoUI.getFormattedDate(jsonResult.docDate),
                    sg.utls.kndoUI.getFormattedDate(jsonResult.dueDate),
                    "n" + invoiceEntryUI.CurrencyDecimals, jsonResult.totalPaymentAmountScheduled,
                    jsonResult.prepaymentAmount);
            } else {
                onSuccess.onCreditClose();
            }
        }
        invoiceEntryUI.ModelData.isModelDirty.reset();
    },

This calls a function in the InvoiceEntryRepository.js file to actually make the call to the server:

    getCreditCheck: function (customerNumber, documentDate, dueDate, decimals, invoiceAmount,
        prepaymentAmount) {
        var data = {
            id: customerNumber,
            docDate: documentDate,
            dueDate: dueDate,
            decimals: decimals,
            totalPaymentAmountScheduled: invoiceAmount,
            prepaymentAmount: prepaymentAmount
        };
        sg.utls.ajaxPostHtml(sg.utls.url.buildUrl("AR", "InvoiceEntry", "GetCreditLimit"), data,
              onSuccess.loadCreditLimit);
    },

This will initiate the call to the server. The URL will be built something like servername/Sage300/AR/InvoiceEntry/GetCreditLimit. The ASP.Net MVC infrastructure will use configuration by convention to look for a matching entry point in a loaded controller and hence call the  GetCreditLimit method in the InvoiceEntryController.cs file:

        [HttpPost]
        public virtual ActionResult GetCreditLimit(string id, string docDate, string dueDate,
               string decimals,decimal totalPaymentAmountScheduled, decimal prepaymentAmount)
        {
            try
            {
                return PartialView(AccountReceivable.ARInvoiceCreditCheck,
                      ControllerInternal.GetCreditLimit(id, docDate, dueDate, decimals,
                      totalPaymentAmountScheduled, prepaymentAmount));
            }
            catch (BusinessException businessException)
            {
                return JsonNet(BuildErrorModelBase(CommonResx.NotFoundMessage, businessException,
                    InvoiceEntryResx.Entity));
            }
        }

Which will call the InvoiceControllerInternal.cs GetCreditLimit method:

        internal ViewModelBase<CustomerBalance> GetCreditLimit(string customerNumber,
            string documentDate,
            string dueDate, string decimals
            , decimal totalPaymentAmountScheduled, decimal prepaymentAmount)
        {
            var creditBalance = Service.GetCreditLimit(customerNumber, totalPaymentAmountScheduled,
                 prepaymentAmount);

            if (creditBalance.CalcCustomerOverdue == CalcCustomerOverdue.Yes &&
                creditBalance.CustomerBalanceOverdue > creditBalance.CustomerAmountOverdue)
            {
                creditBalance.CustomerCreditMessage = string.Format(
                        InvoiceEntryResx.CustCreditDaysOverdue,
                        creditBalance.CustomerDaysOverdue,
                        creditBalance.CustomerBalanceOverdue.ToString(decimals),
                        creditBalance.CustomerAmountOverdue.ToString(decimals));
            }

            if (creditBalance.CalcNatAcctOverdue == CalcNatAcctOverdue.Yes &&
                creditBalance.NatAcctBalanceOverdue > creditBalance.NatAcctAmountOverdue)
            {
                creditBalance.NationalCreditMessage = string.Format(
                        InvoiceEntryResx.NatCreditDaysOverdue,
                        creditBalance.NatAcctDaysOverdue,
                        creditBalance.NatAcctBalanceOverdue.ToString(decimals),
                        creditBalance.NatAcctAmountOverdue.ToString(decimals));
            }

            creditBalance.CustomerCreditLimit =
                 Convert.ToDecimal(creditBalance.CustomerCreditLimit.ToString(decimals));
            creditBalance.CustomerBalanceVal =
                 Convert.ToDecimal(creditBalance.CustomerBalanceVal.ToString(decimals));
            creditBalance.PendingARAmount =
                 Convert.ToDecimal(creditBalance.PendingARAmount.ToString(decimals));
            creditBalance.PendingOEAmount =
                 Convert.ToDecimal(creditBalance.PendingOEAmount.ToString(decimals));
            creditBalance.PendingOtherAmount =
                 Convert.ToDecimal(creditBalance.PendingOtherAmount.ToString(decimals));
            creditBalance.CurrentARInvoiceAmount =
                 Convert.ToDecimal(creditBalance.CurrentARInvoiceAmount.ToString(decimals));
            creditBalance.CurrentARPrepaymentAmount =
                 Convert.ToDecimal(creditBalance.CurrentARPrepaymentAmount.ToString(decimals));
            creditBalance.CustomerOutstanding =
                 Convert.ToDecimal(creditBalance.CustomerOutstanding.ToString(decimals));
            creditBalance.CustomerLimitExceeded =
                 Convert.ToDecimal(creditBalance.CustomerLimitExceeded.ToString(decimals));
            creditBalance.NatAcctCreditLimit =
                 Convert.ToDecimal(creditBalance.NatAcctCreditLimit.ToString(decimals));
            creditBalance.NationalAccountBalance =
                 Convert.ToDecimal(creditBalance.NationalAccountBalance.ToString(decimals));
            creditBalance.NatAcctOutstanding =
                 Convert.ToDecimal(creditBalance.NatAcctOutstanding.ToString(decimals));
            creditBalance.NatAcctLimitLeft =
                 Convert.ToDecimal(creditBalance.NatAcctLimitLeft.ToString(decimals));
            creditBalance.NatAcctLimitExceeded =
                 Convert.ToDecimal(creditBalance.NatAcctLimitExceeded.ToString(decimals));

            return new ViewModelBase<CustomerBalance> { Data = creditBalance };
        }

This routine first calls the GetCreditLimit service in InvoiceEntryEntityService.cs:

        public virtual CustomerBalance GetCreditLimit(string customerNumber,
            decimal totalPaymentAmountScheduled, decimal prepaymentAmount)
        {
            var repository = Resolve<IInvoiceEntryEntity<TBatch, THeader,
                 TDetail, TPayment, TDetailOptional>>();
            return repository.GetCreditLimit(customerNumber,
                 totalPaymentAmountScheduled, prepaymentAmount);
        }

Who then calls the repository GetCreditLimit routine in InvoiceEntryRepository.cs. This routine then appears to do regular View processing using the base repository wrapper routines that insulate us from the session/dblink handling logic as well as do some basic error processing:

        public virtual CustomerBalance GetCreditLimit(string customerNum,
            decimal totalPaymentAmountScheduled, decimal prepaymentAmount)
        {
            _header.Read(false);
            _creditCheck.SetValue(CustomerBalance.Fields.CustomerNumber, customerNum);
            _creditCheck.SetValue(CustomerBalance.Fields.CurrentARInvoiceAmount,
                totalPaymentAmountScheduled);
            _creditCheck.SetValue(CustomerBalance.Fields.CurrentARPrepaymentAmount,
                prepaymentAmount);
            _creditCheck.Process();
            return _creditCheckMapper.Map(_creditCheck);
        }

Finally, down in the business repository, the code should look fairly familiar to anyone you has done any C# coding using our Sage 300 .Net API. Further this code should also appear somewhere in the matching VB code, and besides being translated to using the .Net API, its become quite separated from the UI control code (in this case the JavaScript).

At the end of this all the calls return propagating the returned data back to the Browser in answer to the AJAX call that it made.

It might look like a lot of code here, but remember the business repository and JavaScript bits have corresponding VB code. Then the other layers are there to make all the code more re-usable so that it can be used in contexts like WebAPIs and allow interfaces to provide the hooks needed for customization.

Summary

This article is intended to give you an idea of where to put your code that accesses the Sage 300 Business Logic and then how to call that from the Web UIs. There are a lot of layers but individually most of the layers are fairly simple and most of the code will appear in the Business Repository and the JavaScript behavior code.

Written by smist08

February 12, 2016 at 3:27 am

Stateless Versus Stateful Sage 300c Web UIs

with 2 comments

Introduction

When two computers communicate they use a well-defined communications protocol. In Browser to Server communications these are often broadly categorized as either stateless or stateful. A stateless communications protocol doesn’t require that anything be remembered between calls. In web applications this is desirable for a number of reasons:

  • often calls are load balanced across multiple servers (perhaps even in different locations).
  • storing state in memory can be expensive and will limit how many users can be accessing a web server at once.

On the other hand, maintaining server state has some advantages:

  • less information needs to be transferred between the client and server since the server knows what has gone before.
  • having things handy in memory can make operations faster and more context aware.

Often in the real world these components are combined or stacked on each other, for instance the TCP protocol is stateful and then the HTTP stateless protocol is layered on top of TCP.

The Sage 300c Web UIs use both stateless and stateful technology. This article will talk about when we use each, how to program either case and what are the advantages and disadvantages of each method. Like many things in programming the lines between these two things can become quite blurred.

Since we do have stateful UIs, this does require that if you scale out to multiple web servers then the load balancer must use sticky sessions as we explained in this blog posting. Basically guarantee that all the requests from a given client go to the same web server in case they are running a stateful UI.

Stateless Sage 300 Web UIs

Most of the Sage 300c setup UIs, processing UIs and report UIs are all stateless. This means IIS could be reset between requests and things would still work. It would just be quite slow since it would need to re-open a Sage 300 session and re-open the Views to process the next request. To avoid this we keep a cache of open sessions along with their open Views. This way when a stateless request comes in we match up a session for the right company, user and with the right Views from the session pool and use that to handle the request. If a session in the pool hasn’t been used for a while we will release it and if too many sessions are in use, we will release the oldest if we need another one. This way practically speaking you usually open a session for your first stateless request and then keep using it from the cache of the duration of your work.

schedules

A Typical Stateless UI

Every Sage 300c business logic entity (View) will have a stateless repository defined for it. This is because only the document entry UI needs stateful operation, everything else like finders, export and other UIs will want to use the stateless version. You get all the default behavior for your stateless repository by having your specific repository inherit from one of the stateless base repositories in Sage.CA.SBS.ERP.Sage300.Common.BusinessRepository.Base like FlatRepository, ProcessingRepository or InquiryRepository.

Generally stateless operation fits very well with ASP.Net MVC since this is the natural way that it works. There is a lot of infrastructure to pass the data model back and forth between the client and server in a stateless manner. Add to that our use of knockout data binding and this makes most basic CRUD operations all handled by the framework.

This doesn’t mean that a stateless UI can’t dynamically interact with the user. By default, you have the CRUD operation off the basic navigation and save/delete buttons. But you can certainly add your own custom AJAX calls to dynamically update areas of your form. We provide support in the framework to update things like descriptions of external keys, but in fact you have a lot of power to make your UI very interactive and polished.

Stateful Sage 300 Web UIs

Most of the main Accounting document entry UIs are stateful. This includes UIs like Order Entry, Purchase Orders, G/L Journal Entry and A/R Invoice Entry. These UIs have a lot of sophistication in building up the Accounting document and the size of these documents can be quite large. Sending this entire document back and forth between the browser and the server as a JSON object is quite impractical. When one of these UIs is started, a session and set of Views are assigned to it for the duration that it runs. As changes are made to the UIs they are sent to the server to make the attendant changes to the server model.

oe1100new

A Typical Stateful UI

To create a stateful business repository, just inherit from one of the stateful base repositories in Sage.CA.SBS.ERP.Sage300.Common.BusinessRepository.Base.Statefull like BatchHeaderDetailRepository or SequencedHeaderDetailRepository.

When you exchange information between the server and browser rather than send the entire document back and forth, you tend to send one component back and forth like one order detail line or the order header. This then reduces the amount of data transmitted, but more importantly greatly reduces the size of the JSON object that JavaScript needs to process. If the transferred document gets too large then JavaScript processing speed can become a real bottleneck.

You don’t need to send something to the server every time every field changes, only the fields that cause some business logic to execute. So you don’t need to do anything say when the user changes a description field. When a field changes that causes business logic on the server to execute then you need to send that to the server and get back all the fields that changed as a result. We tend to mostly do this using the default ASP.Net MVC mechanisms along with the knockout data binding. But only doing it for the component record. So say the item number in a detail record is changed, then we would refresh that record by sending it to the server, which would set the changed fields, do the Sage 300 business logic operations (puts and gets) and return the newly updated record where a number of fields have changed.

This works for most cases, but there is room for optimization. If something is rather a major operation, you might want a more tailored AJAX call for the processing. Similarly, if multiple records are affected you might want to denormalize a bit to reduce the dataflow. For instance, when dealing with details, often header totals change, but you might want to associate these with the detail, rather than also refreshing the header.

Summary

This was a quick overview of the main modes or how our Sage 300 Web UIs operation. Stateless operation reduces server overhead, while stateful operation lets us fully leverage our existing business logic, while reducing our bandwidth requirements.

Written by smist08

February 9, 2016 at 8:44 pm

Adding a Grid to Your Sage 300 Web UI

with one comment

Introduction

The grid or table control is a key element for data entry in any Accounting application. With Sage 300 we use the grid control to enter things like Order or Invoice details. Interactions with a grid control tend to be quite complex. The data has to be managed so it is loaded only a page at a time (often called virtual scrolling), since there could be thousands of detail lines and loading them all at once would be quite slow. There is the ability to edit, delete and add lines. Tabbing has to be handled well to enhance data entry. People also have the ability to re-arrange the grid columns, hide columns and then expect these changes to be remembered.

icreceipts

This blog article will talk about the key elements to adding a grid control to your Sage 300 Web UI and what sort of support you need in your UI to support all the desired functionality. A fair bit is handled for you in the Sage 300 Web UI Framework, however you have to handle various events and there is a lot of power to add your own programming.

Configuration

There is a lot of support for standard grid operations in the Sage 300 Web UI framework. Much of this is controlled by a config JSON object which is passed to our @Html.KoKendoGrid function that defines the grid in the Razor View. This file defines a number of properties of the grid along with a number of standard callout functions you can define to add your custom processing. The good news is we have a utility to generate much of this from the ASP.Net MVC Model.

JavaScript Generation Utility

To generate this code we provide a utility which will generate the Razor View code and a lot of the standard JavaScript code that you need. So for instance the code for the Razor View might be:

jsgen1

And then some of the JavaScript code for the config object might be:

jsgen2

Server Side Pagination

In our VB UIs, we had virtual scrolling in our grids, which would basically bring in a page or two at a time. It supported scrolling one page ahead or one page back, go to the top or bottom but you couldn’t go to an arbitrary point in the file without searching (in fact the scroll bar would always be at the top, bottom or right in the middle). In the Web UIs we use the Kendo UI Grid control and try to keep the scrolling mechanism standard for the Web, which means the control tells you how many pages there are and lets you go to any page you like as well as going to the next or previous one.

We provide a lot of the support for doing this in our business repository base classes which expose a get method which takes the page number, page size, filter and order as parameters. Then as long as you match and set the configuration data in the grid’s JavaScript config JSON object, you get the pagination support. There are a couple of things to keep in mind, one is that we rely on our filterCount API call, which translates directly to a SQL statement, which means it can only count based on database fields and not calculated fields, so you can’t restrict the records in your grid based on any calculated fields or the count will be wrong (if you really need this then you need to disable the ability to go to a specific page). You also need to have a hidden SerialNumber column in the grid which contains the record number.

ViewListControl vs AccpacGrid

In our VB UIs, we actually had two grid controls. One was the ViewListControl which would show a separate View record in each line and supported virtual scrolling. Then we had the AccpacGrid control which would usually show an array of fields from a single record (like tax information, or perhaps item structure information).

In the Web UIs we only have one Grid control. It naturally works more like VB’s ViewListControl. So how do we handle the other case of the AccpacGrid? We do this in our controller by translating the array of fields into what looks like a list of details. This way to the Grid control, it doesn’t really see a difference. Usually you don’t need to enable virtual scrolling in this case since there is typically 5 or 10 records and you just provide them all at once. So typically your ViewModel will have a list of records which the controller will populate and then this is set as the Grid’s data source.

Editing

Like VB, the intent of editing cells is to place the correct edit control over the grid cell to perform the edit. There is a lot of framework support for this as well as lots of callouts for you to do your own custom processing. The same is true for adding a new line and deleting a set of lines (note that the Web UI grid supports multiple selection). Also note that the add line, delete line, edit columns buttons aren’t part of the Grid, these are separate buttons styled to look like part of the grid in a region just above the Grid. This means you can easily add your own buttons and controls to this area if you wish.

Saving Preferences

We have API support to help with loading and saving grid column preferences. In VB these are stored in the *_p.ism files, in the Web UIs these are stored in the SQL database in the new USRPROP table. So emptying USRPROP is the Web UI equivalent of deleting the *_p.ism files. Generally, we want to move everything into the database and remove our reliance on the shared data folder over time.

Summary

This article was just a quick introduction to adding a Grid control to a Web UI. Similar to the VB UIs, the grid control is potentially quite complicated as it supports a lot of diverse functionality. But, if you are doing fairly standard functionality, look for a lot of support in the Web UI framework to help you get the job done.

Written by smist08

February 3, 2016 at 6:29 pm

Introducing the SDK for the Sage 300 Web UIs

with 13 comments

Introduction

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:

solnwizard1

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

solnwizard2

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

solnwizard3

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.

uiwiz1

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

uiwiz2

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:

uiwiz25

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:

uiwiz3

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:

uiwiz4

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:

uiwiz45

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

uiwiz5

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.

Summary

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

Sage 300 2016 Operations Beta

with 6 comments

Introduction

We recently released Sage 300 2016 with Web UIs for C/S, Bank, Tax, G/L, A/R and A/P. Now we have released our first beta of the operations modules I/C, O/E and P/O. Internally we are calling this our February 2016 release, I’m not sure what it will be officially called externally yet. This release will be packaged as a Service Pack to the Sage 300 2016 version, so this will need to be installed first. This will be a pretty major Service Pack with a lot of new functionality added. But as a Service Pack, the actual internal program versions won’t change and the upgrade procedures will be the same as for a regular Service Pack.

Due to various dependencies, we needed to produce the Financial Accounting screens for the Web first. Even though most users who can really benefit from Web/Mobile access need the Operations screens. So hopefully having all these Operations screens available should open up a great many possibilities for our customers. Of course you can still use the existing Windows Desktop VB screens, and you can even use a combination of both.

You need to run the “Portal…” dialog from Database Setup again to seed some data for the operations modules into the Portal database.

New KPIs

We have new KPIs for I/C, O/E and P/O. They are in the screen shot below, namely “Top Salespersons”, “Inventory Item Performance” and “Activity Trend”. Also notice the menus for I/C, O/E and P/O have been added to the main menu bar.

operationkpis

Order Entry

We are really pleased to have moved Order Entry to the Web. This is a module where there are often a great many users that are located in different geographic locations, or need to use the module while on the road. This module also integrates with Sage Payment Solutions (SPS) for processing credit cards. Below is a sample showing the main Order Entry UI.

oe1100new

Purchase Order

Purchase Order is a pretty major module that is now in the Web. Perhaps we don’t get as many users running P/O screens as O/E screens, but for a lot of companies, the P/O process is very important. Below is a screen shot of the main P/O Purchase Order Entry screen.

poentry

Inventory Control

I/C is a large module with lots of UIs that now have Web UI versions. We haven’t moved Lot Tracking or Serialized Inventory yet, but most of the other I/C functionality is now available in the Web. Below is a screen shot of the I/C Receipts screen, which is one of the major I/C document entry screens.

icreceipts

Other Screens

A number of the lesser used C/S, G/L, A/P and A/R screens were omitted from the first release. Quite a few of these are now in. For instance C/S Schedules has been added along with the various recurring entry screens that use Schedule Codes.

schedules

We added a number of other screens like the G/L Fiscal Set Comparison screen.

fiscalsetcomp

Another thing you might notice is that the Web UIs are available in Chinese now in addition to English and French.

There will be More

This is just beta 1. It is focused on the new parts of the Web Screens. It doesn’t include the new features that will be included in the Windows Desktop version, these will be appearing in a later Beta.

Summary

With the addition of the I/C, O/E and P/O screens, Sage 300 now has a very large footprint of its functionality in the Web. Hopefully we can get lots of feedback from this Beta release and have a successful launch in February.

It may seem like we are releasing the February version pretty quickly after just releasing the main Sage 300 2016 version, but we are now looking to release three fairly major updates to the product each year. This is the result of our adoption of Agile methodologies and the use of continuous delivery techniques (to release frequently, reliably and easily). Even though this isn’t a cloud release, we can still use the techniques of cloud delivery for our on-premise customers.

 

Written by smist08

November 14, 2015 at 5:51 pm

The New Sage 300 Home Page

with 7 comments

Introduction

In this article I’m going into a bit more detail on the features in the Home Page for our new Sage 300 Web UIs. This is basically the launching point for our web accounting screens as well as provides a number of KPIs and user assistance.

We are calling this a Home Page rather than a Portal to avoid confusion with the 6.0A Portal, the Partner Portal and all sorts of other Portals. This isn’t meant to be an all-in-one entry point to everything you do on the Web, its very specific to making your use of Sage 300 easier and avoids cluttering it up with all sorts of other things.

Home Page of the Home Page

The main entry point to the Home Page is shown below. You can get to this view at any point by hitting the Home link next to the Sage 300 logo at the top left. This screenshot also shows the “Add Widgets” menu where you select which KPIs you want to see.

homepage2

Feature Tour

When you first start the Home Page or at any time from the Help menu you can run the feature tour that steps you through the main features in the Home Page to get you familiarized.

homepagefeaturetour

Mega Menu

We refer to the menu where you select the accounting screen to run as the “Mega Menu” due to its size. As you can see it’s arranged in a very similar manner to the current Sage 300 Desktop, so it should be easy for users to find what they need to do. Of course if you are running with security configured (as you should be), then you will only see the items you have access to which greatly reduces the choices to sift through.

homepage3

Menu Customization

Besides using security you can also customize which menu items you don’t want to display in the Home Page. This might be because you want your users to run the VB screen due to existing screen customizations or perhaps to just reduce clutter.

homepagecust

Window Manager and Related Links

The Home Page lets you run up to ten accounting screens at once. There is a Window Manager widget on the right hand side that you use to switch between screens and to close screens you don’t need open anymore. You can slide the Window Manager widget up and down if it’s in the way of something.

Notice on the screen shot below that each screen always displays the group the screen is in along with the screen (a breadcrumb) and some related links along the top, so in this case you can see links for Tax Classes, Tax Groups and Tax Rates. This way usually you can get to where you need to go quickly without using the menu.

homepagewindowmanager

Crystal Reports

We still use the same Sage 300 Crystal Reports that we’ve always used. Only now they are displayed in the Home Page, just like the accounting screens. These will show up in the Window Manager Widget just like any other screen.

homepagecrystal

Help

Of course there is always help available. Below is a screenshot of the frequently asked questions. There is help for all the accounting screens as well as the Home Page.

homepage4

Summary

This was a quick tour of our new Home Page. There are quite a few usability innovations here, and you can expect quite a few more as we move forwards.

 

 

Written by smist08

August 22, 2015 at 5:16 pm

Installing the Sage 300c Web UIs

with 8 comments

Introduction

In my last post I introduced the new Web UIs for Sage 300. This blog post is on installing the new Web UIs for Sage 300. The product has just gone to beta so I thought it might be helpful to provide a few details on the installation process. I also included details about some rough edges in the beta installation. I’ll update this article as we go along with any problems encountered and helpful workarounds discovered. As we go to final release, I’ll clean up this article to represent the final released state.

For testing all the new features in the classic VB UIs then the normal installation procedures apply. This article is specific to the Web UIs.

Prerequisites

The beta only officially supports Windows Server 2012R2 and SQL Server 2014. By release we will support other versions of Windows and our usual suspects for SQL Server. This only applies to the Web Server where you want to host the Web UIs. All the regular versions of Windows are supported for Workstation setup type installs to run the VB UIs. For accessing the Web UIs from other computers and devices just ensure you are using the latest version of Edge, IE, Firefox, Safari or Chrome.

The main prerequisite is that you must install the Web Server (IIS) server role from the Server Manager. Then you should add all the Application Development sub features. The key ones being that we need the .Net ones and the ISAPI ones.

serverrole

Installer Options

The new Web UIs are an option in our installer. They are checked by default, but you only want to install them on the Web Server where they should run from (similar to the older Portal option).

wsinstall

When you select this the files for these will be added in an online folder under the folder you decided to install to. A number of Windows features will be enabled like .Net 3.5 (needed for Crystal) and Message Queuing. Virtual folders and application pools will be added to IIS. No manual configuration or adjustment of IIS is required.

Database Setup

With Sage300 version 6.0A we introduced a Portal database. This held 4 tables required for the 6.0A Portal. The new web screens also need some database tables. We added them to the Portal Database so that you don’t need to worry about yet another SQL database. So like previous versions you need to create a Portal database in SQL Enterprise Studio, and then run Database Setup to configure it from the “Portal…” button. The dialog from database setup is exactly the same as it was in previous versions.

One difference is that the older Portal populated its tables when it ran. The new Web UIs need a few things populated ahead of time and this is done via Database Setup. So if you delete and re-create the Portal Database then you must run Database Setup again to get these tables re-populated.

Running the Web UIs

Now you should be ready to run. On the server there will be start menu link to the new Home Page. For other computers it will be //servername/sage300. You can use the IP address of the server if you don’t have a proper DNS entry for it.

By default we configure IIS to run these from HTTP. If you expose these to the external internet, make sure it is either via VPN or you enable HTTPS (you need a digital certificate) and turn off the HTTP port in IIS.

Beta Issues

The beta still has a few issues so I thought I would list them all here to put them in one place. I may delete this section when the product ships to avoid confusion once these issues are resolved.

  • You must use Windows Server 2012R2 and SQL Server 2014. Installing in a virtual image (like Virtual Box) is fine.
  • You can’t install both the existing (Orion) Portal and the Web UIs on the same web server. Right now the two Crystal runtimes will conflict and Crystal reports won’t work for one or the other.
  • [Update 2015/08/04] For the Portal database due to a bug, you must give this a case-insensitive collation sequence. If its case sensitive or a bin type collation then you will get some serious errors.
  • Database Setup has a bug where the first time you select the Portal… options, you will get an error about dbconfig.xml not existing. Hit Ok again and it should be created fine.
  • After running Database Setup you need to go to Control Panel – Administrative Tools – Services and restart the Sage.CNA.WindowsService service or functions like posting and import/export may not work.
  • Web UIs that use the system link won’t save properly, this includes Security Groups, Authorizations and the Currency functions.
  • [Update 2015/08/18]: If your Organization ID is less than 6 characters long in Database Setup then you will get a sequence error when you try to signon. For now please make your org-id 6 characters in length.

Diagnostics

One problem with the previous Web versions of Sage 300 is that DBSpy and RVSpy didn’t work on Windows Services (starting with Windows XP). Now these programs have been updated to spy on Sage 300 business logic that is run from a Windows service like IIS. So these tools are quite helpful in diagnosing problems in this new Web UI environment.

There are two main components for the new Web UIs both of these are installed under the online folder for the Sage 300 program files. Each has its own diagnostic log which provide useful information when things go wrong (there is also quite a bit of audit information logged here).

Under the online folder the web folder contains all the files and programs that comprise the ASP.Net MVC program that runs from IIS. Here there is a logs folder which contains a trace.log file which will contain various audit information as well as much more detail on any problems that occur in the system.

Under the online folder the worker folder contains files and programs that make up the Sage.CNA.WindowsService. This service processes any long running jobs like posting functions, create new year and import/export. This to make the web server more responsive to other users when someone is running a long running process. Here there is a logs folder that contains a trace.log file which has detailed diagnostic information when something goes wrong here.

folders

If you want to just reset the Web UIs programs, you need to restart the World Wide Web Publishing Service (IIS) and the Sage.CNA.WindowService Windows Services. Note that the Sage 300 Tomcat and Sage 300 .Net Remoting services are still there, but these aren’t used by the new Web UIs.

Trouble Shooting [2015/09/15]

A couple of troubleshooting notes:

  • If you install on an older version of IIS, you need to edit the application pool and change it from .Net framework v2.0 to v4.0. (Usually this happens when installing on Windows 7).
  • If you get a weird error about web.config, first ensure you have all the ASP.Net options selected when installing IIS. Next try running aspnet_regiis.exe -i. This is usually located somewhere under c:\windows\microsoft.net\Framework\v4.0.xxxx where xxx is your exact version.
  • If the various bitmaps/icons don’t appear, make sure you have “Static Content” included in the IIS installation options.

Summary

We a really excited that the first beta of our new Web UIs is shipping and we are looking forward to getting feedback and input ahead of the main general release in October. The earlier we can get feedback the sooner it can be incorporated into the product. Hopefully this article will help you get up and running and trying out these new screens.

Written by smist08

August 2, 2015 at 6:41 pm

Sage 300 Moves into the Browser

with 53 comments

Introduction

Probably one of Sage’s worst kept secrets is that we’ve been working on a true Web version of Sage 300. Now finally at Sage Summit 2015 the cat is out of the bag and the product is officially announced as Sage 300c. You can see the announcement in this video.

We will be including Web UIs for G/L, A/P, A/R, Bank, Tax, C/S and A/S screens in the upcoming Sage 300 2016 release which is slated for October 2015 (where the year in the product roughly matches car model years).

These are true web screens that run in all the main browsers including IE, Edge, Chrome, Firefox and Safari. There are no plug-ins required, everything is pure HTML, CSS and JavaScript. This means you can access these screens from all sorts of devices like Macs, Windows Desktops and Laptops, Chromebooks, iPads, Android Tablets, Linux Workstations, Raspberry Pi’s and many other devices.

The operations modules including I/C, O/E and P/O will follow shortly after early in 2016 as part of a Product Update.

New PDX Treatment

We have a new Home Page (like the traditional desktop) and all redesigned screens.

Sage300Home

There are 12 KPIs that you can choose from to put on your home page. You run all the screens from the menu and can move between open screens using the little Windows widget on the right.

People familiar with Sage 300 ERP will pick up this new treatment very easily since it is still the same application, just re-imagined to fit into a modern Web environment.

cna2arinv

All the familiar elements are there including finders, import, export and printing via Crystal Reports. There are a lot of extra visual cues to help make the screens easier to learn and use. For instance you don’t have to know to hit tab when in a key field to get it processed, you can just hit the little go button next to it (but of course hitting tab still works as well). In the grid you don’t need to know to hit the Insert key to create a new line, there is an explicit “Add Line” button at the top of the grid.

The controls aren’t as packed together as they were in the classic VB UIs. This is to make it easier to use the screens on touch devices like tablets. Now it’s much easier to touch buttons and controls with your fingers when you don’t have the fine control of a mouse. Although these screens work quite well on tablets, it isn’t recommended you use them on a phone since this then involves a painful amount of scrolling and having a more responsive design for phones is still a version or two away.

Hybrid Offering

If you upgrade to this release, you don’t need to run the Web UIs. You can still run all the classic VB UIs. In fact you can have some users running the new Web UIs and some users running the classic VB UIs. Since everything goes through the same business logic (Views) you can mix and match as you like. Of course for modules like PJC where there aren’t any Web UIs yet, then you must run the VB UIs.

There isn’t a full Web based Financial Reporter yet, so Financial Reporting is still done though the usual built in F/R that is included with G/L or via Sage Intelligence. Both of these are based on the on-premise version of Excel.

Many customers rely on customized versions of the Sage 300 screens. There won’t be a customization toolkit with the first release, it will be provided later. Even if it was available with the initial release, not everyone would want to immediately port their customizations to the new technology. It takes time overcome the learning curve and become proficient in the new technologies. To help with this scenario we provide a tool that lets you hide any UIs in the Web home page, so that users won’t accidentally run the Web UI when you want them running the VB UI (probably due to customizations).

New Technology Stack

This new architecture is based on using standard ASP.Net MVC along with re-using the standard Sage 300 Business Logic. Below is an architectural block diagram of the new components that sit on top of our traditional business logic.

cna2arch

To speed bringing the product to market we were careful to stick to standard off the shelf technology components rather than creating out own. For instance the UI widgets like the editable grid, the graphical charts and the date picker are from the Kendo UI toolkit. We use knockout.js for databinding. We make extensive use of jQuery and leverage quite a number of other standard technologies that are all tried and true in many large scale web applications. All the server code is written in C# and all the Browser code is written in JavaScript.

You can see that there is a Wrapper layer than translates the world of Sage 300 Business Logic into the world of ASP.Net MVC. This way our application is a very standard implementation where the Wrapper layer exposes the standard Sage 300 business logic in more modern interfaces allowing the usage of newer languages and technologies like LINQ in the higher layers.

Lots of Questions

I imagine many people have lots of questions on everything that is going on. This is the first of many articles on the new Sage 300 Web UIs where I’ll be going into much more technical detail. But if you leave questions in the comments of this article, I will endeavor to either answer them or make them the topic of a future posting.

Summary

We are really excited to finally be launching our Web UIs for Sage 300 into the real world. This is a first step in fully modernizing the product and providing a strong foundation for future development.

Our R&D department has been operating using Agile development methodologies and a continuous delivery process. After the first release we are looking to release upates very frequently to add value very quickly to this rather large base release.

Written by smist08

July 29, 2015 at 12:40 am

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 https://smist08.wordpress.com/2009/12/03/the-sage-erp-accpac-6-0a-portal/ and https://smist08.wordpress.com/2009/12/24/sage-erp-accpac-6-0-data-portlets/. 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 (http://www.eclipse.org/). Our SDK involves programming with the Sage Web Toolkit (SWT) which is based on the Google Web Toolkit (GWT – http://code.google.com/webtoolkit/). 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 (http://sdata.sage.com/ or https://smist08.wordpress.com/2009/11/24/sdata-in-sage-erp-accpac-6/). 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 , , ,