Thursday, June 20, 2013

Overriding Ability to Change Price, Qty and Discount in BB2.0 Forms

In BlueBox2.0, we have a 6 settings at item_data level which control whether their item price/qty/discount can be edited in forms. This protects the buying or selling price of an item, as well as stopping staff from discounting items that they shouldn't or changing the tax/vat codes on items that they shouldn't.

Up until now this setting has been global and no user was able to get around these controls if they were set. Now we have a new permission at bb_sales and bb_procurement level which allows this to be bypassed.

Simply setting a user with the permissions bb_sales-can_change_form_prices_qty_and_discount or bb_procurement-can_change_form_prices_qty_and_discount will then allow them to edit these fields where others cannot.

Note that any users who currently have bb_sales-all/admin and bb_procurement-all/admin will also inherit this new ability.

Tuesday, June 18, 2013

Multiple Delivery Addresses in BlueBox

BlueBox2.0 now accommodates multiple delivery addresses via the bb_users module.

When viewing a user you will notice at the bottom of the plugins that there is a plugin called 'User Delivery Addresses and Contacts'. This is intended to be an area where unlimited additional addresses and contact details for this user can be stored.

It's immediate implication in the system is that for Sales Orders and Despatch Notes, if the selected customer file has multiple delivery addresses, they will appear via an ajax insertion just above the manual entry area for 'delivery address' and will allow the author to select any address as required which will be populated into the free-text area in the form.

Sunday, June 9, 2013

Introduction of Multiple Base Currencies in BlueBox

One of the strengths of BlueBox is it's multi-business-unit, mult-location, multi-tax, multi-currency nature. This powerful matrix makes allows us to create extremely flexible, scalable business structures on one database.

One of the historical issues or limitations has been that the currencies table has been a global feature, limiting the entire system for a certain groups of companies to a single base currency. This has now been improved to allow the setting of base/currency values at each BU/Location level. Essentially, this means that you can have a different currency table for each business/country of operation.

This has one key limitation. That is the fact that there is no 'super base' currency sitting at 'group/global' level. Any financial reporting higher than any 'currency point' in the BU/Location matrix will be useless, as it will combine base numeric values that span multiple base-currencies, thereby blurring the various values together and making the totals useless.

This should not detract from the newly found capacity that BlueBox has to allow regions to transact in any number of currencies, and now, to be able to store their base-transactions in the currency of their choice.

For older systems, the currency table will continue to operate as before (essentially at global/global level). But for new installs, there is now this option to set the currency table at various BU/Locations under global, as long as no currency table then exists above these points.


Friday, May 31, 2013

Time for lighter documents

A while ago I blogged about the introduction of font-reducing CSS to standard BlueBox documents.

The purpose of this was to force certain docs, via the Database Templates Module, to show their font at a reduced size and in a lighter font. This was suggested as a manual intervention at the time.

I have decided to make this standard on Sales Orders, Debtors Invoices and StockTake Sheets, for now. This will be added to more documents as they need it over the next few months. If Database Templates already exist for these modules then there will not be any change, but any updates on sites which do not have override templates in place will notice this improvement automatically.

Essentially the change involves wrapping the document print template with this html:

Notice the addition of class=tbl to the table tag as well.

<style>
.tbl table{
   font-family:sans-serif;
   font-size:8pt;
}
.tbl tr{
   font-family:sans-serif;
   font-size:8pt;
}
.tbl tr td{
   font-family:sans-serif;
   font-size:8pt;
}
.tbl td{
   font-family:sans-serif;
   font-size:8pt;
}
</style>
<div style="font-family:Arial,sans-serif;font-size:9pt;">

<!-- old template starts here -->
<!--:template:letterhead_one:-->

