Monday, 20 May 2013

Phil Daintree and his "hate pages"

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.


Writing "Hate Pages" about fellow developers and then denying them the right to reply has always been Phil Daintree's weapon of choice when trying to bully developers out of the project. Back on 11 September 2007 when Phil was trying to bully most of the early webERP developers out of the project, he wrote to me telling me he had written one of his hate pages about them and was going to publish it on weberp.org. 

At the time I dissuaded him from this action. He again brought the subject on the following day, and again I had to dissuade him. Unfortunately when he came to writing his "hate page" about me there was nobody left to dissuade him.

These are used to force developers to leave quietly, as Phil maintains personal control over the mailing lists, the forums, the wiki and the web site, meaning that it is not possible to dispute any of the lies he writes within the project. What really annoys him about me is that I refuse to be intimidated off the project.

I received many warnings about this behaviour when I was first getting deeply involved in the project. Unfortunately I really didn't believe them. Obviously I should have, and have since apologised to those whose warnings I ignored.

Only by taking the stand I have can I hope to save current and future developers being treated in this way.

Tuesday, 14 May 2013

ABC analysis of stock items.

One of the most important methods of keeping accurate stock levels - though by no means the most widely used, especially in Africa - is cyclical stock checking. That is the constant checking of the stock throughout a financial period, rather than leaving stock checks to the period end.

This has two big advantages in the control of an organisations stock. Firstly the stock levels are kept in a much more accurate state as they are checked more frequently, and secondly any variances are far easier to track down if the period between checking the item is much shorter.

A necessary prerequisite of cyclical stock checking is an ABC analysis of the organisations stock. By ABC analysis I mean to rank the items by:

A - The most important items to the organisation
B - Important to the organisation but not critical
C - Slow moving or non important stock items.

At the moment we have no ABC analysis. This is a proposal to rectify that.

ABC classification is a way of grouping your stock items. There are a few different ways to set up an ABC Ranking, such as Velocity (times sold), Quantity sold/Consumed or by Margin. But the most common method is the Annual Sales Volume ranking. This method will allow you to identify the small number of items that usually account for most of your sales value (think 80/20 rule).

My plan is to first implement Annual Sales Volume Ranking method, but to do it in such a way as to make adding other methods easy in the future. To do this I propose to setup a table to hold the methods to be used. This table will have the following structure:

CREATE TABLE `abcmethods` (
     `methodid` TINYINT NOT NULL DEFAULT 0,
     `methodname` VARCHAR(40) NOT NULL DEFAULT '',
     PRIMARY KEY (`methodid`)
);

Initially this will have just one record in, 
methodid=>0 
methodname=>Annual Sales Volume Ranking

The next table will contain the groups that are being used. This will specify the criteria used. Each method can have several groups. I propose the following table:

CREATE TABLE `abcgroups`(
     `groupid` INT(11) NOT NULL DEFAULT 0,
     `groupname` VARCHAR(40) NOT NULL DEFAULT '',
     `methodid` TINYINT NOT NULL DEFAULT 0,
     `apercentage` TINYINT NOT NULL DEFAULT 0,
     `bpercentage` TINYINT NOT NULL DEFAULT 0,
     `cpercentage` TINYINT NOT NULL DEFAULT 0,
     `zerousage` CHAR(1) NOT NULL DEFAULT 'D',
     `months` TINYINT NOT NULL DEFAULT 12,
     PRIMARY KEY (`groupid`),
     CONSTRAINT `abcgroups_ibfk_1` FOREIGN KEY (`methodid`) REFERENCES `abcmethods` (`methodid`) 
);

The zerousage field is intended to hold the category into which items that have no usage at all should be put. This would normally be C or D. The months field is the number of prior months movements that should be analysed.
Finally I propose a separate table to hold the ABC category for each item and group. This would look like:

