This commit is contained in:
Christopher Lam 2025-02-14 11:31:41 +13:00 committed by GitHub
commit de7ce86d97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 284 additions and 0 deletions

View File

@ -394,6 +394,12 @@ endif()
# Determine where to install our guile modules libraries.
find_guile_dirs()
pkg_check_modules (QRENCODE IMPORTED_TARGET libqrencode>=3.4.4)
if (QRENCODE_FOUND)
set (HAVE_QRENCODE TRUE)
endif ()
# ############################################################
if (WITH_AQBANKING)
pkg_check_modules (GWENHYWFAR REQUIRED gwenhywfar>=5.6.0)

View File

@ -365,6 +365,8 @@
(export gnc:*company-url*)
(export gnc:*company-email*)
(export gnc:*company-contact*)
(export gnc:*company-iban*)
(export gnc:*company-bic*)
(export gnc:*fancy-date-label*)
(export gnc:*fancy-date-format*)
(export gnc:*tax-label*)
@ -394,6 +396,8 @@
(define gnc:*company-url* (N_ "Company Website URL"))
(define gnc:*company-email* (N_ "Company Email Address"))
(define gnc:*company-contact* (N_ "Company Contact Person"))
(define gnc:*company-iban* (N_ "Company IBAN"))
(define gnc:*company-bic* (N_ "Company BIC"))
(define gnc:*fancy-date-label* (N_ "Fancy Date Format"))
(define gnc:*fancy-date-format* (N_ "custom"))
(define gnc:*tax-label* (N_ "Tax"))

View File

