how tax-table data structure differs from implementaiton notes

Zhang Weiwu zhangweiwu at realss.com
Thu Jun 20 21:55:21 EDT 2013


I observed, when trying to modify my tax rate following new government 
regulation, that I have many tax-table entries with exactly the same name. I 
could not have done it myself. This prompts me to bug-tracking.

During the bug hunting, I found tax-table in gnucash XML file is a 
contraption. It took me a whole morning to decipher it, so here is what I 
observed to share with others. Someone with privilege my consider

according to http://svn.gnucash.org/docs/HEAD/business1.html:

> Business Design & Implementation Notes
> Derek Atkins <warlord at mit.edu> Version of October 2003

> The gncTaxTable and gncBillTerm business objects have parent, child, 
> refcount, invisible field in thier structures that deserve some 
> explanation:

Why not put children under parents, instead of listing them all together and 
create links to children in parents and to create links to parents in 
children? This contraption makes it so hard to think.

XML is used to structure data, and in this case, data is structured in XML 
like tab-seperated vector and of course then "the structures deserve some 
explanation".

>  a child is a 'frozen' instance of a parent. For example, the tax
>  percentage in a particular tax table may change over time, but you dont
>  want that change to affect already-posted invoices... So you make sure
>  there is an immutable 'copy' (read: child) of the tax table when you post
>  the invoice and repoint at the child.

In that case, parents should be abstracted, and parents should have no real 
instances. In reality some parents are directly used with no children, some 
only have their first child used, some have all their children used.

> a parent can have many children, but it will only have a 'child' pointer 
> if the parent has not been modified. Think of this as a copy-on-write 
> mechanism. posted invoices will continue to use the _same_ child until the 
> parent is modified, at which point a new child will be created.

that doesn't match my observation. the correct description should be:

a parent node corresponds to many other notes who affiliate him as a parent, 
but it always only point to one child, and that is his latest child .

In fact, the parent-children relationship is not a good way to describe this 
scenario. Parent-children relationship in its semantic sense doesn't 
maintain that parents does nothing while children does everythin, nor does 
it maintain parents only keep the last children alive. Besides, there are 
sub-tax-categories in real finance that is more like parent-child, to add 
the confusion. Parent-children here is simple poor choice of words.

> invisible means "dont show this in the list". It's so you dont get all the 
> children in the tax table list -- you only see parents. I suppose this 
> flag could also be called "is-child" as I believe that only children can 
> be invisible, and ALL children are invisible.

In fact, I did once saw all parents and their children appear together, that 
is immediately after I created a new tax-table entry and try to use it in an 
existing not-yet-posted invoice, the drop-down selection list for tax-table 
entries shows everything doubled, high chance that parents and children are 
shown together. This, for a second time, prompted the parent-children 
relationship doesn't fit the scenario.

>  children don't use refcounts, only parents do.

Not inline with my observation. Parents also have them. Evidence below.

>  A child always points to its parent (it can have only 1).

Inline with obbservation.

>  A parent has a list of all children.

Not inline with my observation. I observe parents only maintain pointer to 
one single child, and that is the last child.

>  A parent has a pointer to the current 'replica child', if one exists.

Where is that pointer???

Here is my observation:

The tax-table entries in use are the following:

$ grep entry:i-taxtable realss.gnucash.xml  | sort | uniq -c
       2   <entry:i-taxtable type="guid">150228e18eb55847edd30b1829dcf7a0</entry:i-taxtable>
      11   <entry:i-taxtable type="guid">6fdca2046277d7793512235587a97b1b</entry:i-taxtable>
       1   <entry:i-taxtable type="guid">b57e482167caca81bd565b1003803011</entry:i-taxtable>
      23   <entry:i-taxtable type="guid">c35432350a81acd842710923eb02447d</entry:i-taxtable>
      34   <entry:i-taxtable type="guid">c6509ec67789c7fdf81260043aae51b9</entry:i-taxtable>
     119   <entry:i-taxtable type="guid">df0bbb3b7ae23b939a8ce006272d0b9b</entry:i-taxtable>

The taxtable itself, see below. I  manually re-ordered and indented
to show the parent-child relationship, from the output of:

$ grep -e taxtable:[^e] -e tte:amount realss.gnucash.xml

The number I added before the indent is the actual refcount:

 	  <taxtable:guid type="guid">074025c3781bd5b80e8c8a71d182c365</taxtable:guid>
 	  <taxtable:name>Office IT</taxtable:name>