CREATE TABLE `abcstock` (
     `groupid` INT(11) NOT NULL DEFAULT 0,
     `stockid` VARCHAR(20) NOT NULL DEFAULT '',
     `abccategory` CHAR(1) NOT NULL DEFAULT 'C',
     PRIMARY KEY (`groupid`, `stockid`), 
     CONSTRAINT `abcstock_ibfk_1` FOREIGN KEY (`groupid`) REFERENCES `abcgroups` (`groupid`),
     CONSTRAINT `abcstock_ibfk_2` FOREIGN KEY (`stockid`) REFERENCES `stockmaster` (`stockid`) 
);   

Using these three tables should provide for a very flexible system, easily changed in the future.

The function to actually assign the categories would work something like this:


1.  Calculate the 12 month value usage for all of the stock items.
2.  Rank the items in descending order by value.
3.  The "A" items are the top 80%.
4.  The "B" items make up the next 15%.
5The "C" items are the remaining items that have any usage in the period being looked at.
6.  Label zero-usage items as "D".


Comments and constructive (yes Phil I am looking at you!) criticisms would be very much appreciated.







Wednesday, 8 May 2013

The anatomy of a KwaMoja plugin

As promised in my previous post regarding KwaMoja plugins, here is a tutorial on constructing a plugin.

Each plugin is a zip file. For this tutorial we will use the demo plugin that is available from http://www.kwamoja.com/demo_plugin.zip.

This demo takes the form of a standard "Hello World" type application, as used in most programming tutorials. The plugin will present the user with a text box asking for the users name. If that user has not used the plugin before from that IP address they will get a message saying "Hello John" or "Hello Jane" or whatever his or her name is. If they are returning, they will get a welcome back message.

If you unzip this file you will see it contains 5 files:

HelloWorld.php
HelloWorldDB.php
HelloWorldDBRemoval.php
HelloWorldLinks.txt
summary.xml

ALL KwaMoja plugins must have a summary.xml file. This is the file that tells KwaMoja how to install the plugin. Here is the xml contained in this examples summary.xml:

<plugin>
    <name>Demo Plugin</name>
    <installed>0</installed>
    <license>gpl</license>
    <scripts>
        <script>
            <name>HelloWorld.php</name>
            <pagesecurity>1</pagesecurity>
        </script>
    </scripts>
    <menulinks>HelloWorldLinks.txt</menulinks>
    <dbupdates>HelloWorldDB.php</dbupdates>
    <dbremoval>HelloWorldDBRemoval.php</dbremoval>
</plugin>


The first attribute is a descriptive name for the plugin. I have just called this one "Demo Plugin" .

The next attribute shows whether the plugin has been installed. KwaMoja will automatically set this to 1 when the plugin is installed. This should be set to zero when writing the plugin, and then never manually changed.

Then there follows the name of the license that this plugin is covered by. In this case, the GPL.

Next is an array of scripts that will be installed and a security token for each script. HelloWorld.php is a KwaMoja script. The plugin can contain any number of these scripts. In this simple example we only need the one, and I have given it a security token of one meaning any user can use it. I will go through this script and how to write a KwaMoja script in my next post.

The next attribute is called "menulinks" and contains the name of the file containing details of what new menu items are required to be added, and if any new modules are to be added to the menus. The full contents of this file for our example are:

$ModuleLink[] = 'Test';
$ReportList['Test'] = 'test';
$ModuleList[] = 'Test';

$MenuItems['Test']['Transactions']['Caption'][] = 'Hello World';
$MenuItems['Test']['Transactions']['URL'][] = '/HelloWorld.php';


The first three items on the list will setup a new module called "Test" to appear on the main menu. This is not obligatory. For instance if your plugin fits best in the Manufacturing module, then there is no need to have these lines. The next two lines are necessary for every script that you want the user to have access too via the main menu. These take the form of $MenuItems[Module][Section][Caption] and $MenuItems[Module][Section][URL] where "Module" is the name of the module, either one that you have just created or from the following list:

