Sunday, 10 March 2013

Can open source be developed behind closed doors?

This page is written in response to the lies that +Phil Daintree has written about me, and spread on the internet. Despite years of searching he has been unable to find anything I have written that is untrue, and he has had to resort to vague generalities, faked emails, and badly fabricated screenshots (you can see the joins if you zoom in using any bit mapped image editor). +Phil Daintree is welcome to make any comments to these pages, as he has done in the past. If I agree with what he says I will amend my writings, if I do not agree I have allowed his comments to stand next to mine so that people can make their own judgements. I have every confidence in the intelligence of readers to make a sensible judgement based on the facts. +Phil Daintree will not allow me the right of reply to any of the lies he has told about me. It seems to me significant that he realises that if people see both sides of the argument they will see through his lies.

As with anything I publish, anybody (except the viagara  salesmen) can comment on my blog. I make a public commitment that I will not attempt to forge or censor any posts, as goes on in all the communication channels on webERP. If Phil Daintree wishes to dispute anything in this blog he is free to do so. If I am wrong I will alter my post. I trust in the common sense and intelligence of people to read the facts and to make up their own minds.

WebERP has started to move to a "behind closed doors" development model, whereby most of the code changes don't get pushed out to svn until after a release has been done. For instance the changes made for 4.10 weren't committed to svn until after 4.10 was released and then as one large patch (http://sourceforge.net/p/web-erp/code/5797/). The same has since been done for the 4.10.1 release. So the question is, can this development methodology work in the long term?

Not committing code changes until after a release has been done, was a tactic that Oracle employed with mysql as an attempt to stop any forks (such as mariadb) from using their code until after they had released it (http://www.mysqlperformanceblog.com/2012/08/16/where-to-get-a-bzr-tree-of-the-latest-mysql-releases/), and to make taking those commits harder. It seems the intention was to give Oracle a commercial advantage. Presumably this is also the intention behind Logic Works using this technique for their webERP commits. However eventually Oracle was forced to drop this tactic.

I feel that in the end one of the great advantages that open source development has is the concept of "peer review" where the code can be looked at and reviewed by everybody, thus finding and fixing  bugs before it is unleashed as a release for people to use in their businesses.

This was shown when the latest version of webERP was released with two scripts that wouldn't even run due to syntax errors in them, and the release had to be redone with the fixes in them, leading to the embarrassing result of there being two different file releases with the same name.

I think in the end Logic Works will like Oracle be forced to give up this behind closed doors development methodology.

Amendment 15/01/2014 - Phil has since said that he wasn't deliberately holding back committing his work, some of it was out for testing at customers and he didn't consider the rest of it sufficient to warrant a commit until after the release was made. Strange that when the work was committed it contained so many errors, but as I have said many times I want this blog to be a true and accurate record so I include Phil's comments so that all may judge.

Amendment 04/11/2014 - +Phil Daintree persists in denying this despite the evidence against him being so obvious. This is the initial commit Phil did on the 2/2/2013 for the release of 4.10.1 as is shown by the update to the Change.log file "+2/2/13 Version 4.10.1 Released". There then follows 5 commits of bug fixes. Here is a huge commit he did on the 22/2/2013 containing a lot of files that were initially in the 4.10.1 release but not updated to subversion. As can be seen Phil now updates the release date of 4.10.1 to the 22/2/2013, nearly 3 weeks after the first release. Phil has said "these files had been tested for some time on a customers server". However  here and here are examples of corrections I made immediately after this huge commit to scripts that wouldn't even run as they contain PHP syntax errors. Not only had they not been tested on a customers server they hadn't even been tested by Phil. Then here we have yet another release of 4.10.1 dated 25/2/2013 23 days after the first release of 4.10.1.
How Phil can persist with his lies in the face of such obvious evidence is a mystery only he can explain.

Thursday, 7 March 2013

Programming the KwaMoja API - A simple client part 2

This is the second part of the tutorial on building a PHP client to extract data from KwaMoja via the API. If you missed the first, read this first. In the last part we created a client that queried the KwaMoja installation and extracted a list of stock locations, we then used to populate a drop down list in our HTML page. What we then wanted to do, was to extract the full name of the location, rather than just showing the code.

To do this we need a function much like the one we used to extract the array of location codes. Here is the full code:

    function LocationName($LocationCode) {

        //Encode the data items
        $UserID = php_xmlrpc_encode("admin");
        $Password = php_xmlrpc_encode("kwamoja");
        $Code = php_xmlrpc_encode($LocationCode);

        //Create a client object to use for xmlrpc call and set its debug level to zero
        $Client = new xmlrpc_client("http://localhost/KwaMoja/api/api_xml-rpc.php");
        $Client->setDebug(0);


        //Create a message object, containing the parameters and the function name
        $Message = new xmlrpcmsg('kwamoja.xmlrpc_GetLocationDetails', array($Code, $UserID, $Password));


        //Use the client object to send the message object to the server, returning the response
        $Response = $Client->send($Message);


        //Decode the response and return the array
        $ReturnValue = php_xmlrpc_decode($Response->value());
        if ($ReturnValue[0] == 0) {
            return $ReturnValue[1]['locationname'];
        }
    }


The first section encodes the parameters as XML. The first two parameters are always the userid/password combination, and for this function call we need a third parameter, which is the code of the location that we require the name of. The second section is identical to the previous function and creates an instance of the XML-RPC client class. The third section then creates an instance of the message class, with the first parameter being the full name of the API function being called, in this case kwamoja.xmlrpc_GetLocationDetails, and then the second parameter is an array of the encoded parameters, (location code, userid, password). This message is then sent to the server, and the response decoded into an array called $ReturnValue.

As last time the first element of the array signifies whether the function was successful (a zero), or any other integer for an error code. The second element is an associative array of details for that location. The key of each element is the field name for that value. In our case we just want the location name, so we return the element ['locationname']. If it was the telephone number we were interested in we would just return the ['tel'] element.

Changing the line in the HTML where we fill the drop down box to:

echo '<option value="'.$LocationCode.'">'.LocationName($LocationCode).'</option>';

we can see that the web page in our browser now looks a little better.

The full name of the location appears in the drop down the list, but the value returned by the form is still just the code.

All that is left to complete our client, is to type a stock code in the text box, submit the form and return the amount of stock for that code at the chosen location. First we need to insert some PHP code in the HTML to handle the form being sent:

<?php
        if (isset($_POST['submit'])) {
            echo 'The quantity of '.$_POST['StockID'].' at '.$_POST['location'] . ' is : ''.GetStockQuantity($_POST['StockID'], $_POST['location']);
        }
 ?>


As you can see this calls another PHP function - GetStockQuantity() - that retrieves the stock quantity for the required item at the required location. Looking at the API function reference in the manual the API function we require is kwamoja.xmlrpc_GetStockBalance. However this time there is a small addition we require as this function returns an array containing the stock balances at all the locations for the given stock item.

The full code for the PHP function is:


    function GetStockQuantity($StockID, $LocationCode) {
        //Encode the data items
        $UserID = php_xmlrpc_encode("admin");
        $Password = php_xmlrpc_encode("kwamoja");
        $StockCode = php_xmlrpc_encode($StockID);

        //Create a client object to use for xmlrpc call and set its debug level to zero
        $Client = new xmlrpc_client("http://localhost/KwaMoja/api/api_xml-rpc.php");
        $Client->setDebug(0);
        //Create a message object, containing the parameters and the function name
        $Message = new xmlrpcmsg('kwamoja.xmlrpc_GetStockBalance', array($StockCode, $UserID, $Password));
        //Use the client object to send the message object to the server, returning the response
        $Response = $Client->send($Message);
        //Decode the response and return the array
        $ReturnValue = php_xmlrpc_decode($Response->value());
        if ($ReturnValue[0] == 0) {
            $Items = $ReturnValue[1];
            for ($i=0; $i<sizeOf($Items); $i++) {
                if ($Items[$i]['loccode']==$LocationCode) {
                    return $Items[$i]['quantity'];
                }
            }
        }
    }


I wont go through this in details as it is mostly the same as the previous functions. The key section is the last:

        $ReturnValue = php_xmlrpc_decode($Response->value());
        if ($ReturnValue[0] == 0) {
            $Items = $ReturnValue[1];
            for ($i=0; $i<sizeOf($Items); $i++) {
                if ($Items[$i]['loccode']==$LocationCode) {
                    return $Items[$i]['quantity'];
                }
            }
        }


Here the RPC returns an array of locations with the stock quantities for each location, and we filter out the location we need.

Putting all this together we get the following when we run the script in our browser:

Looking at the stock status in KwaMoja we see:

Showing that we have returned the correct numbers.

I have uploaded the source for this tutorial to http://www.kwamoja.com/documentation/xml-rpc_tutorial.zip please feel free to download and try it out.

In the next part I will introduce some error checking into the code.

Sunday, 3 March 2013

Phil Daintree's shameless lies - Part 2

This page is written in response to the lies that +Phil Daintree has written about me, and spread on the internet. Despite years of searching he has been unable to find anything I have written that is untrue, and he has had to resort to vague generalities, faked emails, and badly fabricated screenshots (you can see the joins if you zoom in using any bit mapped image editor). +Phil Daintree is welcome to make any comments to these pages, as he has done in the past. If I agree with what he says I will amend my writings, if I do not agree I have allowed his comments to stand next to mine so that people can make their own judgements. I have every confidence in the intelligence of readers to make a sensible judgement based on the facts. +Phil Daintree will not allow me the right of reply to any of the lies he has told about me. It seems to me significant that he realises that if people see both sides of the argument they will see through his lies.

As with anything I publish, anybody (except the viagara  salesmen) can comment on my blog. I make a public commitment that I will not attempt to forge or censor any posts, as goes on in all the communication channels on webERP. If Phil Daintree wishes to dispute anything in this blog he is free to do so. If I am wrong I will alter my post. I trust in the common sense and intelligence of people to read the facts and to make up their own minds.

We have a lot of lies to get through so it's time I did another of this series in order to get it completed this year.

Lie number 3 - Phil Daintree's claim to have written "most of the code" in webERP

Phil Daintree claims that other people including me, are exaggerating their contribution to webERP and in a recent email he claimed that "most" of the code had been written by him alone, which justified his claim to own the copyright to the whole code base. Let's examine the basis of this claim. Phil Daintree uses a command that assigns the authorship of a line of code on the basis of the last change to that line. After Phil Daintree discovered this command I noticed that he had started to go through the code adding spaces and tabs to the end of lines of code, where they wouldn't be noticed unless the editor being used was set up to show them. Using his command, this gave him authorship of the line, even though the actual code had been written by someone else.

A little while ago I used a script to remove what is called "trailing white space" and is normally considered a bad thing to have in code. When Phil Daintree realised that this would radically reduce his supposed contribution to the project he accused me of trying to sabotage the project (http://weberp-accounting.1478800.n4.nabble.com/Fwd-Web-erp-svn-SF-net-SVN-web-erp-5765-trunk-td4656055.html#a4656056) due to some unspecified "outside interest". Strangely he reversed out my commit and the posted the identical commit himself, but claiming it as his own work. What was worse about his allegation was that he had by then banned me from posting to the mailing list, and so there was no way to refute this and despite numerous people asking him to, he has never apologised for it.

The other flaw in his argument is that it takes no account of the quality of the code. In other words adding a space onto the end of a line is given the same weight as code that actually does something. One of the most important contributions while I have been involved in the project was Mark Yeager's MRP contribution. But was it actually Mark's? Using Phil Daintree's command, Mark's contribution to the files starting MRP*.* is only 3.1% with the bulk belonging to Phil Daintree. So there you are Phil Daintree is claiming to have written most of the MRP system with the original and true author only being credited with 3.1%!! This claiming other people's work as his own is a familiar theme through all his lies. In the first post of this series I proved how he had taken my purchasing ordering report, copied it and committed it himself as his own work the following day!!

Lie number 4 - Phil Daintree's claim about the sourceforge logo

Phil Daintree claims that my only contribution to making webERP popular was to add the sourceforge logo into the footer of each page of webERP.

This is somewhat extraordinary as it was Phil Daintree himself who added the sourceforge logo to the footer in 2005, nearly two years before I joined the project. I actually took it out for a while!!

Anybody who looks at mailing lists for the period I was the administrator of the project (summer 2007 through to January 2011 when I ceased to be admin because Phil Daintree's ego was put out by the argument over retaining Purchase order history) will see that I spent countless hours helping people with their webERP issues. In fact both before I was admin, and afterwards, until Phil Daintree banned me from helping people on the mailing lists, I spent thousands of hours of my own time helping people. I spent thousands of pounds of my own money traveling, speaking at seminars and conferences helping to promote webERP. This I happily did, without seeking any recompense, or even gratitude from those like Phil Daintree who gained financially from the fact the project had a higher profile. I do however find it sad that Phil Daintree should lie like this in an attempt to denigrate the very hard work I did

Anyway, enough for now, watch out for part 3!

Saturday, 2 March 2013

Programming the KwaMoja API - A simple client part1

The Client:

For this tutorial we will build a small PHP application that will first interrogate KwaMoja for a full list of available stock locations, build them into an HTML drop down list and then allow a user to input a stock item code and return the quantity of stock of that item at the selected location. We will use PHP for simplicity but any language that has an xmlrpc library (just about every language) can be used to write a client. It is a lengthy post, so I am splitting it into two parts. This is part 1.

Firstly we need the xmlrpc library, so we copy the xmlrpc sub-directory from KwaMoja to this new project.

The basic code will look like this, and be saved into a file called index.php:


<html>
    <head>
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    </head>
    <body>
        <form action="index.html" method="post">
            Stock Code:<input type="text" name="StockID" /><br />
            Location:<select name="location">
            <?php // Here will go the available stock locations from KwaMoja?>
            </select><br />
            <input type="submit" name="submit" value="Submit" />
        </form>
    </body>
</html>



As it’s name suggests, the xmlrpc function calls are made by sending an XML file with the function name and the parameters to the server, and receive an XML file back from the server.

To assist with this, the phpxmlrpc library that KwaMoja uses (and we will use as well for our client) contains methods to encode our function call as XML, and to decode the XML that we receive back.

First off we need to include the xmlrpc library in our file, so immediately above the HTML, we need the following:

<?php
    include 'xmlrpc/lib/xmlrpc.inc';
    $xmlrpc_internalencoding='UTF-8';
    include 'xmlrpc/lib/xmlrpcs.inc';

?>

Running this page in our browser looks like this:
Not very pretty but you can see the idea.

Now the next thing we need is the code to populate the drop down box with the stock locations in it. Looking at the API function reference in the manual we see a function called kwamoja.xmlrpc_GetLocationList(). Obviously this is the function we require. Looking at the reference, the function takes two parameters, a valid userid for the KwaMoja instance, and the password for that user. In my case that is admin/kwamoja as in the standard demo setup, you must change yours to be whatever the name of the database is on your target KwaMoja installation.

We require a PHP function to return a list of locations to populate the drop down list. The function will look like this, and be at the bottom of the file, within a PHP code section (ie <?php ?>).

   function GetLocations() {

        //Encode the user/password combination
        $UserID = php_xmlrpc_encode("admin");
        $Password = php_xmlrpc_encode("kwamoja");

        //Create a client object to use for xmlrpc call
        $Client = new xmlrpc_client("http://localhost/KwaMoja/api/api_xml-rpc.php");


        //Create a message object, containing the parameters and the function name
        $Message = new xmlrpcmsg('kwamoja.xmlrpc_GetLocationList', array($UserID, $Password));

<

Friday, 1 March 2013

Programming the KwaMoja API - An introduction

 Introduction

This is a series of blog posts that will attempt to teach the programming and debugging of client applications for KwaMoja, using the API that comes bundled with it.

This can seem daunting at first, but as I hope to show you when you look behind the magic, it is really very easy for anyone who knows a programming language.

KwaMoja comes with a simple to use and flexible API that allows client programs to access KwaMoja in a safe and secure manner. If you wish to write an application that accesses KwaMoja, either to post transactions, or to extract information, then you should use the API, rather than try to access the KwaMoja database directly, as the API makes sure that the integrity of the data is maintained.

In this series I intend to show how to create a simple PHP client application, how to debug that application, then I hope to move on to writing a client in a different programming language, and finally how to extend the API.

The Protocol

The API uses the XML-RPC protocol to communicate between the client and the server. This was chosen because it is lightweight, simple, and easy to use. The API uses the XML-RPC for PHP external library, rather than the XML-RPC extension for PHP as it is small lightweight, and the extension is often not installed by default, so would add another dependency to KwaMoja. 

However the API was structured in a manner that allows other protocols to be used very easily. All that would need to be done to use the SOAP protocol for instance would be to create an api_soap.php file with the same functions as the api_xmlrpc.php file.

Setting up the server:

Before we start on the client there is one thing needed to be changed on the server side. This is to set the database to be used inside the api/api_php.php file. Mine is simply called kwamoja, so line 6 of api_php.php should read as:

$api_DatabaseName='kwamoja';


That is it for this introductory blog. Next time we will get down to some serious programming by starting work on our client application.

Wednesday, 27 February 2013

Phil Daintree's shameless lies - Part 1

An introduction

This page is written in response to the lies that +Phil Daintree has written about me, and spread on the internet. Despite years of searching he has been unable to find anything I have written that is untrue, and he has had to resort to vague generalities, faked emails, and badly fabricated screenshots (you can see the joins if you zoom in using any bit mapped image editor). +Phil Daintree is welcome to make any comments to these pages, as he has done in the past. If I agree with what he says I will amend my writings, if I do not agree I have allowed his comments to stand next to mine so that people can make their own judgements. I have every confidence in the intelligence of readers to make a sensible judgement based on the facts. +Phil Daintree will not allow me the right of reply to any of the lies he has told about me. It seems to me significant that he realises that if people see both sides of the argument they will see through his lies.

As with anything I publish, anybody (except the Viagra  salesmen) can comment on my blog. I make a public commitment that I will not attempt to forge or censor any posts, as goes on in all the communication channels on webERP. If Phil Daintree wishes to dispute anything in this blog he is free to do so. If I am wrong I will alter my post. I trust in the common sense and intelligence of people to read the facts and to make up their own minds.

I thought I would do a series of posts on the libels that Phil Daintree has been putting around the web. I also believe he has been mailing them to anybody who he thinks will listen. There are too many to do in one post so I thought I would make a regular feature of it.

Phil Daintree has admitted to a number of people that he made the whole lot up as an attempt to discredit me, but it seems he is still desperately seeking to find someone to believe him.

Phil Daintree regularly states that I am a liar, but has never managed to find anything I have said that is untrue. A number of people have asked him for an example but he never replies. try it and see....

It's been a bit spooky being the subject of his hate campaign. Sometimes I have felt like I was playing Michael Douglas to his Sharon Stone. He has even been snooping around in the online lives my friends and colleagues, in his desperate attempts to find an example of where I have said something untrue.

The fact that he cannot find an example, despite the closeness of our working relationship over such a long time is a source of great pride to me.

I will state nothing here without backing it up with relevant links to the facts.

Lie number 1 - The reason and timing of his taking away my admin rights

Phil Daintree apparently claims that he withdrew my admin privileges because he didn't like my work on fixed assets (incidentally still in use at one of East Africa's major companies - they don't like his version it doesn't do what they require). This is just untrue.

The truth is Phil Daintree had his ego bruised when somebody agreed with me in a dispute over Purchase Order history being kept, in December 2010 as can be seen here: http://weberp-accounting.1478800.n4.nabble.com/Re-webERP-users-Bug-in-Planning-and-MRP-td3085185.html#a3085235.

I had been administering webERP right up until this date when Phil Daintree suddenly stated that he was withdrawing my admin access. This was the first time either publicly or privately he had mentioned my admin access. Only the day before I had been using my admin rights so the claim that he removed them in November is obviously one of his lies.

Lie number 2 - The purchase ordering system

Phil Daintree apparently then goes on to say that I didn't like his idea of keeping the purchasing conversion factor inside the order class. Phil Daintree has obviously forgotten that revision control systems have a long memory. As can be seen here I actually wrote the code and committed it here http://bazaar.launchpad.net/~tim-weberpafrica/web-erp/trunk/revision/4188 at 2011-01-09 12:27:33 UTC and then Phil Daintree copied my code and committed it here: https://sourceforge.net/p/web-erp/code/4463/#diff-5 on the following day.

So Phil Daintree "claims" I was against his idea and says: "Tim refused to accept my decision, rather than gracefully accepting it was a simple mistake and it was much more elegant to hold the units in the businesses unit of measure. A tirade of angry emails to the list ensued much more than a simple technical disagreement.". Now it turns out that he actually copied my work and claimed it as his own!! This theme of copying other peoples work and claiming it as his own carries on through much of the life of webERP.

The initial purchase ordering system that Phil Daintree initially claimed was "......really good - sorry it has taken me a while to recognise the large improvements you have effected in this area. I can't believe there has not been more excitement around this work. Although perhaps it is only crazy accountants that get excited about such things." (http://weberp-accounting.1478800.n4.nabble.com/Major-upgrade-to-purchasing-td1487909.html#a1487912) wasn't even written by me but by Rob Virgin, so why Phil Daintree thinks I would have behaved like he claims is yet another mystery!!

As Fahad points out here https://sourceforge.net/p/kwamoja/blog/2013/02/lies-damn-lies-and-phil-daintree/ little if anything Phil Daintree says turns out to be true, which is why he needs to so extensively use censorship in the webERP project.

Anyway, that is enough until Part 2  

Monday, 4 February 2013

KwaMoja/webERP and me, the facts!

As with anything I publish, anybody (except the viagara  salesmen) can comment on my blog. I make a public commitment that I will not attempt to forge or censor any posts, as goes on in all the communication channels on webERP. If Phil Daintree wishes to dispute anything in this blog he is free to do so. If I am wrong I will alter my post. I trust in the common sense and intelligence of people to read the facts and to make up their own minds.

This is a post that I didn't really want to have to spend time writing. It is unfair that attention should be taken away from the hard work the guys on KwaMoja have put in, and this is why I have tried to remain silent on the matter. Also I want to concentrate on the code which is far more fun, and far more productive. However it has been brought to my attention that there is much misinformation on this subject that is being propagated on the web by people with their own agendas to push. So, for those reasons I feel I have to put right the facts regarding me, KwaMoja, and webERP.

KwaMoja grew from a series of lectures I gave at a community college in Kenya last year. As part of the course work I set the students to work on some modifications for webERP. Two of the students expressed an interest in continuing this work and doing their own version for Kenya. I had also about that time had an email from an Indian gentleman wanting to know if I wanted to do a fork. I put him in touch with my two students and that is how KwaMoja began. One of my reasons for setting up my company in Africa was always to help African programmers, so I was pleased to help them, and I have donated some code to them. I also leant them some money to purchase the domain name (after their .org domain name was taken by somebody trying to make mischief) and for hosting, which has since been repaid. However this doesn't diminish my commitment to webERP which is a project to which I have given thousands of hours and spent thousands of pounds in promoting over the years. Indeed a look at the recent commits here https://sourceforge.net/p/web-erp/code/commit_browser shows I am still a very active committer to webERP.

One of the things I love most about open source is being able to discuss interesting ideas with like minded people. Technical discussions are a very interesting way of reinforcing your views on a subject. It is a shame that these have been virtually banned on webERP and a pleasure to work with people on KwaMoja who are interested in discussions.

The short answer for those who don't want to read all the stuff above is that I am very committed to both KwaMoja and webERP and intend to keep donating my time and my code to both projects.