<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cuppadev &#187; Development</title>
	<atom:link href="http://www.cuppadev.co.uk/category/dev/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cuppadev.co.uk</link>
	<description>Cuppalicious coding!</description>
	<lastBuildDate>Sat, 14 Aug 2010 10:12:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Double Entry Accounting with Invoicing in Rails</title>
		<link>http://www.cuppadev.co.uk/dev/double-entry-accounting-with-invoicing-in-rails/</link>
		<comments>http://www.cuppadev.co.uk/dev/double-entry-accounting-with-invoicing-in-rails/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 11:51:50 +0000</pubDate>
		<dc:creator>James Urquhart</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[accounting]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[invoicing]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=321</guid>
		<description><![CDATA[You may remember a little post i made ages ago about Double Entry Accounting in Rails, in which i went over what one needed in order to make a simple double entry accounting system within the confines of the Ruby on Rails web development framework. After a few requests by readers, i have decided to [...]]]></description>
			<content:encoded><![CDATA[<p>You may remember a little post i made ages ago about <a href="http://www.cuppadev.co.uk/oldbrew/double-entry-accounting-in-rails/">Double Entry Accounting in Rails</a>, in which i went over what one needed in order to make a simple double entry accounting system within the confines of the Ruby on Rails web development framework.</p>
<p>After a few requests by readers, i have decided to write the sequel. Double Entry Accounting <strong>with Invoicing</strong> in Rails.</p>
<h3>To recap&#8230;</h3>
<p>Last time i identified the following core tables you needed in your database:</p>
<ul>
<li><strong>Account</strong> (has many Postings)</li>
<li><strong>Asset</strong> Type (e.g. £, $, monkeys)</li>
<li><strong>Batch</strong> (has many Journals, links them into a group of transactions &#8211; though not really needed)</li>
<li><strong>Journal</strong> (has many Postings, links them into a <strong>transaction</strong>)</li>
<li><strong>Posting</strong> (associates with Account, Journal, and Asset Type)</li>
</ul>
<p>Though i failed to elaborate on what you really needed to store in these tables. In truth, it can be as complicated or as simple as you&#8217;d like. No need for Batches? Then don&#8217;t include them.</p>
<p>As long as you at least store amounts in Posting&#8217;s, and practice the <a href="http://en.wikipedia.org/wiki/Double-entry_bookkeeping_system">art of double entry accounting</a>, you should be fine.</p>
<p>The next major point of note was how does one calculate the balances in the accounts? Well it turned out the solution was rather simple:</p>
<pre><code>credit_amount = postings.sum(:value, :conditions =&gt; "amount &lt; 0")
debit_amount = postings.sum(:value, :conditions =&gt; "amount &gt; 0")
</code></pre>
<p>Coupled in with the balances were the amounts in the Postings, which had to be flipped depending on the type of account they resided in:</p>
<pre><code>def real_amount
return [:asset, :expense].include?(self.account.account_type) ? self.value : -self.value
end

def real_amount=(val)
self.value = [:asset, :expense].include?(self.account.account_type) ? val : -val
end
</code></pre>
<p>In simpler terms: if an account is an asset or expense account, a positive value = a positive amount. Otherwise, a positive value = a negative amount. Vice versa.</p>
<h3>So how do we factor invoicing into this?</h3>
<p>There are two ways in which invoicing can be linked into a double entry accounting system:</p>
<ol>
<li>Link the <strong>payment</strong> of each invoice to transactions in the system</li>
<li>Link the <strong>amount owed</strong> by each client for each invoice to transactions in the system</li>
</ol>
<p>Realistically though, #1 is a fairly stupid idea as in the real world, clients don&#8217;t always pay on time. Or with the correct amount or order. Not only that, they can also pay off multiple invoices at once!</p>
<p>Which brings us to #2 &#8211; linking the amount owed by each client for each invoice into the system.</p>
<p>How do we do this? Well to summarise:</p>
<ul>
<li>Have a <strong>revenue account</strong> which tracks how much you make.</li>
<li>Have a <strong>checking account</strong> which tracks what is in the bank.</li>
<li>Make an <strong>asset account</strong> for each client.</li>
<li>When you make out an invoice, record a <strong>transaction</strong> which transfers the total amount of the invoice from your <strong>revenue account</strong> into the <strong>client account</strong>.</li>
<li>Link any <strong>transaction</strong>(s) generated by the invoice to the invoice (so you can revert them later if required)</li>
<li> When the client pays, record a <strong>transaction</strong> which transfers the paid amount from the <strong>client account</strong> into your <strong>checking account</strong>.</li>
</ul>
<p>Which might look like this in the system:</p>
<table style="border: 1px solid #000000">
<tr>
<th style="background:#000000;color:#ffffff" colspan="2">Account</th>
<th style="background:#000000;color:#ffffff">Debit</th>
<th style="background:#000000;color:#ffffff">Credit</th>
</tr>
<tr>
<td colspan="2"><strong>Checking Accounts</strong></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>Bank</td>
<td>100</td>
<td>0</td>
</tr>
<tr>
<td colspan="2"><strong>Invoice Accounts</strong></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>Microsoft</td>
<td>50</td>
<td>0</td>
</tr>
<tr>
<td></td>
<td>Apple</td>
<td>50</td>
<td>0</td>
</tr>
<tr>
<td colspan="2"><strong>Revenue Accounts</strong></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>Revenue</td>
<td>0</td>
<td>200</td>
</tr>
</table>
<p>So&#8230;</p>
<ul>
<li>For tax purposes, your revenue account will at least sum up to the total amount in all of your invoices.</li>
<li>If the client&#8217;s account has a positive balance, they owe you money for any one of your invoices.</li>
<li>If the client&#8217;s account has a negative balance, they&#8217;ve obviously overpaid you. So go party!!</li>
</ul>
<p>&#8230; which more or less concludes this article. Happy accounting!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuppadev.co.uk/dev/double-entry-accounting-with-invoicing-in-rails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Making a Real Calendar in Rails</title>
		<link>http://www.cuppadev.co.uk/dev/making-a-real-calendar-in-rails/</link>
		<comments>http://www.cuppadev.co.uk/dev/making-a-real-calendar-in-rails/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 18:46:53 +0000</pubDate>
		<dc:creator>James Urquhart</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[ical]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=355</guid>
		<description><![CDATA[For a while now, i have been looking at the various calendar helpers on Github. One thing stands out over all of them: they all suck. Why? well, they all implement the same basic concept &#8211; that is, they make a table containing rows for each week, and cells for each day, yielding in case [...]]]></description>
			<content:encoded><![CDATA[<p>For a while now, i have been looking at the various <a href="http://github.com/search?type=Repositories&amp;language=rb&amp;q=calendar&amp;repo=&amp;langOverride=&amp;x=0&amp;y=0&amp;start_value=1" target="_blank">calendar helpers on Github</a>. One thing stands out over all of them: <strong>they all suck</strong>.</p>
<p style="text-align: center; "><a href="http://www.cuppadev.co.uk/wp-content/uploads/2009/01/bad_calendar.gif" target="_blank"><img class="size-thumbnail wp-image-359 aligncenter" title="bad_calendar" src="http://www.cuppadev.co.uk/wp-content/uploads/2009/01/bad_calendar-261x200.gif" alt="bad_calendar" width="261" height="200" /></a></p>
<p>Why? well, they all implement the same basic concept &#8211; that is, they make a table containing rows for each week, and cells for each day, yielding in case the user wants to display anything other than a day number in the cell.</p>
<p>This is fine if all you want to do is display single-day events, but if you want to <strong>go to the next level</strong> and display multiple &#8220;all day&#8221; events it is practically impossible as the events are constrained in their table cell. Instead, <strong>another approach</strong> is needed.</p>
<p style="text-align: center; "><a href="http://www.cuppadev.co.uk/wp-content/uploads/2009/01/good_calendar.gif" target="_blank"><img class="size-thumbnail wp-image-358 aligncenter" title="good_calendar" src="http://www.cuppadev.co.uk/wp-content/uploads/2009/01/good_calendar-229x200.gif" alt="good_calendar" width="229" height="200" /></a></p>
<p>The approach? Well, put simply the events are placed in a row below each set of day cells. Events which span more than 1 row are repeated, and a layout algorithm handles vertical placement.</p>
<p>Now rather than writing a whole post describing in agonising detail how to implement this approach, i thought i&#8217;d post a gist on github describing how to do it. <a href="http://gist.github.com/54116" target="_blank">Read it here</a>. Any improvements? Feel free to fork. Comments? feel free to post below!</p>
<p style="text-align: center; "> </p>
<p><strong>Update:</strong> The great guy&#8217;s over at <a href="http://elevationblog.com/">elevation</a> have <a href="http://dev.elevationblog.com/2009/7/23/event-calendar-rails-plugin/comments/1527#comment-1527">turned this code into a plugin</a>. So if you don&#8217;t fancy implementing this all by yourself, just use the easy to install plugin. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuppadev.co.uk/dev/making-a-real-calendar-in-rails/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>A good use for &#8220;:group&#8221; in Rails</title>
		<link>http://www.cuppadev.co.uk/dev/a-good-use-for-group-in-rails/</link>
		<comments>http://www.cuppadev.co.uk/dev/a-good-use-for-group-in-rails/#comments</comments>
		<pubDate>Sun, 24 Aug 2008 12:57:44 +0000</pubDate>
		<dc:creator>James Urquhart</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=260</guid>
		<description><![CDATA[Recently i needed to make a custom view for activity logs in my Ruby on Rails app. I wanted to create a summary of the activity grouped by the day, without any duplicates. e.g. if i performed an action an object twice, i didn&#8217;t want it to be listed twice. So how does one do [...]]]></description>
			<content:encoded><![CDATA[<p>Recently i needed to make a custom view for activity logs in my <a href="http://www.rubyonrails.org">Ruby on Rails</a> app. I wanted to create a summary of the activity <strong>grouped by the day</strong>, <strong>without any duplicates</strong>. e.g. if i performed an action an object twice, i didn&#8217;t want it to be listed twice.</p>
<p>So how does one do this in Rails? Simple &#8211; use the &#8220;<strong>:group</strong>&#8221; (i.e. GROUP BY) parameter when doing a <strong>find()</strong> to combine results into single results.</p>
<h3>The nitty gritty</h3>
<p>For reference i used the following schema on my logs:</p>
<pre><code>
  create_table "application_logs" do |t|
    t.integer  "rel_object_id"
    t.text     "object_name"
    t.string   "rel_object_type"
    t.datetime "created_on",
    t.integer  "created_by_id",
    t.boolean  "is_private",
    t.boolean  "is_silent",
    t.integer  "action_id",
    t.integer  "page_id",
  end
</code></pre>
<p>In my case, most of my objects were linked to pages. And for those, i only wanted page activity to be listed once. e.g. &#8220;Modified page X&#8221; instead of &#8220;Modified object 1 on page X&#8221;, &#8220;Modified object 2 on page X&#8221;. </p>
<p>So i needed to group by <strong>page_id</strong>, <strong>created_by_id</strong>, <strong>created_on</strong> (as a date), and both <strong>rel_object_id and rel_object_id</strong>.</p>
<p>First i came up with the following <strong>:group</strong> :</p>
<pre><code>
"created_by_id,
 date(created_on),
 page_id,
 rel_object_type || rel_object_id"
</code></pre>
<p><em>Note: the &#8220;||&#8221; operator in SQLite and PostgreSQL concatenates strings.</em> </p>
<p>Unfortunately that doesn&#8217;t work properly since i have other objects which aren&#8217;t linked to a page, and they would only get listed once (since for all of them <strong>page_id</strong> would be NULL). So i needed to use the &#8220;CASE&#8221; statement to differentiate between the two:</p>
<pre><code>
"created_by_id,
 date(created_on),
 CASE page_id ISNULL
   WHEN 1 THEN rel_object_type || rel_object_id
   ELSE page_id
 END"
</code></pre>
<p>So now both the page objects and the regular objects were listed once per day. But there was another problem. </p>
<p>After the query i used the <strong>group_by</strong> method to group everything into blocks based on the date. But i also use the <a href="http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/">time zone support</a> in Rails 2.1, and since the database stores its dates in UTC, i got this rather odd issue where in certain circumstances objects were listed twice.</p>
<p>In reality they were the same date, in <strong>UTC</strong>. But not in the <strong>current timezone</strong> i was using. So after a bit of investigation i came up with a solution. I needed to offset the date in the query by the UTC offset for the current timezone.</p>
<p>It turns out that there are a ton of different ways to do it, depending on which database you are using. In my case i was testing with <a href="http://www.sqlite.org/">SQLite</a>, so the following sufficed:</p>
<pre><code>
date(created_on, '+#{Time.zone.utc_offset} seconds')
</code></pre>
<p>And for <a href="http://mysql.org">MYSQL</a> (and perhaps others), using INTERVAL works:</p>
<pre><code>
date(created_on + INTERVAL #{Time.zone.utc_offset} SECOND)
</code></pre>
<p>Of course, this still has its problems. Like what about daylight savings time? </p>
<p>Unfortunately, since there doesn&#8217;t seem to be any set standard for specifying what timezone to evaluate times in, you are either going to have to write a specific case for it, or just put up with the dates potentially being off for an hour or two.</p>
<h3>The end result</h3>
<p>Well, it looks something like this:</p>
<p style="text-align:center"><a href="http://www.cuppadev.co.uk/wp-content/uploads/2008/08/rck_overview.png"><img src="http://www.cuppadev.co.uk/wp-content/uploads/2008/08/rck_overview-300x138.png" alt="" title="rck_overview" width="300" height="138" class="alignnone size-thumbnail wp-image-276" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuppadev.co.uk/dev/a-good-use-for-group-in-rails/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fuzzy Times</title>
		<link>http://www.cuppadev.co.uk/dev/fuzzy-times/</link>
		<comments>http://www.cuppadev.co.uk/dev/fuzzy-times/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 20:04:28 +0000</pubDate>
		<dc:creator>James Urquhart</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[natural language parsing]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.cuppadev.co.uk/?p=218</guid>
		<description><![CDATA[Recently i have been writing a simple web-based reminder app which requires one to input dates and times. To input the date and time, normally one would add some sort of calendar widget which pops up. But personally i think this tends to be really awkward, especially if you don&#8217;t want to be specific about [...]]]></description>
			<content:encoded><![CDATA[<p>Recently i have been writing a simple web-based reminder app which requires one to input dates and times. To input the date and time, normally one would add some sort of calendar widget which pops up. </p>
<p style="text-align:center"><img src="http://www.cuppadev.co.uk/wp-content/uploads/2008/08/calendar-widget.png" alt="" title="calendar-widget1" width="138" height="185" class="alignnone size-thumbnail wp-image-223" /></p>
<p>But personally i think this tends to be really awkward, especially if you don&#8217;t want to be specific about dates or times. e.g. Speculative Opportunities. It also requires a lot of mouse clicking to find and enter the correct date and time.</p>
<p style="text-align:center"><img src="http://www.cuppadev.co.uk/wp-content/uploads/2008/08/reminders-parsing.png" alt="" title="reminders-parsing" width="275" height="143" class="alignnone size-thumbnail wp-image-220" /></p>
<p>Fortunately, there are libraries about which aim to solve this issue by allowing you to specify the time in English. Typically they are referred to as &#8220;Natural language&#8221; date/time parsers. In my case, i found one called <a href="http://chronic.rubyforge.org/">Chronic</a> which is distributed as a gem for Ruby. It has even got a nice <a href="http://www.rubyinside.com/chronic-ruby-date-time-parser-screencast-263.html">screencast</a>.</p>
<pre><code>sudo gem install chronic</code></pre>
<p>Consisting of only one public function, Chronic is really easy to use:</p>
<pre><code>
require 'chronic'
Chronic.parse("tomorrow at 5")
 #=> Fri Aug 08 17:00:00 +0100 2008
</code></pre>
<p>See? Nice and simple. We can also use the options to help chronic get the right time. e.g. If i really meant to say &#8220;Tomorrow at 5 AM&#8221;, i could fix it like this:</p>
<pre><code>
require 'chronic'
Chronic.parse("tomorrow at 5", :ambiguous_time_range => :none)
 #=> Fri Aug 08 5:00:00 +0100 2008
</code></pre>
<p>The options you can choose from are as follows:</p>
<ul>
<li><strong>:context</strong> &#8211; the context in which the time is assessed (<strong>:past</strong> or <strong>:future</strong>).</li>
<li><strong>:now</strong> &#8211; current time.</li>
<li><strong>:guess</strong> &#8211; if false, this returns a time range instead of guessing at a specific time.</li>
<li><strong>:ambiguous_time_range</strong> &#8211; range in hours in which an ambiguous time will be resolved. Best to think of it as hours to skip in the day when picking a time. e.g. setting this to 18 and inputting 5 will result in 5am the next day being chosen.</li>
</ul>
<p>Sadly i couldn&#8217;t seem to find any way of setting which time zone to evaluate the time in. This would have been useful when working with <a href="http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/">Ruby on Rails 2.1&#8242;s new TimeZone support</a>. Fortunately though, i figured out a workaround which is as follows:</p>
<pre><code>
# grab time using current time zone as reference
ctime = Chronic.parse(value, :now => Time.zone.now)
# re-interpret time in current timezone
ctime = Time.zone.local(ctime.year, ctime.mon, ctime.day, ctime.hour, ctime.min, ctime.sec)
</code></pre>
<p>Basically this gives Chronic the time in the current time zone, which deals with relative times (e.g. &#8220;tomorrow&#8221;). It also re-interprets the calculated time in case you are a bit more specific (e.g. &#8220;5AM&#8221;).</p>
<p>For something a bit less hackish, one might want to check out <a href="http://github.com/technoweenie/chronic/tree/master">technoweenie&#8217;s fork on github</a>. This appears to allow you to tell Chronic to use a different Time class for calculating times, which should solve the problem.</p>
<p>So to conclude, i think Chronic is a nice and simple solution that works rather nicely for common cases.</p>
<h3>Other libraries</h3>
<p>If you aren&#8217;t using Ruby, have no fear. There are similar &#8220;Natural language&#8221; parsers available for other programming environments which work in a similar fashion to Chronic.</p>
<ul>
<li><a href="http://www.datejs.com/">Datejs</a> for JavaScript</li>
<li><a href="http://code.google.com/p/parsedatetime/">parsedatetime</a> for Python</li>
<li><a href="http://search.cpan.org/~schubiger/DateTime-Format-Natural-0.71/lib/DateTime/Format/Natural.pm">DateTime::Format::Natural</a> for Perl</li>
<li><a href="http://www.codeplex.com/DateTimeEnglishParse">DateTimeEnglishParser</a> for .net</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.cuppadev.co.uk/dev/fuzzy-times/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An Analogue Clock using Safari Transforms</title>
		<link>http://www.cuppadev.co.uk/dev/an-analogue-clock-using-safari-transforms/</link>
		<comments>http://www.cuppadev.co.uk/dev/an-analogue-clock-using-safari-transforms/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 07:25:52 +0000</pubDate>
		<dc:creator>James Urquhart</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[safari]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://crm.cuppadev.co.uk/?p=141</guid>
		<description><![CDATA[Recently Safari 3.1 has been released for Mac and Windows, boasting a whole load of useful new features. One of these is support for CSS transforms &#8211; i.e. you can translate, scale, and rotate HTML elements in a web page. CSS transforms can come in quite handy for making complex dynamic objects, without the need [...]]]></description>
			<content:encoded><![CDATA[<p>Recently <a href="http://www.apple.com/safari">Safari 3.1</a> has been released for Mac and Windows, boasting a whole load of useful new features. One of these is support for <a href="http://webkit.org/blog/130/css-transforms/"><span class="caps">CSS</span> transforms</a> &#8211; i.e. you can translate, scale, and rotate <span class="caps">HTML</span> elements in a web page.</p>
<p><span class="caps">CSS</span> transforms can come in quite handy for making complex dynamic objects, without the need for 3rd party plugins or applets. For example i was able to make the following <span class="caps">BBC</span>-esque analogue clock, using only <span class="caps">DIV</span>&#8217;s and JavaScript :</p>
<p><strong>(Note that currently this only works in Safari 3.1)</strong><br />
<iframe width="132" height="132" frameborder="0" src ="http://www.cuppadev.co.uk/assets/test.html"></iframe></p>
<p><b>EDIT: </b> Now works in FireFox too!</p>
<p>Yes, <span class="caps">DIV</span>&#8217;s and JavaScript. No Canvas, no Flash, no SilverLight, no Java Applets, no Plugins.</p>
<p>It makes me wonder, considering that browsers seem to be getting so powerful nowadays, should one really bother using Flash &#38; co anymore?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuppadev.co.uk/dev/an-analogue-clock-using-safari-transforms/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>What not to write in haXe, Part II</title>
		<link>http://www.cuppadev.co.uk/dev/what-not-to-write-in-haxe-part-ii/</link>
		<comments>http://www.cuppadev.co.uk/dev/what-not-to-write-in-haxe-part-ii/#comments</comments>
		<pubDate>Fri, 07 Mar 2008 22:40:51 +0000</pubDate>
		<dc:creator>James Urquhart</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[haxe]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://crm.cuppadev.co.uk/?p=140</guid>
		<description><![CDATA[I decided to have another go at writing some awe-inspiring haXe code again. This time, i picked up from where i left off &#8211; that was trying to get my infamous SCUMM interpreter working on additional platforms which haXe supports. For reference, i concentrated on getting it to work on the neko platform. To start [...]]]></description>
			<content:encoded><![CDATA[<p>I decided to have another go at writing some awe-inspiring haXe code again. This time, i picked up from where <a href="http://www.cuppadev.co.uk/2008/01/27/what-not-to-write-in-haxe/">i left off</a> &#8211; that was trying to get my infamous <a href="http://www.cuppadev.co.uk/2007/11/22/flash-plays-scumm-take-two/"><span class="caps">SCUMM</span> interpreter</a> working on additional platforms which haXe supports.</p>
<p>For reference, i concentrated on getting it to work on the <a href="http://www.nekovm.org">neko</a> platform.</p>
<p>To start off with, i took notice of a suggestion to simplify the import statements which littered the top of the source code. So instead of this:</p>
<pre>
<code>
#if flash9
import flash.display.Bitmap;
...
#else neko
import noflash.Bitmap;
...
#end
</code>
</pre>
<p>I consolidated everything into a single file which looked like this:</p>
<pre>
<code>
#if flash9
typedef Bitmap = flash.display.Bitmap;
...
#else neko
typedef ByteArray = noflash.ByteArray;
...
#end
</code>
</pre>
<p>So when i used &#8220;import hiscumm.Common&#8221;, i could now access all of the classes listed with little fuss!</p>
<p>Another change i made was to re-factor the way resources were loaded. Before, i just used flash 9&#8217;s ByteArray. However as there is no direct equivalent of this on the neko platform, i had to implement my own.</p>
<p>Thinking more, i determined that only a relatively small portion of my code actually needed to use all of the features of ByteArray, so instead i changed all of the IO code to use the neko api&#8217;s Input &#38; Output classes.</p>
<p>Finally i made all 32bit integers Int32&#8217;s. Consequently, i had to re-implement the Int32 class for the flash platform, but all things considered it was the best solution.</p>
<h3>Problems</h3>
<p>As before, i ran into a fair share of problems. Most were minor, and others were solved when i upgraded from haXe 1.17 to 1.18. Here are some of the more notable ones i came across.</p>
<p><strong>&#8220;No arrays larger than 115 elements&#8221;</strong></p>
<p>I ended up finding a rather obvious solution to this problem which worked transparently with the other platforms. All one has to do is split up the troublesome array into several smaller arrays and then concatenate them together. e.g.</p>
<pre>
<code>
var longarray = [1,2,3].concat([4,5,6]).concat(7,8,9); // works
</code>
</pre>
<p>Problem solved.</p>
<p><strong>&#8220;Beware of classes extending Int&#8221;</strong></p>
<p>In an earlier implementation of my Int32 class, i had it extending Int. This turned out to be a fatal mistake, as when i tested out the code absolutely nothing worked.</p>
<p>The solution of course was just to not extend from Int.</p>
<p><strong>&#8220;haxe.Timer does not have a constructor&#8221;</strong></p>
<p>I kept getting a rather odd compile error. It seemed that no constructor was defined for the Timer class, which i used to run the game loop. This was very odd, as the <span class="caps">API</span> documentation didn&#8217;t state anything unusual about the Timer class on the neko platform.</p>
<p>However after checking out the code to the Timer, i soon came to realise the horrifying truth: the Timer class wasn&#8217;t implemented for the neko platform. Arrrgh! I got this far and now i&#8217;m stopped by something as simple as this?</p>
<p>Thankfully i figured out a rather obvious workaround. Instead of using the timer, i merely made a typical run-of-the-mill game loop. Problem solved.</p>
<pre>
<code>
while (true)
{
onTime();
neko.Sys.sleep(0.01);
}
</code>
</pre>
<h3>The result</h3>
<p>As the output below shows, the interpreter now actually runs on neko. Unfortunately there appears to be a rather nasty bug when decoding the room image. But then again i&#8217;ve not implemented any video code for the neko platform yet, so the usefulness of this is questionable to say the least.</p>
<pre>
<code>
$ neko test.n
NekoTest.hx:42: Engine init
SCUMM.hx:486: boot state
SPUTMResource.hx:308: Loading resource 1 from file 1, room 2 (SCRIPT)
SCUMM.hx:488: Started
SCUMM6.hx:1249: ARRAY = ""
SCUMM6.hx:1249: ARRAY = "ScummC Paused !"
SCUMM6.hx:1249: ARRAY = "Are you sure you want to quit ? (Y/N)Y"
SCUMM6.hx:1249: ARRAY = "Are you sure you want to restart ? (Y/N)Y"
SCUMM6.hx:1249: ARRAY = "Save it"
SCUMM6.hx:1249: ARRAY = "Load it"
SCUMM6.hx:1249: ARRAY = "Continue"
SCUMM6.hx:1249: ARRAY = "Cancel"
SCUMM6.hx:1249: ARRAY = "Quit"
SCUMM6.hx:1249: ARRAY = "Ok"
SCUMM6.hx:1249: ARRAY = "Saveing '%s'"
SCUMM6.hx:1249: ARRAY = "Loading '%s'"
SCUMM6.hx:1249: ARRAY = "ScummC test Menu"
SCUMM6.hx:1249: ARRAY = "Save game"
SCUMM6.hx:1249: ARRAY = "Load game"
SCUMM6.hx:1249: ARRAY = "Game NOT saved"
SCUMM6.hx:1249: ARRAY = "Game NOT loaded"
SCUMM6.hx:1249: ARRAY = "Insert disk %c"
SCUMM6.hx:1249: ARRAY = "You must enter a name"
SCUMM6.hx:1249: ARRAY = "Insert your save disk"
SCUMM6.hx:1249: ARRAY = "Failed to open %s (%c%d)"
SCUMM6.hx:1249: ARRAY = "Read error on disk %c (%c%d)"
SCUMM6.hx:788: 103, 645
SPUTMResource.hx:308: Loading resource 2 from file 1, room 2 (ROOM)
SPUTMRoom.hx:173: RMIM == RMIM
SPUTMImage.hx:109: smap size == 8
SPUTM.hx:1096: Internal exception, aborting! (state=SPUTM_RUNNING)
SPUTM.hx:1097: &gt;&gt;
</code>
</pre>
<p>As before, the hiscumm code is available for reference. Unlike last time however, the code is now hosted in a git repository so you can now see all the nitty gritty changes i have made to it. Great!</p>
<p><a href="http://projects.cuppadev.co.uk/gitweb/?p=experiments/hiscumm.git;a=summary">Click here</a> to check it out!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuppadev.co.uk/dev/what-not-to-write-in-haxe-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What not to write in haXe</title>
		<link>http://www.cuppadev.co.uk/dev/what-not-to-write-in-haxe/</link>
		<comments>http://www.cuppadev.co.uk/dev/what-not-to-write-in-haxe/#comments</comments>
		<pubDate>Mon, 28 Jan 2008 06:05:49 +0000</pubDate>
		<dc:creator>James Urquhart</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[haxe]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://crm.cuppadev.co.uk/?p=139</guid>
		<description><![CDATA[You might have notice that during the past few months i&#8217;ve written a few articles about haXe, a language and compiler which pits itself as a &#8220;toolbox for the web developer&#8221;. Recently i decided to test out haXe&#8217;s platform support. I did this by taking my SCUMM interpreter code &#8211; which i had previously written [...]]]></description>
			<content:encoded><![CDATA[<p>You might have notice that during the past few months i&#8217;ve written a <a href="http://www.cuppadev.co.uk/2008/01/14/a-wiki-written-in-haxe/">few</a> <a href="http://www.cuppadev.co.uk/2007/11/22/flash-plays-scumm-take-two/">articles</a> <a href="http://www.cuppadev.co.uk/2007/10/06/flash-plays-scumm-sort-of/">about</a> <a href="http://www.cuppadev.co.uk/2007/10/04/haxe-web-oriented-universal-language/">haXe</a>, a language and compiler which pits itself as a &#8220;toolbox for the web developer&#8221;.</p>
<p>Recently i decided to test out haXe&#8217;s platform support. I did this by taking my <span class="caps">SCUMM</span> interpreter code &#8211; which i had previously written for flash 9 &#8211; and tried to get it to work on the other two major platforms haXe supports, javascript and neko.</p>
<p>To start off with, i had to remove its dependency on flash. This was achieved by making replacement classes and switching between the two using the conditional pre-processor. i.e.:</p>
<pre>
<code>
#if flash9
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.ByteArray;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Timer;
import flash.events.TimerEvent;
#else neko
import noflash.ByteArray;
import noflash.Bitmap;
import noflash.BitmapData;
import noflash.Point;
import noflash.Rectangle;
import noflash.Timer;
import noflash.TimerEvent;
#end
</code>
</pre>
<p>Most of the modifications to the code looked like this, with liberal sprinklings of &#8221;#if flash9 &#8230; #end&#8221; round the flash specific code.</p>
<p>Eventually i got to the point where things started to look like they were going to compile, or <strong>so i thought</strong>&#8230;</p>
<h3>Problems</h3>
<p><em><strong>&#8220;Array too big&#8221;</strong></em></p>
<p>The first problem i encountered was that it wouldn&#8217;t compile.</p>
<pre>
<code>
hiscumm/SCUMM6.hx:1870: lines 1870-2127 : This array declaration is too big, try to split it
</code>
</pre>
<p>Array declaration too big? What on earth was it going on about?</p>
<pre>
<code>
| TArrayDecl el -&gt;
if List.length el &gt; 115 then error "This array declaration is too big, try to split it" e.epos;
call p (field p (ident p "Array") "new1") [array p (List.map (gen_expr ctx) el); int p (List.length el)]
</code>
</pre>
<p>Oh, right. Seems i cannot have arrays declared with more than <strong>115 elements</strong>. A seemingly arbitrary limitation that is not referenced anywhere in the documentation &#8211; great!</p>
<p>Not needing the opcode table for my little experiment, i commented most of it out. Problem solved.</p>
<p><strong>&#8220;32bit? no, 31bit!&#8221;</strong></p>
<p>Now the first time i got the interpreter to compile for neko, i thought &#8220;Wow, great! Looks like this is going to work.&#8221; Unfortunately though, it didn&#8217;t. Instead, i got a rather odd exception when reading out of my replacement ByteArray:</p>
<pre>
<code>
Uncaught exception - Overflow
</code>
</pre>
<p>Turns out the problem was with this code here, in neko.Input:</p>
<pre>
<code>
public function readInt32() {
var ch1 = readChar();
var ch2 = readChar();
var ch3 = readChar();
var ch4 = readChar();
if( (ch4 &#38; 128) != 0 ) {
if( ch4 &#38; 64 == 0 ) throw Error.Overflow;
return ch1 | (ch2 &lt;&lt; 8) | (ch3 &lt;&lt; 16) | ((ch4 &#38; 127) &lt;&lt; 24);
} else {
if( ch4 &#38; 64 != 0 ) throw Error.Overflow;
return ch1 | (ch2 &lt;&lt; 8) | (ch3 &lt;&lt; 16) | (ch4 &lt;&lt; 24);
}
}
</code>
</pre>
<p>So basically the reader was trying to stuff the whole <strong>32 bit value</strong> into a neko Integer, which is actually <strong>31 bits</strong>. Oddly enough though, the value being read was identical to a value i specified in the code.</p>
<p>But haXe never bothered to complain about an <strong>overflow</strong>!</p>
<p>This can be demonstrated by the following code, which prints &#8220;-766623411&#8221; instead of the expected &#8220;1380860237&#8221;.</p>
<pre>
<code>
trace(1380860237);
</code>
</pre>
<p>Thankfully, a solution exists. There is an &#8220;Int32&#8221; type which properly handles 32bit integers. However there is a really big snag with it &#8211; it&#8217;s a <strong>class</strong>.</p>
<p>That means you cannot use any fancy inbuilt operators with it &#8211; you have to use a set of functions instead.</p>
<pre>
<code>
import neko.Int32;

var result: Int = 1 + 2; // simple
var result32: Int32 = Int32.add(Int32.ofInt(1), Int32.ofInt(2)); // aaaarrrghh!!!

result += 1; // simple
result32 += 1; // don't even think about it, it won't work
</code>
</pre>
<p>And to top it all off, this &#8220;Int32&#8221; class only exists for the neko platform, you cannot use it with flash or javascript. Unless you write it yourself, but that is besides the point. It should at least have been there to fill in the gap.</p>
<h3>Conclusion</h3>
<p>If you are looking at writing code in haXe and want it to work across all 3 of its supported platforms (flash*, neko and javascript), then beware if you are reading, writing, or otherwise processing 32bit integers.</p>
<p>In addition watch out for mysterious arbitrary limitations such as the 115 item limit for declared arrays.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuppadev.co.uk/dev/what-not-to-write-in-haxe/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Wiki written in haXe</title>
		<link>http://www.cuppadev.co.uk/dev/a-wiki-written-in-haxe/</link>
		<comments>http://www.cuppadev.co.uk/dev/a-wiki-written-in-haxe/#comments</comments>
		<pubDate>Mon, 14 Jan 2008 07:05:21 +0000</pubDate>
		<dc:creator>James Urquhart</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[haxe]]></category>
		<category><![CDATA[neko]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[wiki]]></category>

		<guid isPermaLink="false">http://crm.cuppadev.co.uk/?p=138</guid>
		<description><![CDATA[A while ago now, i writ a piece about haXe, a language and compiler which pits itself as a &#8220;toolbox for the web developer&#8221;. Now i thought haXe was a great idea, with a great potential for consolidating the mess that is web development. But at the time, i couldn&#8217;t find any examples of its [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago now, i <a href="http://www.cuppadev.co.uk/2007/10/04/haxe-web-oriented-universal-language/">writ a piece about haXe</a>, a language and compiler which pits itself as a &#8220;toolbox for the web developer&#8221;.</p>
<p>Now i thought haXe was a great idea, with a great potential for consolidating the mess that is web development. But at the time, i couldn&#8217;t find any examples of its full use out in the field.</p>
<p>That was until today, when i discovered <a href="http://myminicity.com/">MyMiniCity</a>!</p>
<p>I have heard that MyMiniCity is the first example of a web based game completely written using haXe. The back-end appears to run on <a href="http://nekovm.org/doc/mod_neko">mod_neko</a>, while the front-end uses a mix of JavaScript and Flash, both compiled using haXe (from what i can tell at least).</p>
<h3>Getting to the point&#8230;</h3>
<p>Now i shall get to the point. I was so impressed with MyMiniCity that i decided to have a go at writing a Wiki in haXe. This pretty much took me most of the day as i had to make heads and tails of haXe&#8217;s library&#8217;s.</p>
<p>In any case, ended up with something which kind of works. For the code, see overleaf.</p>
<p>&lt;!<del>-more</del>-&gt;</p>
<h3>The code</h3>
<p>Beware! this code ain&#8217;t pretty. But it works for the most part. Note that you might also have to make a dummy file called &#8220;macros.mtt&#8221;.</p>
<h4>index.hxml</h4>
<pre>
<code>
-cp /usr/lib/haxe/lib/mtwin/1,2,6
-neko Index.n
-main Index
</code>
</pre>
<h4>Index.hx</h4>
<pre>
<code>

// Main web application class.

import mtwin.web.Handler;

class Page extends neko.db.Object {
public var id : Int;
public var name : String;
public var content : String;

public var last_edited : Date;

public function toHTML() : String
{
return mtwin.text.Text2Xhtml.transform(content);
}

public static var manager = new neko.db.Manager&lt;Page&gt;(Page);
}

class Index {
// mtwin.web.Request represents the current http request with url, parameters, etc...
static var request : mtwin.web.Request;
// for this example we will use mtwin.templo XHTML template engine
static public var template : mtwin.templo.Loader;
// this is some dynamic template context for templo
static public var context : Dynamic;

// Instance vars
static var cnx : neko.db.Connection;

public static function main(){
mtwin.templo.Loader.BASE_DIR = "/Users/jamesu/Projects/Experiments/haxe/web/";
mtwin.templo.Loader.TMP_DIR = "/tmp/";
context = Reflect.empty();
template = null;

request = new mtwin.web.Request();

// connect to database
cnx = neko.db.Mysql.connect({
host : "localhost",
port : 3306,
database : "HaxeWiki",
user : "root",
pass : "",
socket : null
});

neko.db.Manager.cnx = cnx;
neko.db.Manager.initialize();

// creates the main application handler
var handler = new WikiHandler();

// little check to avoid index.n in path
var level = if (request.getPathInfoPart(0) == "index.n") 1 else 0;

// start processing the request starting from specified path info part
handler.execute(request, level);

// if the templo template is defined, we execute it
if (template != null){
neko.Web.setHeader("Context-Type", "text/html; charset=UTF-8");
neko.Lib.print(template.execute(context));
}

// close database connection
neko.db.Manager.cleanup();
cnx.close();
}
}

class WikiHandler extends Handler&lt;String&gt; {

public function new(){
super();

// Edit page
free("edit", "editpage.mtt", doEditWikiPage);
}

// Overide execute so we can process wiki pages
override public function execute( request:mtwin.web.Request, ?pathLevel:Int ){
if (pathLevel == null)
pathLevel = 0;

var part = request.getPathInfoPart(pathLevel);

this.request = request;
this.level = pathLevel;

if (part == "")
part = "default";

part = part.toLowerCase();
initialize();

// Check for special wiki pages
if (actions.exists(part)){
actions.get(part)();
return;
}

doWikiPage(part);
}

function doWikiPage(title: String){
var context = Index.context;

// Search for wiki page in database
var wikipages = Page.manager.search({name : title}, true);
var wikipage : Page = wikipages.isEmpty() ? null : wikipages.first();

if (wikipage == null)
{
context.wikipage = new Page();
context.wikipage.name = title;
context.wikipage.content = '';
context.wikipage_new = true;
prepareTemplate("editpage.mtt");
}
else
{
context.wikipage = wikipage;
prepareTemplate("viewpage.mtt");
}
}

function doEditWikiPage(){
var context = Index.context;

var realtitle = request.get('name').toLowerCase();
var wikipages = Page.manager.search({name : realtitle}, true);
var wikipage : Page = wikipages.isEmpty() ? null : wikipages.first();

if (wikipage == null)
{
context.wikipage_new = true;
wikipage = new Page();
wikipage.name = realtitle;
}
else
{
context.wikipage_new = false;
}
context.wikipage = wikipage;

if (request.get('content') != null)
wikipage.content = request.get('content');

// Skip rest if not POST'ing
if (neko.Web.getPostData() == null)
return;

if (context.wikipage_new)
{
// Make page
wikipage.last_edited = Date.now();

wikipage.insert();
neko.Web.redirect("/" + wikipage.name);
}
else
{
// Edit page
wikipage.last_edited = Date.now();

wikipage.update();
neko.Web.redirect("/" + wikipage.name);
}
}

// same as above
override function prepareTemplate( t:String ){
Index.template = new mtwin.templo.Loader(t);
}
}

</code>
</pre>
<h4>database.sql</h4>
<p>MySQL schema.</p>
<p><code></p>
<pre>
CREATE TABLE Page (
id int(10) unsigned NOT NULL auto_increment,
name varchar(40) NOT NULL,
content TEXT NOT NULL DEFAULT '',
last_edited datetime default NULL,
PRIMARY KEY (id)
);
</code>
</pre>
<h4>viewpage.mtt</h4>
<pre>
<code>

&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Viewing page ::wikipage.name::&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
&lt;h1&gt;::wikipage.name::&lt;/h1&gt;
&lt;div id="content"&gt;
::raw wikipage.toHTML()::
&lt;/div&gt;
&lt;p&gt;&lt;a href="/edit?name=::wikipage.name::"&gt;Edit page&lt;/a&gt; (Last edited : ::wikipage.last_edited::)&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>
</pre>
<h4>editpage.mtt</h4>
<pre>
<code>
&lt;html&gt;
&lt;head&gt;
::if (!wikipage_newl)::
&lt;title&gt;Editing page ::wikipage.name::&lt;/title&gt;
::else::
&lt;title&gt;New page&lt;/title&gt;
::end::
&lt;/head&gt;

&lt;body&gt;
&lt;h1&gt;Edit page&lt;/h1&gt;
&lt;form method="post" action="/edit"&gt;
&lt;input type="hidden" name="name" value="::wikipage.name::"/&gt;
&lt;textarea name="content" rows="10" cols="50"&gt;::wikipage.content::&lt;/textarea&gt;
::if !wikipage_new::
&lt;input type="submit" value="Edit"/&gt;
::else::
&lt;input type="submit" value="Save"/&gt;
::end::
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</code>
</pre>
<h4>Instructions</h4>
<p>Assuming you have got haXe installed, but never got the web stuff working you might want to do the following:</p>
<ol>
<li>sudo haxelib install mtwin</li>
<li>cd /usr/lib/haxe/lib/mtwin/1,2,6/mtwin/templo</li>
<li>sudo haxe temploc.hxml</li>
<li>sudo cp temploc /usr/bin/</li>
</ol>
<p>Then something like this should suffice to get the wiki code running:</p>
<ol>
<li>mysql -u root HaxeWiki &lt; database.sql</li>
<li>haxe index.hxml</li>
<li>nekotools server -rewrite</li>
</ol>
<p>And you can make wiki</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuppadev.co.uk/dev/a-wiki-written-in-haxe/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Double Entry Accounting in Rails</title>
		<link>http://www.cuppadev.co.uk/dev/double-entry-accounting-in-rails/</link>
		<comments>http://www.cuppadev.co.uk/dev/double-entry-accounting-in-rails/#comments</comments>
		<pubDate>Thu, 06 Dec 2007 21:53:00 +0000</pubDate>
		<dc:creator>James Urquhart</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[accounting]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://crm.cuppadev.co.uk/?p=133</guid>
		<description><![CDATA[The first helpful article i found, Double Entry Accounting in a Relational Database, suggests i need at least the following models in my system: Account (has many Postings) Asset Type (e.g. £, $, monkeys) Batch (has many Journals, though not really needed) Journal (has many Postings) Posting (associates with Account, Journal, and Asset Type) However [...]]]></description>
			<content:encoded><![CDATA[<p>The first helpful article i found, <a href="http://homepages.tcp.co.uk/~m-wigley/gc_wp_ded.html">Double Entry Accounting in a Relational Database</a>, suggests i need at least the following models in my system:</p>
<ul>
<li>Account (has many Postings)</li>
<li>Asset Type (e.g. £, $, monkeys)</li>
<li>Batch (has many Journals, though not really needed)</li>
<li>Journal (has many Postings)</li>
<li>Posting (associates with Account, Journal, and Asset Type)</li>
</ul>
<p>However one problem i noticed with the article was that instead of separate &#8220;credit&#8221; and &#8220;debit&#8221; fields, everything is consolidated into an &#8220;amount&#8221; field. This meant that the abstraction between debiting and crediting needed to be handled in the model rather than the actual database.</p>
<p>Puzzled by this, i decided to look at the database schema used in other Accounting products: <a href="http://www.ledgersmb.org/">LedgerSMB</a> and <a href="http://jgnash.sourceforge.net">jGnash</a>.</p>
<p style="text-align:left;"><a href="http://www.ledgersmb.org"><img src="http://www.cuppadev.co.uk/assets/2007/12/6/garland_logo.jpg" style="border:none;" title="LedgerSMB Logo" alt="LedgerSMB Logo" /></a></p>
<p>LedgerSMB uses a rather complex database schema. I couldn&#8217;t make much sense of it, apart from like the aforementioned article it consolidated credits and debits into an &#8220;amount&#8221; field rather than have them as separate fields.</p>
<p style="text-align:left;"><a href="http://jgnash.sourceforge.net"><img src="http://www.cuppadev.co.uk/assets/2007/12/6/Jgnash_logo.png" style="border:none;" title="jGnash Logo" alt="jGnash Logo" /></a></p>
<p>jGnash was a bit different as instead of a proper database it uses an <span class="caps">XML</span> file to store its data. Still, there were a few distinctive elements which are the equivalent of models:</p>
<ul>
<li>Account (linked to Transaction and CurrencyNode)</li>
<li>SingleEntryTransaction (linked to Account, used to insert money out of thin air)</li>
<li>DoubleEntryTransaction (linked to 2 Accounts &#8216;credit&#8217; and &#8216;debit&#8217;. Also links with CurrencyNode)</li>
<li>SplitTransaction (used to link multiple SplitEntryTransaction&#8217;s together to indicate a split transaction)</li>
<li>SplitEntryTransaction (linked to SplitTransaction, otherwise the same as DoubleEntryTransaction)</li>
<li>CurrencyNode (e.g. £, $, giraffes)</li>
</ul>
<p>Personally i found jGnash&#8217;s <span class="caps">XML</span> format needlessly complicated, though much more comprehensible than LedgerSMB&#8217;s database schema.</p>
<p>Though really, the approach i liked the best was the one mentioned in the article. It made the most sense, and wasn&#8217;t needlessly complicated. So i decided to implement it.</p>
<p>While implementing it however, i became a bit stuck on how to abstract the credit and debit in the Posting entries.</p>
<p>Whenever i have looked at Double Entry Accounting in the past, i always assumed that when you take money out of one account, you need to put the same amount back into another account. Thus i made this rather mistaken test data:</p>
<pre>
<code>
# Begin asset types

gbp = AssetType.new(:name =&gt; 'GBP', :symbol =&gt; '£')
gbp.save!

# Begin accounts

assets = Account.new(:parent_account =&gt; nil,
:asset_type =&gt; gbp,
:name =&gt; 'Assets',
:account_type =&gt; :asset)
assets.save!
equipment = Account.new(:parent_account =&gt; assets,
:asset_type =&gt; gbp,
:name =&gt; 'Equipment',
:account_type =&gt; :asset)
equipment.save!

liabilities = Account.new(:parent_account =&gt; nil,
:asset_type =&gt; gbp,
:name =&gt; 'Liabilities',
:account_type =&gt; :liability)
liabilities.save!
fred = Account.new(:parent_account =&gt; liabilities,
:asset_type =&gt; gbp,
:name =&gt; 'Fred',
:account_type =&gt; :liability)
fred.save!
george = Account.new(:parent_account =&gt; liabilities,
:asset_type =&gt; gbp,
:name =&gt; 'George',
:account_type =&gt; :liability)
george.save!

# Begin transactions

first_transaction = Journal.new(:transaction_type =&gt; :transfer, :start_date =&gt; Time.now)
first_transaction.save!
Posting.new(:account =&gt; george,
:asset_type =&gt; gbp,
:journal =&gt; first_transaction,
:account_period =&gt; 0,
:description =&gt; 'Funding',
:amount =&gt; -250.00).save!
Posting.new(:account =&gt; equipment,
:asset_type =&gt; gbp,
:journal =&gt; first_transaction,
:account_period =&gt; 0,
:description =&gt; 'Funding',
:amount =&gt; +250.00).save!
first_transaction.end_date = Time.now
first_transaction.save!

second_transaction = Journal.new(:transaction_type =&gt; :transfer, :start_date =&gt; Time.now)
second_transaction.save!
Posting.new(:account =&gt; equipment,
:asset_type =&gt; gbp,
:journal =&gt; second_transaction,
:account_period =&gt; 0,
:description =&gt; 'Payback',
:amount =&gt; -100.00).save!
Posting.new(:account =&gt; george,
:asset_type =&gt; gbp,
:journal =&gt; second_transaction,
:account_period =&gt; 0,
:description =&gt; 'Payback',
:amount =&gt; +100.00).save!
second_transaction.end_date = Time.now
second_transaction.save!

third_transaction = Journal.new(:transaction_type =&gt; :transfer, :start_date =&gt; Time.now)
third_transaction.save!
Posting.new(:account =&gt; fred,
:asset_type =&gt; gbp,
:journal =&gt; third_transaction,
:account_period =&gt; 0,
:description =&gt; 'Investment',
:amount =&gt; -300.00).save!
Posting.new(:account =&gt; equipment,
:asset_type =&gt; gbp,
:journal =&gt; third_transaction,
:account_period =&gt; 0,
:description =&gt; 'Investment',
:amount =&gt; +300.00).save!
third_transaction.end_date = Time.now
third_transaction.save!
</code>
</pre>
<p>Which actually appeared to work fine (as in everything sum&#8217;d to 0, and if i ignored the minus then Assets = Liabilities) before i started to delve into what debiting and crediting means in relation to whether or not an account is classed as an <strong>Asset</strong> or a <strong>Liability</strong>.</p>
<p><em>(Note that to simplify things when i say Asset i could alternatively be meaning Expenses, and when i say Liability i could alternatively be meaning Shareholder Equity or Revenue)</em></p>
<table>
<tr>
<th>Account</th>
<th>Debit</th>
<th>Credit</th>
</tr>
<tr>
<td>Assets</td>
<td>+</td>
<td>-</td>
</tr>
<tr>
<td>Expenses</td>
<td>+</td>
<td>(-)</td>
</tr>
<tr>
<td>Liabilities</td>
<td>-</td>
<td>+</td>
</tr>
<tr>
<td>Shareholder Equity</td>
<td>-</td>
<td>+</td>
</tr>
<tr>
<td>Revenue</td>
<td>(-)</td>
<td>+</td>
</tr>
</table>
<p>After applying the logic from the above table (<a href="http://en.wikipedia.org/wiki/Double-entry_bookkeeping_system">courtesy of Wikipedia</a>), i noticed something rather odd. The credit and debit columns on my printout didn&#8217;t match. For reference, i was using the following queries to grab the credit and debit amounts for each account.:</p>
<pre>
<code>
credit_amount = Posting.sum(:amount, :conditions =&gt; "amount #{account_type == :asset ? '&lt;' : '&gt;'} 0")
debit_amount = Posting.sum(:amount, :conditions =&gt; "amount #{account_type == :asset ? '&gt;' : '&lt;'} 0")
</code>
</pre>
<p>However if i modified the code slightly:</p>
<pre>
<code>
credit_amount = Posting.sum(:amount, :conditions =&gt; "amount &lt; 0")
debit_amount = Posting.sum(:amount, :conditions =&gt; "amount &gt; 0")
</code>
</pre>
<p>The credit and debit columns mysteriously matched. So what happened?</p>
<p>Well i puzzled over this for a while, until i read Wikipedia&#8217;s article on Double Entry Accounting again. This rather simple summary was very insightful:</p>
<p><strong>Purchase of a Computer</strong></p>
<ul>
<li>Debit Computer A/c (Fixed Asset A/c)</li>
<li>Credit Creditors A/c (Liability A/c)</li>
</ul>
<p><em>(A/c being an abbreviation of &#8220;account current&#8221;)</em></p>
<p><strong>Paying supplier for the computer</strong></p>
<ul>
<li>Debit Creditors A/c (Liability A/c) You are reducing a Liability A/c</li>
<li>Credit Bank A/c (Asset A/c) Money going Out, an asset account is being reduced</li>
</ul>
<p>So in fact all the transactions in my test data should have been <strong>increasing</strong> the amount in the liability accounts rather than <strong>decreasing</strong> it (and vice versa when paying back).</p>
<p>It makes sense now i think about it. The second approach worked because in effect i flipped the meaning of debit and credit by decreasing the amount in the liability accounts and calling it credit rather than increasing the amount in the liability accounts and calling it credit (and vice versa).</p>
<p>Now i could just go ahead and fix my test data. But then my amounts would cease to sum up to zero, and i would have to run multiple queries (each for debit and credit) to ensure integrity of the data.</p>
<p>Thus what i really need to do is make an attribute in the Posting model which stores and retrieves the correct &#8220;amount&#8221; depending on what type of account it is. Something like this should suffice:</p>
<pre>
<code>
def real_amount
return self.account.account_type == :asset ? self.amount : -self.amount
end

def real_amount=(val)
self.amount = self.account.account_type == :asset ? val : -val
end
</code>
</pre>
<p>So to sum it up, the only thing i really have to do with liability accounts to satisfy accounting rules is to subtract when i really mean add, and then flip the balance when calculating it. Confusion eliminated!</p>
<p>Now lets hope i don&#8217;t get confused again when i start to think &#8220;Did i get this right?&#8221;.</p>
<p>Currently i am looking into how i can effectively incorporate business concepts such as Invoices, Taxation, and so on into my little Double Entry Accounting system. So expect to see a &#8220;Double Entry Accounting with Invoicing in Rails&#8221; post in the near future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuppadev.co.uk/dev/double-entry-accounting-in-rails/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Rotating OpenLaszlo with Internet Explorer</title>
		<link>http://www.cuppadev.co.uk/dev/rotating-openlaszlo-with-internet-explorer/</link>
		<comments>http://www.cuppadev.co.uk/dev/rotating-openlaszlo-with-internet-explorer/#comments</comments>
		<pubDate>Fri, 09 Nov 2007 22:36:00 +0000</pubDate>
		<dc:creator>James Urquhart</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[openlaszlo]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://crm.cuppadev.co.uk/?p=129</guid>
		<description><![CDATA[In my Rotating OpenLaszlo with Webkit post, i showed how it was possible to rotate OpenLaszlo elements using a recent build of Webkit, the HTML engine used in Safari. Soon after i came across some very interesting documents on MSDN. It seems that Internet Explorer has support for visual filters and transitions. These &#8220;visual filters [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://cuppadev.co.uk/2007/10/31/rotating-openlaszlo-with-webkit">Rotating OpenLaszlo with Webkit</a> post, i showed how it was possible to rotate OpenLaszlo elements using a recent build of Webkit, the <span class="caps">HTML</span> engine used in Safari.</p>
<p>Soon after i came across some <a href="http://msdn2.microsoft.com/en-us/library/ms532853.aspx">very interesting documents</a> on <span class="caps">MSDN</span>. It seems that <a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx">Internet Explorer</a> has support for visual filters and transitions.</p>
<p>These &#8220;visual filters and transitions&#8221; cover anything from simple Photoshop effects (including blur which i used in my Flash only <a href="http://cuppadev.co.uk/2007/10/22/flex-style-dialog-blur-in-openlaszlo">Flex-style dialog blur in OpenLaszlo</a>) to more complex transformations. More interestingly, like WebKit you can <strong>rotate elements</strong>!</p>
<p>An example which rotates by 270 degrees is as follows. Make sure you are viewing this page in Internet Explorer 5 or later, else this won&#8217;t work!</p>
<div style="background-color: black; width:200; left: 20px; height: 100; text-align: center; position: absolute;" onclick="this.style.filter='progid:DXImageTransform.Microsoft.BasicImage(rotation=3)'">Click here</div>
<div style="height: 200px;"></div>
<p>Unfortunately there are rather strange limitations with Internet Explorer&#8217;s rotation support.</p>
<p>You can only rotate in increments of 90 degrees, as opposed to Webkit which allows you to rotate by any angle. I guess they figured back in Web 1.0 that nobody wanted to rotate their elements using arbitrary angles.</p>
<p>Another thing is that elements you want to rotate need to have absolute positioning. Although this isn&#8217;t really a problem with OpenLaszlo as all the div&#8217;s it produces use absolute positioning.</p>
<p>Another perhaps more worrying problem is that with a 270 degree rotation one would expect an element to appear above the initial position. Although this could be worked around by altering the positioning in the <span class="caps">CSS</span> accordingly.</p>
<p>I guess that coupled with the apparent lack of support for changing the center of rotation and bugs with form controls limits the full effectiveness of this rotation support.</p>
<pre>
<code>
&lt;canvas&gt;
&lt;class name="itrotatable" extends="view"&gt;
&lt;attribute name="wrot" type="number" value="0"
setter="this.wrot = wrot; this.updateRot(wrot);"/&gt;

&lt;method name="updateRot" args="val"&gt;
var real_rot = Math.round(val / 90.0) % 4;
this.sprite.__LZdiv.style['filter'] = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + val + ')';
&lt;/method&gt;
&lt;/class&gt;

&lt;itrotatable name="item" x="20" y="10" width="100" height="25" bgcolor="blue"&gt;
&lt;text&gt;Test&lt;/text&gt;
&lt;animatorgroup name="move" process="sequential"
duration="1000" start="true" repeat="Infinity"&gt;
&lt;animator attribute="wrot" to="4" /&gt;
&lt;animator attribute="wrot" to="2" /&gt;
&lt;animator attribute="wrot" to="0" /&gt;
&lt;/animatorgroup&gt;
&lt;/itrotatable &gt;
&lt;/canvas&gt;
</code>
</pre>
<p>Still, that&#8217;s one more Web Browser i can sort-of rotate OpenLaszlo elements in!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuppadev.co.uk/dev/rotating-openlaszlo-with-internet-explorer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
