Wednesday, March 27, 2013

How BlueBox meets the needs of the Retail Sector

ABOUT THE BLUEBOX
The BlueBox has been providing ePOS, inventory, logistics and procurement software solutions since 1996. Our strengths are the flexibility of our platform combined with our ability to fit it to the bespoke requirements of our customers quickly and affordably. We charge a single monthly fee per store (from £50 per month) which includes unlimited tills, software upgrades and free support via our UK support team.

POWER OF THE CLOUD COMBINED WITH OFFLINE ACCESS
Our systems are next-generation, 100% web/cloud based. No software installation is required and your data is live and central at all times. Our ePOS module works online and offline ensuring you don’t have any downtime.

SIZES, OPTIONS AND STYLES
We have been working in the garment retail sector for over 8 years and our system features powerful size/colour/style options. Our retail reporting includes automated replenishment and supplier/item league tables which keep you informed about winners and losers in your catalogue.

INTEGRATED LOYALTY SYSTEM
We have a powerful integrated Loyalty System which issues reward vouchers and points automatically and offers online self-help services to your members. Our Promotions Engine features unlimited combinations of ‘buy-x-get-y- free’ type deals.

E-COMMERCE & WEB DEVELOPMENT
We also offer e-commerce/web-development solutions that dove-tail seamlessly with your stores, allowing you to run your on-line store as an ‘extra branch’ and click-and-collect features as well as traditional shipping options.

FULL FREE DEMO
You can get full access to your own demo copy of our full system at our website -  www.blueboxonline.com.

Monday, March 25, 2013

A small neat PHP Captcha Script

I cannot stand the way some Captcha scripts look and work. Personally I give up very quickly when signing onto a web-service if I cannot 'identify' the Captcha characters easily. making hard for spider-bots is one thing, but making it impossible for humans is quite another.

So, here is a simple, clear captcha script written in PHP that makes it harder for bots to submit your forms, but obviously it not impenetrable (I would presume).

I have called it 'Matcha' to differentate it from other Captcha scripts (at least for us BlueBox-ers).

Invoke the Matcha session string at the top of your form like this:
  • $_SESSION["matcha"]=strtoupper(chr(65+rand(0,25)).chr(65+rand(0,25)).chr(65+rand(0,25)).chr(65+rand(0,25)).chr(65+rand(0,25)));
  • This will create a string of 5 uppercase A-Z characters.
In your form add these 2 rows to the layout:
  • <div class=cr_form_label>
    Characters to Match:
    </div>
    <div>
    <img src=\"<!--:class:bb_mymodule:matcha:-->\" >
    </div>

    <div class=cr_form_label>
    Enter Characters*:
    </div>
    <div>
    <input class=cr_form_field id=matcha name=global[matcha]>
    </div>
  • Remember to create a new BlueBox2.0 module called bb_mymodule (use the module name here, not this example name)
In the PHP BlueBox2.0 module (bb_mymodule) create a function as follows:
  • function matcha($err){
            global $global;
            $im = @imagecreatetruecolor(257, 36);
            $text_color = imagecolorallocate($im, 140, 140, 140);
            $white = imagecolorallocate($im, 255, 255, 255);
            imagefilledrectangle($im, 0, 0, 257, 36, $white);
            $font_file = 'portal/database_name/custom_modules/captcha.ttf';
            imagefttext($im, 15, 3, 70, 30, $text_color, $font_file, $_SESSION["matcha"]);
            imagepng($im,"portal/database_name/custom_modules/c/$_SESSION[matcha].jpg");
            imagedestroy($im);
            resp("portal/database_name/custom_modules/c/$_SESSION[matcha].jpg?".uniqid());
        }
  • You will need to upload a TTF font to the server that is suitably difficult to read for a bot-scanner.
 Finally, do a check when your form gets posted, to see if the entered amount matches the Matcha string:
  • if(strtoupper($global[matcha])!=$_SESSION[matcha]){
         resp("The characters you have entered do no match the string shown.");
         return;
    }

Wednesday, March 20, 2013

What a small Samsung Android Phone can do.

I recently spent a few days on-site doing an ERP implementation of BlueBox for a new customer, and was reminded how powerful a simple Android phone can be in business systematisation.

Our clients run a small sports and schoolwear clothing manufacturing and sales business and required point of sale, inventory, production control and integrated accounts with xero.com.

Easy enough with BlueBox, I had a 3 days scoping session with them, followed by a week of bespoke PHP/MySQL programming, and this last visit was the final implementation of another 3 days. (Side note - it always amazes me how long it takes for 'big ERP systems' to eventually fail in their implementations, while BlueBox quietly achieves what to most in the industry would consider impossible when it comes to speed and success of deployment.)