'orders', 

'AR', 
'AP', 
'PO', 
'stock', 
'manuf',  
'GL', 
'FA', 
'PC', 
'system', 
'Utilities'

The section is either "Transactions", "Reports", or "Maintenance" and determines whether the item appears in the left, centre, or right section of the menu. The Caption is the string that will appear in the menu, and the URL is the path to that menu, which must include a "/" at the beginning, as in "/HelloWorld.php".

Penultimately there is an attribute called dbupdates. This provides a link to a file containing the following:

<?php
CreateTable('helloworld',
"CREATE TABLE helloworld (
ipaddress char(13),
name varchar(30),
PRIMARY KEY  (`ipaddress`, `name`)
)", $db);

$SQL = "UPDATE www_users SET modulesallowed=modulesallowed+'1, WHERE userid='" . $_SESSION['UserID'] . "'";
executeSQL($SQL, $db);
?>


These are commands used to make any necessary changes to the database for your plugin to work. If it doesn't need any changes there should still be a file that just contains the <?php ?> tags in it. KwaMoja comes with an api to allow you to access the database, and facilitates the use of different DBMS's. You can find the functions here. The first call is to the CreateTable() function. Secondly there is some sql to update the users modulesallowed field and finally there is a call to the executeSQL() function to run this SQL.


The final attribute in the summary.xml file is called dbremoval. This is a reference to the file that contains the commands required to remove the database changes when the user uninstalls the plugin. Our demo file contains the following:

<?php
DropTable('helloworld', 'name', $db);

$SQL = "SELECT modulesallowed FROM www_users WHERE userid='" . $_SESSION['UserID'] . "'";
$Result = DB_query($SQL, $db);
$MyRow = DB_fetch_array($Result);

$SQL = "UPDATE www_users SET modulesallowed='" . substr($MyRow['modulesallowed'], 0, strlen($MyRow['modulesallowed'])-2) . "' WHERE userid='" . $_SESSION['UserID'] . "'";
executeSQL($SQL, $db);

?>
As you can see above, both the dbupdates and the dbremoval files can contain php code to verify information before updating the database.




So that is a simple KwaMoja plugin. This zip file can be imported into KwaMoja, and you can see and use this plugin directly from the menu.
The next post will cover actually writing the script.


Sunday, 5 May 2013

KwaMoja now has a plugin architecture!

Yesterday Munir blogged about the new KwaMoja plugin architecture. As he says in his post this will enable both open source and commercial plugins to be written for KwaMoja. The code with this system in can be found here, and a demo plugin can be downloaded from here.

This is an exciting new development as it means that specialist areas, such as health and education, to name but two, can now have full KwaMoja support. Previously code for this sort of area would not have been part of the main line, as it would be too specific to be included.

It also provides an opportunity for third party developers to make money from the KwaMoja ecosystem.

KwaMoja plugins come as zip files, they must be uploaded to the KwaMoja installation from the browser interface, and then unpacked and installed via the same interface.

There are three scripts that have been added to KwaMoja: PluginUpload.php to load the plugin to the installation, PluginInstall.php to unpack and install the plugin and PluginUnInstall.php to remove the plugin.

Later today I hope to post a tutorial on how to create your own plugins.

This code could be adapted to work in webERP if Phil Daintree wanted to work with us on doing that. From his recent behaviour I suspect he wont.

Friday, 3 May 2013

Where did you say the truth was Phil?

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 apologise and 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.


Phil Daintree has recently started to say that the truth is at the web site he hijacked from a project that was started by an Indian gentleman as a result of this exchange on here:

http://weberp-accounting.1478800.n4.nabble.com/Add-all-into-Shipment-td4655643.html#a4655738

However let us ignore the ethics of stealing another projects domain name to use to attack a developer in your own project, but rather let us put to rest what is really the truth once and for all.

