Manual do Utilizador GnuCash
<<< Previous |  | Next >>>

# Desenvolvimento de Relatórios

Os relatórios do `GnuCash` são gerados de uma forma que é bastante retrospectiva dos CGI da web; envolve:

- Escrever programas que gerem "janelas de opções".

  Ao contrário da aproximação CGI, as opções do `GnuCash` acabam por gerar directamente widgets GNOME, e não utilizam etiquetas de FORMs HTML. As semelhanças são, no entanto, bastante grandes já que ambos os sistemas de opções involvem:

  - Construir uma lista de propriedades que descreve opções e valores de defeito;

  - Submeter essa lista de propriedades para que o utilizador faça modificações;

  - Retornar outra lista de propriedades contendo as modificações do utilzador.

- Escrever programas que obtenham dados da aplicação, baseados na lista de propriedades das opções, e depois gerem resultados em HTML.

  Muitas aplicações web produzem HTML de integridade questionável visto o programador gerar HTML na forma atabalhoada de apenas imprimir comandos que possam conter um tipo de dados com "pseudo-etiquetas". Por contraste, `GnuCash` utiliza uma estrutura de registos orientada para o HTML que torna mais difícil construir mau HTML do que o torna escrever HTML correcto.

Esta apresentação irá assumir que o leitor já está de uma forma genérica familiarizado com o Scheme, particularmente com os seguintes conceitos:

- Ligar valores e funções utilizando `define`

  Como em:

      (define *value-x* 25)
      (define *value-y* 30)
      (define *string-a* "Aqui está uma string!")
      (define *string-b* "Uma string com uma aspa \" embebida")
      (define (add-1 x)
        (+ x 1))

- Definir ligações locais utilizando `let` e `let`

      > (define let-to-hide-stuff
        (lambda (x y z)
          (let ((x 25);; Local binding of x inside the let
          (w 11))
            (display "Dentro do let, x é:") (display x) (newline)
            (display "E w apenas existe dentro do let como ") (display w)
            (newline)
            (display "Adicionar x, y, z, w dentro do let:")
            (display (+ x y z w)) (newline))
          (display "Agora, fora do let:") (newline)
          (display "x é:") (display x) (newline)
          (display "y é:") (display y) (newline)
          (display "z é:") (display z) (newline)
          (display "w é:") (display w) (newline)))
      > (let-to-hide-stuff 10 20 30)
      > (let-to-hide-stuff 10 20 30)
      Dentro do let, x é:25
      E w apenas existe dentro do let como 11
      Adicionar x, y, z, w dentro do let:86
      Agora, fora do let:
      x é:10
      y é:20
      z é:30
      reference to undefined identifier: w
      w é:>