In this process we identified that bespoke order-taking facilities would be required at the front-desk (ePOS) and have implemented sales order creation facilities within our ePOS to allow sales people to take the order, amongst normal sales items, which then creates the required sales orders in the back-office.

These are then displayed on a dashboard for production control and visibility, and various automated customer communication triggers (SMS/text message and email) are sent at points in the process.

Now to the phone. In order to track and simplify jobs through the production process, we added QR codes to the bottom of each Sales Order, one for 'previous stage' and one for 'next stage'. Stages are mapped to Sales Order categories which essentially become production process maps. Initially I thought we'd need small tablets to scan the barcodes/QR codes at each stage, but, strangely, we found that tablets (no names mentioned because it seems to apply across the board) have notoriously poor cameras, which do not seem to offer the ability to macro-focus on barcodes. Who came to the rescue? A dirt-cheap Samsung Galaxy Ace (old model!) for under £80 with a 5MP camera scanned the QR codes from stage to stage perfectly.

So our final implementation used web-served QR codes on each sales order, delivered by Qrickit.com, and these were scanned into the Samsung Galaxy Ace using the Barcode Scanner App by Zxing Team, which neatly bounces each scan onto our BlueBox cloud based system to a bespoke script that moves the sales order forwards or backwards in the production process.

So quick. So affordable. So powerful. And... so easy!

Friday, March 8, 2013

What does BlueBox do?

I get asked to prepare a short summary on 'what does BlueBox do' quite regularly, and wanted to blog this answer here this week, as I feel it can assist some of our partners and staff for future reference.

It is difficult to answer this question generically, as we are a multi-disciplinary platform that appeals to many business sectors. When putting together a statement like this you want to bear your target audience in mind. In retail, for example, somebody may be looking for ePOS or Inventory Control, whereas in manufacturing they would be looking for Bills of Materials and MRP functionality.

BlueBox2.0's feature list is extensive and growing all the time, so it is always worth referring there as well.

Here is a recent summary I put together with a focus on the para-statal market:



"The BlueBox has been providing bespoke business system and database solutions since 1996 for large brands like Old Mutual, KFC, Barclays/ABSA, Skype and Standard Bank as well as small to medium sized businesses. 

We are a small, customer-focused company who do not believe in the one-size-fits-all approach to system implementation. Our systems are 100% web/cloud based, requiring no software installation and ensuring all data is live and central at all times.  We take great care to fit our solutions to your requirements while using all the tools at our disposal to ensure this can be done quickly and affordably.

Included in our modules are Stock Control and Asset Management, Sales Orders and Billing, CRM, Procurement Management with MRP and Replenishment, Loyalty and Customer Retention, Human Resources, Manufacturing, Marketing Campaigns and Communications.

Recently added to this list is our Process Management module. This allows us to map business processes within your organisation to system generated procedures. 

If you would like an introduction to BlueBox please do not hesitate to visit our website at www.BlueBoxOnline.com where a full free demo of our system is available to you."

Monday, March 4, 2013

New Ajax/JSON Functionality for BB2.0

From Steven de Klerk, Senior Developer at BlueBox:

New Ajax functionality has been added to BB2 this week, allowing for any PHP function to be easily accessed via JavaScript through the use of Ajax and optional JSON objects, without the need for additional coding. The function to call via Ajax is simply called "ajax" and is available on all BB2 modules. This function accepts a few parameters, listed below:
  • global[ajax_method] - Required. Sets the function to be called within the module
  • global[param] - Optional. The parameters to be passed to the called function, as an indexed array. So, param[0], would be the first parameter. param[1] the second, and so on. e.g. $_class->method(param[0], param[1]);
  • global[json_encode] - Optional. Sets the response to the Ajax call. Default is a basic "success" response, otherwise when this param is set to "1", it will return a JSON encoded object.