Writing "Hate Pages" about fellow developers and then denying them the right to reply has always been Phil Daintree's weapon of choice when trying to bully developers out of the project. Back on 11 September 2007 when Phil was trying to bully most of the early webERP developers out of the project, he wrote to me telling me he had written one of his hate pages about them and was going to publish it on weberp.org. At the time I dissuaded him from this action. He again brought the subject on the following day, and again I had to dissuade him. Unfortunately when he came to writing his "hate page" about me there was nobody left to dissuade him.

Phil starts off by saying that the page is a defense against things I have said in this blog. However as anybody associated with the project for long can tell you Phil has been putting up hate pages about me for several years now, as can be seen rightv back in this thread: http://weberp-accounting.1478800.n4.nabble.com/AP-checks-td4019909.html#a4040317 All my blog posts are date stamped, so this is a lie.

Phil then says that anybody who opposes him must be me in disguise and says all their messages come from the same IP address. Where is your proof of this silly statement Phil? Oh there is none, because it is a lie! This from a man who poses on the internet as somebody called Anthony to attack me!!

Phil then goes on to say that the fixed asset module I wrote did not work. Yes it did, and is still in use at one of Uganda's biggest retailers (Bata shoes). Where is the link to these bugs Phil? Oh there is none because it is a lie.

Phil says he then removed me as admin. I have linked to the posts where he removed me as admin in an earlier blog post. The real reason was that he was upset that we had an argument over retaining the purchase order history. Where is your proof that this when you removed me Phil? Oh there is none because it is a lie!

Amendment 2712/2013:

Phil has now sent me evidence that he withdrew my svn access before the discussion on purchase ordering. This may or may not prove that he also withdrew my admin at this point, but he certainly didn't have the courage to tell me this either publicly or privately until after he had his ego dented by the PO conversation.

Phil then claims credit for some changes done to purchase ordering. As I have linked to in an earlier post the changes were written by me. As I had at that point had my access to svn removed, I posted the changes to a different repository. As demonstrated in the earlier post, Phil took my commit and then posted it the following day (these commits are date stamped by sourceforge) claiming it as his own work!! What is more incredible is that he now claims I "bitterly opposed" my own changes. Phil where is your proof of any of this? Oh there is none because it is a lie.

Phil says he originally removed my svn access because I was overwriting his changes. Does he post any links to this? No he doesn't because there are none. It is just another of his lies.

Amendment 27/12/2013

Phil has now sent me a commit where I had accidentally over written some changes that he had done. I apologised for this almost immediately after, as our commits had crossed. I was in Africa at the time on a very slow internet connection and hadn't had time to update. The commit only overwrote some case changes to variable names. Hardly the crime of the century. Certainly not as bad as his recent commit forcing many users off webERP. My​ reaction was to immediately apologise to Phil , and explain. His reaction was to remove my SVN access.

Phil says I wanted to do the database upgrades in a new language of my own invention calle "pseudo sql" In fact the language was PHP as can be seen here:
https://sourceforge.net/p/weberp/code/9402/ Where is the proof of this new language Phil? Oh there is none because it is a lie!

Phil then claims I was "violently" opposed to his number formatting system. All I suggested was that we used the functionality that PHP provides for doing this instead of inventing his own functionality. No violence used whatsoever!! Phil's solution also requires that the locale be installed, as has been discovered by him since. Where is your proof of this "violence" Phil? Oh there is none because it is another lie!

Phil then goes into a long diatribe on his attempt to claim the copyright to the whole codebase. This contradicts itself at every twist and turn, in his desperate attempts to deny it. As far as I can make out the latest story is that saying that the copyright is owned by weberp.org is a secret code for saying that the copyright is actually owned by the individual authors. Really Phil? In that case why the need for a secret code? Why the need for subterfuge? If thats what you mean just say it and be clear! Or is it just another lie?

