PayPal has updated its SDK, and has warned me that the buttons on the Store page will stop working soon.

There is no easy fix for this. As nobody uses this feature, I have pulled it for the time being.

Custom controls


Sample custom controls

The custom controls are added to the Header and Line screens, and the data is filled in by the user. These controls can be header text, spinners (drop-down lists), checkboxes and text. The example above shows header text, a checkbox and a text field.

The header text (in this case “Extras”) creates a block for the controls that follow it, and gives it a name. The data from the other controls is joined together, and stored in the custom fields of the corresponding Order and Order Details records.

In the example shown above, the custom field would contain the string “1|VC”. Here the 1 says that the Gift Wrap checkbox is checked , the | symbol is a field separator, and “VC” is the value of the Voucher Code.

Custom table

Custom table
Sample Custom table

The custom controls are defined in the Custom table. This is populated on the web server, and is downloaded to client devices, along with the rest of the company data.

The system administrator defines the custom controls used by the company, by either uploading a CSV file or editing the table directly. The Table Layouts describes the use of this table.


  1. My first attempt to implement this feature was very poor, and did not involve the web server at all.
  2. My second attempt was much better, and used a new table, which I called Custom.
  3. For some reason, I forgot to expose the new table in the admin site (or at least I think that is what happened).
  4. This meant that custom controls could not be used in the hosting service.
  5. I have only just realised this, but the table is now fully visible.
  6. I have added this post, by way of apology.


This form allows you to update various parameters associated with your account, as follows:

Field Usage Default
Company Name This appears at the top of the main menu, for information only.
Contact Email An email address that we can use to contact you.
Password The password used to logon to the hosting service. password
Page Size The number of rows that the table editor displays. 10

Downloading customers

The mobile app allows users to add new customers in the field, or to change the details of existing ones. It also allows them to upload these new or changed customer records to the web server.

As with orders, they hosting service allows uploaded customer records ti be downloaded as a CSV file, and uses change flags to acoid downloading records more than once.

The main difference is that mobile users can be expected to make legitimate changes to existing customer records. They cannot do this with orders, because orders cannot be modified once they have been sent.

Downloading orders

CSV File

Orders are downloaded from the web server in CSV format. The file in unnormalised form: the orders and orderDetails tables are joined together, and the product name is also included. This is a fairly standard format for downloading data from a web server. Orders for more than one item are split over several lines, with line for each item. Only fresh orders are downloaded.

Change Flags

In order to avoid downloading the samer record more than once, change flags is used. Every record has a flag that indicates whether it has been downloaded (or processed in some other way). The flag is set when the record is uploaded from a mobile device and reset when the Clear change flags option is selected. The standard procedure is:

  1. download orders
  2. process CSV file
  3. reset change flags

Repeat Uploads

The system allows users to upload an order more than once. This usually happens when the first attempt fails for some reason, or when the data has not been uploaded correctly. The hosting service also allows orders to be uploaded more than once, and updated records are output in the CSV file together with fresh ones. This means that the same order can be downloaded more than once.

Duplicate Order Ids

The mobile app allocates order numbers in sequence, and in a multi-user environment each user is allocated a separate reange of order ids. In principle this should ensure that order ids are always unique. However it is always possible that two users will use the same order id by mistake.

The hosting service can handle this, and both orders will be output to the CSV file. But the system that you are importing the CSV files to probably expects unique order ids. To help resolve this, the Find duplicates option lists all orders with duplicate ids. Hopefully there will not be any.

Maintaining stock levels


The hosting service has a basic stock monitoring feature. A column called stock has been added to the products table, to record the stock level for each product. When an invoice is uploaded to the server, the corresponding stock levels are debited.

A new section Stock has also been added to the main menu, with the following options:

Option Function
Adjust stock levels Uploads a CSV file containing current stock levels.The stock values in the file overwrite the ones in the products table. Other rows are unaffected, and no other columns are changed.
List stock levels Displays the current stock level for each product.
Download stock levels Downloads a CSV file containing the stock levels for all the items in the products table. This file can be modified, and used as input to the Adjust stock levels option.

CSV File

The CSV file used for stock levels has the following format:

