Last-Update: 2012-02-13
Author: Dmitry Smirnov <onlyjob@member.fsf.org>
Bug-Debian: http://bugs.debian.org/655951
Description: make taxinvoice customizable
 Original taxinvoice template lacks flexibility necessary to make
 legaly valid Australian Tax Invoices.
 This patch introduces customisation options
 useful to comply with Australian requirements, but not limited to.
 * Functional changes
   + Reference number moved to the right side from under the invoice
     owner address (improves visibility and makes invoice layout
     more compact)
   + added option to show Job Name
   + added option to show Job Number
   + added options to enable/disable columns with dynamic adjustments
     to the table layout.
   + added options to enable/disable display of some invoice elements
   + some spaces in Headings1 defaults replaced with non-breaking space
   + added "Thank you for your patronage" text as default value for
     footnote to match other invoices' defaults
 * Hardcoded messages in English are replaced with options and
   default values to match original report.
   This makes possible report localization, like changing
   "Invoice" to "Tax Invoice" where required by law etc.
 * New dialog element in [Report Options]:[General]
   + [Report Currency]
     (Because dollar sign '$' is used by many countries for their national
     currency, invoicing between Australia and New Zealand often
     causing confusion unless invoice currency is stated in the
     invoice.)
 * New dialog elements in [Report Options]:[Headings2]
   + Invoice number text (string)
   + To text (string)
   + Ref text (string)
   + Job Name text (string)
   + Job Number text (string)
 * New dialog elements page [Report Options]:[Elements]
   + column: Date (boolean)
   + column: Tax Rate (boolean)
   + column: Units (boolean)
   + row: Contact (boolean)
   + row: Address (boolean)
   + row: Invoice Number (boolean)
   + row: Company Name (boolean)
   + Invoice number next to title (boolean)
   + Show Job name (boolean)
   + Show Job number (boolean)
 * Fixed bug when customer name is listed twice above invoice owner address.
   (this change is hard to separate into standalone patch because fix
    involving changes affected by new customisation options)
 * Added modification date and copyright comments
 * spancols* variables renamed to have more readable names


--- a/src/report/business-reports/taxinvoice.eguile.scm
+++ b/src/report/business-reports/taxinvoice.eguile.scm
@@ -7,8 +7,10 @@
 ;; taxinvoice.eguile.scm  0.03
 ;; GnuCash report template called from taxinvoice.scm 0.02
 ;; (c) 2009 Chris Dennis chris@starsoftanalysis.co.uk
+;;  ©  2012 Dmitry Smirnov <onlyjob@member.fsf.org>
 ;;
 ;; $Author: chris $ $Date: 2009/07/23 10:42:08 $ $Revision: 1.33 $
+;; Modified by Dmitry Smirnov <onlyjob@member.fsf.org>  14 Feb 2012
 ;;
 ;; This file is a mixture of HTML and Guile --
 ;; see eguile-gnc.scm for details.
@@ -53,7 +55,10 @@
            (coyfax     (coy-info slots gnc:*company-fax*))
            (coyurl     (coy-info slots gnc:*company-url*))
            (coyemail   (coy-info slots gnc:*company-email*))