The new "ajax" function does a permission check to ensure the user can run the "ajax_method" listed, and then either returns a basic "success" if the function was run without problems, or returns a JSON object, which would be the primary use for this new functionality.
Let's say we wanted to add a new user with the user name of "testuser" and the first name of "Paul". To do this, we'd simply call the following url:
/?class=bb_users&method=ajax&global[ajax_method]=add&global[param][0][this_class]=bb_users&global[param][0][fields][name]=testuser&global[param][0][fields][first_name]=Paul
Breaking that up, you'll see we've called "ajax" on the class "bb_users", and set the PHP function as "add". We then pass through the parameters. Since the "add" function only takes one mixed array, we're going to set global[param][0] with our array of data. In this case, it's just the "this_class" parameter, and then the "name" and "first_name" fields. Since we haven't set it to return a JSON encoded object, it will just print out the text "success" on completing. If you use this method, make sure to check that the response text only contains the word "success" (responseText == 'success'), as an error could also be present, and should be displayed to the user in that case.
This, however, doesn't fully utilize the new functionality. To do this, "global[json_encode]=1" should be passed in the url, telling the ajax function to return a usable JSON object, which provides far more information. For example, running the same url above, but with the included JSON encoding switch, we see the returned data is:
{"response":{"this_class":"bb_users","fields":{"name":"testuser","first_name":"Paul"},"do_not_redirect":"true","_id":"52"},"rows":4,"html":"","status":"success","error":""}
This is a JSON encoded string, and thanks to JavaScript libraries such as Prototype, we can turn this into an easy to use object by calling "evalJSON()" on the reponseText. The JSON object contains a few parameters:
  • response - the response from the function called. This can be anything, depending on what the function returns
  • rows - the number of rows. If there's only 1 result (such as a "get" or "add" call), it will list the number of elements.
  • html - any outputted HTML while running the function. Useful if the function does resp/print calls
  • status - whether the function completed successfully or not
  • error - any errors that may have been caught while running the function
The first thing to do when checking the response, is to make sure that the "status" parameter == 'success', and if it doesn't, then check the "error" parameter to see if any errors were caught. If it was successful, you can now check the function response and use the returned data. So, if we wanted to alert the new _id of the user we added, we can do so like this (assuming that the variable "data" is the evaluated JSON object):
if (data.status == 'success') {
     alert(data.response._id);
} else {
     alert('Error: ' + data.error);
}
Handling and calling the new "ajax" function can all be done fairly easily through Prototype's Ajax.Request functionality, however, to make things even easier, there's a new BB2 ajax function which handles most of the leg work described above.
The new JavaScript function is called "ajax2json", and is a quick and easy gateway to the above functionality.
The new function takes the following parameters:
ajax2json(callback, className, method, param, loaderElm, largeLoader)
  • callback - Required. (function) The callback function when the response has arrived from the request
  • className - Required. (string) The BB2 class/module to call
  • method - Required. (string) The BB2 method to call on the above class
  • param - Optional. (object) An object containing the parameters to be passed to the above class->method
  • loaderElm - Optional. (string) The HTML element to add a loading spinner during the request
  • largeLoader - Optional. (bool) Whether or not to use a large spinner
So, let's do the same user add as above, and then get a list of users with the same name as what we've added. To start off with, we'll create a callback handler and then an "add" function:
 function handleAddResponse(data) {
  if (data.status == 'success') {
   alert('New record added with _id: ' + data.response._id);
  } else {
   alert('Error: ' + data.error);
  }
 }
 function addUser() {
  var param = {
   0: {
    fields: {
     name: 'testuser',
     first_name: 'Paul'
    }
   }
  };

  ajax2json(handleAddResponse, 'bb_users', 'add', param);
 }
Breaking down the above, we call "ajax2json" with the callback function "handleAddResponse", which checks to make sure the response was successful, and if so, it alerts the new _id. We then set the class, method and parameters which is a basic JavaScript object, made up of the fields we want to set.
Once we've added our user, we want to get a list of users with the name "Paul" and then handle that data. This can be done like so:
 function handleListResponse(data) {
  if (data.status == 'success') {
   alert('Found ' + data.rows + ' row(s).');
   data.response.each(function (row) {
    var output = '';
    for (var field in row) {
     output += field + ': ' + row[field] + '\n';
    }
    alert(output);
   });
  } else {
   alert('Error: ' + data.error);
  }
 }
 function listUsers() {
  var param = {
   0: {
    where: 'first_name LIKE \'%paul%\''
   }
  };

  ajax2json(
handleListResponse, 'bb_users', 'getList', param);
 }
This time our callback function is a bit more advanced, as we're going to run through the response data and alert the values. If we do the add before the list, we'll get back at least one row containing all of the data for our new user record. We can now display this data in a table, use it in another add, and more.
With this new functionality, there should no longer be a need to create additional BB2 functions to act as "proxies" between standard and custom BB2 functions and the browser, as we can now pass and receive data between the PHP side of BB2 and the client/browser side seamlessly.

Sunday, March 3, 2013

New sales discount by user group (and item category)

BlueBox20 now has the option of managing sales discount by user group (previously only possible at user level).

Any discount applied at user group level will automatically apply to any sales item added to sales orders (and their subsequent downstream documents despatch notes, debtor invoices etc), as well as point of sale till slips.

A further level of control is available whereby you can now link a user group to a specific Item category, and at that point specify the sales discount that applies to that user group for all items in that item category.