<table width=100% bgcolor=(#COLOR2#) cellspacing=1 cellpadding=3 class=tbl>

<!-- old template ends here -->
</div>

Wednesday, May 22, 2013

Sales Orders and Automated Lead Times

Recently added to BlueBox 2.0 a new setting at Sales Order Category level whereby the number of days lead-time for the delivery of the SO can be auto-set.

If you edit the Sales Order Category, you will see a new field called 'Default Lead Time Days' - this number will be added to today's date to determine the ship-date for the associated Sales Order.

A small routine then determines if the ship-date falls on a Saturday or Sunday, or if bank/public holidays are set in the calendar (Publishing->CMS->Public Holidays) these are avoided too.

If a ship-date is manually set when adding the Sales Order this automated process is skipped.

Friday, May 17, 2013

Password Reset Request Tokens

Just a small bit of code to explain the use of password reset request tokens.

If a user forgets their password there are numerous methods of helping them.

I suggest using bb_users_passwd_reset_request_tokens as this method allows the user to verify their reset before actually triggering it.

The approach would be something like this:

if($global[reset_password]){
                $u=new bb_users();
                $u=$u->get(array("where"=>"

                             name=".sqlstr($global[reset_password])." OR email=".sqlstr($global[reset_password])."
                             "));
                if($u){


                    $new_token=new bb_users_passwd_reset_request_tokens();
                    $new_token=$new_token->add(array(

                         "do_not_redirect"=>"true",
                         "this_class"=>"bb_users_passwd_reset_request_tokens",
                         "fields"=>array("userISbb_usersID"=>$u[_id])));

                    $reload_token=new bb_users_passwd_reset_request_tokens();
                    $reload_token=$reload_token->get(array("_id"=>$new_token[_id]));


                    bb_sendmail(array("subject"=>"Your Password Reset Token - ".date("YmdHis"),
                        "from"=>"some@email.com",
                        "to"=>$u[email],
                        "body"=>
                        "
                        <html>
                        <head>
                        </head>
                        <body>
                        <table align=center width=640>
                        <tr>
                        <td align=left>
                        Dear ".$u[first_name].",<br>
                        <br>
                        You have requested a password reset token.<br>
                        <br>
                        Click on this link to reset your password:<br>
                        <br>
                        http://".$_SERVER[HTTP_HOST]."/?somepage&global[pwrs]=$reload_token[_apikey]
                        <br>
                        <br>
                        from<br>
                        Support
                        </td>
                        </tr>
                        </table>
                        </body>
                        </html>
                        "));

                }else{
                   //error no user found for email
                }
            }


Then, the link they click on will trigger:


if($global[pwrs]){
                $reload_token=new bb_users_passwd_reset_request_tokens();
                $reload_token=$reload_token->get(array("_apikey"=>$global[pwrs]));
                if($reload_token){
                    $u=new bb_users();
                    $u=$u->get(array("_id"=>$reload_token[userISbb_usersID]));
                    if($u){


                        $alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
                        $pass = array(); //remember to declare $pass as an array
                        $alphaLength = strlen($alphabet) - 1;
                        for ($i = 0; $i < 8; $i++) {
                            $n = rand(0, $alphaLength);
                            $pass[] = $alphabet[$n];
                        }
                        $pwd= implode($pass);


                        $update_password=new bb_users();
                        $update_password=$update_password->edit(array(

                              "do_not_redirect"=>"true",
                              "this_class"=>"bb_users",
                              "fields"=>array("_id"=>$u[_id],"password"=>$pwd,"password_reminder"=>"set_by_password_reset")));

                        bb_sendmail(array("subject"=>"Your New Password - ".date("YmdHis"),
                            "from"=>"support@domain.com",
                            "to"=>$u[email],
                            "body"=>
                            "
                            <html>
                            <head>
                            </head>
                            <body>
                            <table align=center width=640>
                            <tr>
                            <td align=left>
                            Dear ".$u[first_name].",<br>
                            <br>
                            You have requested a password reset.<br>
                            <br>
                            Your new password is $pwd
                            <br><br>
                            Please be sure to change this to something secure, which you will remember, when you log in next.
                            <br>
                            from<br>

                            Support
                            </td>
                            </tr>
                            </table>
                            </body>
                            </html>
                            "));
                    }
                }else{
                    //error: token failed
                }
            }