0	  <taxtable:refcount>0</taxtable:refcount>
 	  <taxtable:invisible>0</taxtable:invisible>
 	      <tte:amount>550000/100000</tte:amount>
 	  <taxtable:guid type="guid">150228e18eb55847edd30b1829dcf7a0</taxtable:guid>
 	  <taxtable:name>Office IT</taxtable:name>
2	  <taxtable:refcount>2</taxtable:refcount>
 	  <taxtable:invisible>0</taxtable:invisible>
 	      <tte:amount>550000/100000</tte:amount>
 	  <taxtable:guid type="guid">1d17df5b5b5f44b0a51a008c2f9db014</taxtable:guid>
 	  <taxtable:name>Office IT</taxtable:name>
0	  <taxtable:refcount>0</taxtable:refcount>
 	  <taxtable:invisible>0</taxtable:invisible>
 	      <tte:amount>550000/100000</tte:amount>
 	  <taxtable:guid type="guid">46a0b9772268ea5ad5d370fa9ab82b24</taxtable:guid>
 	  <taxtable:name>Office IT</taxtable:name>
0	  <taxtable:refcount>0</taxtable:refcount>
 	  <taxtable:invisible>0</taxtable:invisible>
 	      <tte:amount>550000/100000</tte:amount>

 	<taxtable:guid type="guid">b6703aeb162dde454b4bd96b390c2eba</taxtable:guid>
 	<taxtable:name>Shanghai service tax</taxtable:name>
0	<taxtable:refcount>0</taxtable:refcount>
 	<taxtable:invisible>0</taxtable:invisible>
 	<taxtable:child type="guid">b57e482167caca81bd565b1003803011</taxtable:child>
 	    <tte:amount>530000/100000</tte:amount>
 	  <taxtable:guid type="guid">b57e482167caca81bd565b1003803011</taxtable:guid>
 	  <taxtable:name>Shanghai service tax</taxtable:name>
1	  <taxtable:refcount>0</taxtable:refcount>
 	  <taxtable:invisible>1</taxtable:invisible>
 	  <taxtable:parent type="guid">b6703aeb162dde454b4bd96b390c2eba</taxtable:parent>
 	      <tte:amount>530000/100000</tte:amount>

 	<taxtable:guid type="guid">c6509ec67789c7fdf81260043aae51b9</taxtable:guid>
 	<taxtable:name>Software Service</taxtable:name>
34	<taxtable:refcount>36</taxtable:refcount>
 	<taxtable:invisible>0</taxtable:invisible>
 	<taxtable:child type="guid">c35432350a81acd842710923eb02447d</taxtable:child>
 	    <tte:amount>550000/100000</tte:amount>
 	  <taxtable:guid type="guid">31923e676230dafa48ee1c75c7672f0c</taxtable:guid>
 	  <taxtable:name>Software Service</taxtable:name>
0	  <taxtable:refcount>0</taxtable:refcount>
 	  <taxtable:invisible>1</taxtable:invisible>
 	  <taxtable:parent type="guid">c6509ec67789c7fdf81260043aae51b9</taxtable:parent>
 	      <tte:amount>550000/100000</tte:amount>
 	  <taxtable:guid type="guid">df0bbb3b7ae23b939a8ce006272d0b9b</taxtable:guid>
 	  <taxtable:name>Software Service</taxtable:name>
119	  <taxtable:refcount>0</taxtable:refcount>
 	  <taxtable:invisible>1</taxtable:invisible>
 	  <taxtable:parent type="guid">c6509ec67789c7fdf81260043aae51b9</taxtable:parent>
 	      <tte:amount>605000/100000</tte:amount>
 	  <taxtable:guid type="guid">6fdca2046277d7793512235587a97b1b</taxtable:guid>
 	  <taxtable:name>Software Service</taxtable:name>
11	  <taxtable:refcount>0</taxtable:refcount>
 	  <taxtable:invisible>1</taxtable:invisible>
 	  <taxtable:parent type="guid">c6509ec67789c7fdf81260043aae51b9</taxtable:parent>
 	      <tte:amount>550000/100000</tte:amount>
 	  <taxtable:guid type="guid">c35432350a81acd842710923eb02447d</taxtable:guid>
 	  <taxtable:name>Software Service</taxtable:name>
23	  <taxtable:refcount>0</taxtable:refcount>
 	  <taxtable:invisible>1</taxtable:invisible>
 	  <taxtable:parent type="guid">c6509ec67789c7fdf81260043aae51b9</taxtable:parent>
 	      <tte:amount>550000/100000</tte:amount>


More information about the gnucash-devel mailing list