He then goes on to say that my access to the mailing list is only moderated! Not so as anyone can see from the messages to that nabble forum. For instance here:
http://weberp-accounting.1478800.n4.nabble.com/BOMExtendedQTY-php-does-not-properly-handle-PO-Quantities-td4656253.html As anyone can see Bob's postings to the nabble forum are allowed through to the mailing lists mine are not. Are these postings in any way abusive? No, it is just another of Phil's lies.

On the subject of abuse as anybody can see by reading the archives, more often than not the abuse was started by Phil, as a result of him losing a technical discussion.

Phil says he took away my svn access because I was no longer making a useful contribution. Strange that he has continued to take my code and commit it, just claiming it as his own code!! Does he post any links to where my contribution was not useful? No he doesn't.

Phil then goes into a long quote purportedly written by me. Does he post a link to this post? No he doesn't. Can he find it in googles cache? No he can't. In fact can he find it anywhere? No can you as a reader? I have tried searching for it by using some phrases from it, and the only person who appears to have written it is Phil Daintree. Oh dear another lie Phil?

He then prints a reply to his own comment. I shall ignore most of this as commenting on his own comment is just silly.

Then he tries to justify a different method of calculating a developers contribution to the code. All I can do is point people to his original comment here: http://weberp-accounting.1478800.n4.nabble.com/Copyright-notices-and-License-statements-tt1487216.html#a1487221 How bitter do you have to be to keep changing these things to try and show that you are a bigger and more important person??

+Phil Daintree  says in his hate pages:
 

"http://sourceforge.net/p/web-erp/code/5834
 
contained references to his Kwamoja fork.
I asked him to review and fix it... he refused."
 
Strange because http://sourceforge.net/p/web-erp/code/5836/ clearly shows me 
removing these references to KwaMoja immediately +Phil Daintree  pointed out my mistake - An 
accidental mistake I apologised to him about straight away. He then goes on to fabricate
an email where I apparently say I wasn't going to remove these references, even
though sourceforges SVN clearly shows I already had!!  
 
+Phil Daintree says that I am not a member of the ICAEW. Quite right I am not, but when did I claim to be?
What I have said is that I am a UK qualified accountant. Phil is very careful in his choice of language
here because he implies that I am not a qualified accountant without actually saying so. 
He knows what my qualifications are because I have shown them to him so he resorts to such
innuendo in the hope people won't read too deeply into what he says. This is another reason why
+Phil Daintree  is so frightened of allowing me a right to reply to his lies.

+Phil Daintree has said I overwrote some of his work on purchase ordering and has
linked to some commits on this subject. Yes I fixed some bugs as Phil's work didn't  
deal with cancelled orders. I notice these bug fixes are still in the webERP code 
today!! Strange that exactly 5 years on Phil hasn't got around to removing this
code if it is so bad!! It is typical of the man that he tells these lies and doesn't have the 
honesty to allow me to link to the evidence showing that all that he says about me
is just lies, lies, and yet more lies! 

+Phil Daintree says in his hate pages that the reason he removed my ability to commit to the webERP project was that I misspelled  the name of a CSS class in one of my commits. As anybody who understands HTML/CSS programming can tell him if a web browser finds a css class it doesn't know it just ignores it. There was no performance loss or harm to the user interface. Compare this to some of the really bad commits he and others have done! Interestingly a css class of the exact same name was soon added to webERP meaning that +Phil Daintree  himself now commits code with this identical css class in it!!

So that's it? No comments on what I have said in this blog at all, despite that being what it was titled as. Just lies and nasty innuendos about my coding and my character that he cannot prove because they are just lies.

I will leave it to the reader to judge what is the truth. I have always been content to put the facts before the community and let them judge. I see no need for censorship or banning. So why does Phil believe in censorship and banning to avoid criticism?

ps Phil, can you stop sending the hate mail that pollutes my inbox every day?

Hate blog????????

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.

