Saturday 30 March 2013

Phil Daintree's shameless lies - Part 3

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.

Lie number 5 - Phil Daintree makes untrue statements about me on the mailing list, and refuses me the right to reply

This is more than one lie, but to save space (there are so many lies to get through) I will combine them all into one. Here are a selected few of his untrue statements:

  1. Phil Daintree said here http://weberp-accounting.1478800.n4.nabble.com/Copyright-td4655625i20.html#a4655722 that "I understand Tim is ranting to everyone he can off list now". This was totally untrue. The only emails I had sent to people off list were helping them with webERP queries that they had put on the list, and that Phil Daintree had rejected my replies to them on the list. I challenge Phil Daintree to find one person who had received a "rant" from me. Why does this upset me? Because Phil Daintree has sent this to a publicly archived mailing list. He refuses me the right to reply to that list to challenge this assertion. This gives credibility to his lie.
  2. Phil Daintree said in a post to the mailing list here http://weberp-accounting.1478800.n4.nabble.com/Fwd-Web-erp-svn-SF-net-SVN-web-erp-5765-trunk-tt4656055.html that I was "..hell bent on destroying the project..". This because I had removed the trailing white space that he had put onto the end of the lines. The interesting thing here is that Phil Daintree reversed my patch, and then immediately applied it as his own work, and then in some of his recent web pages about me has even included it to prove that he has written "most of the code in webERP". If that patch shows I am "hell bent on destroying the project" then obviously so is he!! Again I was not given the right of reply. Why does this upset me? Because Phil Daintree has sent this to a publicly archived mailing list. He refuses me the right to reply to that list to challenge this assertion. This gives credibility to his lie.
  3. Phil Daintree says in a post here http://weberp-accounting.1478800.n4.nabble.com/Fwd-Re-WebERP-developers-Tag-tt4656191.html#a4656194 that "... I get these silly emails almost daily!..". On that particular day I had just returned from nearly three weeks away trying out the new golf clubs! I hadn't even taken a laptop with me! I couldn't have been sending him any emails let alone silly ones. I do occasionally write to Phil Daintree when he has posted a lie about me, and if I send an email to anyone that mentions Phil Daintree I do copy him on it, so that he can be sure there is no rant, and so that he has the opportunity to reply! Can Phil Daintree say that he copies me on emails that refer to me? Has anyone received an email about me from him that mentions me that doesn't include me in the address? I know that many have as they have forwarded them to me. Why does this upset me? Because Phil Daintree has sent this to a publicly archived mailing list. He refuses me the right to reply to that list to challenge this assertion. This gives credibility to his lie.
On the subject of right to reply Phil Daintree can make any comments on this blog that he wants, and I publicly promise that I wont interfere with them in any way. I am more than happy to debate any issue with him, and to let others decide on the basis of the facts. Unlike him I see no need for forgery or censorship to push my point of view, I am happy for the facts to be debated and for others to decide.

As this post is basically three lies rolled into one, and its longer than I intended I will leave it there for this time.

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.