Name Contents
productId Unique id of product
stock Stock level
name Name of product (optional, for reference only)

Uploading a CSV file

This form allows you to upload data to your virtual web server. The data must be in a file on your computer, in CSV format. It must also contain a header line, with the names of the fields that you want to upload. Most fields are optional, and can be omitted if not used.

The fields are as follows:

Field Usage Default
Table The table to upload your data to. Choose a name from the drop-down list.
File Selects a CSV file on your computer.
Encoding Refers to the character set of the CSV file, which can either be ANSI or UTF-8. ANSI
Convert case If checked, fields will be converted to upper case, title case or sentence case, depending on their usage. checked
Trim spaces If checked, trailing spaces will be stripped strip from all fields. checked
Delete existing rows If checked, all the data in the table will be removed before the data in the CSV file is inserted. checked

N.B. The form will stop uploading data after ten errors have occurred.

Choosing a locale


The language that an Android or iOS app uses, and the way that it formats numbers and dates, depends on the locale. For computers, this is a combination of the location and the language, e.g. British English or Canadian French. The standard on both platforms is that the locale is determined by the user, and not by the app itself.

Changing the Locale on Android

  1. Launch the Settings app.
  2. Go to the Language & input section.
  3. Choose a Language from the drop down list at the top.

Changing the Locale on iOS

  1. Launch the Settings app.
  2. Go to the General section.
  3. Select a Language.

Working with categories


The product categories have a simple breadcrumb structure, which is well illustrated by the categories in the sample data, as shown in the screenshot on the right.


Categories must obey a few simple rules:

  1. The “>” (greater than) character is used as a separator, so for example Wines is a subcategory of Beverages, and its full name is “Beverages>Wines”.
  2. The full name of a category includes the names of all its parent categories. For instance Bitters is a subcategory of Beers, which in turn is a subcategory of Beverages. Its full name is “Beverages>Beers>Bitters”.
  3. Categories can either contain products or other categories, but not both.
  4. If a category contains other categories, its full name end in a separator, e.g. “Beverages>”.
  5. A product can only belong to one category.

The last three rules are not intuitively obvious. They are included to make things easier, both for the user and the app.


Because categories can be nested, they are represented as a tree structure. The screenshot on the right shows a category being selected from the sample data. The icon for the Beverages category indicates that it contains other categories, but no products. Tapping this category expands it, as shown below.

Note that the Beverages category has expanded, and its icon has changed. Now tapping on it would cause it to contract again, hiding all its subcategories. Beers is another parent category, which shows that categories can be nested more than one level deep.

Large lists


One of the features that distinguishes the Sales Manager from its competitors is its ability to handle large amounts of data. It can easily cope with 50,000 customers or products, with almost no loss of performance. To achieve this, the mobile app is heavily optimised, and provides a rich set of features to search such large datasets.

The lists involved are:

  1. The customer list.
  2. The product list.
  3. The list of lines that can be added to an order.

The main difference between the customer and product lists is that the latter can be divided into categories. The lines behave in a similar way, but have additional properties. This chapter will focus primarily on the product list, but the others behave in a similar manner.
The name of the category is used as the title of the screen, and tapping on it displays a list of categories to choose from. This is a standard Android paradigm.

Sort Order

The list can be sorted either by id or by name. When a list is opened, it is always sorted by name, but this can be changed by tapping on the Sort button in the action bar. Changing the sort order also changes the field that gets searched. If the list is ordered by name, that is the field that gets searched, and vice versa.


To search a list:

  1. Tap the Search icon (magnifying glass) in the action bar. The action bar is filled with an input field, and the input panel (soft keyboard) pops up.
  2. Enter the target text to search for, and tap the back button, to dismiss the input panel. The list will now be restricted to the items whose names (or ids) contain the target text. If a category has been selected, only the items in that category will be displayed. An example is shown in the screenshot on the right.
  3. Tap the back button, to end the search and return the list to its normal state.
    Note that the search is case insensitive – upper and lower case characters are treated in exactly the same way. Note also that only the key field is searched. It is not possible to search for text in any other field. This is done by design, in order to speed up the search process.