-           (owneraddr  (gnc:owner-get-name-and-address-dep owner))
+           (owneraddr  (gnc:owner-get-address-dep owner))
+           (ownername  (gnc:owner-get-name-dep owner))
+           (jobnumber  (gncJobGetID (gncOwnerGetJob (gncInvoiceGetOwner  opt-invoice))))
+           (jobname    (gncJobGetName (gncOwnerGetJob (gncInvoiceGetOwner  opt-invoice))))
            (billcontact (gncAddressGetName (gnc:owner-get-address owner)))
            ; flags and counters
            (discount?  #f) ; any discounts on this invoice?
@@ -62,8 +67,9 @@
            (payments?  #f) ; have any payments been made on this invoice?
            (units?     #f) ; does any row specify units?
            (qty?       #f) ; does any row have qty <> 1?
-           (spancols1  2)  ; for total line
-           (spancols2  2)) ; for subtotal line
+           (spancols_subtotal	1)	; for subtotal line
+           (spancols_payments	0)	; for payments line (between total and subtotal)
+           (spancols_total	0))	; for total line
 
       ; load splits, if any
       (if (not (null? lot))
@@ -156,16 +162,15 @@
   <td align="left">
     <h1 class="coyname"><?scm:d (or coyname (_ "Company Name")) ?></h1>
   </td>
-  <td align="right"><h2 class="invoice"><?scm:d opt-report-title ?></h2></td>
+  <td align="right"><h2 class="invoice"><?scm:d opt-report-title ?>
+    <?scm (if opt-invnum-next-to-title (begin ?><?scm:d (nbsp opt-invoice-number-text) ?><?scm:d invoiceid ?><?scm )) ?>
+  </h2></td>
 </tr>
 </table>
 <table border="0" width="100%">
 <tr valign="top">
   <td align="left">
-    <?scm (if coycontact (begin ?>
-      <strong><?scm:d coycontact ?></strong><br>
-    <?scm )) ?>
-    <?scm (if coyaddr (begin ?>
+    <?scm (if (and opt-row-address coyaddr) (begin ?>
       <?scm:d (nl->br coyaddr) ?><br>
     <?scm )) ?>
     <?scm (if coyid (begin ?>
@@ -174,6 +179,11 @@
   </td>
   <td align="right">
     <table border="0">
+      <?scm (if (and opt-row-contact coycontact) (begin ?>
+        <tr>
+          <th colspan="2" align="right"><?scm:d coycontact ?></th>
+        </tr>
+      <?scm )) ?>
       <?scm (if coyphone (begin ?>
         <tr>
           <td align="right"><?scm:d (_ "Phone") ?>:&nbsp;</td>
@@ -206,21 +216,24 @@
 <table border="0" width="100%">
 <tr valign="top">
   <!-- customer info -->
+  <th align="right" width="1%"><?scm:d opt-to-text ?></th>
   <td align="left">
-    <?scm (if (not (string=? billcontact "")) (begin ?>
-      <strong>Attn: <?scm:d billcontact ?></strong><br>
+    <?scm (if (and opt-row-company-name (not (string=? ownername ""))) (begin ?>
+        <?scm:d ownername ?><br>
     <?scm )) ?>
     <?scm (if (not (string=? owneraddr "")) (begin ?>
-      <strong><?scm:d (nl->br owneraddr) ?></strong>
+      <?scm:d (nl->br owneraddr) ?>
     <?scm )) ?>
   </td>
   <!-- invoice number etc. -->
   <td align="right">
     <table border="0">
+      <?scm (if opt-row-invoice-number (begin ?>
       <tr>
-        <td align="right" class="invnum"><big><strong><?scm:d (nbsp (_ "Invoice Number")) ?>:</strong></big>&nbsp;</td>
+        <td align="right" class="invnum"><big><strong><?scm:d (nbsp opt-invoice-number-text) ?></strong></big></td>
         <td align="right" class="invnum"><big><strong><?scm:d invoiceid ?></strong></big></td>
       </tr>
+      <?scm )) ?>
       <?scm (if (equal? postdate (cons 0 0)) (begin ?>
         <tr>
            <td colspan="2" align="right"><?scm:d (_ "Invoice in progress...") ?></td>
@@ -234,6 +247,24 @@
            <td align="right"><?scm:d (nbsp (_ "Due Date")) ?>:&nbsp;</td>
            <td align="right"><?scm:d (gnc-print-date duedate) ?></td>
         </tr>
+        <?scm (if (not (string=? billingid "")) (begin ?>
+          <tr>
+            <td align="right"><?scm:d opt-ref-text ?></td>
+            <td align="right"><?scm:d billingid ?></td>
+          </tr>
+        <?scm )) ?>
+        <?scm (if (and opt-jobname-show (not (string=? jobname ""))) (begin ?>
+          <tr>
+            <td align="right"><?scm:d opt-jobname-text ?></td>
+            <td align="right"><?scm:d jobname ?></td>
+          </tr>
+        <?scm )) ?>
+        <?scm (if (and opt-jobnumber-show (not (string=? jobnumber ""))) (begin ?>
+          <tr>
+            <td align="right"><?scm:d opt-jobnumber-text ?></td>
+            <td align="right"><?scm:d jobnumber ?></td>
+          </tr>
+        <?scm )) ?>
       <?scm )) ?>
       <?scm (if (not (string=? termsdesc "")) (begin ?>
         <tr><td colspan="2" align="right"><?scm:d termsdesc ?></td></tr>
@@ -241,11 +272,6 @@
     </table>
   </td>
 </tr>
-<?scm (if (not (string=? billingid "")) (begin ?>
-  <tr>
-    <td>Your ref: <?scm:d billingid ?></td>
-  </tr>
-<?scm )) ?>
 </table>
 
 <!-- invoice lines table -->
@@ -253,31 +279,36 @@
 <table border="1" width="100%" cellpadding="4" class="entries"> 
   <thead>
     <tr bgcolor="#ccc" valign="bottom">
+      <?scm (if opt-col-date (begin ?>
       <th align="center" ><?scm:d (_ "Date") ?></th>
+      <?scm (set! spancols_subtotal (+ spancols_subtotal 1))
+            (set! spancols_total (+ spancols_total 1)))) ?>
       <th align="left" width="80%"><?scm:d (_ "Description") ?></th>
-      <?scm (if units? (begin ?>
+      <?scm (if (and units? opt-col-units) (begin ?>
         <th align="left"><?scm:d opt-units-heading ?></th>
-        <?scm (set! spancols1 (+ spancols1 1)) 
-              (set! spancols2 (+ spancols2 1)))) ?>
+        <?scm (set! spancols_subtotal (+ spancols_subtotal 1))
+              (set! spancols_total (+ spancols_total 1)))) ?>
       <?scm (if (or units? qty?) (begin ?>
         <th align="right"><?scm:d opt-qty-heading ?></th>
-        <?scm (set! spancols1 (+ spancols1 1)) 
-              (set! spancols2 (+ spancols2 1)))) ?>
+        <?scm (set! spancols_total (+ spancols_total 1))
+               (set! spancols_subtotal (+ spancols_subtotal 1)))) ?>
       <?scm (if (or units? qty? discount?) (begin ?>
         <th align="right"><?scm:d opt-unit-price-heading ?></th>
-        <?scm (set! spancols1 (+ spancols1 1)) 
-              (set! spancols2 (+ spancols2 1)))) ?>
+        <?scm (set! spancols_total (+ spancols_total 1))
+              (set! spancols_subtotal (+ spancols_subtotal 1)))) ?>
       <?scm (if discount? (begin ?>
         <th align="right"><?scm:d opt-disc-rate-heading ?></th>
         <th align="right"><?scm:d opt-disc-amount-heading ?></th>
-        <?scm (set! spancols1 (+ spancols1 2)) 
-              (set! spancols2 (+ spancols2 1)))) ?>
+        <?scm (set! spancols_total (+ spancols_total 3))
+              (set! spancols_subtotal (+ spancols_subtotal 1)))) ?>
       <?scm (if (and tax? taxtables?) (begin ?>
         <th align="right"><?scm:d opt-net-price-heading ?></th>
+        <?scm (if opt-col-taxrate (begin ?>
         <th align="right"><?scm:d opt-tax-rate-heading ?></th>
+        <?scm (set! spancols_total (+ spancols_total 1)))) ?>
         <th align="right"><?scm:d opt-tax-amount-heading ?></th>
-        <?scm (set! spancols1 (+ spancols1 3))
-              (set! spancols2 (+ spancols2 0)))) ?>
+        <?scm (set! spancols_total (+ spancols_total 3))
+              (set! spancols_subtotal (+ spancols_subtotal 0)))) ?>
       <th align="right"><?scm:d opt-total-price-heading ?></th>
     </tr>
   </thead>
@@ -307,12 +338,16 @@
               (dsc-total 'add currency rdiscval)
     ?>
     <tr valign="top">
+      <?scm (if opt-col-date (begin ?>
       <td align="center"><?scm:d (nbsp (gnc-print-date (gncEntryGetDate entry))) ?></td>
+      <?scm )) ?>
       <td align="left"><?scm:d (gncEntryGetDescription entry) ?></td>
       <!-- td align="left">< ?scm:d (gncEntryGetNotes entry) ?></td -->
+      <?scm (if opt-col-units (begin ?>
       <?scm (if units? (begin ?>
         <td align="left"><?scm:d action ?></td>
       <?scm )) ?>
+      <?scm )) ?>
       <?scm (if (or units? qty?) (begin ?>
         <td align="right"><?scm:d (fmtnumeric qty) ?></td>
       <?scm )) ?>
@@ -329,7 +364,9 @@
       <?scm )) ?>
       <?scm (if (and tax? taxtables?) (begin ?>
         <td align="right"><?scm:d (fmtmoney currency rval) ?></td>
+        <?scm (if opt-col-taxrate (begin ?>
         <td align="right"><?scm (taxrate taxable taxtable currency) ?></td>  
+        <?scm )) ?>
         <td align="right"><?scm:d (fmtmoney currency rtaxval) ?></td>
       <?scm )) ?>
       <!-- TO DO: need an option about whether to display the tax-inclusive total? -->
@@ -340,13 +377,15 @@
     <!-- display subtotals row -->
     <?scm (if (or tax? discount? payments?) (begin ?>
       <tr valign="top"> 
-        <td align="left" class="subtotal" colspan="<?scm:d spancols2 ?>"><strong><?scm:d opt-subtotal-heading ?></strong></td>
+        <td align="left" class="subtotal" colspan="<?scm:d spancols_subtotal ?>"><strong><?scm:d opt-subtotal-heading ?></strong></td>
         <?scm (if discount? (begin ?>
           <td align="right" class="subtotal"><strong><?scm (display-comm-coll-total dsc-total #f) ?></strong></td>
         <?scm )) ?>
         <?scm (if (and tax? taxtables?) (begin ?>
           <td align="right" class="subtotal"><strong><?scm (display-comm-coll-total sub-total #f) ?></strong></td>
+          <?scm (if opt-col-taxrate (begin ?>
           <td>&nbsp;</td>
+          <?scm )) ?>
           <td align="right" class="subtotal"><strong><?scm (display-comm-coll-total tax-total #f) ?></strong></td>
         <?scm )) ?>
         <td align="right" class="subtotal"><strong><?scm (display-comm-coll-total inv-total #f) ?></strong></td>
@@ -362,17 +401,21 @@
                 (let ((c (xaccTransGetCurrency t))
                       (a (xaccSplitGetValue    split))) 
                   (inv-total 'add c a) 
+        (set! spancols_payments (+ 0 spancols_total))
     ?>
     <tr valign="top">
+      <?scm (if opt-col-date (begin ?>
       <td align="center"><?scm:d (gnc-print-date (gnc-transaction-get-date-posted t)) ?></td>
-      <td align="left" colspan="<?scm:d (- spancols1 1) ?>"><?scm:d opt-payment-recd-heading ?></td> 
+      <?scm (set! spancols_payments (- spancols_payments 1)))) ?>
+      <td align="left" colspan="<?scm:d spancols_payments ?>"><?scm:d opt-payment-recd-heading ?></td> 
       <td align="right"><?scm:d (fmtmoney c a) ?></td>
     </tr>
     <?scm ))))) ?>
 
     <!-- total row -->
     <tr valign="top">
-      <td align="left" class="total" colspan="<?scm:d spancols1 ?>"><strong><?scm:d opt-amount-due-heading ?></strong></td>
+      <td align="left" class="total" colspan="<?scm:d spancols_total ?>"><strong><?scm:d opt-amount-due-heading ?><?scm (if (not (string=? (gnc-commodity-get-mnemonic opt-report-currency) "")) (begin ?>,
+        <?scm:d (gnc-commodity-get-mnemonic opt-report-currency) ?><?scm )) ?></strong></td>
       <td align="right" class="total"><strong><?scm (display-comm-coll-total inv-total #f) ?></strong></td>
     </tr>
 
--- a/src/report/business-reports/taxinvoice.scm
+++ b/src/report/business-reports/taxinvoice.scm
@@ -1,5 +1,6 @@
 
 ;; $Author: chris $ $Date: 2009/07/29 09:31:44 $ $Revision: 1.33 $
+;; Modified by Dmitry Smirnov <onlyjob@member.fsf.org>  14 Feb 2012
 ;;
 ;; This program is free software; you can redistribute it and/or
 ;; modify it under the terms of the GNU General Public License as
@@ -87,7 +88,24 @@
 ;(define filespage    (N_ "Files"))
 (define displaypage  (N_ "Display"))
 (define generalpage  gnc:pagename-general)
+(define elementspage			(N_ "Elements"))
 ; option names 
+(define optname-col-date		(N_ "column: Date"))
+(define optname-col-taxrate		(N_ "column: Tax Rate"))
+(define optname-col-units		(N_ "column: Units"))
+(define optname-row-address		(N_ "row: Address"))
+(define optname-row-contact		(N_ "row: Contact"))
+(define optname-row-invoice-number	(N_ "row: Invoice Number"))
+(define optname-row-company-name		(N_ "row: Company Name"))
+(define optname-report-currency		(N_ "Report Currency"))
+(define optname-invoice-number-text	(N_ "Invoice number text"))
+(define optname-to-text			(N_ "To text"))
+(define optname-ref-text		(N_ "Ref text"))
+(define optname-jobname-text		(N_ "Job Number text"))
+(define optname-jobnumber-text		(N_ "Job Name text"))
+(define optname-jobname-show		(N_ "Show Job name"))
+(define optname-jobnumber-show		(N_ "Sjow Job number"))
+(define optname-invnum-next-to-title	(N_ "Invoice number next to title"))
 (define optname-border-collapse		(N_ "table-border-collapse"))
 (define optname-border-color-th		(N_ "table-header-border-color"))
 (define optname-border-color-td		(N_ "table-cell-border-color"))
@@ -140,6 +158,20 @@
       "a" "" (lambda () '()) 
       #f))        ;customers-only)) ;-- see above
 
+(add-option (gnc:make-currency-option		generalpage	optname-report-currency		"b" "" (N_ "")))
+
+  ;; Elements page options
+(add-option (gnc:make-simple-boolean-option	elementspage	optname-col-date		"a" (N_ "Display the date?") #t))
+(add-option (gnc:make-simple-boolean-option	elementspage	optname-col-taxrate		"b" (N_ "Display the Tax Rate?") #t))
+(add-option (gnc:make-simple-boolean-option	elementspage	optname-col-units		"c" (N_ "Display the Units?") #t))
+(add-option (gnc:make-simple-boolean-option	elementspage	optname-row-contact		"d" (N_ "Display the contact?") #t))
+(add-option (gnc:make-simple-boolean-option	elementspage	optname-row-address		"e" (N_ "Display the address?") #t))
+(add-option (gnc:make-simple-boolean-option	elementspage	optname-row-invoice-number	"f" (N_ "Display the Invoice Number?") #t))
+(add-option (gnc:make-simple-boolean-option	elementspage	optname-row-company-name	"g" (N_ "Display the Company Name?") #t))
+(add-option (gnc:make-simple-boolean-option	elementspage	optname-invnum-next-to-title	"h" (N_ "Invoice Number next to title?") #f))
+(add-option (gnc:make-simple-boolean-option	elementspage	optname-jobname-show		"i" (N_ "Display Job name?") #t))
+(add-option (gnc:make-simple-boolean-option	elementspage	optname-jobnumber-show		"j" (N_ "Invoice Job number?") #f))
+
   ;; Display options
   (add-option (gnc:make-string-option displaypage optname-template-file "a" 
     (N_ "The file name of the eguile template part of this report.  This file should either be in your .gnucash directory, or else in its proper place within the GnuCash installation directories.")
@@ -178,25 +210,35 @@
   (add-option (gnc:make-string-option
                 headingpage optname-disc-amount "f" "" (N_ "Discount Amount")))
   (add-option (gnc:make-string-option
-                headingpage optname-net-price "g" "" (N_ "Net Price")))
+                headingpage optname-net-price "g" "" (N_ "Net Price")))
   (add-option (gnc:make-string-option
                 headingpage optname-tax-rate "h" "" (N_ "Tax Rate")))
   (add-option (gnc:make-string-option
                 headingpage optname-tax-amount "i" "" (N_ "Tax Amount")))
   (add-option (gnc:make-string-option
-                headingpage optname-total-price "j" "" (N_ "Total Price")))
+                headingpage optname-total-price "j" "" (N_ "Total Price")))
   (add-option (gnc:make-string-option
                 headingpage2 optname-subtotal "a" "" (N_ "Sub-total")))
   (add-option (gnc:make-string-option
-                headingpage2 optname-amount-due "b" "" (N_ "Amount Due")))
+                headingpage2 optname-amount-due "b" "" (N_ "Amount Due")))
   (add-option (gnc:make-string-option
                 headingpage2 optname-payment-recd "c" "" 
                 (N_ "Payment received, thank you")))
+  (add-option (gnc:make-string-option	headingpage2	optname-invoice-number-text
+    "d" "" (N_ "Invoice number: ")))
+  (add-option (gnc:make-string-option	headingpage2	optname-to-text
+    "e" "" (N_ "To: ")))
+  (add-option (gnc:make-string-option	headingpage2	optname-ref-text
+    "f" "" (N_ "Your ref: ")))
+  (add-option (gnc:make-string-option	headingpage2	optname-jobnumber-text
+    "g" "" (N_ "Job number: ")))
+  (add-option (gnc:make-string-option	headingpage2	optname-jobname-text
+    "h" "" (N_ "Job name: ")))
 
   (add-option (gnc:make-text-option
                 notespage optname-extra-notes "a"
                 (N_ "Notes added at end of invoice -- may contain HTML markup") 
-                ""))
+                "Thank you for your patronage."))
                 ;(N_ "(Development version -- don't rely on the numbers on this report without double-checking them.<br>Change the 'Extra Notes' option to get rid of this message)")))
 
   (add-option (gnc:make-text-option	notespage optname-extra-css "b"
@@ -231,6 +273,17 @@
                                       (opt-value displaypage optname-text-font)))
          (opt-logofile              (opt-value displaypage  optname-logofile)) 
          (opt-logo-width            (opt-value displaypage  optname-logo-width)) 
+         (opt-col-date              (opt-value elementspage  optname-col-date))
+         (opt-col-taxrate           (opt-value elementspage  optname-col-taxrate))
+         (opt-col-units             (opt-value elementspage  optname-col-units))
+         (opt-row-contact           (opt-value elementspage  optname-row-contact))
+         (opt-row-address           (opt-value elementspage  optname-row-address))
+         (opt-row-invoice-number    (opt-value elementspage  optname-row-invoice-number))
+         (opt-row-company-name      (opt-value elementspage  optname-row-company-name))
+         (opt-invnum-next-to-title  (opt-value elementspage  optname-invnum-next-to-title))
+         (opt-jobname-show          (opt-value elementspage  optname-jobname-show))
+         (opt-jobnumber-show        (opt-value elementspage  optname-jobnumber-show))
+         (opt-report-currency       (opt-value generalpage optname-report-currency))
          (opt-css-border-collapse   (if (opt-value displaypage optname-border-collapse) "border-collapse:collapse;"))
          (opt-css-border-color-th   (opt-value displaypage optname-border-color-th))
          (opt-css-border-color-td   (opt-value displaypage optname-border-color-td))
@@ -247,6 +300,11 @@
          (opt-subtotal-heading      (opt-value headingpage2 optname-subtotal))
          (opt-amount-due-heading    (opt-value headingpage2 optname-amount-due))
          (opt-payment-recd-heading  (opt-value headingpage2 optname-payment-recd))
+         (opt-invoice-number-text   (opt-value headingpage2 optname-invoice-number-text))
+         (opt-to-text		    (opt-value headingpage2 optname-to-text))
+         (opt-ref-text		    (opt-value headingpage2 optname-ref-text))
+         (opt-jobnumber-text	    (opt-value headingpage2 optname-jobnumber-text))
+         (opt-jobname-text		    (opt-value headingpage2 optname-jobname-text))
          (opt-extra-css             (opt-value notespage    optname-extra-css)) 
          (opt-extra-notes           (opt-value notespage    optname-extra-notes)) 
          (css? #t) ;(and (defined? 'gnc-html-engine-supports-css) (gnc-html-engine-supports-css)))
