;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; income-statement.scm: income statement (a.k.a. Profit & Loss) ;; ;; By David Montenegro ;; 2004.07.13 - 2004.07.14 ;; ;; Modified by Michael McKay ;; 2009.01.20 ;; ;; * BUGS: ;; ;; This code makes the assumption that you want your income ;; statement to no more than daily resolution. ;; ;; The Company Name field does not currently default to the name ;; in (gnc-get-current-book). ;; ;; Line & column alignments may still not conform with ;; textbook accounting practice (they're close though!). ;; The 'canonically-tabbed option is currently broken. ;; ;; Progress bar functionality is currently mostly broken. ;; ;; The variables in this code could use more consistent naming. ;; ;; See also all the "FIXME"s in the code. ;; ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License as ;; published by the Free Software Foundation; either version 2 of ;; the License, or (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program; if not, contact: ;; ;; Free Software Foundation Voice: +1-617-542-5942 ;; 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 ;; Boston, MA 02110-1301, USA gnu@gnu.org ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define-module (gnucash report income-statement)) (use-modules (gnucash main)) ;; FIXME: delete after we finish modularizing. (use-modules (ice-9 slib)) (use-modules (gnucash gnc-module)) (gnc:module-load "gnucash/report/report-system" 0) (gnc:module-load "gnucash/business-utils" 0) (define reportname (N_ "Income Statement")) ;; define all option's names and help text so that they are properly ;; defined in *one* place. (define optname-report-title (N_ "Report Title")) (define opthelp-report-title (N_ "Title for this report")) (define optname-party-name (N_ "Company name")) (define opthelp-party-name (N_ "Name of company/individual")) (define optname-start-date (N_ "Start Date")) (define optname-end-date (N_ "End Date")) ;; FIXME this could use an indent option ;; Setup account groupings independent of account types (define optname-income-accounts (N_ "Income accounts to include")) (define opthelp-income-accounts (N_ "Report on these accounts as income, if display depth allows.")) (define optname-cos-accounts (N_ "Cost of Sales accounts to include")) (define opthelp-cos-accounts (N_ "Report on these accounts as cost of sales, if display depth allows.")) (define optname-expense-accounts (N_ "Operating Expense accounts to include")) (define opthelp-expense-accounts (N_ "Report on these accounts as operating expenses, if display depth allows.")) (define optname-other-accounts (N_ "Other expense accounts to include")) (define opthelp-other-accounts (N_ "Report on these accounts as other expenses, if display depth allows.")) (define optname-depth-limit (N_ "Levels of Subaccounts")) (define opthelp-depth-limit (N_ "Maximum number of levels in the account tree displayed")) (define optname-bottom-behavior (N_ "Flatten list to depth limit")) (define opthelp-bottom-behavior (N_ "Displays accounts which exceed the depth limit at the depth limit")) (define optname-parent-balance-mode (N_ "Parent account balances")) (define optname-parent-total-mode (N_ "Parent account subtotals")) (define optname-show-zb-accts (N_ "Include accounts with zero total balances")) (define opthelp-show-zb-accts (N_ "Include accounts with zero total (recursive) balances in this report")) (define optname-omit-zb-bals (N_ "Omit zero balance figures")) (define opthelp-omit-zb-bals (N_ "Show blank space in place of any zero balances which would be shown")) (define optname-use-rules (N_ "Show accounting-style rules")) (define opthelp-use-rules (N_ "Use rules beneath columns of added numbers like accountants do")) (define optname-account-links (N_ "Display accounts as hyperlinks")) (define opthelp-account-links (N_ "Shows each account in the table as a hyperlink to its register window")) (define optname-label-revenue (N_ "Label the revenue section")) (define opthelp-label-revenue (N_ "Whether or not to include a label for the revenue section")) (define optname-total-revenue (N_ "Include revenue total")) (define opthelp-total-revenue (N_ "Whether or not to include a line indicating total revenue")) (define optname-label-cos (N_ "Label the cost of sales section")) (define opthelp-label-cos (N_ "Whether or not to include a label for the cost of sales section")) (define optname-calc-gm (N_ "Calculate the gross margin")) (define opthelp-calc-gm (N_ "Whether or not to calculate the gross margin")) (define optname-total-cos (N_ "Include cost of sales total")) (define opthelp-total-cos (N_ "Whether or not to include a line indicating total cost of sales")) (define optname-label-expense (N_ "Label the operating expense section")) (define opthelp-label-expense (N_ "Whether or not to include a label for the operating expense section")) (define optname-total-expense (N_ "Include operating expense total")) (define opthelp-total-expense (N_ "Whether or not to include a line indicating total operating expense")) (define optname-ebitda (N_ "Calculate EBITDA")) (define opthelp-ebitda (N_ "Whether or not to include a line indicating EBITDA")) (define optname-label-other (N_ "Label the other expense section")) (define opthelp-label-other (N_ "Whether or not to include a label for the other expense section")) (define optname-total-other (N_ "Include other expense total")) (define opthelp-total-other (N_ "Whether or not to include a line indicating total other expense")) (define pagename-commodities (N_ "Commodities")) (define optname-report-commodity (N_ "Report's currency")) (define optname-price-source (N_ "Price Source")) (define optname-show-foreign (N_ "Show Foreign Currencies")) (define opthelp-show-foreign (N_ "Display any foreign currency amount in an account")) (define optname-show-rates (N_ "Show Exchange Rates")) (define opthelp-show-rates (N_ "Show the exchange rates used")) (define pagename-entries (N_ "Entries")) (define optname-closing-pattern (N_ "Closing Entries pattern")) (define opthelp-closing-pattern (N_ "Any text in the Description column which identifies closing entries")) (define optname-closing-casing (N_ "Closing Entries pattern is case-sensitive")) (define opthelp-closing-casing (N_ "Causes the Closing Entries Pattern match to be case-sensitive")) (define optname-closing-regexp (N_ "Closing Entries Pattern is regular expression")) (define opthelp-closing-regexp (N_ "Causes the Closing Entries Pattern to be treated as a regular expression")) (define optname-two-column (N_ "Display as a two column report")) (define opthelp-two-column (N_ "Divides the report into an income column and an expense column")) (define optname-standard-order (N_ "Display in standard, income first, order")) (define opthelp-standard-order (N_ "Causes the report to display in the standard order, placing income before expenses")) ;; options generator (define (income-statement-options-generator) (let* ((options (gnc:new-options)) (add-option (lambda (new-option) (gnc:register-option options new-option)))) (add-option (gnc:make-string-option gnc:pagename-general optname-report-title "a" opthelp-report-title (_ reportname))) (add-option (gnc:make-string-option gnc:pagename-general optname-party-name "b" opthelp-party-name "")) ;; this should default to company name in (gnc-get-current-book) ;; does anyone know the function to get the company name?? ;; (GnuCash is *so* well documented... sigh) ;; period over which to report income (gnc:options-add-date-interval! options gnc:pagename-general optname-start-date optname-end-date "c") ;; accounts to work on ;; Revenue Accounts (add-option (gnc:make-account-list-option gnc:pagename-accounts optname-income-accounts "a" opthelp-income-accounts (lambda () (gnc:filter-accountlist-type ;; select, by default, only income accounts (list ACCT-TYPE-INCOME) (gnc-account-get-descendants-sorted (gnc-get-current-root-account)))) #f #t)) ;; COS Accounts (add-option (gnc:make-account-list-option gnc:pagename-accounts optname-cos-accounts "b" opthelp-cos-accounts (lambda () (gnc:filter-accountlist-type ;; select, by default, only expense accounts (list ACCT-TYPE-EXPENSE) (gnc-account-get-descendants-sorted (gnc-get-current-root-account)))) #f #t)) ;; Operating Expenses (add-option (gnc:make-account-list-option gnc:pagename-accounts optname-expense-accounts "c" opthelp-expense-accounts (lambda () (gnc:filter-accountlist-type ;; select, by default, only income and expense accounts (list ACCT-TYPE-INCOME ACCT-TYPE-EXPENSE) (gnc-account-get-descendants-sorted (gnc-get-current-root-account)))) #f #t)) ;; Other Expenses (add-option (gnc:make-account-list-option gnc:pagename-accounts optname-other-accounts "d" opthelp-other-accounts (lambda () (gnc:filter-accountlist-type ;; select, by default, only income and expense accounts (list ACCT-TYPE-INCOME ACCT-TYPE-EXPENSE) (gnc-account-get-descendants-sorted (gnc-get-current-root-account)))) #f #t)) (gnc:options-add-account-levels! options gnc:pagename-accounts optname-depth-limit "e" opthelp-depth-limit 3) (add-option (gnc:make-simple-boolean-option gnc:pagename-accounts optname-bottom-behavior "f" opthelp-bottom-behavior #f)) ;; all about currencies (gnc:options-add-currency! options pagename-commodities optname-report-commodity "a") (gnc:options-add-price-source! options pagename-commodities optname-price-source "b" 'average-cost) (add-option (gnc:make-simple-boolean-option pagename-commodities optname-show-foreign "c" opthelp-show-foreign #t)) (add-option (gnc:make-simple-boolean-option pagename-commodities optname-show-rates "d" opthelp-show-rates #f)) ;; what to show for zero-balance accounts (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-show-zb-accts "a" opthelp-show-zb-accts #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-omit-zb-bals "b" opthelp-omit-zb-bals #f)) ;; what to show for non-leaf accounts (gnc:options-add-subtotal-view! options gnc:pagename-display optname-parent-balance-mode optname-parent-total-mode "c") ;; some detailed formatting options (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-account-links "e" opthelp-account-links #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-use-rules "f" opthelp-use-rules #f)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-label-revenue "g" opthelp-label-revenue #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-total-revenue "h" opthelp-total-revenue #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-label-cos "i" opthelp-label-cos #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-total-cos "j" opthelp-total-cos #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-calc-gm "k" opthelp-calc-gm #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-ebitda "l" opthelp-ebitda #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-label-expense "m" opthelp-label-expense #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-total-expense "n" opthelp-total-expense #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-label-other "o" opthelp-label-other #t)) (add-option (gnc:make-simple-boolean-option gnc:pagename-display optname-total-other "p" opthelp-total-other #t)) ;;(add-option ;; (gnc:make-simple-boolean-option ;; gnc:pagename-display optname-two-column ;; "q" opthelp-two-column #f)) ;;(add-option ;; (gnc:make-simple-boolean-option ;; gnc:pagename-display optname-standard-order ;; "r" opthelp-standard-order #t)) ;; closing entry match criteria ;; ;; N.B.: transactions really should have a field where we can put ;; transaction types like "Adjusting/Closing/Correcting Entries" (add-option (gnc:make-string-option pagename-entries optname-closing-pattern "a" opthelp-closing-pattern (N_ "Closing Entries"))) (add-option (gnc:make-simple-boolean-option pagename-entries optname-closing-casing "b" opthelp-closing-casing #f)) (add-option (gnc:make-simple-boolean-option pagename-entries optname-closing-regexp "c" opthelp-closing-regexp #f)) ;; Set the accounts page as default option tab (gnc:options-set-default-section options gnc:pagename-accounts) options)) ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; income-statement-renderer ;; set up the document and add the table ;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (income-statement-renderer report-obj) (define (get-option pagename optname) (gnc:option-value (gnc:lookup-option (gnc:report-options report-obj) pagename optname))) (gnc:report-starting reportname) ;; get all option's values (let* ( (report-title (get-option gnc:pagename-general optname-report-title)) (company-name (get-option gnc:pagename-general optname-party-name)) (start-date-printable (gnc:date-option-absolute-time (get-option gnc:pagename-general optname-start-date))) (start-date-tp (gnc:timepair-start-day-time (gnc:date-option-absolute-time (get-option gnc:pagename-general optname-start-date)))) (end-date-tp (gnc:timepair-end-day-time (gnc:date-option-absolute-time (get-option gnc:pagename-general optname-end-date)))) (revenue-accounts (get-option gnc:pagename-accounts optname-income-accounts)) (cos-accounts (get-option gnc:pagename-accounts optname-cos-accounts)) (expense-accounts (get-option gnc:pagename-accounts optname-expense-accounts)) (other-accounts (get-option gnc:pagename-accounts optname-other-accounts)) (depth-limit (get-option gnc:pagename-accounts optname-depth-limit)) (bottom-behavior (get-option gnc:pagename-accounts optname-bottom-behavior)) (report-commodity (get-option pagename-commodities optname-report-commodity)) (price-source (get-option pagename-commodities optname-price-source)) (show-fcur? (get-option pagename-commodities optname-show-foreign)) (show-rates? (get-option pagename-commodities optname-show-rates)) (parent-balance-mode (get-option gnc:pagename-display optname-parent-balance-mode)) (parent-total-mode (car (assoc-ref '((t #t) (f #f) (canonically-tabbed canonically-tabbed)) (get-option gnc:pagename-display optname-parent-total-mode)))) (show-zb-accts? (get-option gnc:pagename-display optname-show-zb-accts)) (omit-zb-bals? (get-option gnc:pagename-display optname-omit-zb-bals)) (label-revenue? (get-option gnc:pagename-display optname-label-revenue)) (total-revenue? (get-option gnc:pagename-display optname-total-revenue)) (label-cos? (get-option gnc:pagename-display optname-label-cos)) (total-cos? (get-option gnc:pagename-display optname-total-cos)) (calc-gm? (get-option gnc:pagename-display optname-calc-gm)) (show-ebitda? (get-option gnc:pagename-display optname-ebitda)) (label-expense? (get-option gnc:pagename-display optname-label-expense)) (total-expense? (get-option gnc:pagename-display optname-total-expense)) (label-other? (get-option gnc:pagename-display optname-label-other)) (total-other? (get-option gnc:pagename-display optname-total-other)) (use-links? (get-option gnc:pagename-display optname-account-links)) (use-rules? (get-option gnc:pagename-display optname-use-rules)) (closing-str (get-option pagename-entries optname-closing-pattern)) (closing-cased (get-option pagename-entries optname-closing-casing)) (closing-regexp (get-option pagename-entries optname-closing-regexp)) ;(two-column? (get-option gnc:pagename-display ; optname-two-column)) ;(standard-order? (get-option gnc:pagename-display ; optname-standard-order)) (closing-pattern (list (list 'str closing-str) (list 'cased closing-cased) (list 'regexp closing-regexp) ) ) (indent 0) (tabbing #f) (doc (gnc:make-html-document)) ;; this can occasionally put extra (blank) columns in our ;; table (when there is one account at the maximum depth and ;; it has at least one of its ancestors deselected), but this ;; is the only simple way to ensure that both tables ;; (revenue, expense) have the same width. (tree-depth (if (equal? depth-limit 'all) (gnc:get-current-account-tree-depth) depth-limit)) ;; exchange rates calculation parameters (exchange-fn (gnc:case-exchange-fn price-source report-commodity end-date-tp)) ) ;; Wrapper to call gnc:html-table-add-labeled-amount-line! ;; with the proper arguments. (define (add-subtotal-line table pos-label neg-label signed-balance) (define allow-same-column-totals #t) (let* ((neg? (and signed-balance neg-label (gnc-numeric-negative-p (gnc:gnc-monetary-amount (gnc:sum-collector-commodity signed-balance report-commodity exchange-fn))))) (label (if neg? (or neg-label pos-label) pos-label)) (balance (if neg? (let ((bal (gnc:make-commodity-collector))) (bal 'minusmerge signed-balance #f) bal) signed-balance)) ) (gnc:html-table-add-labeled-amount-line! table (+ indent (* tree-depth 2) (if (equal? tabbing 'canonically-tabbed) 1 0)) "primary-subheading" (and (not allow-same-column-totals) balance use-rules?) label indent 1 "total-label-cell" (gnc:sum-collector-commodity balance report-commodity exchange-fn) (+ indent (* tree-depth 2) (- 0 1) (if (equal? tabbing 'canonically-tabbed) 1 0)) 1 "total-number-cell") ) ) ;; wrapper around gnc:html-table-append-ruler! (define (add-rule table) (gnc:html-table-append-ruler! table (+ (* 2 tree-depth) (if (equal? tabbing 'canonically-tabbed) 1 0)))) ;; wrapper around gnc:html-table-append-ruler! (define (add-row table) (gnc:html-table-append-row! table " ")) ; (gnc:html-document-set-title! ; doc (sprintf #f ; (string-append "%s %s " ; (_ "For Period Covering %s to %s")) ; company-name report-title ; (gnc-print-date start-date-printable) ; (gnc-print-date end-date-tp))) (gnc:html-document-add-object! doc (gnc:make-html-text (gnc:html-markup-h3 company-name) (gnc:html-markup-h3 report-title) (gnc:html-markup-p (sprintf #f "For Period Covering %s to %s" (gnc-print-date start-date-printable) (gnc-print-date end-date-tp))))) ;; fix-me: only tests expense accounts (if (null? expense-accounts) ;; error condition: no accounts specified ;; is this *really* necessary?? ;; i'd be fine with an all-zero P&L ;; that would, technically, be correct.... (gnc:html-document-add-object! doc (gnc:html-make-no-account-warning reportname (gnc:report-id report-obj))) ;; Get all the balances for each of the account types. (let* ((revenue-closing #f) (cos-closing #f) (expense-closing #f) (other-closing #f) (neg-revenue-total #f) (revenue-total #f) (cos-total #f) (expense-total #f) (other-total #f) (net-income #f) (gross-margin #f) (EBITDA #f) ;; Create the account tables below where their ;; percentage time can be tracked. ;; Try making a single table (my-table (gnc:make-html-table)) ;; gnc:html-table (table-env #f) ;; parameters for :make- (params #f) ;; and -add-account- (revenue-table #f) ;; gnc:html-acct-table (expense-table #f) ;; used to hold the accounts (costofsales-table #f) ;; in that part of the (other-table #f) ;; larger my-table (terse-period? #t) (period-for (if terse-period? (string-append " " (_ "for Period")) (sprintf #f (string-append ", " (_ "%s to %s")) (gnc-print-date start-date-printable) (gnc-print-date end-date-tp)) ) ) ) ;; a helper to add a line to our report (define (report-line table pos-label neg-label amount col exchange-fn rule? row-style) (let* ((neg? (and amount neg-label (gnc-numeric-negative-p (gnc:gnc-monetary-amount (gnc:sum-collector-commodity amount report-commodity exchange-fn))))) (label (if neg? (or neg-label pos-label) pos-label)) (pos-bal (if neg? (let ((bal (gnc:make-commodity-collector))) (bal 'minusmerge amount #f) bal) amount)) (bal (gnc:sum-collector-commodity pos-bal report-commodity exchange-fn)) (balance (or (and (gnc:uniform-commodity? pos-bal report-commodity) bal) (and show-fcur? (gnc-commodity-table pos-bal report-commodity exchange-fn)) bal )) (column (or col 0)) ) (gnc:html-table-add-labeled-amount-line! table (* 2 tree-depth) row-style rule? label 0 1 "text-cell" bal (+ col 1) 1 "number-cell") ) ) ;; sum revenues and expenses (set! revenue-closing (gnc:account-get-trans-type-balance-interval revenue-accounts closing-pattern start-date-tp end-date-tp) ) ;; this is norm positive (debit) (set! cos-closing (gnc:account-get-trans-type-balance-interval cos-accounts closing-pattern start-date-tp end-date-tp) ) ;; this is norm negative (credit) (set! cos-total (gnc:accountlist-get-comm-balance-interval cos-accounts start-date-tp end-date-tp)) (cos-total 'minusmerge cos-closing #f) (set! expense-closing (gnc:account-get-trans-type-balance-interval expense-accounts closing-pattern start-date-tp end-date-tp) ) ;; this is norm negative (credit) (set! expense-total (gnc:accountlist-get-comm-balance-interval expense-accounts start-date-tp end-date-tp)) (expense-total 'minusmerge expense-closing #f) (set! other-closing (gnc:account-get-trans-type-balance-interval other-accounts closing-pattern start-date-tp end-date-tp) ) ;; this is norm negative (credit) (set! other-total (gnc:accountlist-get-comm-balance-interval other-accounts start-date-tp end-date-tp)) (other-total 'minusmerge other-closing #f) (set! neg-revenue-total (gnc:accountlist-get-comm-balance-interval revenue-accounts start-date-tp end-date-tp)) (neg-revenue-total 'minusmerge revenue-closing #f) (set! revenue-total (gnc:make-commodity-collector)) (revenue-total 'minusmerge neg-revenue-total #f) (set! gross-margin (gnc:make-commodity-collector)) (gross-margin 'merge revenue-total #f) (gross-margin 'minusmerge cos-total #f) (set! EBITDA (gnc:make-commodity-collector)) (EBITDA 'merge gross-margin #f) (EBITDA 'minusmerge expense-total #f) ;; calculate net income (set! net-income (gnc:make-commodity-collector)) (net-income 'merge revenue-total #f) (net-income 'minusmerge cos-total #f) (net-income 'minusmerge expense-total #f) (net-income 'minusmerge other-total #f) (set! table-env (list (list 'start-date start-date-tp) (list 'end-date end-date-tp) (list 'display-tree-depth tree-depth) (list 'depth-limit-behavior (if bottom-behavior 'flatten 'summarize)) (list 'report-commodity report-commodity) (list 'exchange-fn exchange-fn) (list 'parent-account-subtotal-mode parent-total-mode) (list 'zero-balance-mode (if show-zb-accts? 'show-leaf-acct 'omit-leaf-acct)) (list 'account-label-mode (if use-links? 'anchor 'name)) ;; we may, at some point, want to add an option to ;; generate a pre-adjustment income statement... (list 'balance-mode 'pre-closing) (list 'closing-pattern closing-pattern) ) ) (set! params (list (list 'parent-account-balance-mode parent-balance-mode) (list 'zero-balance-display-mode (if omit-zb-bals? 'omit-balance 'show-balance)) (list 'multicommodity-mode (if show-fcur? 'table #f)) (list 'rule-mode use-rules?) ) ) (gnc:report-percent-done 80) (if label-revenue? (add-subtotal-line my-table (_ "Revenues") #f #f)) (set! revenue-table (gnc:make-html-acct-table/env/accts table-env revenue-accounts)) (gnc:html-table-add-account-balances my-table revenue-table params) (if total-revenue? (add-subtotal-line my-table (_ "Total Revenue") #f revenue-total)) (add-row my-table) (if label-cos? (add-subtotal-line my-table (_ "Cost of Sales") #f #f)) (set! costofsales-table (gnc:make-html-acct-table/env/accts table-env cos-accounts)) (gnc:html-table-add-account-balances my-table costofsales-table params) (if total-cos? (add-subtotal-line my-table (_ "Total Cost of Sales") #f cos-total)) (add-row my-table) (if calc-gm? (add-subtotal-line my-table (_ "Gross Margin") #f gross-margin)) (add-row my-table) (gnc:report-percent-done 85) (if label-expense? (add-subtotal-line my-table (_ "Operating Expenses") #f #f)) (set! expense-table (gnc:make-html-acct-table/env/accts table-env expense-accounts)) (gnc:html-table-add-account-balances my-table expense-table params) (if total-expense? (add-subtotal-line my-table (_ "Total Operating Expenses") #f expense-total)) (add-row my-table) (if show-ebitda? (add-subtotal-line my-table (_ "Operating Profit (EBITDA)") #f EBITDA)) (add-row my-table) (if label-other? (add-subtotal-line my-table (_ "Other Expenses") #f #f)) (set! other-table (gnc:make-html-acct-table/env/accts table-env other-accounts)) (gnc:html-table-add-account-balances my-table other-table params) (if total-other? (add-subtotal-line my-table (_ "Total Other Expenses") #f other-total)) (add-row my-table) ;; Add the net income / net loss line. (add-subtotal-line my-table (if (gnc-numeric-negative-p (gnc:gnc-monetary-amount (gnc:sum-collector-commodity net-income report-commodity exchange-fn))) (string-append (_ "Net loss") period-for) (string-append (_ "Net income") period-for) ) #f net-income) ;; Make this a single column report (gnc:html-document-add-object! doc (let* ((build-table (gnc:make-html-table))) (gnc:html-table-append-row! build-table (list(gnc:make-html-table-cell my-table))) (gnc:html-table-set-style! build-table "td" 'attribute '("align" "left") 'attribute '("valign" "top")) build-table ) ) ;; add currency information if requested ;; FIXME: - only uses the expense-accounts (gnc:report-percent-done 90) (if show-rates? (gnc:html-document-add-object! doc ;;(gnc:html-markup-p) (gnc:html-make-exchangerates report-commodity exchange-fn expense-accounts))) (gnc:report-percent-done 100) ) ) (gnc:report-finished) doc ) ) (gnc:define-report 'version 1 'name reportname 'menu-path (list gnc:menuname-income-expense) 'options-generator income-statement-options-generator 'renderer income-statement-renderer ) ;; END