- Definir listas utilizando `list`

  Como em:

      > (list 1 2 3 "four" 'five)
      (1 2 3 "four" five)
      > '(1 2 3 "four" five)
      (1 2 3 "four" five)

- Representar funções anónimas utilizando `lambda`

  A função `add-1` mostrada anteriormente é na verdade definida como:

      (define add-1
        (lambda (x) (+ x 1)))

- A estrutura de controlo `if`

- Utilizar `map` para aplicar uma função a todos os membros de uma lista, produzindo outra lista, como em:

      > (map (lambda (x) (+ x 1)) '(1 2 3 4))
      (2 3 4 5)

  ou

      > (map  (lambda (s n) (string-append s ":" (number->string n)))
           '("one" "two" "three" "four") '(1 2 3 4))
      ("one:1" "two:2" "three:3" "four:4")

Se os significados de alguns destes não são muito claros, veja as referências na secção sobre Documentação Scheme, e tente executar código como o acima utilizando Guile.

## Visão Geral de Relatórios

Um relatório do GnuCash é adicionado ao sistena utilizando a função `gnc:define-report`, para a qual são passados os seguintes parâmetros:

- `versão`

  Este é um número de versão; actualmente não é utilizado para fazer nada particularmente inteligente.

- `nome`

  Este é um nome não-traduzido para o relatório que é notavelmente utilizado para disponibilizar o nome que será adicionado ao menu de relatórios do `GnuCash`.

- `gerador de opções`

  Este argumento é uma função que não leva parâmetros, e gera um conjunto de opções que serão utilizadas para apresentar uma janela que o utilizador pode utilizar para seleccionar valores para os parâmetros do relatório.

  Isto tipicamente irá incluir coisas como intrevalos de datas e listas de contas, para determinar que dados deverão ser seleccionados para o relatório, bem como outros controlos que determinam como os dados irão ser visualizados.

- `visualizador`

  O "visualizador" faz o trabalho de gerar o relatório. Aceita uma "base de dados" de opções, tal como a gerada pelo `gerador de opções` , obtem os dados correspondentes do motor do `GnuCash`, e gera, como resultado, um objecto do tipo `documento html` , que é o que o motor de relatórios do `GnuCash` sabe como apresentar.

Um exemplo trivial poderá assemelhar-se ao seguinte:

    (let ()
      (define (options-generator)
         (let ((options (gnc:new-options)))  ;;; Criar nova lista de opções
              options))       ;;; Devolve-la
      (define (renderer options)
        (let ((document (gnc:make-html-document)))
           document))      ;;; Gera um documento vazio
      (gnc:define-report
       'version 1
       'name (N_ "Trivial Example")
       'options-generator options-generator
       'renderer renderer))

Note que os relatórios são tipicamente definidos dentro de um ambiente `let` ; as "funções de trabalho" serão assim todas invisíveis para o código fora do ambiente `let` , o que significa que não precisará de se preocupar em criar nomes de funções únicos. Apenas o nome do relatório tem forçosamente de ser único.

Desde que cada relatório esteja do mesmo modo envolto num ambiente `let` , você poderia chamar a todas as funções de "renderização" `rederizar` sem causar quaisquer conflitos.

## A função de gerador de opções

O gerador de opções introduz um número adicional de funções que são utilizadas para definir janelas de opções.

    (define (options-generator)
      (let ((option-set (gnc:new-options)))  (1)
     (gnc:options-add-report-date!  (2)
      option-set pagename-general "End Date" "a")
     (gnc:options-add-date-interval!  (3)
      option-set pagename-general "From" "To" "a")
     (gnc:options-add-interval-choice!  (4)
      option-set pagename-general
      "Step Size" "b" 'YearDelta)
     (gnc:options-add-account-levels! (5)
      option-set pagename-general
      "Show Accounts down to Level" "c" 2)
     (gnc:options-add-account-selection! (6)
      option-set pagename-general "Account Display Depth"
      "Always show subaccounts" "Accounts" "a" 3
      *LIST-OF-INCOME-AND-EXPENSE-ACCOUNTS*
     options))

(1)
  `gnc:new-options` cria um conjunto novo de opções, vazio. Isto tem de ser executado primeiro; as funções seguintes necessitam de ter um conjunto de opções a que se referir.
(2)
  `gnc:options-add-report-date!` adiciona uma opção de selecção que indica uma data única, geralmente utilizada como a data de final.
(3)
  `gnc:options-add-date-interval!` adiciona uma opção de selecção que permite especificar um intrevalo de datas.
(4)
  `gnc:options-add-interval-choice!` adiciona uma opção de selecção que permite escolher entre vários intrevalos de tempo, incluindo dias, semanas, quinzenas, meses, e anos.
(5)
  `gnc:options-add-account-levels!` adiciona uma opção que indica até que profundidade um conjunto de níveis de contas deverá ser mostrado.
(6)
  `gnc:options-add-account-selection!` permite seleccionar um conjunto de contas.

  Note que o último argumento é uma lista de contas de onde seleccionar, o que significa ser necessário, a um determinado ponto, filtrar uma lista de contas relevantes.

Existem ainda funções de opções adicionais:

- `gnc:options-add-currency!` para seleccionar uma moeda;

- `gnc:options-add-plot-size!` para controlar como um gráfico deverá ser dimensionado.

Subjacentes a estas existem as seguintes funções base do "gerador de opções" definidas em `options-utilities.scm`, que podem ser utilizadas para criar novos tipos de opções:

- `gnc:register-option`

- `gnc:make-date-option`

- `gnc:make-multichoice-option`

- `gnc:make-simple-boolean-option`

- `gnc:make-account-list-option`

- `gnc:make-currency-option`

- `gnc:make-number-range-option`

## Aceder aos Dados do GnuCash

Existem vários formatos de dados que poderá querer aceder:

- Informação de Contas

- Preços de Acções

- Dados de Leitura de Opções

### Aceder aos Dados do Motor

As funções utilizadas para aceder às várias formas de dados contabilísticos podem ser encontradas no ficheiro `src/g-wrap/gnc.html`.

| São necessários alguns exemplos aqui...

### Aceder a Dados de Opções

Functions `gnc:lookup-option`, `gnc:report-options`, e `gnc:option-value` são as funções cruciais que mais provavelmente utilizará em `src/scm/options.scm`

Um excerto do `src/scm/report/hello-world.scm` é o seguinte:

    ;; Primeiro, construir algumas funções de apoio para procurar valores de opções.
    (define (get-op section name)
      (gnc:lookup-option (gnc:report-options report-obj) section name))

    (define (op-value section name)
      (gnc:option-value (get-op section name)))

    ;; O próximo passo é criar variáveis locais para todas as opções
    ;; específicas no conjunto de opções passado à função.
    (let
        ((bool-val     (op-value "Hello, World!" "Boolean Option"))
         (mult-val     (op-value "Hello, World!" "Multi Choice Option"))
         (string-val   (op-value "Hello, World!" "String Option"))
         (date-val     (gnc:date-option-absolute-time
            (op-value "Hello, World!" "Just a Date Option")))
         (date2-val    (gnc:date-option-absolute-time
            (op-value "Hello, World!" "Time and Date Option")))
         (rel-date-val (gnc:date-option-absolute-time
            (op-value "Hello, World!" "Relative Date Option")))
         (combo-date-val (gnc:date-option-absolute-time
              (op-value "Hello, World!" "Combo Date Option")))
         (num-val      (op-value "Hello, World!" "Number Option"))
         (bg-color-op  (get-op   "Hello, World!" "Background Color"))
         (txt-color-op (get-op   "Hello, World!" "Text Color"))
         (accounts     (op-value "Hello Again"   "An account list option"))
         (list-val     (op-value "Hello Again"   "A list option"))
         (crash-val    (op-value "Testing"       "Crash the report")))
      (now-do-stuff-with-options))

### Preços de Acções

| A base de dados de preços de acções está em desenvolvimento, pelo que é um pouco sedo para ser específico sobre isto...

## Funções de Geração HTML

Os relatórios são gerados como uma árvore de registos Guile, tendo como raíz um registo <documento html>, que consiste em informação de estilos, um título, e uma lista de registos <objecto html> que consistem numa função de renderização e noutra lista de objectos.

Poderemos assim gerar um relatório simples:

    (define (build-simple-document)
      (let* ((document (gnc:make-html-document))
       ;;; Aqui está um par de funções auxiliares
       (addfpara (lambda (obj)
            (gnc:html-document-add-object!
             document
             (gnc:make-html-text
              (gnc:html-markup-p obj)))))
       (addpara (lambda (text)
            (addfpara
             (gnc:html-markup/format text)))))
           ;;; Definir o título
        (gnc:html-document-set-title! document (_ "Simple List of Values"))
        ;;; Adicionar um parágrafo de texto
        (addpara
         (_ "This is a simple report, starting with a paragraph of text"))
        (addpara
         (_ "Next, we calculate random values, adding them to a balance."))
        (let loop
      ((balance 0))
          (if (< balance 500)
        (let ((newamt (- (random 500 200))))  ;;; Random number
          (addfpara
             (gnc:html-markup/format
        (_ "Another random adjustment of %s yields %s")
        (gnc:html-markup-tt (number->string newamt))
        (gnc:html-markup-b (number->string balance))))
            (loop (+ balance newamt)))))
        document))  ;;; Finalmente, devolver o documento

## A função de renderização

A função de renderização é onde as funções das secções anteriores se juntam.

- Recebe, como entrada, uma "base de dados" de opções geradas assim que o utilizador adiciona os seus dados à janela produzida pelo generador de opções .

- Utiliza essas opções para controlar como aceder aos dados do GnuCash

- Finalmente, a partir desses dados, gera uma "base de dados" de texto HTML.

A fnção de renderização disponibiliza, como valor de retorno, a "base de dados de HTML," que o `GnuCash` apresenta no visualizador de HTML.

    (define (renderer options)
      (let ((document (gnc:make-html-document)))
     document))      ;;; Gera um documento vazio

## Para Mais Informações

Se necessitar de mais informações, ou tiver desenvolvido um relatório novo que possa ser útil para outros, por favor contacte a lista de desenvolvimento do GnuCash em `< gnucash-devel@gnucash.org >`.

<<< Previous | Home | Next >>>
Relatório de Cotações de Acções |  | Que Novidades Há?