Phil has described my blog in the webERP forums as a hate blog!!

This is a very strange description for it. I assume he is not talking about the tutorials on the use of the api that he banned from the forums, or yesterdays tutorial on the security systems.

This blog was written as a reaction  to his continually posting hate pages about me on the web. I ignored them for years, but in the end was persuaded to to publish the truth here. There is nothing in this blog that Phil disputes. All posts are sent to him first to allow him the opportunity to review and dispute anything. He can freely comment (though I am not allowed to comment on the lies he says about me) anywhere in this blog. I back up all my allegations with facts, and links to those facts. Unlike Phil.

I feel sad for Phil, after all we were friends for a while. The life of a liar is not easy, continually looking over your shoulder to see if you are being found out. Look at the lengths the poor guy has to go censoring me, to try and ensure nobody finds him out. No Phil, I don't hate you, if you brings out any emotion it is just pity. It really saddens me that you have fallen to such a low level that you should resort to such lies in pursuit of your rather pathetic personal vendetta against me.

Phil and I have both worked hard at webERP over the years, and you can see the amount we have both done by following the link he recommends here:
http://weberp-accounting.1478800.n4.nabble.com/Copyright-notices-and-License-statements-tt1487216.html#a1487221

Thursday, 2 May 2013

KwaMoja/webERP security

This question came up recently on the webERP forum:

I'm new to webERP and naturally have some questions. I've created a role called "Inventory" in Access Permission Maintenance, then a user for this role and limited access to just "Display Inventory" module in User Maintenance. But I'd like to further limit access so my inventory user can NOT see pages in this range:

• Inventory Valuation Report
...
• List Negative Stocks
• Stock Transfer Note[/align]

The webERP Manual is vague on this. Is there a doc I can read to find out can I restrict a user, for example, to just Inventory.Maintenance.View or Update Prices Based On Costs?


Unfortunately the advice the poster was given was complex and not really correct, and the administrator of the forum has blocked me from helping people there. However, there is a much simpler answer which doesn't involve setting up phantom security tokens, and other complexities. This is to go to each of the reports they want removed in the "Page Security Settings" option in the setup module, and from there just give it a security token of a higher level than the inventory user. For instance set it to "General Ledger Reports/Inquiries" which makes more sense for something like an Inventory Valuation report. Then the report will be gone from the users screen the next time they log in. It's as simple as that!

However that led me to thinking that a lot of people (including it seems the current webERP project developer) who don't really understand the security system within KwaMoja/webERP so I thought it might be good to explain how it works.

Every user has a security role. These roles are meant to mirror their real life roles. So for instance we may have a role of an inventory clerk, and a role of an accountant. There can be any number of inventory clerks, and any number of accountants, all having the same role. As many roles as are wanted can be created.

Each role is given a number of security tokens. Each of these tokens permits the user with that role to perform different functions. There are a number of predefined tokens:


0 Main Index Page

1 Order Entry/Inquiries customer access only

2 Basic Reports and Inquiries with selection options

3 Credit notes and AR management

4 Purchasing data/PO Entry/Reorder Levels

5 Accounts Payable

6 Petty Cash

7 Bank Reconciliations

8 General ledger reports/inquiries

9 Supplier centre - Supplier access only

10 General Ledger Maintenance, stock valuation & Configuration

11 Inventory Management and Pricing

15
User Management and System Administration

When a user tries to access a function, the security token for that functionality is looked up in a database table called scripts and it is then compared with the array of security tokens that is owned by the role allotted to that user. If the token is in that array, the functionality can be accessed, if not, then access is denied.

This lookup is also performed when displaying the menus, and if the security token is not there, the menu option will not be displayed.

This system is simple elegant and flexible. It can be made as simple or as complex as an organisation requires. For instance a one person business only needs one security token, and one role, whereas a large business with hundreds of employees will have a very complex structure.

I hope this helps provide some insight into how the system works.