@ -17,9 +17,21 @@ set (report_SOURCES
gnc-report.cpp
)
set (qrencode_HEADERS gnc-qrencode.h)
if (HAVE_QRENCODE)
set (qrencode_SOURCES gnc-qrencode.c)
set (qrencode_LIBRARY PkgConfig::QRENCODE)
else ()
set (qrencode_SOURCES gnc-qrencode-stub.c)
set (qrencode_LIBRARY)
endif ()
add_library (gnc-report
${report_SOURCES}
${report_HEADERS}
${qrencode_SOURCES}
${qrencode_HEADERS}
${SWIG_REPORT_C}
)
@ -32,6 +44,7 @@ target_link_libraries(gnc-report
gnucash-guile
gnc-expressions-guile
PkgConfig::GTK3
${qrencode_LIBRARY}
${GUILE_LDFLAGS})
target_include_directories (gnc-report
@ -58,6 +71,7 @@ install(FILES ${report_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gnucash)
set (report_SCHEME_1
commodity-utilities.scm
gnc-qrencode.scm
html-acct-table.scm
html-chart.scm
html-document.scm
@ -126,6 +140,7 @@ add_custom_target(scm-report ALL DEPENDS scm-report-2 scm-report-eguile)
set_local_dist(report_DIST_local CMakeLists.txt
report.i
${report_HEADERS} ${report_SOURCES}
gnc-qrencode.c gnc-qrencode-stub.c ${qrencode_HEADERS}
${report_SCHEME} ${report_SCHEME_1} ${report_SCHEME_2}
${report_eguile_parts_SCHEME} ${report_eguile_SCHEME})

View File

@ -0,0 +1,33 @@
/********************************************************************\
* gnc-qrencode-stub.c -- stub if libqrencode is not available *
* Copyright (C) 2021 Christopher Lam *
* *
* 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 *
\********************************************************************/
#include "gnc-qrencode.h"
SCM gnc_qrcode_encodestring (const char *str)
{
return SCM_EOL;
}
SCM gnc_qrcode_available ()
{
return SCM_BOOL_F;
}

View File

@ -0,0 +1,60 @@
/********************************************************************\
* gnc-qrencode.c -- link to libqrencode *
* Copyright (C) 2021 Christopher Lam *
* *
* 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 *
\********************************************************************/
#include <config.h>
#include <qrencode.h>
#include <stdio.h>
#include "gnc-qrencode.h"
#include "gnc-engine.h"
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = "gnc.qrencode";
SCM gnc_qrcode_encodestring (const char *str)
{
QRcode *qr = QRcode_encodeString (str, 0, QR_ECLEVEL_M, QR_MODE_8, FALSE);
SCM output = SCM_EOL;
if (!qr)
{
PERR ("QRcode_encodeString failed: %s", strerror (errno));
return output;
}
for (unsigned int i = (qr->width * qr->width); i != 0; )
{
i--;
output = scm_cons ((qr->data[i] & 1) ? SCM_BOOL_T : SCM_BOOL_F, output);
}
output = scm_cons (scm_from_uint (qr->width), output);
output = scm_cons (scm_from_uint (qr->version), output);
QRcode_free (qr);
return output;
}
SCM gnc_qrcode_available ()
{
return SCM_BOOL_T;
}

View File

@ -0,0 +1,40 @@
/********************************************************************\
* gnc-qrencode.h -- link to libqrencode or stub *
* Copyright (C) Christopher Lam *
* *
* 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 *
\********************************************************************/
#ifndef GNC_QRENCODE_H
#define GNC_QRENCODE_H
#include <libguile.h>
#include <glib.h>
#ifdef __cplusplus
extern "C" {
#endif
SCM gnc_qrcode_encodestring (const char *str);
SCM gnc_qrcode_available (void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,89 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; gnc-qrencode.scm : link with gnc-qrencode.c
;; Copyright 2021 Christopher Lam
;;
;; 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 gnc-qrencode))
(eval-when (compile load eval expand)
(load-extension "libgnc-report" "scm_init_sw_report_module"))
(use-modules (ice-9 match))
(use-modules (sxml simple))
(use-modules (gnucash core-utils))
(use-modules (gnucash utilities))
(use-modules (gnucash engine))
(use-modules (gnucash app-utils))
(use-modules (gnucash options))
(use-modules (sw_report))
(export gnc:make-epc-qrcode)
(define (data->svg data width size source)
(define (make-rect row col)
(format #f "M~a,~ah~av~ah~aZ " (* row size) (* col size) size size (- size)))
(let lp ((col 0) (row 0) (data data) (accum '()))
(match data
(()
(call-with-output-string
(lambda (port)
(sxml->xml
`(svg (@ (xmlns "http://www.w3.org/2000/svg")
(width ,(* width size))
(height ,(* row size)))
(title ,source) (desc "QR code")
(path (@ (d ,(string-concatenate accum)))))
port))))
((datum . rest)
(let ((newcol (modulo (1+ col) width)))
(lp newcol (if (zero? newcol) (1+ row) row) rest
(if datum (cons (make-rect row col) accum) accum)))))))
(define (string-max str maxlen)
(cond
((<= (string-length str) maxlen) str)
(else (gnc:warn "QR: truncated " str " at " maxlen " characters")
(string-take str maxlen))))
(define (gnc:make-epc-qrcode invoice)
(define (quit msg) (gnc:warn "QR Error:" msg) (list "qr-code-error" msg))
(let* ((book (gncInvoiceGetBook invoice))
(currency (gncInvoiceGetCurrency invoice))
(amount (abs (gncInvoiceGetTotal invoice)))
(ref (gncInvoiceGetID invoice))
(bic (or (gnc:company-info book gnc:*company-bic*) ""))
(name (or (gnc:company-info book gnc:*company-name*) ""))
(iban (or (gnc:company-info book gnc:*company-iban*) ""))
(print-info (gnc-commodity-print-info currency #f))
(amount-str (string-append
(gnc-commodity-get-mnemonic currency)
(xaccPrintAmount amount print-info))))
(cond
((not (gnc-qrcode-available)) (quit "Error: qrencode not available"))
((not (<= 4 (string-length iban) 34)) (quit "IBAN invalid"))
((not (<= (string-length bic) 11)) (quit "BIC cannot exceed 11 characters"))
((not (<= 1/100 amount 99999999999/100)) (quit "Amount out of bounds"))
(else (let ((QRC (string-join
(list "BCD" "001" "1" "SCT" bic (string-max name 70)
iban amount-str "" (string-max ref 140) "") "\n")))
(match (gnc-qrcode-encodestring QRC)
((version width . data)
(list "qr-code" (data->svg data width 3 QRC)))
(_ (quit "libqrencode error"))))))))

View File

@ -188,5 +188,7 @@
"td.centered-label-cell { text-align: center; " centered-label-cell-info " }\n"
"sub { top: 0.4em; }\n"
"sub, sup { vertical-align: baseline; position: relative; top: -0.4em; }\n"
".qr-code-error { color: white; background-color: red }\n"
"@media print { .qr-code-error { display:none; }}\n"
"@media print { html, body { height: unset; }}\n"
(or (gnc:html-document-style-text doc) "")))))

View File

@ -23,6 +23,7 @@
/* Includes the header in the wrapper code */
#include <config.h>
#include <gnc-report.h>
#include <gnc-qrencode.h>
%}
#if defined(SWIGGUILE)
%{
@ -42,3 +43,6 @@ gchar* gnc_get_default_report_font_family();
void gnc_saved_reports_backup (void);
gboolean gnc_saved_reports_write_to_file (const gchar* report_def, gboolean overwrite);
SCM gnc_qrcode_encodestring (gchar *str);
SCM gnc_qrcode_available (void);

View File

@ -36,6 +36,7 @@
(load-and-reexport (gnucash html)
(gnucash report html-style-sheet)
(gnucash report gnc-qrencode)
(gnucash report report-register-hooks)
(gnucash report html-utilities)
(gnucash report commodity-utilities)

View File

@ -515,6 +515,18 @@ for styling the invoice. Please see the exported report for the CSS class names.
"u" (N_ "Extra notes to put on the invoice.")
(G_ "Thank you for your patronage!"))
(gnc-register-multichoice-callback-option
options
(N_ "Display") (N_ "QR Code")
"te" "QR Code"
"none"
(list
(vector 'none (N_ "None") (N_ "None"))
(vector 'epc (N_ "EPC QR Code") (N_ "EPC QR Code")))
(lambda _
(gnc-optiondb-set-option-selectable-by-name
options "Display" "QR Code" (gnc-qrcode-available))))
(gnc-register-multichoice-option options
(N_ "Layout") (N_ "Row 1 Left")
"1a" "1st row, left"
@ -781,6 +793,7 @@ for styling the invoice. Please see the exported report for the CSS class names.
(else
(G_ "Invoice"))))
(title (if (string-null? custom-title) default-title custom-title))
(opt-qrcode (opt-val "Display" "QR Code"))
;; Translators: This is the format of the invoice
;; title. The first ~a is one of "Invoice", "Credit
;; Note", and so on and the second the number. Replace
@ -856,6 +869,17 @@ for styling the invoice. Please see the exported report for the CSS class names.
(multiline-to-html-text
(string-append contact-str ": " contact)))))))
(cond
((eq? opt-qrcode 'none) #f)
((not (gnc-qrcode-available))
(gnc:warn "invoice QR: libqrencode not available"))
((eq? opt-qrcode 'epc)
(gnc:html-table-append-row!
main-table
(gnc:make-html-table-cell/size
1 2 (apply gnc:make-html-div/markup (gnc:make-epc-qrcode invoice)))))
(else (gnc:warn "QR option invalid")))
(gnc:html-table-append-row! main-table
(gnc:make-html-table-cell/size
1 2 (gnc:make-html-div/markup

View File

@ -1335,6 +1335,12 @@ gnc_option_db_book_options(GncOptionDB* odb)
OPTION_NAME_DEFAULT_INVOICE_REPORT_TIMEOUT, "e2",
N_("Length of time to change the used invoice report. A value of 0 means disabled."),
0.0, 0.0, 20.0, 1.0);
gnc_register_string_option (odb, business_section, N_("Company IBAN"), "c7",
N_ ("The International Bank Account Number for receiving payments."),
empty_string);
gnc_register_string_option (odb, business_section, N_("Company BIC"), "c8",
N_ ("The Business Identifier Codes (or SWIFT) for your bank."),
empty_string);
gnc_register_taxtable_option(odb, business_section,
N_("Default Customer TaxTable"), "f1",
N_("The default tax table to apply to customers."),