<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3284231539337141448</id><updated>2012-02-16T14:04:39.293-08:00</updated><title type='text'>Google Invoicing</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-8732939595644228192</id><published>2009-09-05T22:52:00.000-07:00</published><updated>2009-09-05T22:54:18.049-07:00</updated><title type='text'>Vector Drawing in a browser</title><content type='html'>&lt;DIV&gt;&lt;FONT face=Arial size=2&gt;Inevitably, the apps project is going to have BOMS,  or builds, or a product hierarchy.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;A hierarchy already exists inasfar as products  belong to product groups, which in turn belong to ranges. A build is slightly  different because a product does not need to belong only to one  group.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;The definition of&amp;nbsp;a products 'belonging' then  does not come from the product itself, but from its parent. i.e. you create a  parent product, and then decide what products belong to it. Some of those  products may themselves be builds and so on.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;If you haven't come across the concept before, then  it is difficult to get your head around without a picture, which is where the  subject of this blog comes in.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;Browsers are notoriously difficult to get dynamic,  vector pictures into. The problem has been addressed with flash, java applets  and front end applications. However there is another answer&amp;nbsp;:&amp;nbsp;clever  javascript libraries.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;Include a small 7k library from &lt;A  href="http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm"&gt;&lt;FONT  face="Times New Roman"  size=3&gt;http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm&lt;/FONT&gt;&lt;/A&gt;, then  call the drawing elements of the library from java like this:&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;function myDrawFunction() {&lt;BR&gt;&amp;nbsp; for (i = 10;  i &amp;lt; 259 ; i = i + 100) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;  jg_doc.setColor("#"+genHex());&lt;BR&gt;&amp;nbsp;&amp;nbsp;  jg_doc.drawRect(300-i,300-i,i*2,i*2)&lt;BR&gt;&amp;nbsp;&amp;nbsp; jg_doc.drawString("Some  Text",300-i,300-i);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; jg_doc.paint(); // draws, in this  case, directly into the document&lt;BR&gt;}&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;var jg_doc = new jsGraphics(); // draw directly  into document&lt;BR&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;It works ! It is cross browser and fast  !&lt;/DIV&gt;&lt;/FONT&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-8732939595644228192?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/8732939595644228192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/09/vector-drawing-in-browser.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/8732939595644228192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/8732939595644228192'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/09/vector-drawing-in-browser.html' title='Vector Drawing in a browser'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-4110859531786950055</id><published>2009-05-18T02:03:00.001-07:00</published><updated>2009-05-18T02:03:33.845-07:00</updated><title type='text'>PHP and variable scope</title><content type='html'>For some historical reason, ostensibly to do with the design philosophy, PHP&lt;br&gt;can store data in the user session, but can&amp;#39;t store data with application&lt;br&gt;scope.&lt;p&gt;ASPs can do it, JSPs can do it, but PHP doesn&amp;#39;t, and has no plans to any&lt;br&gt;time in the future.&lt;p&gt;For this application, it means that every single user is going to have to&lt;br&gt;grab hold of a copy of the database schema every time they start their&lt;br&gt;session. When we reach the point of tens of thousands of hits per second, we&lt;br&gt;are going to need far more power in the database than would otherwise be the&lt;br&gt;case. As it happens, this particular application is designed such that users&lt;br&gt;of a particular size are going to be happy to pay for their own, uncontended&lt;br&gt;database instance, and no single company is ever going to grow to a size&lt;br&gt;where they would need anything more.&lt;p&gt;It is the principle which counts, though.&lt;p&gt;You could simply write stuff to disk, and put up with the performance&lt;br&gt;overhead, but then you might as well use a federated or replicated MySQL&lt;br&gt;instance. A better solution is to use Memcached. It is a highly scaleable&lt;br&gt;cacheing tool with a handy PHP interface called Memcache. Install the&lt;br&gt;package, start the daemon, and throw objects at it. For private objects, use&lt;br&gt;a name prepended to the session id. For public objects like the schema, just&lt;br&gt;use a common name. Although it isn&amp;#39;t a straightforward install, we&lt;br&gt;essentially have application scope objects.&lt;p&gt;To use the memcache interface, I would need to rewrite some code. The code&lt;br&gt;is going to first check for object existence in memcache, then read from DB&lt;br&gt;and put into memcache if it isn&amp;#39;t already there. I probably wouldn&amp;#39;t&lt;br&gt;normally use the options, but it is possible to put objects into memcache&lt;br&gt;with a limited time, and to restrict the memory usage of the daemon.&lt;p&gt;Not something I need to worry about yet (the apps are lightning-fast), but&lt;br&gt;good to know there&amp;#39;s a solution when I need one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-4110859531786950055?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/4110859531786950055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/05/php-and-variable-scope.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/4110859531786950055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/4110859531786950055'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/05/php-and-variable-scope.html' title='PHP and variable scope'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-7044394629325266630</id><published>2009-05-17T01:12:00.001-07:00</published><updated>2009-05-17T01:12:34.244-07:00</updated><title type='text'>PHP - Mysql vs Mysqli vs open database conns</title><content type='html'>There is an ongoing question over what database the application should use,&lt;br&gt;and indeed whether it should be database independent.&lt;p&gt;My view on this is that there is pretty much only MySQL. It is free, fast,&lt;br&gt;scalable, widely used and easy to find support for. Beyond MySQL, there is&lt;br&gt;Oracle which isn&amp;#39;t free, but is more scalable for certain types of&lt;br&gt;application. Importantly, if it is being used in a site with expertise in&lt;br&gt;some other database, MySQL really can be left alone, and it will work away&lt;br&gt;happily without needing maintenance.&lt;p&gt;Of course MySQL won&amp;#39;t be free forever now that Sun own it, and upgrades are&lt;br&gt;likely to be sporadic with the best features being a cost option.&lt;p&gt;MySQL also has two distinct php interfaces. MySQLI, and the older MySQL. The&lt;br&gt;uptake of MySQLI has been relatively poor even though it has been out for a&lt;br&gt;few years, possibly because there isn&amp;#39;t currently an implementation for a&lt;br&gt;persistent connection.&lt;p&gt;As a consequence of all this, there are a few design philosophies:&lt;p&gt;- All database connections are controlled through a single include.php, the&lt;br&gt;class needs to be extended in order to be used.&lt;br&gt;- All SQL outside the class needs to be ANSI-99.&lt;br&gt;- Accomodating a new database should only need a quick whip through the&lt;br&gt;parent class. An hour or so&amp;#39;s work.&lt;br&gt;- I am using MySQLI as an interface, although it should be a simple matter&lt;br&gt;to revert to MySQL, or indeed implement memcache within the parent if&lt;br&gt;necessary.&lt;p&gt;...job done, and I am not giong to even bother with the complexities of user&lt;br&gt;configured database connections. In practise, the configuration of DB&lt;br&gt;connections gives rise to at least 50% of all installation problems anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-7044394629325266630?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/7044394629325266630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/05/php-mysql-vs-mysqli-vs-open-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/7044394629325266630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/7044394629325266630'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/05/php-mysql-vs-mysqli-vs-open-database.html' title='PHP - Mysql vs Mysqli vs open database conns'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-983893120680877480</id><published>2009-05-08T23:42:00.001-07:00</published><updated>2009-05-08T23:52:54.457-07:00</updated><title type='text'>Quotation Creation</title><content type='html'>I've spent some time going through all of the bugs in the quotation creation program this week and have arrived at the point where I can't find any more to fix! &lt;p&gt;The program emails PDFs, or prints from emails, allows for the entry of notes against both the line or header, maintains details of GST numbers etc.&lt;/p&gt;&lt;p&gt;I'm now at the stage where I can go in one of two directions. Either :&lt;/p&gt;&lt;p&gt;- I expand functionality to allow for multi-currency, variable GST rates, complex formatting against notes and optional quote layouts etc.&lt;br /&gt;- I expand breadth to encompass invoicing, ordering, stock control, credit control etc.&lt;/p&gt;&lt;p&gt;Every step in additional functionality is also a direction toward complexity, so I'm going to head down the latter of the two options above.&lt;br /&gt;With an architecture painfully assembled around the quotes, adding new form types should be straightforward. We'll see, as I start on sales orders.&lt;/p&gt;&lt;p&gt;Example of PDF attached.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-983893120680877480?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/983893120680877480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/05/quotation-creation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/983893120680877480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/983893120680877480'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/05/quotation-creation.html' title='Quotation Creation'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-4952035701503141783</id><published>2009-04-30T01:24:00.001-07:00</published><updated>2009-04-30T04:01:32.759-07:00</updated><title type='text'>Updated quote interface</title><content type='html'>&lt;span style="font-family:Arial;font-size:85%;"&gt;I've spent some time on the quote interface trying to weigh off a very simple interface (such that first time users aren't turned off) against the flexibility of a system which caters for different types of business.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;Oracle, for example, has an interface which is far too complex with too many options. Most online invoicing systems aren't going to be viable most of the time because they are just too simple.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;The way I have tried to get around this is with context-sensitive tabs. You see the basics by default, but you can click a tab to see more. When you are editing a quote header, there is one set of tabs, and when you are editing the lines, the tabs change.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;All best explained in the video below.&lt;/span&gt;&lt;br /&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-64e3d4e42e2fb6b8" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v22.nonxt6.googlevideo.com/videoplayback?id%3D64e3d4e42e2fb6b8%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331578132%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D45020246EC3D3097EF338BB97CE107357DCCA580.54E47A73C9625BE28AD5F6B8C29491729FB7DDD7%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D64e3d4e42e2fb6b8%26offsetms%3D5000%26itag%3Dw160%26sigh%3DGXYBm7_GQGsYbV65_GTUM7UYoCU&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v22.nonxt6.googlevideo.com/videoplayback?id%3D64e3d4e42e2fb6b8%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331578132%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D45020246EC3D3097EF338BB97CE107357DCCA580.54E47A73C9625BE28AD5F6B8C29491729FB7DDD7%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D64e3d4e42e2fb6b8%26offsetms%3D5000%26itag%3Dw160%26sigh%3DGXYBm7_GQGsYbV65_GTUM7UYoCU&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-4952035701503141783?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='enclosure' type='video/mp4' href='http://www.blogger.com/video-play.mp4?contentId=64e3d4e42e2fb6b8&amp;type=video%2Fmp4' length='0'/><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/4952035701503141783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/04/updated-quote-interface.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/4952035701503141783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/4952035701503141783'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/04/updated-quote-interface.html' title='Updated quote interface'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-3595988051021661820</id><published>2009-04-23T20:43:00.001-07:00</published><updated>2009-04-23T20:43:07.362-07:00</updated><title type='text'>Making PDFs using PHP</title><content type='html'>&lt;DIV&gt;&lt;FONT face=Arial size=2&gt;Having spent several days using a HTML-&amp;gt;PDF  conversion program (DOMPDF), I've become disappointed with the original  conversion software. Part of the reason was the the code was abstracted beyond  belief. Every line of code seemed to make a reference to a class whose name was  calculated then dynamically loaded; every function referred to another function  in the same class which contained only one line setting a protected object in  the class.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;The code was also unneccessarily padded out with  comments like the one below making a thousand lines into five  thousand:&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;&lt;FONT face=Arial&gt; &lt;DIV&gt;&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp; /**&lt;BR&gt;&amp;nbsp;&amp;nbsp; * a record  of the current font&lt;BR&gt;&amp;nbsp;&amp;nbsp; */&lt;BR&gt;&amp;nbsp; public&amp;nbsp; $currentFont =  '';&lt;BR&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;SPAN class=549323203-24042009&gt;&lt;FONT size=2&gt;and here's the bit which really  upset me:&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;SPAN class=549323203-24042009&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;SPAN class=549323203-24042009&gt;&lt;FONT face="Courier New" size=2&gt;function  DOMPDF_autoload($class) {&lt;BR&gt;&amp;nbsp; $filename = mb_strtolower($class) .  ".cls.php";&lt;BR&gt;&amp;nbsp; require_once(DOMPDF_INC_DIR .  "/$filename");&lt;BR&gt;}&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face="Courier New"&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;SPAN class=549323203-24042009&gt;&lt;FONT face="Courier New" size=2&gt;if (  !function_exists("__autoload") ) {&lt;BR&gt;&amp;nbsp; /**&lt;BR&gt;&amp;nbsp;&amp;nbsp; * Default  __autoload() function&lt;BR&gt;&amp;nbsp;&amp;nbsp; *&lt;BR&gt;&amp;nbsp;&amp;nbsp; * @param string  $class&lt;BR&gt;&amp;nbsp;&amp;nbsp; */&lt;BR&gt;&amp;nbsp; function __autoload($class)  {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DOMPDF_autoload($class);&lt;BR&gt;&amp;nbsp;  }&lt;BR&gt;}&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/DIV&gt; &lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;SPAN class=549323203-24042009&gt;&lt;FONT size=2&gt;What the above code does is to  hunt through an (abstracted) directory for a file of a particular description  whenever a class or function is called which isn't in the already loaded code.  Not only that, but the whole thing has been abstracted to a further external  function. Try debugging that !&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;SPAN class=549323203-24042009&gt;&lt;FONT  size=2&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/FONT&gt; &lt;DIV&gt;&lt;FONT face=Arial&gt;&lt;FONT size=2&gt;&lt;SPAN class=549323203-24042009&gt;So in summary,  &lt;/SPAN&gt;I couldn't really tell what was going on. More importantly, the code has  some serious security vulnerabilities, didn't convert images accurately, and was  unnecessarily slow. In fact, the DOMPDF code represents everything I hate about  obsessively written abstracted software.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;Predictably, the set of classes didn't actually  create PDFS. It was itself an abstraction of a beautiful set of code written  right here in New Zealand, which also has a concisely written manual. &lt;A  href="http://www.ros.co.nz/pdf/readme.pdf"&gt;http://www.ros.co.nz/pdf/readme.pdf&lt;/A&gt;.  Like all good code, it isn't loosely coupled, everything works the way you  expect first time, and you can quickly find out what is going on.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;To run it, you load a single file containing a  single class, instantiate the class and call the methods laid out in the manual.  Like this:&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face="Courier New" size=2&gt;require_once("class.ezpdf.php");&lt;BR&gt;$pdf  =&amp;amp; new Cezpdf();&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face="Courier New" size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN class=549323203-24042009&gt;Add an image like  this:&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN  class=549323203-24042009&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN class=549323203-24042009&gt;&lt;FONT  face="Courier New"&gt;$pdf-&amp;gt;addJpegFromFile('COLDHOT2.JPG',150,650,100);&lt;/FONT&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN class=549323203-24042009&gt;Add a table like  this:&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN  class=549323203-24042009&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN class=549323203-24042009&gt;$dblink =  getconn();&lt;BR&gt;$results = "";&lt;BR&gt;$stmt = "select itemid,name from  gst";&lt;BR&gt;$result = mysqli_query($dblink,$stmt);&lt;BR&gt;if ($result)  {&lt;BR&gt;&amp;nbsp;while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)){&lt;BR&gt;&amp;nbsp;  $results[]=$row;&lt;BR&gt;&amp;nbsp;}&lt;BR&gt;}&lt;BR&gt;$data =  $results;&lt;BR&gt;mysqli_close($dblink);&lt;BR&gt;$pdf-&amp;gt;ezTable($data,'',$title,$opts);&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN class=549323203-24042009&gt;Add a block of text  on the page like this:&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN  class=549323203-24042009&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN class=549323203-24042009&gt;$opts =  array('shaded'=&amp;gt;0);$opts['showHeadings'] = 0;&lt;BR&gt;$opts['yPos'] = 400;  $opts['xPos'] = 200;&lt;BR&gt;$opts['fontSize'] = 11; $opts['showLines'] = 0;&lt;BR&gt;$data  = array(array('aaa'=&amp;gt;"Is this a\nmulti line  problem"));&lt;BR&gt;$pdf-&amp;gt;ezTable($data,'',$title,$opts);&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN class=549323203-24042009&gt;File it to disk like  this:&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN  class=549323203-24042009&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN class=549323203-24042009&gt;&lt;FONT  face="Courier New"&gt;$pdfcode =  $pdf-&amp;gt;ezOutput();&lt;BR&gt;$fp=fopen('findthis.pdf','wb');&lt;BR&gt;fwrite($fp,$pdfcode);&lt;BR&gt;fclose($fp);&lt;/FONT&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN class=549323203-24042009&gt;Or push it to  the&amp;nbsp;browser like this:&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT size=2&gt;&lt;SPAN class=549323203-24042009&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN class=549323203-24042009&gt;&lt;FONT  face="Courier New"&gt;$pdf-&amp;gt;ezStream();&lt;/FONT&gt;&lt;BR&gt;&lt;/DIV&gt;&lt;/SPAN&gt;&lt;/FONT&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;SPAN class=549323203-24042009&gt;The big problem is  that I now have two output types. Firstly, an html representation of a document,  and secondly a PDF representation. It is certainly possible that the two will  diverge over time so that what is printed on the user's printer is different  from what is PDF'ed up and sent to a trading partner. In my opinion, this is a  small price to pay for a much faster, more reliable, safer and better looking  result. DOMPDF is now officially scrapped!&lt;/DIV&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-3595988051021661820?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/3595988051021661820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/04/making-pdfs-using-php.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/3595988051021661820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/3595988051021661820'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/04/making-pdfs-using-php.html' title='Making PDFs using PHP'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-413318773424302192</id><published>2009-04-22T21:17:00.001-07:00</published><updated>2009-04-22T21:17:46.867-07:00</updated><title type='text'>Printing</title><content type='html'>&lt;P&gt;&lt;FONT face=Arial size=2&gt;The previous post brings me on to the general area of  printing.&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;STRONG&gt;To print a document which has just been  created&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;For example a delivery note. Typically, this can be  done via&amp;nbsp;a browser as suggested in the previous post. It isn't possible to  override the local user's browser setting, however they can change their own  settings so that page headers are not printing, shading and images are printed,  and even that they are not prompted for permission to print.&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;STRONG&gt;To print a batch, or print on someone else's  printer&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;For example a batch of customer statements, or a  batch of customer invoices, 100 sites worth of P&amp;amp;Ls etc. The print run might  take a long time to prepare, which would result in a browser timeout.&amp;nbsp;In  this context, we are not going to be printing via the user's browser.  &lt;/FONT&gt;&lt;/P&gt; &lt;UL&gt;   &lt;LI&gt;&lt;FONT face=Arial size=2&gt;Have network access from a central print server to    the client's printer. The job can then be run invisibly in the background, and    the print can spool when the print is ready. A fairly simple print spooler can    be run on a standalone linux/windows machine.&lt;/FONT&gt;&lt;/LI&gt;   &lt;LI&gt;&lt;FONT face=Arial size=2&gt;Emailing the user with the results of the print.    The user can then open the document, print at their convenience, or depending    on the format, cut/paste and analyse the results.&lt;/FONT&gt;&lt;/LI&gt;   &lt;LI&gt;&lt;FONT face=Arial size=2&gt;Emailing the user with a link to the results of    the print. As above, other than that some central storage would be required,    along with some sort of job schedule listing.&lt;/FONT&gt;&lt;/LI&gt;   &lt;LI&gt;&lt;FONT face=Arial size=2&gt;Introducing a job scheduler or concurrent process    manager, and running the job in the background.&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;Pretty much all of the above need the ability for  jobs to run in the background. This potentially opens up the complex area of job  scheduling, including precedents, parallelisation, the ability to classify jobs  by user, view and cancel jobs, and user time scheduling limitations, recurring  jobs etc.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;For the practical purpose of this application, I'm  going to avoid batch processing entirely. Everything is going to go via the  user's browser or otherwise complete while the user has their browser open, and  applications will be written with this in mind. When timeouts eventually occur,  clients will be given the option of running the application on a dedicated  server, or will be of the size where they can afford some programming expertise  to meet their requirements.&lt;/FONT&gt;&lt;/DIV&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-413318773424302192?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/413318773424302192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/04/printing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/413318773424302192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/413318773424302192'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/04/printing.html' title='Printing'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-9098599009092681996</id><published>2009-04-22T20:59:00.001-07:00</published><updated>2009-04-22T20:59:07.089-07:00</updated><title type='text'>Using CSS to differentiate between printable and unprintable elements</title><content type='html'>&lt;P&gt;&lt;FONT face=Arial size=2&gt;As long as the browser is CSS2.1 compliant (IE7 and  Chrome are fine), it is possible to have a web page looking quite differently  when printed from the way it appears on screen.&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;Doing this is fairly simple - each CSS element can be  enclosed in a media envelope to determine how the html is interpreted when  printed, or on screen.&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;So for example we have:&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt; &lt;P&gt;&lt;FONT face="Courier New" size=2&gt;@media screen {&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face="Courier New" size=2&gt;.bt {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; background:  transparent url('button.gif') scroll top right;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; font:  normal 12px arial, sans-serif;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; height:  24px;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; margin-right: 6px;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;  text-decoration: none;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;  top-border:none;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bottom-border:none;&lt;BR&gt;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face="Courier New" size=2&gt;@media print {&lt;BR&gt;&amp;nbsp;&amp;nbsp; .bt {display:  none;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;lt;input name=sub class=bt type=submit  value='Click to Continue'&amp;gt;&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;In the above, buttons aren't printed, but are shown  on screen. The principle is ideal for web pages with drop down menus which are  usually meaningless when printed. To convert any existing CSS, simply enclose it  in @media screen brackets, then create a new @media print section for each css  indicator.&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;For print-only html pages, the reverse can be done.  i.e. the page is not visible to the user unless they print it.&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt; &lt;P&gt;&lt;FONT face=Arial size=2&gt;&amp;nbsp;&lt;/P&gt;&lt;/FONT&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-9098599009092681996?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/9098599009092681996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/04/using-css-to-differentiate-between.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/9098599009092681996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/9098599009092681996'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/04/using-css-to-differentiate-between.html' title='Using CSS to differentiate between printable and unprintable elements'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-3759077977911700190</id><published>2009-04-21T00:36:00.001-07:00</published><updated>2009-04-21T00:36:53.197-07:00</updated><title type='text'>PDF Invoice / Quote</title><content type='html'>&lt;P&gt;&lt;FONT face=Arial size=1&gt;It took some time to find CSS which rendered properly  in cross-browser and pdf scenearios, and I've arrived at the source  below.&lt;/FONT&gt;&lt;/P&gt; &lt;P&gt;&lt;FONT face="Courier New" size=1&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt; &lt;P&gt;&lt;FONT face="Courier New"  size=1&gt;&amp;lt;html&amp;gt;&lt;BR&gt;&amp;lt;head&amp;gt;&lt;BR&gt;&amp;lt;style&amp;gt;&lt;BR&gt;td.c1  {font-family:Helvetica;font-size:50px;font-weight:bolder;color:#c0c0c0;}&lt;BR&gt;td.c2  {font-family:Helvetica;font-size:13px;}&lt;BR&gt;td.c3  {font-family:Helvetica;font-size:12px;}&lt;BR&gt;td.c4  {font-family:Helvetica;font-size:12px;border-bottom:solid 1px gray;  border-left:solid 1px gray; }&lt;BR&gt;td.c5  {font-family:Helvetica;font-size:12px;border-bottom:solid 1px gray;  border-right:solid 1px gray; border-left:solid 1px gray}&lt;BR&gt;th.h1  {font-family:Helvetica;font-size:12px;border-bottom:solid 1px gray;  border-left:solid 1px gray; border-top:solid 1px gray}&lt;BR&gt;th.h2  {font-family:Helvetica;font-size:12px;border-bottom:solid 1px gray;  border-left:solid 1px gray; border-right:solid 1px gray; border-top:solid 1px  gray}&lt;BR&gt;table  {margin-left:50px;margin-top:10px;margin-right:10px;}&lt;BR&gt;&amp;lt;/style&amp;gt;&lt;BR&gt;&amp;lt;/head&amp;gt;&lt;BR&gt;&amp;lt;body&amp;gt;&lt;BR&gt;&amp;lt;table  width=90%&amp;gt;&lt;BR&gt;&amp;lt;tr&amp;gt;&amp;lt;td width=15%&amp;gt;&lt;BR&gt;&amp;lt;img src="coldhot2.jpg"  width=100px&amp;gt;&lt;BR&gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;lt;td class=c2  valign=top&amp;gt;&amp;lt;b&amp;gt;PickMaster&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;BR&gt;&amp;nbsp;37 Isobel  Road&amp;lt;br&amp;gt;&lt;BR&gt;&amp;nbsp;Greenhithe&amp;lt;br&amp;gt;&lt;BR&gt;&amp;nbsp;Auckland&amp;lt;br&amp;gt;&lt;BR&gt;&amp;nbsp;0632&lt;BR&gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;lt;td  valign=top align=right  class=c1&amp;gt;&lt;BR&gt;Invoice&lt;BR&gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;lt;/table&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;lt;table  width=90%&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;td  width=50%&amp;gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;td valign=top align=right  class=c3&amp;gt;Invoice Number&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;td valign=top&amp;nbsp;  class=c3&amp;gt;10302&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp;  &amp;lt;td width=50%&amp;gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;td valign=top align=right  class=c3&amp;gt;Tax Date&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;td valign=top class=c3&amp;gt;12 Dec  2009&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;td  width=50%&amp;gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;td valign=top align=right  class=c3&amp;gt;Order Number&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;td valign=top  class=c3&amp;gt;Customer Order Number Goes  Here&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;lt;/table&amp;gt;&lt;BR&gt;&amp;lt;br&amp;gt;&lt;BR&gt;&amp;lt;br&amp;gt;&lt;BR&gt;&amp;lt;table  width=60%&amp;gt;&lt;BR&gt;&amp;lt;tr&amp;gt;&lt;BR&gt;&amp;lt;td class=c3 width=30%&amp;gt;Customer  Addy&amp;lt;br&amp;gt;&lt;BR&gt;Address Line 1&amp;lt;br&amp;gt;&lt;BR&gt;Address Line  2&amp;lt;br&amp;gt;&lt;BR&gt;Address Line 3&amp;lt;br&amp;gt;&lt;BR&gt;Post Code&lt;BR&gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;lt;td  class=c3 width=30%&amp;gt;Customer Addy&amp;lt;br&amp;gt;&lt;BR&gt;Address Line  1&amp;lt;br&amp;gt;&lt;BR&gt;Address Line 2&amp;lt;br&amp;gt;&lt;BR&gt;Address Line 3&amp;lt;br&amp;gt;&lt;BR&gt;Post  Code&lt;BR&gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;lt;/table&amp;gt;&lt;BR&gt;&amp;lt;br&amp;gt;&lt;BR&gt;&amp;lt;br&amp;gt;&lt;BR&gt;&lt;BR&gt;&amp;lt;table  width=90% style=" border: 0pt none black;" cellspacing=0;  &amp;gt;&lt;BR&gt;&amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;th valign=top class=h1 align=left  width=15%&amp;gt;Code&amp;lt;/th&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;th valign=top class=h1 align=left  width=60%&amp;gt;Description&amp;lt;/th&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;th valign=top class=h1  align=right width=15%&amp;gt;Qty&amp;lt;/th&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;th valign=top class=h2  align=right  width=10%&amp;gt;Price&amp;lt;/th&amp;gt;&lt;BR&gt;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td  valign=top class=c4&amp;gt;ActualCode&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td valign=top  class=c4&amp;gt;Full Textual Description Description&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td  valign=top class=c4 align=right&amp;gt;14&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td valign=top  class=c5  align=right&amp;gt;23.00&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td  valign=top class=c4&amp;gt;ActualCode&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td valign=top  class=c4&amp;gt;Full Textual Description Description&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td  valign=top class=c4 align=right&amp;gt;14&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td valign=top  class=c5  align=right&amp;gt;23.00&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td  align=right valign=top class=c4&amp;gt;Total&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td valign=top  class=c5  align=right&amp;gt;23.00&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td  align=right valign=top class=c4&amp;gt;GST&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td valign=top  class=c5  align=right&amp;gt;2.30&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td  align=right valign=top class=c4&amp;gt;Total&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;lt;td valign=top  class=c5  align=right&amp;gt;25.00&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;lt;/table&amp;gt;&lt;BR&gt;&amp;lt;/body&amp;gt;  &amp;lt;/html&amp;gt; &lt;/FONT&gt;&lt;/P&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-3759077977911700190?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/3759077977911700190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/04/pdf-invoice-quote.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/3759077977911700190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/3759077977911700190'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/04/pdf-invoice-quote.html' title='PDF Invoice / Quote'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-7986323869678666597</id><published>2009-04-14T23:40:00.001-07:00</published><updated>2009-04-14T23:40:08.945-07:00</updated><title type='text'>Search Algorithms</title><content type='html'>&lt;P&gt;&lt;FONT size=2&gt;I also went through all of the searching algorithms.&lt;/FONT&gt;&lt;/P&gt; &lt;UL&gt;   &lt;LI&gt;   &lt;DIV align=left&gt;&lt;FONT size=2&gt;Limits results within master    class&lt;/FONT&gt;&lt;/DIV&gt;&lt;/LI&gt;   &lt;LI&gt;   &lt;DIV align=left&gt;&lt;FONT size=2&gt;Lightning fast on almost any size    table&lt;/FONT&gt;&lt;/DIV&gt;&lt;/LI&gt;   &lt;LI&gt;   &lt;DIV align=left&gt;&lt;FONT size=2&gt;Allows for selection of 'none of the    above'&lt;/FONT&gt;&lt;/DIV&gt;&lt;/LI&gt;   &lt;LI&gt;   &lt;DIV align=left&gt;&lt;FONT size=2&gt;Fixed bug on where multi-page select lists used    in conjunction with a change of search criteria&lt;/FONT&gt;&lt;/DIV&gt;&lt;/LI&gt;   &lt;LI&gt;   &lt;DIV align=left&gt;&lt;FONT size=2&gt;Cached results for further speed    enhancements&lt;/FONT&gt;&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt; &lt;DIV align=left&gt;&amp;nbsp;&lt;/DIV&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-7986323869678666597?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/7986323869678666597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/04/search-algorithms.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/7986323869678666597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/7986323869678666597'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/04/search-algorithms.html' title='Search Algorithms'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-5457483421223733331</id><published>2009-04-14T23:29:00.001-07:00</published><updated>2009-04-14T23:29:29.540-07:00</updated><title type='text'>Rendering in pdf</title><content type='html'>&lt;DIV&gt;&lt;FONT face=Arial size=2&gt;First off, I should point out that I *hate*  PDFs.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;When the format was first launched, I remember a  review of it, and the article posed the question "What is the point?" It was  inconclusive, and I have still not worked out what the point of a PDF is. Does  it stop the receiver from editing the document? - No. Is it easier to transmit ?  - No. Is it easier to write software for ? - Definitely No. Is it in some way  more secure? - No. Is it easier to read ? - No, more difficult. Is it more  portable than HTML? - No.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;Notwithstanding, people expect to be able to  transmit documents as PDFs.&amp;nbsp;Adobe have done a wonderful marketing job, and  it isn't my place to unilaterally open everyones' eyes to the pointlessness of  their proprietary document format.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;The solution?&amp;nbsp;The applications produce html  (probably from within the database), then have the facility to convert it to pdf  at application level. The user can then transmit the PDF as an email attachment  or file it somewhere as they see fit. Production of XML, direct import into  google apps and other machine-readable formats will follow later.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;To perform the translation, I am using dompdf v  0.5.1. This is a free, downloadable set of classes specifically for converting  html to pdf, it is all done natively in php and requires no further downloads.  It has limited font support (suggest stick with Helvetica), but understands CSS,  tables and graphics, and even some support for inline scripting.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;Here's an example bit of conversion  code:&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Courier  size=2&gt;&amp;lt;?php&lt;BR&gt;require_once("dompdf_config.inc.php");&lt;BR&gt;$dompdf = new  DOMPDF();&lt;BR&gt;$dompdf-&amp;gt;load_html_file("test.htm");&lt;BR&gt;$dompdf-&amp;gt;render();&lt;BR&gt;$dompdf-&amp;gt;stream("sample".time().".pdf");&lt;BR&gt;?&amp;gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;And it seems pretty happy to convert something like  this:&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Courier  size=2&gt;&amp;lt;html&amp;gt;&lt;BR&gt;&amp;lt;head&amp;gt;&lt;BR&gt;&amp;lt;style&amp;gt;&lt;BR&gt;td  {font-family:Helvetica;font-size:10px;background-color:#ffffff;border-style:solid;border:thin  solid #c0c0c0}&lt;BR&gt;th  {font-family:Helvetica;font-size:30px;background-color:#e0e0e0;border:thin solid  #c0c0c0}&lt;BR&gt;table {border:none;border-spacing:0;border-collapse:collapse;}&lt;BR&gt;h1  {font-family:Helvetica;font-size:20px}&lt;BR&gt;&amp;lt;/style&amp;gt;&lt;BR&gt;&amp;lt;/head&amp;gt;&lt;BR&gt;&amp;lt;h1&amp;gt;A  Heading&amp;lt;/h1&amp;gt;&lt;BR&gt;&amp;lt;table width="100%"&amp;gt;&lt;BR&gt;&amp;nbsp;  &amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tH&amp;gt;a&amp;lt;/tH&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;lt;tH&amp;gt;b&amp;lt;/tH&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tH&amp;gt;c&amp;lt;/tH&amp;gt;&lt;BR&gt;&amp;nbsp;  &amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;nbsp; &amp;lt;tr&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;lt;td&amp;gt;d&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &amp;lt;td&amp;gt;e&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;f&amp;lt;/td&amp;gt;&lt;BR&gt;&amp;nbsp;  &amp;lt;/tr&amp;gt;&lt;BR&gt;&amp;lt;/table&amp;gt;&lt;BR&gt;&amp;lt;img  src=".\coldhot.jpg"&amp;gt;&lt;BR&gt;&amp;lt;/html&amp;gt;&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;Here's some more documentation.&lt;/FONT&gt;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt; &lt;DIV&gt;&lt;FONT face=Arial size=2&gt;&lt;A  href="http://digg.com/d11Kqn"&gt;http://digg.com/d11Kqn&lt;/A&gt;&lt;/FONT&gt;&lt;/DIV&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-5457483421223733331?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/5457483421223733331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/04/rendering-in-pdf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/5457483421223733331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/5457483421223733331'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/04/rendering-in-pdf.html' title='Rendering in pdf'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-648832400387341472</id><published>2009-04-13T00:36:00.001-07:00</published><updated>2009-04-15T04:54:21.806-07:00</updated><title type='text'>Sales Order Interface</title><content type='html'>&lt;span style="font-family:Arial;font-size:85%;"&gt;The sales order input program is probably the most important one for a number of reasons:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;Strategically, it is close to the customer. In a telereactive sales environment, it gives the customer an impression of the business.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;It should be the thing you do most often in your business - invoicing, quoting and raising orders.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;The quote program is mostly written in principle. Further enhancements:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;Ability to enter 'Manual' lines, i.e. not affecting stock, and not in the product file.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;Ability to enter 'Special' lines, i.e. a physical product, so purchase order needed.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;A 'type' grid for quotes, invoices, credits, collections, orders, directs, credits (no stock), cash type sales. Conditional conversion between types.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;Calculation of customer selling prices, incorporating discount grid.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;Packs and kits.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;Credit control / order hold.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;Printing / transmission.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;Consequently, and with the above goals, it is the quotes (and order processing) routines I am concentrating on this week.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"   style="font-family:Arial;font-size:13;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-22075bb05adee30e" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v4.nonxt7.googlevideo.com/videoplayback?id%3D22075bb05adee30e%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331578132%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D195F61F8222050795C72B3D90EFBDA72B62EBC51.281A6834BEE968FC1CA8C1FE93EB20C0B83F0CA0%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D22075bb05adee30e%26offsetms%3D5000%26itag%3Dw160%26sigh%3D4_mIEX64Jel9xzChaj6TXJ66oGU&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v4.nonxt7.googlevideo.com/videoplayback?id%3D22075bb05adee30e%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331578132%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D195F61F8222050795C72B3D90EFBDA72B62EBC51.281A6834BEE968FC1CA8C1FE93EB20C0B83F0CA0%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D22075bb05adee30e%26offsetms%3D5000%26itag%3Dw160%26sigh%3D4_mIEX64Jel9xzChaj6TXJ66oGU&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-648832400387341472?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='enclosure' type='video/mp4' href='http://www.blogger.com/video-play.mp4?contentId=22075bb05adee30e&amp;type=video%2Fmp4' length='0'/><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/648832400387341472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/04/sales-order-interface.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/648832400387341472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/648832400387341472'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/04/sales-order-interface.html' title='Sales Order Interface'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-2556487767138478163</id><published>2009-04-09T17:13:00.001-07:00</published><updated>2009-04-09T17:19:09.963-07:00</updated><title type='text'>Disabling form resubmission</title><content type='html'>&lt;p&gt;&lt;span style="font-size:85%;"&gt;When the user of a web site clicks on the submit button, the  page is wrapped up and sent to the web server for processing. Depending on the  speed of the connection and the web server, the user may click submit  twice.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;When this happens, the web server will receive exactly the same  page twice, and will need to decide what to do. Depending on the complexity of  the server-side application, you may need to cater for many different situations  in a complex application.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;It is much simpler to reduce the number of duplicated  submissions (many users still think double-clicking is the right thing to do!),  and to generate a general error. So how do you prevent form  resubmission?&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-size:85%;"&gt;Answer : like this:&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 4pt; BACKGROUND: #e0e0e0; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 0.5pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 0.5pt solid"&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;lt;%@ page  contentType="text/html;charset=windows-1252"%&amp;gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Disabling form  resubmission&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;lt;HTML&amp;gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;lt;HEAD&amp;gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;lt;SCRIPT  language="JavaScript"&amp;gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;function  submitform()&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;{&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;document.myform.getme.disabled = true  ;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;}&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;lt;/SCRIPT&amp;gt;  &lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;lt;form name="myform"  onsubmit = "return false"&amp;gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Search: &amp;lt;input  type='text' name='query'&amp;gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;lt;input name=getme  type=submit value=test onclick="submitform()"&amp;gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt; &lt;h5 style="MARGIN: 0cm 0cm 0pt"&gt;&lt;span lang="EN-US" style="mso-ansi-language: EN-US"&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;lt;/form&amp;amp;g&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;t;  &lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h5&gt;&lt;span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-2556487767138478163?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/2556487767138478163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/04/disabling-form-resubmission.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/2556487767138478163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/2556487767138478163'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/04/disabling-form-resubmission.html' title='Disabling form resubmission'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284231539337141448.post-2353232709352581959</id><published>2009-04-09T16:18:00.000-07:00</published><updated>2009-04-09T17:17:36.758-07:00</updated><title type='text'>Google Apps</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_u9XLmpGrgpM/Sd6JxOyHjAI/AAAAAAAABEw/8mYtnxRU4zE/s1600-h/image2.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 257px; height: 320px;" src="http://4.bp.blogspot.com/_u9XLmpGrgpM/Sd6JxOyHjAI/AAAAAAAABEw/8mYtnxRU4zE/s320/image2.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5322843288473406466" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Every small business has the same problem.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you are a builder, a taxi driver, an electrician, an IT contractor, a masseur, cleaner or whatever, people want quotes and they want invoices. You need to keep records for tax and GST, and you need to keep details of who owes you money.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what do you do?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Go out and buy MYOB or Sage / some other small accounting package, or you try to keep paper records using MS Word/Excel.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Both options are full of problems:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt; If you set up a small accounting package, you need to spend some cash.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; You spend ages setting the software up and it's complex. You then need to keep installing updates.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When your hard disk fails, you lose your records. Either that, or you need to be good at backup and restore.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You need to be at your computer to create the quotes, or you write them out by hand while on site, and then need to rekey them as invoices later on, hoping you don't make any mistakes.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If you use Word, you keep saving your invoices and deleting the old copies. You also can't keep track of who owes you money.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Importantly, the setup won't grow with your business. As soon as you have more employees, need to open another site, employ an accountant or expand, you need to change software. Then before you know it you need to employ someone to look after the application.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what's the solution ?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Googapps online invoicing. You don't need to worry about backup, keeping up to date with the latest GST legislation, updating software or expansion. Furthermore, because the software is online, you can create quotes and invoices from any computer with a browser and internet connectivity - even your phone.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On site with your customer and want to see how much they owe? Use your phone to access their account, then email them the details. Better still, if they are a googapps user too, they can import the invoices directly into their own googapps account.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Computer hard drive crashes? Get a new computer, borrow someone else's or use your phone. It won't affect your business.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-d589b4a6a47178eb" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v5.nonxt7.googlevideo.com/videoplayback?id%3Dd589b4a6a47178eb%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331578132%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D62741717B9777ABCAC445A0949E7D25E507697F1.3F8B9BD38D664EE1C8FC386B3B4AD612CC45CF28%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Dd589b4a6a47178eb%26offsetms%3D5000%26itag%3Dw160%26sigh%3DNCaCEzcOCawG6HC0_Tx4Orrwarw&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v5.nonxt7.googlevideo.com/videoplayback?id%3Dd589b4a6a47178eb%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331578132%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D62741717B9777ABCAC445A0949E7D25E507697F1.3F8B9BD38D664EE1C8FC386B3B4AD612CC45CF28%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Dd589b4a6a47178eb%26offsetms%3D5000%26itag%3Dw160%26sigh%3DNCaCEzcOCawG6HC0_Tx4Orrwarw&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284231539337141448-2353232709352581959?l=googapps.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='enclosure' type='video/mp4' href='http://www.blogger.com/video-play.mp4?contentId=d589b4a6a47178eb&amp;type=video%2Fmp4' length='0'/><link rel='replies' type='application/atom+xml' href='http://googapps.blogspot.com/feeds/2353232709352581959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://googapps.blogspot.com/2009/04/google-apps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/2353232709352581959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284231539337141448/posts/default/2353232709352581959'/><link rel='alternate' type='text/html' href='http://googapps.blogspot.com/2009/04/google-apps.html' title='Google Apps'/><author><name>Catman</name><uri>http://www.blogger.com/profile/02716332787160129047</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_u9XLmpGrgpM/Sd6JxOyHjAI/AAAAAAAABEw/8mYtnxRU4zE/s72-c/image2.jpg' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
