mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
A plugin to import CSV data as a new invoice or bill. Based on code written by Sebastian Held.
Also includes a python script to massage a downloaded order form into the correct format for import. See contrib/rapid2gnucash.py This works with Rapid Electronics (UK) and can be used as a basis for other vendors. Users need to add a line in their ~/.gnucash/config.user for the module to be loaded: (gnc:module-load "gnucash/plugins/bi_import" 0) See bug #624911 for more details. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@20034 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
e8d8c4be42
commit
c33270221d
37
configure.ac
37
configure.ac
@ -240,7 +240,7 @@ update to latest darwin])
|
|||||||
AC_MSG_CHECKING(For GDK-Quartz)
|
AC_MSG_CHECKING(For GDK-Quartz)
|
||||||
platform=osx
|
platform=osx
|
||||||
_gdk_tgt=`$PKG_CONFIG --variable=target gdk-2.0`
|
_gdk_tgt=`$PKG_CONFIG --variable=target gdk-2.0`
|
||||||
if test "x$_gdk_tgt" = xquartz; then
|
if test "x$_gdk_tgt" = xquartz; then
|
||||||
platform=darwin/quartz
|
platform=darwin/quartz
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(GDK_QUARTZ,,[Using GDK Quartz (not X11)])
|
AC_DEFINE(GDK_QUARTZ,,[Using GDK Quartz (not X11)])
|
||||||
@ -311,8 +311,8 @@ AM_CONDITIONAL(OS_WIN32, test "x$native_win32" = "xyes")
|
|||||||
|
|
||||||
# These are unavailable on windows/mingw32 and X11 isn't desired or
|
# These are unavailable on windows/mingw32 and X11 isn't desired or
|
||||||
# required for MacOSX Quartz
|
# required for MacOSX Quartz
|
||||||
if test "x$_gdk_tgt" = xquartz;
|
if test "x$_gdk_tgt" = xquartz;
|
||||||
then
|
then
|
||||||
AC_CHECK_HEADERS(glob.h)
|
AC_CHECK_HEADERS(glob.h)
|
||||||
else
|
else
|
||||||
AC_CHECK_HEADERS(X11/Xlib.h glob.h)
|
AC_CHECK_HEADERS(X11/Xlib.h glob.h)
|
||||||
@ -321,7 +321,7 @@ AM_CONDITIONAL(HAVE_X11_XLIB_H, test "x$ac_cv_header_X11_Xlib_h" = "xyes")
|
|||||||
AC_CHECK_FUNCS(chown gethostname getppid getuid gettimeofday gmtime_r)
|
AC_CHECK_FUNCS(chown gethostname getppid getuid gettimeofday gmtime_r)
|
||||||
AC_CHECK_FUNCS(gethostid link)
|
AC_CHECK_FUNCS(gethostid link)
|
||||||
##################################################
|
##################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### --------------------------------------------------------------------------
|
### --------------------------------------------------------------------------
|
||||||
@ -663,7 +663,7 @@ case "${want_ofx}" in
|
|||||||
esac
|
esac
|
||||||
if test x${want_ofx} != xno ;
|
if test x${want_ofx} != xno ;
|
||||||
then
|
then
|
||||||
AC_ARG_WITH( ofx-prefix,
|
AC_ARG_WITH( ofx-prefix,
|
||||||
[AS_HELP_STRING([--with-ofx-prefix=DIR],[specify where to look for libOFX])],
|
[AS_HELP_STRING([--with-ofx-prefix=DIR],[specify where to look for libOFX])],
|
||||||
OFXPREFIX="$with_ofx_prefix" )
|
OFXPREFIX="$with_ofx_prefix" )
|
||||||
|
|
||||||
@ -698,7 +698,7 @@ then
|
|||||||
] )
|
] )
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x${want_ofx}" != xno ; then
|
if test "x${want_ofx}" != xno ; then
|
||||||
LIBOFX_LIBS="${LIBOFX_LIBS} -lofx"
|
LIBOFX_LIBS="${LIBOFX_LIBS} -lofx"
|
||||||
AC_MSG_CHECKING(for libofx)
|
AC_MSG_CHECKING(for libofx)
|
||||||
save_LIBS="${LIBS}"
|
save_LIBS="${LIBS}"
|
||||||
@ -896,11 +896,11 @@ AC_DEFUN([BB_ENABLE_DOXYGEN],
|
|||||||
[
|
[
|
||||||
AC_ARG_ENABLE(doxygen, [AS_HELP_STRING([--enable-doxygen],[enable documentation generation with doxygen (auto)])])
|
AC_ARG_ENABLE(doxygen, [AS_HELP_STRING([--enable-doxygen],[enable documentation generation with doxygen (auto)])])
|
||||||
AC_ARG_ENABLE(dot, [AS_HELP_STRING([--enable-dot],[use 'dot' to generate graphs in doxygen (auto)])])
|
AC_ARG_ENABLE(dot, [AS_HELP_STRING([--enable-dot],[use 'dot' to generate graphs in doxygen (auto)])])
|
||||||
AC_ARG_ENABLE(html-docs, [AS_HELP_STRING([--enable-html-docs],[enable HTML generation with doxygen (yes)])], [], [ enable_html_docs=yes])
|
AC_ARG_ENABLE(html-docs, [AS_HELP_STRING([--enable-html-docs],[enable HTML generation with doxygen (yes)])], [], [ enable_html_docs=yes])
|
||||||
AC_ARG_ENABLE(latex-docs, [AS_HELP_STRING([--enable-latex-docs],[enable LaTeX documentation generation with doxygen (no)])], [], [ enable_latex_docs=no])
|
AC_ARG_ENABLE(latex-docs, [AS_HELP_STRING([--enable-latex-docs],[enable LaTeX documentation generation with doxygen (no)])], [], [ enable_latex_docs=no])
|
||||||
if test "x$enable_doxygen" = xno; then
|
if test "x$enable_doxygen" = xno; then
|
||||||
enable_doc=no
|
enable_doc=no
|
||||||
else
|
else
|
||||||
AC_PATH_PROG(DOXYGEN, doxygen, , $PATH)
|
AC_PATH_PROG(DOXYGEN, doxygen, , $PATH)
|
||||||
if test x$DOXYGEN = x; then
|
if test x$DOXYGEN = x; then
|
||||||
if test "x$enable_doxygen" = xyes; then
|
if test "x$enable_doxygen" = xyes; then
|
||||||
@ -942,7 +942,7 @@ LIBS="$LIBS -lm"
|
|||||||
### When disabled, we don't even need to check for them!
|
### When disabled, we don't even need to check for them!
|
||||||
### --------------------------------------------------------------------------
|
### --------------------------------------------------------------------------
|
||||||
|
|
||||||
AC_ARG_ENABLE(gui,
|
AC_ARG_ENABLE(gui,
|
||||||
[AS_HELP_STRING([--disable-gui],[build without the GNOME GUI components of Gnucash])],
|
[AS_HELP_STRING([--disable-gui],[build without the GNOME GUI components of Gnucash])],
|
||||||
[case "${enableval}" in
|
[case "${enableval}" in
|
||||||
yes) gnc_build_gui=true ;;
|
yes) gnc_build_gui=true ;;
|
||||||
@ -955,7 +955,7 @@ AM_CONDITIONAL(GNUCASH_ENABLE_GUI, test x${gnc_build_gui} = xtrue)
|
|||||||
|
|
||||||
### --------------------------------------------------------------------------
|
### --------------------------------------------------------------------------
|
||||||
### GNOME gui components -- built by default, but not if --enable-gui=no
|
### GNOME gui components -- built by default, but not if --enable-gui=no
|
||||||
### or --disable-gui is passed to autogen
|
### or --disable-gui is passed to autogen
|
||||||
### --------------------------------------------------------------------------
|
### --------------------------------------------------------------------------
|
||||||
|
|
||||||
if test x${gnc_build_gui} = xtrue ;
|
if test x${gnc_build_gui} = xtrue ;
|
||||||
@ -1118,7 +1118,7 @@ then
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
### ----------------------------------------------------------------------
|
### ----------------------------------------------------------------------
|
||||||
|
|
||||||
AC_ARG_ENABLE( efence,
|
AC_ARG_ENABLE( efence,
|
||||||
[AS_HELP_STRING([--enable-efence],[link using efence])],
|
[AS_HELP_STRING([--enable-efence],[link using efence])],
|
||||||
if test x$enableval = xyes; then
|
if test x$enableval = xyes; then
|
||||||
@ -1134,7 +1134,7 @@ then
|
|||||||
## For now, we just presume you're using the GNOME version. The other
|
## For now, we just presume you're using the GNOME version. The other
|
||||||
## UI's haven't been carried over during the automake transition. At
|
## UI's haven't been carried over during the automake transition. At
|
||||||
## some point, if it's deemed worthwhile, they can be resurrected...
|
## some point, if it's deemed worthwhile, they can be resurrected...
|
||||||
|
|
||||||
GNOME=1
|
GNOME=1
|
||||||
AC_DEFINE(GNOME,,using GNOME)
|
AC_DEFINE(GNOME,,using GNOME)
|
||||||
|
|
||||||
@ -1293,7 +1293,7 @@ then
|
|||||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-error-on-warning) ;;
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-error-on-warning) ;;
|
||||||
esac],
|
esac],
|
||||||
[ if test "${error_on_warning_as_default}" = "yes"; then
|
[ if test "${error_on_warning_as_default}" = "yes"; then
|
||||||
warnFLAGS="${warnFLAGS} -Werror";
|
warnFLAGS="${warnFLAGS} -Werror";
|
||||||
gnc_error_on_warning=auto
|
gnc_error_on_warning=auto
|
||||||
else
|
else
|
||||||
gnc_error_on_warning=no
|
gnc_error_on_warning=no
|
||||||
@ -1401,10 +1401,10 @@ AC_CONFIG_FILES(
|
|||||||
src/bin/test/Makefile
|
src/bin/test/Makefile
|
||||||
src/core-utils/Makefile
|
src/core-utils/Makefile
|
||||||
src/core-utils/test/Makefile
|
src/core-utils/test/Makefile
|
||||||
src/calculation/Makefile
|
src/calculation/Makefile
|
||||||
src/calculation/test/Makefile
|
src/calculation/test/Makefile
|
||||||
src/debug/Makefile
|
src/debug/Makefile
|
||||||
src/debug/valgrind/Makefile
|
src/debug/valgrind/Makefile
|
||||||
src/doc/Makefile
|
src/doc/Makefile
|
||||||
src/doc/design/Makefile
|
src/doc/design/Makefile
|
||||||
src/doc/xml/Makefile
|
src/doc/xml/Makefile
|
||||||
@ -1495,6 +1495,11 @@ AC_CONFIG_FILES(
|
|||||||
src/business/business-gnome/ui/Makefile
|
src/business/business-gnome/ui/Makefile
|
||||||
src/business/business-ledger/Makefile
|
src/business/business-ledger/Makefile
|
||||||
|
|
||||||
|
dnl # Stuff for bill/invoice import plugin
|
||||||
|
src/plugins/Makefile
|
||||||
|
src/plugins/bi_import/Makefile
|
||||||
|
src/plugins/bi_import/glade/Makefile
|
||||||
|
src/plugins/bi_import/ui/Makefile
|
||||||
dnl # non-makefiles
|
dnl # non-makefiles
|
||||||
dnl # Please read doc/build-system before adding *anything* here
|
dnl # Please read doc/build-system before adding *anything* here
|
||||||
|
|
||||||
|
74
contrib/rapid2gnucash.py
Executable file
74
contrib/rapid2gnucash.py
Executable file
@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
'''
|
||||||
|
# rapid2gnucash.py
|
||||||
|
#
|
||||||
|
# Copyright 2010 Mike Evans <mikee@millstreamcomputing.co.uk>
|
||||||
|
#
|
||||||
|
# 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, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
# MA 02110-1301, USA.
|
||||||
|
|
||||||
|
Convert a CSV file exported from Rapid Electronics (UK) to a form importable by GnuCash
|
||||||
|
Line format is:
|
||||||
|
line number,product code,quantity,availability,product description,unit price,discounts,line total,delivery,sub total,vat,grand total
|
||||||
|
|
||||||
|
Useage: rapid2gnucash.py DOWNLOADED_BASKET.csv "ORDER_NUMBER" <"Expense account"> > output.csv
|
||||||
|
|
||||||
|
We need to remove first line and totals
|
||||||
|
|
||||||
|
Format needs to be:
|
||||||
|
#id,date_opened,vendor_id,billing_id,notes,date,desc,action,account,quantity,price,disc_type,disc_how,discount,taxable,taxincluded,tax_table,date_posted,due_date,account_posted,memo_posted,accu_splits,
|
||||||
|
Not all fields need to have values but the delimiters (,) do.
|
||||||
|
Some fields are compulsory: id, vendor_id, action, quantity, price, taxable
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
import csv
|
||||||
|
|
||||||
|
VENDOR_ID="000013" # Obviously this needs to match your vendor ID
|
||||||
|
try:
|
||||||
|
INFILE=sys.argv[1]
|
||||||
|
except:
|
||||||
|
print "No input files specified."
|
||||||
|
print "Useage: Useage: rapid2gnucash.py DOWNLOADED_BASKET.csv \"ORDER_NUMBER\""
|
||||||
|
quit(1)
|
||||||
|
try:
|
||||||
|
INV_ID=sys.argv[2]
|
||||||
|
except:
|
||||||
|
print "No order number specified."
|
||||||
|
print "Useage: Useage: rapid2gnucash.py DOWNLOADED_BASKET.csv \"ORDER_NUMBER\""
|
||||||
|
quit(1)
|
||||||
|
try:
|
||||||
|
ACCOUNT=sys.argv[3]
|
||||||
|
except:
|
||||||
|
ACCOUNT="Expenses:Materials General" # Default if absent on the command line. Edit to suit your account tree
|
||||||
|
|
||||||
|
Reader = csv.reader(open(INFILE), delimiter=',')
|
||||||
|
|
||||||
|
# Need to ignore 1st and last rows.
|
||||||
|
#Last row contains delivery, subtotal, VAT, total so these should be read too
|
||||||
|
|
||||||
|
for row in Reader:
|
||||||
|
if row[0].isdigit(): # We only use numbered lines
|
||||||
|
outline=(INV_ID + ",," + VENDOR_ID + ",,,," + row[1] + " > " + row[4] + ",ea," +
|
||||||
|
ACCOUNT + "," + row[2] + "," + row[5].replace("GBP", "") + ",,,,no,,,,,,,,")
|
||||||
|
print outline
|
||||||
|
elif not row[0]: # Last row? Has empty first element
|
||||||
|
delivery = row[8].replace("GBP", "")
|
||||||
|
vat = row[10].replace("GBP", "")
|
||||||
|
outline=(INV_ID + ",," + VENDOR_ID + ",,,," + "DELIVERY" + ",ea," +
|
||||||
|
"Expenses:Postage and Delivery" + "," + "1" + "," + delivery + ",,,,no,,,,,,,,")
|
||||||
|
print outline # pipe to file for GnuCash import
|
||||||
|
outline=(INV_ID + ",," + VENDOR_ID + ",,,," + "VAT" + ",tax," +
|
||||||
|
"Expenses:VAT" + "," + "1" + "," + vat + ",,,,no,,,,,,,,")
|
||||||
|
print outline # pipe to file for GnuCash import
|
@ -25,13 +25,14 @@ GUI_SUBDIRS_2 = \
|
|||||||
import-export \
|
import-export \
|
||||||
business \
|
business \
|
||||||
optional \
|
optional \
|
||||||
|
plugins \
|
||||||
bin
|
bin
|
||||||
|
|
||||||
DIST_SUBDIRS = $(NONGUI_SUBDIRS) $(GUI_SUBDIRS_1) report $(GUI_SUBDIRS_2)
|
DIST_SUBDIRS = $(NONGUI_SUBDIRS) $(GUI_SUBDIRS_1) report $(GUI_SUBDIRS_2)
|
||||||
|
|
||||||
if GNUCASH_ENABLE_GUI
|
if GNUCASH_ENABLE_GUI
|
||||||
SUBDIRS = . $(DIST_SUBDIRS)
|
SUBDIRS = . $(DIST_SUBDIRS)
|
||||||
else
|
else
|
||||||
SUBDIRS = . $(NONGUI_SUBDIRS) report
|
SUBDIRS = . $(NONGUI_SUBDIRS) report
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
1
src/plugins/Makefile.am
Normal file
1
src/plugins/Makefile.am
Normal file
@ -0,0 +1 @@
|
|||||||
|
SUBDIRS=bi_import
|
43
src/plugins/bi_import/Makefile.am
Normal file
43
src/plugins/bi_import/Makefile.am
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
SUBDIRS = ui glade .
|
||||||
|
|
||||||
|
pkglib_LTLIBRARIES = libgncmod-bi_import.la
|
||||||
|
|
||||||
|
libgncmod_bi_import_la_SOURCES = \
|
||||||
|
gnc-plugin-bi_import.c \
|
||||||
|
gncmod-bi_import.c \
|
||||||
|
gui.c \
|
||||||
|
helpers.c \
|
||||||
|
bi_import.c
|
||||||
|
|
||||||
|
noinst_HEADERS = \
|
||||||
|
gnc-plugin-bi_import.h \
|
||||||
|
gui.h \
|
||||||
|
helpers.h \
|
||||||
|
bi_import.h
|
||||||
|
|
||||||
|
libgncmod_bi_import_la_LDFLAGS = -avoid-version
|
||||||
|
|
||||||
|
libgncmod_bi_import_la_LIBADD = \
|
||||||
|
${top_builddir}/src/gnc-module/libgnc-module.la \
|
||||||
|
${GNOME_LIBS} \
|
||||||
|
${GLADE_LIBS} \
|
||||||
|
${QOF_LIBS} \
|
||||||
|
${GLIB_LIBS}
|
||||||
|
|
||||||
|
AM_CFLAGS = \
|
||||||
|
-I${top_srcdir}/src \
|
||||||
|
-I${top_srcdir}/src/gnome \
|
||||||
|
-I${top_srcdir}/src/register/ledger-core \
|
||||||
|
-I${top_srcdir}/src/register/register-gnome \
|
||||||
|
-I${top_srcdir}/src/register/register-core \
|
||||||
|
-I${top_srcdir}/src/gnome-utils \
|
||||||
|
-I${top_srcdir}/src/app-utils \
|
||||||
|
-I${top_srcdir}/src/engine \
|
||||||
|
-I${top_srcdir}/src/core-utils \
|
||||||
|
-I${top_srcdir}/src/gnc-module \
|
||||||
|
${GNOME_CFLAGS} \
|
||||||
|
${GLADE_CFLAGS} \
|
||||||
|
${QOF_CFLAGS} \
|
||||||
|
${GLIB_CFLAGS}
|
||||||
|
|
||||||
|
INCLUDES = -DG_LOG_DOMAIN=\"gnc.plugin.bi_import\"
|
5
src/plugins/bi_import/README
Normal file
5
src/plugins/bi_import/README
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Things and thoughs AKA the TODO and README pages.
|
||||||
|
|
||||||
|
BAD THINGS BAOUT THE IMPORTER
|
||||||
|
The importer should be limited to a singe invoice per file, perhaps creating a new invoice number each time.
|
||||||
|
Too many fields, and too inflexible field format.
|
710
src/plugins/bi_import/bi_import.c
Normal file
710
src/plugins/bi_import/bi_import.c
Normal file
@ -0,0 +1,710 @@
|
|||||||
|
/*
|
||||||
|
* bi_import.c --
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @file bi_import.c
|
||||||
|
* @brief core import functions for invoice import plugin
|
||||||
|
* @author Copyright (C) 2009 Sebastian Held <sebastian.held@gmx.de>
|
||||||
|
* @author Mike Evans <mikee@saxicola.co.uk>
|
||||||
|
* @todo Create an option to import a pre-formed regex when it is present
|
||||||
|
* to enable the use of custom output csv formats.
|
||||||
|
* @todo Open the newly created invoice(es).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
|
#include "gnc-ui.h"
|
||||||
|
#include "gnc-ui-util.h"
|
||||||
|
#include "gnc-gui-query.h"
|
||||||
|
#include "gncAddress.h"
|
||||||
|
#include "gncVendorP.h"
|
||||||
|
#include "gncVendor.h"
|
||||||
|
#include "gncEntry.h"
|
||||||
|
|
||||||
|
#include "gnc-exp-parser.h"
|
||||||
|
|
||||||
|
// query
|
||||||
|
#include "Query.h"
|
||||||
|
#include "qof.h"
|
||||||
|
#include "GNCId.h"
|
||||||
|
#include "gncIDSearch.h"
|
||||||
|
#include "bi_import.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#ifdef HAVE_GLIB_2_14
|
||||||
|
// glib >= 2.14.0
|
||||||
|
// perl regular expressions are available
|
||||||
|
|
||||||
|
// this helper macro takes a regexp match and fills the model
|
||||||
|
#define FILL_IN_HELPER(match_name,column) \
|
||||||
|
temp = g_match_info_fetch_named (match_info, match_name); \
|
||||||
|
if (temp) \
|
||||||
|
{ \
|
||||||
|
g_strstrip( temp ); \
|
||||||
|
gtk_list_store_set (store, &iter, column, temp, -1); \
|
||||||
|
g_free (temp); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bi_import_result
|
||||||
|
gnc_bi_import_read_file (const gchar * filename, const gchar * parser_regexp,
|
||||||
|
GtkListStore * store, guint max_rows,
|
||||||
|
bi_import_stats * stats)
|
||||||
|
{
|
||||||
|
// some statistics
|
||||||
|
bi_import_stats stats_fallback;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
// regexp
|
||||||
|
char *line;
|
||||||
|
gchar *line_utf8, *temp;
|
||||||
|
GMatchInfo *match_info;
|
||||||
|
GError *err;
|
||||||
|
GRegex *regexpat;
|
||||||
|
|
||||||
|
// model
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
f = g_fopen (filename, "rt");
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
//gnc_error_dialog( 0, _("File %s cannot be opened."), filename );
|
||||||
|
return RESULT_OPEN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up statistics
|
||||||
|
if (!stats)
|
||||||
|
stats = &stats_fallback;
|
||||||
|
|
||||||
|
// compile the regular expression and check for errors
|
||||||
|
err = NULL;
|
||||||
|
regexpat =
|
||||||
|
g_regex_new (parser_regexp, G_REGEX_EXTENDED | G_REGEX_OPTIMIZE, 0, &err);
|
||||||
|
if (err != NULL)
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
gchar *errmsg;
|
||||||
|
|
||||||
|
errmsg = g_strdup_printf (_("Error in regular expression '%s':\n%s"),
|
||||||
|
parser_regexp, err->message);
|
||||||
|
g_error_free (err);
|
||||||
|
err = NULL;
|
||||||
|
|
||||||
|
dialog = gtk_message_dialog_new (NULL,
|
||||||
|
GTK_DIALOG_MODAL,
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_OK, "%s", errmsg);
|
||||||
|
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||||
|
gtk_widget_destroy (dialog);
|
||||||
|
g_free (errmsg);
|
||||||
|
errmsg = 0;
|
||||||
|
|
||||||
|
fclose (f);
|
||||||
|
return RESULT_ERROR_IN_REGEXP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start the import
|
||||||
|
stats->n_imported = 0;
|
||||||
|
stats->n_ignored = 0;
|
||||||
|
stats->ignored_lines = g_string_new (NULL);
|
||||||
|
#define buffer_size 1000
|
||||||
|
line = g_malloc0 (buffer_size);
|
||||||
|
while (!feof (f)
|
||||||
|
&& ((max_rows == 0)
|
||||||
|
|| (stats->n_imported + stats->n_ignored < max_rows)))
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
// read one line
|
||||||
|
if (!fgets (line, buffer_size, f))
|
||||||
|
break; // eof
|
||||||
|
// now strip the '\n' from the end of the line
|
||||||
|
l = strlen (line);
|
||||||
|
if ((l > 0) && (line[l - 1] == '\n'))
|
||||||
|
line[l - 1] = 0;
|
||||||
|
|
||||||
|
// convert line from locale into utf8
|
||||||
|
line_utf8 = g_locale_to_utf8 (line, -1, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
// parse the line
|
||||||
|
match_info = NULL; // it seems, that in contrast to documentation, match_info is not alsways set -> g_match_info_free will segfault
|
||||||
|
if (g_regex_match (regexpat, line_utf8, 0, &match_info))
|
||||||
|
{
|
||||||
|
// match found
|
||||||
|
stats->n_imported++;
|
||||||
|
|
||||||
|
// fill in the values
|
||||||
|
gtk_list_store_append (store, &iter);
|
||||||
|
FILL_IN_HELPER (_("id"), ID);
|
||||||
|
FILL_IN_HELPER ("date_opened", DATE_OPENED);
|
||||||
|
FILL_IN_HELPER ("owner_id", OWNER_ID);
|
||||||
|
FILL_IN_HELPER ("biing_id", BILLING_ID);
|
||||||
|
FILL_IN_HELPER ("notes", NOTES);
|
||||||
|
|
||||||
|
FILL_IN_HELPER ("date", DATE);
|
||||||
|
FILL_IN_HELPER ("desc", DESC);
|
||||||
|
FILL_IN_HELPER ("action", ACTION);
|
||||||
|
FILL_IN_HELPER ("account", ACCOUNT);
|
||||||
|
FILL_IN_HELPER ("quantity", QUANTITY);
|
||||||
|
FILL_IN_HELPER ("price", PRICE);
|
||||||
|
FILL_IN_HELPER ("disc_type", DISC_TYPE);
|
||||||
|
FILL_IN_HELPER ("disc_how", DISC_HOW);
|
||||||
|
FILL_IN_HELPER ("discount", DISCOUNT);
|
||||||
|
FILL_IN_HELPER ("taxable", TAXABLE);
|
||||||
|
FILL_IN_HELPER ("taxincluded", TAXINCLUDED);
|
||||||
|
FILL_IN_HELPER ("tax_table", TAX_TABLE);
|
||||||
|
|
||||||
|
FILL_IN_HELPER ("date_posted", DATE_POSTED);
|
||||||
|
FILL_IN_HELPER ("due_date", DUE_DATE);
|
||||||
|
FILL_IN_HELPER ("account_posted", ACCOUNT_POSTED);
|
||||||
|
FILL_IN_HELPER ("memo_posted", MEMO_POSTED);
|
||||||
|
FILL_IN_HELPER ("accu_splits", ACCU_SPLITS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ignore line
|
||||||
|
stats->n_ignored++;
|
||||||
|
g_string_append (stats->ignored_lines, line_utf8);
|
||||||
|
g_string_append_c (stats->ignored_lines, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
g_match_info_free (match_info);
|
||||||
|
match_info = 0;
|
||||||
|
g_free (line_utf8);
|
||||||
|
line_utf8 = 0;
|
||||||
|
}
|
||||||
|
g_free (line);
|
||||||
|
line = 0;
|
||||||
|
|
||||||
|
g_regex_unref (regexpat);
|
||||||
|
regexpat = 0;
|
||||||
|
fclose (f);
|
||||||
|
|
||||||
|
if (stats == &stats_fallback)
|
||||||
|
// stats are not requested -> free the string
|
||||||
|
g_string_free (stats->ignored_lines, TRUE);
|
||||||
|
|
||||||
|
return RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! \brief try to fix some common errors in the csv representation of invoices
|
||||||
|
//! * corrects the date format
|
||||||
|
//! * corrects ambigous values in multi line invoices
|
||||||
|
//! * ensures customer exists
|
||||||
|
//! * if quantity is unset, set to 1
|
||||||
|
//! * if price is unset, delete row
|
||||||
|
void
|
||||||
|
gnc_bi_import_fix_bis (GtkListStore * store, guint * fixed, guint * deleted,
|
||||||
|
GString * info)
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gboolean valid, row_deleted, row_fixed;
|
||||||
|
gchar *id, *date_opened, *date_posted, *owner_id, *date, *quantity, *price;
|
||||||
|
GString *prev_id, *prev_date_opened, *prev_date_posted, *prev_owner_id, *prev_date; // needed to fix multi line invoices
|
||||||
|
guint dummy;
|
||||||
|
|
||||||
|
// allow the call to this function with only GtkListeStore* specified
|
||||||
|
if (!fixed)
|
||||||
|
fixed = &dummy;
|
||||||
|
if (!deleted)
|
||||||
|
deleted = &dummy;
|
||||||
|
|
||||||
|
*fixed = 0;
|
||||||
|
*deleted = 0;
|
||||||
|
|
||||||
|
// init strings
|
||||||
|
prev_id = g_string_new ("");
|
||||||
|
prev_date_opened = g_string_new ("");
|
||||||
|
prev_date_posted = g_string_new ("");
|
||||||
|
prev_owner_id = g_string_new ("");
|
||||||
|
prev_date = g_string_new ("");
|
||||||
|
|
||||||
|
valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
|
||||||
|
while (valid)
|
||||||
|
{
|
||||||
|
row_deleted = FALSE;
|
||||||
|
row_fixed = FALSE;
|
||||||
|
|
||||||
|
// Walk through the list, reading each row
|
||||||
|
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
|
||||||
|
ID, &id,
|
||||||
|
DATE_OPENED, &date_opened,
|
||||||
|
DATE_POSTED, &date_posted,
|
||||||
|
OWNER_ID, &owner_id,
|
||||||
|
DATE, &date,
|
||||||
|
QUANTITY, &quantity, PRICE, &price, -1);
|
||||||
|
|
||||||
|
if (strlen (price) == 0)
|
||||||
|
{
|
||||||
|
// invalid row (no price given)
|
||||||
|
// no fix possible -> delete row
|
||||||
|
gtk_list_store_remove (store, &iter);
|
||||||
|
row_deleted = TRUE;
|
||||||
|
g_string_append_printf (info,
|
||||||
|
_("ROW DELETED, PRICE_NOT_SET: id=%s\n"),
|
||||||
|
id);
|
||||||
|
}
|
||||||
|
else if (strlen (quantity) == 0)
|
||||||
|
{
|
||||||
|
// invalid row (no quantity given)
|
||||||
|
// no fix possible -> delete row
|
||||||
|
gtk_list_store_remove (store, &iter);
|
||||||
|
row_deleted = TRUE;
|
||||||
|
g_string_append_printf (info, _("ROW DELETED, QTY_NOT_SET: id=%s\n"),
|
||||||
|
id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (strlen (id) == 0)
|
||||||
|
{
|
||||||
|
// no invoice id specified
|
||||||
|
if (prev_id->len == 0)
|
||||||
|
{
|
||||||
|
// cannot fix -> delete row
|
||||||
|
gtk_list_store_remove (store, &iter);
|
||||||
|
row_deleted = TRUE;
|
||||||
|
g_string_append_printf (info,
|
||||||
|
_("ROW DELETED, ID_NOT_SET\n"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this is a fixable multi line invoice
|
||||||
|
gtk_list_store_set (store, &iter, ID, prev_id->str, -1);
|
||||||
|
row_fixed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remember invoice id (to be able to fix multi line invoices)
|
||||||
|
g_string_assign (prev_id, id);
|
||||||
|
// new invoice => reset all other fixable entries
|
||||||
|
g_string_assign (prev_date_opened, "");
|
||||||
|
g_string_assign (prev_date_posted, "");
|
||||||
|
g_string_assign (prev_owner_id, "");
|
||||||
|
g_string_assign (prev_date, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!row_deleted)
|
||||||
|
{
|
||||||
|
// the row is valid (price and id are valid)
|
||||||
|
|
||||||
|
if (strlen (date_opened) == 0)
|
||||||
|
{
|
||||||
|
if (prev_date_opened->len == 0)
|
||||||
|
{
|
||||||
|
// fix this by using the current date (why is this so complicated?)
|
||||||
|
gchar temp[20];
|
||||||
|
GDate *date;
|
||||||
|
time_t secs;
|
||||||
|
struct tm now;
|
||||||
|
time (&secs);
|
||||||
|
localtime_r (&secs, &now);
|
||||||
|
date =
|
||||||
|
g_date_new_dmy (now.tm_mday, now.tm_mon + 1,
|
||||||
|
now.tm_year + 1900);
|
||||||
|
g_date_strftime (temp, 20, "%x", date); // create a locale specific date string
|
||||||
|
g_string_assign (prev_date_opened, temp);
|
||||||
|
g_date_free (date);
|
||||||
|
}
|
||||||
|
// fix this by using the previous date_opened value (multi line invoice)
|
||||||
|
gtk_list_store_set (store, &iter, DATE_OPENED,
|
||||||
|
prev_date_opened->str, -1);
|
||||||
|
row_fixed = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remember date_opened (to be able to fix multi line invoices)
|
||||||
|
g_string_assign (prev_date_opened, date_opened);
|
||||||
|
}
|
||||||
|
|
||||||
|
// date_opened is valid
|
||||||
|
|
||||||
|
if (strlen (date_posted) == 0)
|
||||||
|
{
|
||||||
|
if (prev_date_posted->len == 0)
|
||||||
|
{
|
||||||
|
// this invoice will have to get posted manually
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// multi line invoice => fix it
|
||||||
|
gtk_list_store_set (store, &iter, DATE_POSTED,
|
||||||
|
prev_date_posted->str, -1);
|
||||||
|
row_fixed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remember date_opened (to be able to fix multi line invoices)
|
||||||
|
g_string_assign (prev_date_posted, date_posted);
|
||||||
|
}
|
||||||
|
|
||||||
|
// date_posted is valid
|
||||||
|
|
||||||
|
if (strlen (quantity) == 0)
|
||||||
|
{
|
||||||
|
// quantity is unset => set to 1
|
||||||
|
gtk_list_store_set (store, &iter, QUANTITY, "1", -1);
|
||||||
|
row_fixed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// quantity is valid
|
||||||
|
|
||||||
|
if (strlen (owner_id) == 0)
|
||||||
|
{
|
||||||
|
if (prev_owner_id->len == 0)
|
||||||
|
{
|
||||||
|
// no customer given and not fixable => delete row
|
||||||
|
gtk_list_store_remove (store, &iter);
|
||||||
|
row_deleted = TRUE;
|
||||||
|
g_string_append_printf (info,
|
||||||
|
_("ROW DELETED, VENDOR_NOT_SET: id=%s\n"),
|
||||||
|
id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_list_store_set (store, &iter, owner_id,
|
||||||
|
prev_owner_id->str, -1);
|
||||||
|
row_fixed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remember owner_id
|
||||||
|
g_string_assign (prev_owner_id, owner_id);
|
||||||
|
}
|
||||||
|
// now check, if customer exists
|
||||||
|
if (!gnc_search_vendor_on_id
|
||||||
|
(gnc_get_current_book (), prev_owner_id->str))
|
||||||
|
{
|
||||||
|
// customer not found => delete row
|
||||||
|
gtk_list_store_remove (store, &iter);
|
||||||
|
row_deleted = TRUE;
|
||||||
|
g_string_append_printf (info,
|
||||||
|
_("ROW DELETED, VENDOR_DOES_NOT_EXIST: id=%s\n"),
|
||||||
|
id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// owner_id is valid
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (id);
|
||||||
|
g_free (date_opened);
|
||||||
|
g_free (date_posted);
|
||||||
|
g_free (owner_id);
|
||||||
|
g_free (date);
|
||||||
|
g_free (quantity);
|
||||||
|
g_free (price);
|
||||||
|
if (row_deleted)
|
||||||
|
{
|
||||||
|
(*deleted)++;
|
||||||
|
// reset all remembered values
|
||||||
|
g_string_assign (prev_id, "");
|
||||||
|
g_string_assign (prev_date_opened, "");
|
||||||
|
g_string_assign (prev_date_posted, "");
|
||||||
|
g_string_assign (prev_owner_id, "");
|
||||||
|
g_string_assign (prev_date, "");
|
||||||
|
}
|
||||||
|
else if (row_fixed)
|
||||||
|
(*fixed)++;
|
||||||
|
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// deallocate strings
|
||||||
|
g_string_free (prev_id, TRUE);
|
||||||
|
g_string_free (prev_date_opened, TRUE);
|
||||||
|
g_string_free (prev_date_posted, TRUE);
|
||||||
|
g_string_free (prev_owner_id, TRUE);
|
||||||
|
g_string_free (prev_date, TRUE);
|
||||||
|
|
||||||
|
if (info && (info->len > 0))
|
||||||
|
g_string_prepend (info, _("These rows were deleted:\n\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* @todo Maybe invoice checking should be done in gnc_bi_import_fix_bis (...)
|
||||||
|
* rather than in here? But that is more concerned with ensuring the csv is consistent.
|
||||||
|
* @param GtkListStore *store
|
||||||
|
* @param guint *n_invoices_created
|
||||||
|
* @param guint *n_invoices_updated
|
||||||
|
* @return void
|
||||||
|
***********************************************************************/
|
||||||
|
void
|
||||||
|
gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
|
||||||
|
guint * n_invoices_created,
|
||||||
|
guint * n_invoices_updated, gchar * type)
|
||||||
|
{
|
||||||
|
gboolean valid;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar *id, *date_opened, *owner_id, *biing_id, *notes;
|
||||||
|
gchar *date, *desc, *action, *account, *quantity, *price, *disc_type,
|
||||||
|
*disc_how, *discount, *taxable, *taxincluded, *tax_table;
|
||||||
|
gchar *date_posted, *due_date, *account_posted, *memo_posted,
|
||||||
|
*accumulatesplits;
|
||||||
|
guint dummy;
|
||||||
|
GncInvoice *invoice;
|
||||||
|
GncOrder *order;
|
||||||
|
GncEntry *entry;
|
||||||
|
gint day, month, year;
|
||||||
|
gnc_numeric n;
|
||||||
|
GncOwner *owner;
|
||||||
|
Account *acc;
|
||||||
|
enum update{YES = GTK_RESPONSE_YES, NO = GTK_RESPONSE_NO}update;
|
||||||
|
GtkWidget *dialog;
|
||||||
|
Timespec today;
|
||||||
|
|
||||||
|
|
||||||
|
// these arguments are needed
|
||||||
|
g_return_if_fail (store && book);
|
||||||
|
|
||||||
|
// allow to call this function without statistics
|
||||||
|
if (!n_invoices_created)
|
||||||
|
n_invoices_created = &dummy;
|
||||||
|
if (!n_invoices_updated)
|
||||||
|
n_invoices_updated = &dummy;
|
||||||
|
*n_invoices_created = 0;
|
||||||
|
*n_invoices_updated = 0;
|
||||||
|
|
||||||
|
invoice = NULL;
|
||||||
|
order = NULL;
|
||||||
|
update = NO;
|
||||||
|
|
||||||
|
valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
|
||||||
|
while (valid)
|
||||||
|
{
|
||||||
|
// Walk through the list, reading each row
|
||||||
|
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ID, &id, DATE_OPENED, &date_opened, DATE_POSTED, &date_posted, // if autoposting requested
|
||||||
|
DUE_DATE, &due_date, // if autoposting requested
|
||||||
|
ACCOUNT_POSTED, &account_posted, // if autoposting requested
|
||||||
|
MEMO_POSTED, &memo_posted, // if autoposting requested
|
||||||
|
ACCU_SPLITS, &accumulatesplits, // if autoposting requested
|
||||||
|
OWNER_ID, &owner_id,
|
||||||
|
BILLING_ID, &biing_id,
|
||||||
|
NOTES, ¬es,
|
||||||
|
DATE, &date,
|
||||||
|
DESC, &desc,
|
||||||
|
ACTION, &action,
|
||||||
|
ACCOUNT, &account,
|
||||||
|
QUANTITY, &quantity,
|
||||||
|
PRICE, &price,
|
||||||
|
DISC_TYPE, &disc_type,
|
||||||
|
DISC_HOW, &disc_how,
|
||||||
|
DISCOUNT, &discount,
|
||||||
|
TAXABLE, &taxable,
|
||||||
|
TAXINCLUDED, &taxincluded,
|
||||||
|
TAX_TABLE, &tax_table, -1);
|
||||||
|
|
||||||
|
// TODO: Assign a new invoice number if one is absent. BUT we don't want to assign a new invoice for every line!!
|
||||||
|
// so we'd have to flag this up somehow or add an option in the import GUI. The former implies that we make
|
||||||
|
// an assumption about what the importer (person) wants to do. It seems resonable that a CSV file full of items with
|
||||||
|
// If an invoice exists then we add to it in this current schema.
|
||||||
|
// no predefined invoice number is a new invoice that's in need of a new number.
|
||||||
|
// This was not designed to satisfy the need for repeat invoices however, so maybe we need a another method for this, after all
|
||||||
|
// It should be easier to copy an invoice with a new ID than to go through all this malarky.
|
||||||
|
if (g_ascii_strcasecmp (type, "BILL"))
|
||||||
|
invoice = gnc_search_bill_on_id (book, id);
|
||||||
|
else if (g_ascii_strcasecmp (type, "INVOICE"))
|
||||||
|
invoice = gnc_search_invoice_on_id (book, id);
|
||||||
|
|
||||||
|
if (!invoice)
|
||||||
|
{
|
||||||
|
// new invoice
|
||||||
|
invoice = gncInvoiceCreate (book);
|
||||||
|
gncInvoiceSetID (invoice, id);
|
||||||
|
owner = gncOwnerCreate ();
|
||||||
|
if (g_ascii_strcasecmp (type, "BILL") == 0)
|
||||||
|
gncOwnerInitVendor (owner,
|
||||||
|
gnc_search_vendor_on_id (book, owner_id));
|
||||||
|
else if (g_ascii_strcasecmp (type, "INVOICE") == 0)
|
||||||
|
gncOwnerInitCustomer (owner,
|
||||||
|
gnc_search_customer_on_id (book, owner_id));
|
||||||
|
gncInvoiceSetOwner (invoice, owner);
|
||||||
|
gncInvoiceSetCurrency (invoice, gncOwnerGetCurrency (owner)); // Set the invoice currency based on the owner
|
||||||
|
if (!(g_ascii_strcasecmp (type, ""))) // If a date is specified in CSV
|
||||||
|
{
|
||||||
|
qof_scan_date (date_opened, &day, &month, &year);
|
||||||
|
gncInvoiceSetDateOpened (invoice,
|
||||||
|
gnc_dmy2timespec (day, month, year));
|
||||||
|
}
|
||||||
|
else // If no date in CSV
|
||||||
|
{
|
||||||
|
time_t now = time (NULL);
|
||||||
|
Timespec now_timespec;
|
||||||
|
timespecFromTime_t (&now_timespec, now);
|
||||||
|
gncInvoiceSetDateOpened (invoice, now_timespec);
|
||||||
|
}
|
||||||
|
gncInvoiceSetBillingID (invoice, biing_id);
|
||||||
|
gncInvoiceSetNotes (invoice, notes);
|
||||||
|
gncInvoiceSetActive (invoice, TRUE);
|
||||||
|
//if (g_ascii_strcasecmp(type,"INVOICE"))gncInvoiceSetBillTo( invoice, billto );
|
||||||
|
(*n_invoices_created)++;
|
||||||
|
update = YES;
|
||||||
|
}
|
||||||
|
// I want to warn the user that an existing billvoice exists, but not every
|
||||||
|
// time.
|
||||||
|
// An import can contain many lines usually referring to the same invoice.
|
||||||
|
// NB: Posted invoices are NEVER updated.
|
||||||
|
else // if invoice exists
|
||||||
|
{
|
||||||
|
if (gncInvoiceIsPosted (invoice)) // Is it already posted?
|
||||||
|
{
|
||||||
|
valid =
|
||||||
|
gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
|
||||||
|
continue; // If already posted then never import
|
||||||
|
}
|
||||||
|
if (update != YES) // Pop up a dialog to ask if updates are the expected action
|
||||||
|
{
|
||||||
|
dialog = gtk_message_dialog_new (NULL,
|
||||||
|
GTK_DIALOG_MODAL,
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_YES_NO,
|
||||||
|
"%s",
|
||||||
|
_("Are you sure you have bills/invoices to update?"));
|
||||||
|
update = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||||
|
gtk_widget_destroy (dialog);
|
||||||
|
if (update == NO)
|
||||||
|
{ // Cleanup and leave
|
||||||
|
g_free (id); g_free (date_opened); g_free (owner_id); g_free (biing_id);
|
||||||
|
g_free (notes); g_free (date); g_free (desc); g_free (action);
|
||||||
|
g_free (account); g_free (quantity); g_free (price); g_free (disc_type);
|
||||||
|
g_free (disc_how); g_free (discount); g_free (taxable); g_free (taxincluded);
|
||||||
|
g_free (tax_table); g_free (date_posted); g_free (due_date); g_free (account_posted);
|
||||||
|
g_free (memo_posted); g_free (accumulatesplits);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*n_invoices_updated)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// add entry to invoice/bill
|
||||||
|
entry = gncEntryCreate (book);
|
||||||
|
qof_scan_date (date, &day, &month, &year);
|
||||||
|
gncEntrySetDate (entry, gnc_dmy2timespec (day, month, year));
|
||||||
|
timespecFromTime_t (&today, time (NULL)); // set today to the current date
|
||||||
|
gncEntrySetDateEntered (entry, today);
|
||||||
|
gncEntrySetDescription (entry, desc);
|
||||||
|
gncEntrySetAction (entry, action);
|
||||||
|
|
||||||
|
n = gnc_numeric_zero ();
|
||||||
|
gnc_exp_parser_parse (quantity, &n, NULL);
|
||||||
|
gncEntrySetQuantity (entry, n);
|
||||||
|
acc = gnc_account_lookup_for_register (gnc_get_current_root_account (),
|
||||||
|
account);
|
||||||
|
if (g_ascii_strcasecmp (type, "BILL") == 0)
|
||||||
|
{
|
||||||
|
gncEntrySetBillAccount (entry, acc);
|
||||||
|
n = gnc_numeric_zero ();
|
||||||
|
gnc_exp_parser_parse (price, &n, NULL);
|
||||||
|
gncEntrySetBillPrice (entry, n);
|
||||||
|
gncEntrySetBillTaxable (entry, text2bool (taxable));
|
||||||
|
gncEntrySetBillTaxIncluded (entry, text2bool (taxincluded));
|
||||||
|
gncEntrySetBillTaxTable (entry,
|
||||||
|
gncTaxTableLookupByName (book, tax_table));
|
||||||
|
n = gnc_numeric_zero ();
|
||||||
|
gnc_exp_parser_parse (discount, &n, NULL);
|
||||||
|
gncBillAddEntry (invoice, entry);
|
||||||
|
}
|
||||||
|
else if (g_ascii_strcasecmp (type, "INVOICE") == 0)
|
||||||
|
{
|
||||||
|
gncEntrySetNotes (entry, notes);
|
||||||
|
gncEntrySetInvAccount (entry, acc);
|
||||||
|
n = gnc_numeric_zero ();
|
||||||
|
gnc_exp_parser_parse (price, &n, NULL);
|
||||||
|
gncEntrySetInvPrice (entry, n);
|
||||||
|
gncEntrySetInvTaxable (entry, text2bool (taxable));
|
||||||
|
gncEntrySetInvTaxIncluded (entry, text2bool (taxincluded));
|
||||||
|
gncEntrySetInvTaxTable (entry,
|
||||||
|
gncTaxTableLookupByName (book, tax_table));
|
||||||
|
n = gnc_numeric_zero ();
|
||||||
|
gnc_exp_parser_parse (discount, &n, NULL);
|
||||||
|
gncEntrySetInvDiscount (entry, n);
|
||||||
|
gncEntrySetInvDiscountType (entry, text2disc_type (disc_type));
|
||||||
|
gncEntrySetInvDiscountHow (entry, text2disc_how (disc_how));
|
||||||
|
gncInvoiceAddEntry (invoice, entry);
|
||||||
|
}
|
||||||
|
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
|
||||||
|
|
||||||
|
// handle auto posting of invoices
|
||||||
|
{
|
||||||
|
gchar *new_id = NULL;
|
||||||
|
Transaction *tnx;
|
||||||
|
if (valid)
|
||||||
|
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ID, &new_id, -1);
|
||||||
|
if (g_strcmp0 (id, new_id) != 0)
|
||||||
|
{
|
||||||
|
// the next invoice id is different => try to autopost this invoice
|
||||||
|
if (qof_scan_date (date_posted, &day, &month, &year))
|
||||||
|
{
|
||||||
|
// autopost this invoice
|
||||||
|
Timespec d1, d2;
|
||||||
|
d1 = gnc_dmy2timespec (day, month, year);
|
||||||
|
qof_scan_date (due_date, &day, &month, &year); // obtains the due date, or leaves it at date_posted
|
||||||
|
d2 = gnc_dmy2timespec (day, month, year);
|
||||||
|
acc = gnc_account_lookup_for_register
|
||||||
|
(gnc_get_current_root_account (), account_posted);
|
||||||
|
tnx = gncInvoicePostToAccount (invoice, acc, &d1, &d2,
|
||||||
|
memo_posted,
|
||||||
|
text2bool (accumulatesplits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free (new_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
g_free (id);
|
||||||
|
g_free (date_opened);
|
||||||
|
g_free (owner_id);
|
||||||
|
g_free (biing_id);
|
||||||
|
g_free (notes);
|
||||||
|
g_free (date);
|
||||||
|
g_free (desc);
|
||||||
|
g_free (action);
|
||||||
|
g_free (account);
|
||||||
|
g_free (quantity);
|
||||||
|
g_free (price);
|
||||||
|
g_free (disc_type);
|
||||||
|
g_free (disc_how);
|
||||||
|
g_free (discount);
|
||||||
|
g_free (taxable);
|
||||||
|
g_free (taxincluded);
|
||||||
|
g_free (tax_table);
|
||||||
|
g_free (date_posted);
|
||||||
|
g_free (due_date);
|
||||||
|
g_free (account_posted);
|
||||||
|
g_free (memo_posted);
|
||||||
|
g_free (accumulatesplits);
|
||||||
|
}
|
||||||
|
}
|
75
src/plugins/bi_import/bi_import.h
Normal file
75
src/plugins/bi_import/bi_import.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* bi_import.h --
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup Tools
|
||||||
|
* @{
|
||||||
|
* @file bi_import.h
|
||||||
|
* @brief core import functions for invoice import plugin
|
||||||
|
* @author Copyright (C) 2009 Sebastian Held <sebastian.held@gmx.de>
|
||||||
|
* @author Mike Evans <mikee@saxicola.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GNC_PLUGIN_bi_import_bi_import_H
|
||||||
|
#define GNC_PLUGIN_bi_import_bi_import_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
// model
|
||||||
|
enum bi_import_model_columns {
|
||||||
|
ID, DATE_OPENED, OWNER_ID, BILLING_ID, NOTES, // invoice settings
|
||||||
|
DATE, DESC, ACTION, ACCOUNT, QUANTITY, PRICE, DISC_TYPE, DISC_HOW, DISCOUNT, TAXABLE, TAXINCLUDED, TAX_TABLE, // entry settings
|
||||||
|
DATE_POSTED, DUE_DATE, ACCOUNT_POSTED, MEMO_POSTED, ACCU_SPLITS, // autopost settings
|
||||||
|
N_COLUMNS
|
||||||
|
};
|
||||||
|
|
||||||
|
enum _bi_import_result {
|
||||||
|
RESULT_OK,
|
||||||
|
RESULT_OPEN_FAILED,
|
||||||
|
RESULT_ERROR_IN_REGEXP,
|
||||||
|
};
|
||||||
|
typedef enum _bi_import_result bi_import_result;
|
||||||
|
|
||||||
|
struct _bi_import_stats {
|
||||||
|
int n_imported, n_ignored;
|
||||||
|
GString *ignored_lines;
|
||||||
|
};
|
||||||
|
typedef struct _bi_import_stats bi_import_stats;
|
||||||
|
|
||||||
|
|
||||||
|
bi_import_result
|
||||||
|
gnc_bi_import_read_file (const gchar *filename, const gchar *parser_regexp, GtkListStore *store, guint max_rows, bi_import_stats *stats);
|
||||||
|
|
||||||
|
void
|
||||||
|
gnc_bi_import_fix_bis (GtkListStore *store, guint *fixed, guint *deleted, GString *info);
|
||||||
|
|
||||||
|
void
|
||||||
|
gnc_bi_import_create_bis (GtkListStore *store, QofBook *book, guint *n_invoices_created, guint *n_invoices_updated, gchar *type);
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* GNC_PLUGIN_bi_import_bi_import_H */
|
||||||
|
|
||||||
|
/** @} */
|
4
src/plugins/bi_import/glade/Makefile.am
Normal file
4
src/plugins/bi_import/glade/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
gladedir = $(GNC_GLADE_DIR)
|
||||||
|
glade_DATA = bi_import.glade
|
||||||
|
|
||||||
|
EXTRA_DIST = ${glade_DATA}
|
370
src/plugins/bi_import/glade/bi_import.glade
Normal file
370
src/plugins/bi_import/glade/bi_import.glade
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<glade-interface>
|
||||||
|
<!-- interface-requires gtk+ 2.6 -->
|
||||||
|
<!-- interface-naming-policy toplevel-contextual -->
|
||||||
|
<widget class="GtkDialog" id="bi_import Dialog">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="title" translatable="yes">Import transactions from text file</property>
|
||||||
|
<property name="type_hint">dialog</property>
|
||||||
|
<signal name="destroy" handler="gnc_bi_import_gui_destroy_cb"/>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<widget class="GtkVBox" id="dialog-vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">8</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkFrame" id="frame1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="border_width">3</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="alignment1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="left_padding">12</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkHBox" id="hbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkEntry" id="entryFilename">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<signal name="changed" handler="gnc_bi_import_gui_filenameChanged_cb"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="buttonOpen">
|
||||||
|
<property name="label">gtk-open</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="gnc_bi_import_gui_buttonOpen_cb"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">1. Choose the file to import</property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="type">label_item</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkFrame" id="frame4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="alignment4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="left_padding">12</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="alignment5">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkHBox" id="hbox2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkRadioButton" id="radiobuttonBill">
|
||||||
|
<property name="label" translatable="yes">Bill</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="has_default">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="has_tooltip">True</property>
|
||||||
|
<property name="tooltip" translatable="yes">Import bill CSV data</property>
|
||||||
|
<property name="xalign">0.4699999988079071</property>
|
||||||
|
<property name="active">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<signal name="toggled" handler="gnc_import_gui_type"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkRadioButton" id="radiobuttonInvoice">
|
||||||
|
<property name="label" translatable="yes">Invoice</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="has_tooltip">True</property>
|
||||||
|
<property name="tooltip" translatable="yes">Import invoice CSV data</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<property name="group">radiobuttonBill</property>
|
||||||
|
<signal name="toggled" handler="gnc_import_gui_type"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">2, Select import type</property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="type">label_item</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkFrame" id="frame2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="border_width">3</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="alignment2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="left_padding">12</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkRadioButton" id="radiobutton1">
|
||||||
|
<property name="label" translatable="yes">Semicolon separated</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<signal name="toggled" handler="gnc_bi_import_gui_option1_cb"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkRadioButton" id="radiobutton2">
|
||||||
|
<property name="label" translatable="yes">Comma separated</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<property name="group">radiobutton1</property>
|
||||||
|
<signal name="toggled" handler="gnc_bi_import_gui_option2_cb"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkRadioButton" id="radiobutton3">
|
||||||
|
<property name="label" translatable="yes">Semicolon separated with quotes</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<property name="group">radiobutton1</property>
|
||||||
|
<signal name="toggled" handler="gnc_bi_import_gui_option3_cb"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkRadioButton" id="radiobutton4">
|
||||||
|
<property name="label" translatable="yes">Comma separated with quotes</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<property name="group">radiobutton1</property>
|
||||||
|
<signal name="toggled" handler="gnc_bi_import_gui_option4_cb"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkRadioButton" id="radiobutton5">
|
||||||
|
<property name="label" translatable="yes">Custom regular expression</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<property name="group">radiobutton1</property>
|
||||||
|
<signal name="clicked" handler="gnc_bi_import_gui_option5_cb"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">3. Select import options</property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="type">label_item</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkFrame" id="frame3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="border_width">3</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="alignment3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="left_padding">12</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkScrolledWindow" id="scrolledwindow2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkTreeView" id="treeview1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">4. Preview</property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="type">label_item</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="helpbutton">
|
||||||
|
<property name="label">gtk-help</property>
|
||||||
|
<property name="response_id">-11</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="can_default">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="gnc_bi_import_gui_help_cb"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="cancelbutton">
|
||||||
|
<property name="label">gtk-cancel</property>
|
||||||
|
<property name="response_id">-6</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="can_default">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="gnc_bi_import_gui_cancel_cb"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="okbutton">
|
||||||
|
<property name="label">gtk-ok</property>
|
||||||
|
<property name="response_id">-5</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="can_default">True</property>
|
||||||
|
<property name="has_default">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="gnc_bi_import_gui_ok_cb"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">5</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</glade-interface>
|
115
src/plugins/bi_import/gnc-plugin-bi_import.c
Normal file
115
src/plugins/bi_import/gnc-plugin-bi_import.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* gnc-plugin-bi_import.c --
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @file gnc-plugin-bi_import.c
|
||||||
|
* @brief Plugin registration of the bi_import plugin
|
||||||
|
* @author Copyright (C) 2009 Sebastian Held <sebastian.held@gmx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
#include "dialog-utils.h"
|
||||||
|
|
||||||
|
#include "gnc-plugin-bi_import.h"
|
||||||
|
#include "gui.h"
|
||||||
|
|
||||||
|
/* This static indicates the debugging module that this .o belongs to. */
|
||||||
|
static QofLogModule log_module = G_LOG_DOMAIN;
|
||||||
|
|
||||||
|
static void gnc_plugin_bi_import_class_init (GncPluginbi_importClass *klass);
|
||||||
|
static void gnc_plugin_bi_import_init (GncPluginbi_import *plugin);
|
||||||
|
static void gnc_plugin_bi_import_finalize (GObject *object);
|
||||||
|
|
||||||
|
/* Command callbacks */
|
||||||
|
static void gnc_plugin_bi_import_cmd_test (GtkAction *action, GncMainWindowActionData *data);
|
||||||
|
|
||||||
|
#define PLUGIN_ACTIONS_NAME "gnc-plugin-bi_import-actions"
|
||||||
|
#define PLUGIN_UI_FILENAME "gnc-plugin-bi_import-ui.xml"
|
||||||
|
|
||||||
|
static GtkActionEntry gnc_plugin_actions [] = {
|
||||||
|
/* Menu Items */
|
||||||
|
{ "ImportMenuAction", NULL, N_("_Import"), NULL, NULL, NULL },
|
||||||
|
{ "bi_importAction", NULL, N_("Import Bills & Invoices..."), NULL, N_("bi_import tooltip"), G_CALLBACK(gnc_plugin_bi_import_cmd_test) },
|
||||||
|
};
|
||||||
|
static guint gnc_plugin_n_actions = G_N_ELEMENTS(gnc_plugin_actions);
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Object Implementation *
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(GncPluginbi_import, gnc_plugin_bi_import, GNC_TYPE_PLUGIN);
|
||||||
|
|
||||||
|
GncPlugin *
|
||||||
|
gnc_plugin_bi_import_new (void)
|
||||||
|
{
|
||||||
|
return GNC_PLUGIN (g_object_new (GNC_TYPE_PLUGIN_bi_import, (gchar*) NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnc_plugin_bi_import_class_init (GncPluginbi_importClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GncPluginClass *plugin_class = GNC_PLUGIN_CLASS(klass);
|
||||||
|
|
||||||
|
object_class->finalize = gnc_plugin_bi_import_finalize;
|
||||||
|
|
||||||
|
/* plugin info */
|
||||||
|
plugin_class->plugin_name = GNC_PLUGIN_bi_import_NAME;
|
||||||
|
|
||||||
|
/* widget addition/removal */
|
||||||
|
plugin_class->actions_name = PLUGIN_ACTIONS_NAME;
|
||||||
|
plugin_class->actions = gnc_plugin_actions;
|
||||||
|
plugin_class->n_actions = gnc_plugin_n_actions;
|
||||||
|
plugin_class->ui_filename = PLUGIN_UI_FILENAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnc_plugin_bi_import_init (GncPluginbi_import *plugin)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnc_plugin_bi_import_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
* Command Callbacks *
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnc_plugin_bi_import_cmd_test (GtkAction *action, GncMainWindowActionData *data)
|
||||||
|
{
|
||||||
|
ENTER ("action %p, main window data %p", action, data);
|
||||||
|
g_message ("bi_import");
|
||||||
|
|
||||||
|
gnc_plugin_bi_import_showGUI();
|
||||||
|
|
||||||
|
LEAVE (" ");
|
||||||
|
}
|
78
src/plugins/bi_import/gnc-plugin-bi_import.h
Normal file
78
src/plugins/bi_import/gnc-plugin-bi_import.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* gnc-plugin-bi_import.h --
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup Tools
|
||||||
|
* @{
|
||||||
|
* @file gnc-plugin-bi_import.h
|
||||||
|
* @brief Plugin registration of the bi_import module
|
||||||
|
* @author Copyright (C) 2009 Sebastian Held <sebastian.held@gmx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GNC_PLUGIN_bi_import_H
|
||||||
|
#define GNC_PLUGIN_bi_import_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "gnc-plugin.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/* type macros */
|
||||||
|
#define GNC_TYPE_PLUGIN_bi_import (gnc_plugin_bi_import_get_type())
|
||||||
|
#define GNC_PLUGIN_bi_import(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNC_TYPE_PLUGIN_bi_import, GncPluginbi_import))
|
||||||
|
#define GNC_PLUGIN_bi_import_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNC_TYPE_PLUGIN_bi_import, GncPluginbi_importClass))
|
||||||
|
#define GNC_IS_PLUGIN_bi_import(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNC_TYPE_PLUGIN_bi_import))
|
||||||
|
#define GNC_IS_PLUGIN_bi_import_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNC_TYPE_PLUGIN_bi_import))
|
||||||
|
#define GNC_PLUGIN_bi_import_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNC_TYPE_PLUGIN_bi_import, GncPluginbi_importClass))
|
||||||
|
|
||||||
|
#define GNC_PLUGIN_bi_import_NAME "gnc-plugin-bi_import"
|
||||||
|
|
||||||
|
/* typedefs & structures */
|
||||||
|
typedef struct {
|
||||||
|
GncPlugin gnc_plugin;
|
||||||
|
} GncPluginbi_import;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GncPluginClass gnc_plugin;
|
||||||
|
} GncPluginbi_importClass;
|
||||||
|
|
||||||
|
/* function prototypes */
|
||||||
|
/**
|
||||||
|
* @return The glib runtime type of an bi_import plugin page
|
||||||
|
**/
|
||||||
|
GType gnc_plugin_bi_import_get_type (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A new GncPluginbi_import object
|
||||||
|
*/
|
||||||
|
GncPlugin* gnc_plugin_bi_import_new (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new GncPluginbi_import object and register it.
|
||||||
|
*/
|
||||||
|
void gnc_plugin_bi_import_create_plugin (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* GNC_PLUGIN_bi_import_H */
|
100
src/plugins/bi_import/gncmod-bi_import.c
Normal file
100
src/plugins/bi_import/gncmod-bi_import.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* gncmod-bi_import.c
|
||||||
|
* module definition/initialization for the bi_import GNOME UI module
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 Sebastian Held <sebastian.held@gmx.de>
|
||||||
|
* Copyright (c) 2001 Derek Atkins <warlord@MIT.EDU>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gmodule.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <libguile.h>
|
||||||
|
|
||||||
|
#include "gnc-hooks.h"
|
||||||
|
#include "gnc-module.h"
|
||||||
|
#include "gnc-module-api.h"
|
||||||
|
|
||||||
|
#include "gnc-plugin-manager.h"
|
||||||
|
#include "gnc-plugin-bi_import.h"
|
||||||
|
|
||||||
|
GNC_MODULE_API_DECL(libgncmod_bi_import);
|
||||||
|
|
||||||
|
/* version of the gnc module system interface we require */
|
||||||
|
int libgncmod_bi_import_gnc_module_system_interface = 0;
|
||||||
|
|
||||||
|
/* module versioning uses libtool semantics. */
|
||||||
|
int libgncmod_bi_import_gnc_module_current = 0;
|
||||||
|
int libgncmod_bi_import_gnc_module_revision = 0;
|
||||||
|
int libgncmod_bi_import_gnc_module_age = 0;
|
||||||
|
|
||||||
|
|
||||||
|
char *
|
||||||
|
libgncmod_bi_import_gnc_module_path (void)
|
||||||
|
{
|
||||||
|
return g_strdup("gnucash/plugins/bi_import");
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
libgncmod_bi_import_gnc_module_description (void)
|
||||||
|
{
|
||||||
|
return g_strdup("The GnuCash bi_import plugin");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
libgncmod_bi_import_gnc_module_init (int refcount)
|
||||||
|
{
|
||||||
|
if (!gnc_module_load ("gnucash/app-utils", 0)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!gnc_module_load ("gnucash/gnome-utils", 0)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!gnc_module_load ("gnucash/business-core", 0)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!gnc_module_load ("gnucash/engine", 0)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refcount == 0) {
|
||||||
|
/* this is the first time the module is loaded */
|
||||||
|
|
||||||
|
gnc_plugin_manager_add_plugin ( gnc_plugin_manager_get (),
|
||||||
|
gnc_plugin_bi_import_new ());
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
libgncmod_bi_import_gnc_module_end (int refcount)
|
||||||
|
{
|
||||||
|
if (refcount == 0) {
|
||||||
|
/* this is the last time the module is unloaded */
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
471
src/plugins/bi_import/gui.c
Normal file
471
src/plugins/bi_import/gui.c
Normal file
@ -0,0 +1,471 @@
|
|||||||
|
/*
|
||||||
|
* gui.c --
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @file gui.c
|
||||||
|
* @brief GUI handling for bi import plugin
|
||||||
|
* @author Copyright (C) 2009 Sebastian Held <sebastian.held@gmx.de>
|
||||||
|
* @author Mike Evans <mikee@saxicola.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
#include "gnc-ui.h"
|
||||||
|
#include "gnc-ui-util.h"
|
||||||
|
#include "gnc-component-manager.h"
|
||||||
|
#include "dialog-utils.h"
|
||||||
|
#include "gnc-gui-query.h"
|
||||||
|
#include "gnc-file.h"
|
||||||
|
#include "gnc-gnome-utils.h"
|
||||||
|
#include "bi_import.h"
|
||||||
|
#include "gui.h"
|
||||||
|
|
||||||
|
struct _bi_import_gui {
|
||||||
|
GtkWidget *dialog;
|
||||||
|
GtkWidget *tree_view;
|
||||||
|
GtkWidget *entryFilename;
|
||||||
|
GtkListStore *store;
|
||||||
|
gint component_id;
|
||||||
|
GString *regexp;
|
||||||
|
QofBook *book;
|
||||||
|
gchar *type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// callback routines
|
||||||
|
void gnc_bi_import_gui_ok_cb (GtkWidget *widget, gpointer data);
|
||||||
|
void gnc_bi_import_gui_cancel_cb (GtkWidget *widget, gpointer data);
|
||||||
|
void gnc_bi_import_gui_help_cb (GtkWidget *widget, gpointer data);
|
||||||
|
void gnc_bi_import_gui_destroy_cb (GtkWidget *widget, gpointer data);
|
||||||
|
static void gnc_bi_import_gui_close_handler (gpointer user_data);
|
||||||
|
void gnc_bi_import_gui_buttonOpen_cb (GtkWidget *widget, gpointer data);
|
||||||
|
void gnc_bi_import_gui_filenameChanged_cb (GtkWidget *widget, gpointer data);
|
||||||
|
void gnc_bi_import_gui_option1_cb (GtkWidget *widget, gpointer data);
|
||||||
|
void gnc_bi_import_gui_option2_cb (GtkWidget *widget, gpointer data);
|
||||||
|
void gnc_bi_import_gui_option3_cb (GtkWidget *widget, gpointer data);
|
||||||
|
void gnc_bi_import_gui_option4_cb (GtkWidget *widget, gpointer data);
|
||||||
|
void gnc_bi_import_gui_option5_cb (GtkWidget *widget, gpointer data);
|
||||||
|
void gnc_import_gui_type(GtkWidget *widget, gpointer data);
|
||||||
|
|
||||||
|
// utils
|
||||||
|
static gchar *gnc_input_dialog (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input);
|
||||||
|
static void gnc_info2_dialog (GtkWidget *parent, const gchar *title, const gchar *msg);
|
||||||
|
|
||||||
|
|
||||||
|
BillImportGui *
|
||||||
|
gnc_plugin_bi_import_showGUI(void)
|
||||||
|
{
|
||||||
|
BillImportGui *gui;
|
||||||
|
GladeXML *xml;
|
||||||
|
GList *glist;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GtkCellRenderer *renderer;
|
||||||
|
GtkTreeViewColumn *column;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// if window exists already, activate it
|
||||||
|
glist = gnc_find_gui_components ("dialog-bi_import_gui", NULL, NULL);
|
||||||
|
if (glist) {
|
||||||
|
// window found
|
||||||
|
gui = g_list_nth_data (glist,0);
|
||||||
|
g_list_free (glist);
|
||||||
|
gtk_window_present (GTK_WINDOW(gui->dialog));
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new window
|
||||||
|
gui = g_new0 (BillImportGui, 1);
|
||||||
|
gui->type = "BILL"; // Set default type to match gui. really shouldn't be here TODO change me
|
||||||
|
xml = gnc_glade_xml_new ("bi_import.glade", "bi_import Dialog");
|
||||||
|
gui->dialog = glade_xml_get_widget (xml, "bi_import Dialog");
|
||||||
|
gui->tree_view = glade_xml_get_widget (xml, "treeview1");
|
||||||
|
gui->entryFilename = glade_xml_get_widget (xml, "entryFilename");
|
||||||
|
|
||||||
|
gui->book = gnc_get_current_book();
|
||||||
|
|
||||||
|
gui->regexp = g_string_new ( "^(?<id>[^;]*);(?<date_opened>[^;]*);(?<owner_id>[^;]*);(?<billingid>[^;]*);?(?<notes>[^;]*);?(?<date>[^;]*);?(?<desc>[^;]*);?(?<action>[^;]*);?(?<account>[^;]*);?(?<quantity>[^;]*);?(?<price>[^;]*)(;?(?<disc_type>[^;]*)(;?(?<disc_how>[^;]*)(;?(?<discount>[^;]*)(;?(?<taxable>[^;]*)(;?(?<taxincluded>[^;]*)(;?(?<tax_table>[^;]*)(;(?<date_posted>[^;]*)(;(?<due_date>[^;]*)(;(?<account_posted>[^;]*)(;(?<memo_posted>[^;]*)(;(?<accu_splits>[^;]*))?)?)?)?)?)?)?)?)?)?)?");
|
||||||
|
|
||||||
|
// create model and bind to view
|
||||||
|
gui->store = gtk_list_store_new (N_COLUMNS,
|
||||||
|
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, // invoice settings
|
||||||
|
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, // entry settings
|
||||||
|
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); // autopost settings
|
||||||
|
gtk_tree_view_set_model( GTK_TREE_VIEW(gui->tree_view), GTK_TREE_MODEL(gui->store) );
|
||||||
|
#define CREATE_COLUMN(description,column_id) \
|
||||||
|
renderer = gtk_cell_renderer_text_new (); \
|
||||||
|
column = gtk_tree_view_column_new_with_attributes (description, renderer, "text", column_id, NULL); \
|
||||||
|
gtk_tree_view_column_set_resizable (column, TRUE); \
|
||||||
|
gtk_tree_view_append_column (GTK_TREE_VIEW (gui->tree_view), column);
|
||||||
|
CREATE_COLUMN ("id", ID);
|
||||||
|
CREATE_COLUMN ("date__opened", DATE_OPENED);
|
||||||
|
CREATE_COLUMN ("owner__id", OWNER_ID);
|
||||||
|
CREATE_COLUMN ("billing_id", BILLING_ID);
|
||||||
|
CREATE_COLUMN ("notes", NOTES);
|
||||||
|
|
||||||
|
CREATE_COLUMN ("date", DATE);
|
||||||
|
CREATE_COLUMN ("desc", DESC);
|
||||||
|
CREATE_COLUMN ("action", ACTION);
|
||||||
|
CREATE_COLUMN ("account", ACCOUNT);
|
||||||
|
CREATE_COLUMN ("quantity", QUANTITY);
|
||||||
|
CREATE_COLUMN ("price", PRICE);
|
||||||
|
CREATE_COLUMN ("disc__type", DISC_TYPE);
|
||||||
|
CREATE_COLUMN ("disc__how", DISC_HOW);
|
||||||
|
CREATE_COLUMN ("discount", DISCOUNT);
|
||||||
|
CREATE_COLUMN ("taxable", TAXABLE);
|
||||||
|
CREATE_COLUMN ("taxincluded", TAXINCLUDED);
|
||||||
|
CREATE_COLUMN ("tax__table", TAX_TABLE);
|
||||||
|
|
||||||
|
CREATE_COLUMN ("date__posted", DATE_POSTED);
|
||||||
|
CREATE_COLUMN ("due__date", DUE_DATE);
|
||||||
|
CREATE_COLUMN ("account__posted", ACCOUNT_POSTED);
|
||||||
|
CREATE_COLUMN ("memo__posted", MEMO_POSTED);
|
||||||
|
CREATE_COLUMN ("accu__splits", ACCU_SPLITS);
|
||||||
|
|
||||||
|
gui->component_id = gnc_register_gui_component ("dialog-bi_import_gui",
|
||||||
|
NULL,
|
||||||
|
gnc_bi_import_gui_close_handler,
|
||||||
|
gui);
|
||||||
|
|
||||||
|
/* Setup signals */
|
||||||
|
glade_xml_signal_autoconnect_full( xml, gnc_glade_autoconnect_full_func, gui );
|
||||||
|
|
||||||
|
gtk_widget_show_all ( gui->dialog );
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
gnc_plugin_bi_import_getFilename(void)
|
||||||
|
{
|
||||||
|
// prepare file import dialog
|
||||||
|
gchar *filename;
|
||||||
|
GList *filters;
|
||||||
|
GtkFileFilter *filter;
|
||||||
|
filters = NULL;
|
||||||
|
filter = gtk_file_filter_new ();
|
||||||
|
gtk_file_filter_set_name (filter, "comma separated values (*.csv)");
|
||||||
|
gtk_file_filter_add_pattern (filter, "*.csv");
|
||||||
|
filters = g_list_append( filters, filter );
|
||||||
|
filter = gtk_file_filter_new ();
|
||||||
|
gtk_file_filter_set_name (filter, "text files (*.txt)");
|
||||||
|
gtk_file_filter_add_pattern (filter, "*.txt");
|
||||||
|
filters = g_list_append( filters, filter );
|
||||||
|
filename = gnc_file_dialog(_("Import Bills or Invoices from csv"), filters, NULL, GNC_FILE_DIALOG_IMPORT);
|
||||||
|
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gnc_bi_import_gui_ok_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
gchar *filename = g_strdup( gtk_entry_get_text( GTK_ENTRY(gui->entryFilename) ) );
|
||||||
|
bi_import_stats stats;
|
||||||
|
bi_import_result res;
|
||||||
|
guint n_fixed, n_deleted, n_invoices_created, n_invoices_updated;
|
||||||
|
GString *info;
|
||||||
|
|
||||||
|
// import
|
||||||
|
info = g_string_new("");
|
||||||
|
|
||||||
|
gtk_list_store_clear (gui->store);
|
||||||
|
res = gnc_bi_import_read_file (filename, gui->regexp->str, gui->store, 0, &stats);
|
||||||
|
if (res == RESULT_OK) {
|
||||||
|
gnc_bi_import_fix_bis (gui->store, &n_fixed, &n_deleted, info);
|
||||||
|
if (info->len > 0)
|
||||||
|
gnc_info_dialog (gui->dialog, "%s", info->str);
|
||||||
|
g_string_free( info, TRUE );
|
||||||
|
gnc_bi_import_create_bis (gui->store, gui->book, &n_invoices_created, &n_invoices_updated, gui->type);
|
||||||
|
gnc_info_dialog (gui->dialog, _("Import results:\n%i lines were ignored\n%i lines imported:\n %u fixes\n %u ignored (not fixable)\n\n %u created\n %u updated (based on id)"), stats.n_ignored, stats.n_imported, n_fixed, n_deleted, n_invoices_created, n_invoices_updated);
|
||||||
|
|
||||||
|
if (stats.n_ignored > 0)
|
||||||
|
gnc_info2_dialog (gui->dialog, _("These lines were ignored during import"), stats.ignored_lines->str);
|
||||||
|
|
||||||
|
g_string_free (stats.ignored_lines,TRUE);
|
||||||
|
gnc_close_gui_component (gui->component_id);
|
||||||
|
} else
|
||||||
|
if (res == RESULT_OPEN_FAILED) {
|
||||||
|
gnc_error_dialog (gui->dialog, _("The input file can not be opened."));
|
||||||
|
} else
|
||||||
|
if (res == RESULT_ERROR_IN_REGEXP) {
|
||||||
|
//gnc_error_dialog (gui->dialog, "The regular expression is faulty:\n\n%s", stats.err->str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gnc_bi_import_gui_cancel_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
|
||||||
|
gnc_close_gui_component (gui->component_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gnc_bi_import_gui_help_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
gnc_gnome_help(HF_HELP, HL_USAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gnc_bi_import_gui_close_handler (gpointer user_data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = user_data;
|
||||||
|
|
||||||
|
gtk_widget_destroy (gui->dialog);
|
||||||
|
// gui has already been freed by this point.
|
||||||
|
// gui->dialog = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gnc_bi_import_gui_destroy_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
|
||||||
|
gnc_suspend_gui_refresh ();
|
||||||
|
gnc_unregister_gui_component (gui->component_id);
|
||||||
|
gnc_resume_gui_refresh ();
|
||||||
|
|
||||||
|
g_object_unref (gui->store);
|
||||||
|
g_string_free (gui->regexp, TRUE);
|
||||||
|
g_free (gui);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gnc_bi_import_gui_buttonOpen_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
gchar *filename;
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
|
||||||
|
filename = gnc_plugin_bi_import_getFilename();
|
||||||
|
if (filename) {
|
||||||
|
//printf("Setting filename"); // debug
|
||||||
|
gtk_entry_set_text( GTK_ENTRY(gui->entryFilename), filename );
|
||||||
|
//printf("Set filename"); // debug
|
||||||
|
g_free( filename );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gnc_bi_import_gui_filenameChanged_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
gchar *filename = g_strdup( gtk_entry_get_text( GTK_ENTRY(gui->entryFilename) ) );
|
||||||
|
|
||||||
|
// generate preview
|
||||||
|
gtk_list_store_clear (gui->store);
|
||||||
|
gnc_bi_import_read_file (filename, gui->regexp->str, gui->store, 10, NULL);
|
||||||
|
|
||||||
|
g_free( filename );
|
||||||
|
}
|
||||||
|
|
||||||
|
void gnc_bi_import_gui_option1_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
|
||||||
|
return;
|
||||||
|
g_string_assign (gui->regexp, "^(?<id>[^!#+^;]*);(?<date_opened>[^;]*);(?<owner_id>[^;]*);(?<billingid>[^;]*);?(?<notes>[^;]*);?(?<date>[^;]*);?(?<desc>[^;]*);?(?<action>[^;]*);?(?<account>[^;]*);?(?<quantity>[^;]*);?(?<price>[^;]*);?(?<disc_type>[^;]*);?(?<disc_how>[^;]*);?(?<discount>[^;]*);?(?<taxable>[^;]*);?(?<taxincluded>[^;]*);?(?<tax_table>[^;]*);(?<date_posted>[^;]*);(?<due_date>[^;]*);(?<account_posted>[^;]*);(?<memo_posted>[^;]*);(?<accu_splits>[^;]*)");
|
||||||
|
gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
|
||||||
|
}
|
||||||
|
void gnc_bi_import_gui_option2_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
|
||||||
|
return;
|
||||||
|
g_string_assign (gui->regexp, "^(?<id>[^!#+^,]*),(?<date_opened>[^,]*),(?<owner_id>[^,]*),(?<billingid>[^,]*),?(?<notes>[^,]*),?(?<date>[^,]*),?(?<desc>[^,]*),?(?<action>[^,]*),?(?<account>[^,]*),?(?<quantity>[^,]*),?(?<price>[^,]*),?(?<disc_type>[^,]*),?(?<disc_how>[^,]*),?(?<discount>[^,]*),?(?<taxable>[^,]*),?(?<taxincluded>[^,]*),?(?<tax_table>[^,]*),(?<date_posted>[^,]*),(?<due_date>[^,]*),(?<account_posted>[^,]*),(?<memo_posted>[^,]*),(?<accu_splits>[^,]*)");
|
||||||
|
gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
|
||||||
|
}
|
||||||
|
void gnc_bi_import_gui_option3_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
|
||||||
|
return;
|
||||||
|
g_string_assign (gui->regexp, "^(?<id>[^!#+^;]*);(?<date_opened>[^;]*);(?<owner_id>[^;]*);(?<billingid>[^;]*);?(?<notes>[^;]*);?(?<date>[^;]*);?(?<desc>[^;]*);?(?<action>[^;]*);?(?<account>[^;]*);?(?<quantity>[^;]*);?(?<price>[^;]*);?(?<disc_type>[^;]*);?(?<disc_how>[^;]*);?(?<discount>[^;]*);?(?<taxable>[^;]*);?(?<taxincluded>[^;]*);?(?<tax_table>[^;]*);(?<date_posted>[^;]*);(?<due_date>[^;]*);(?<account_posted>[^;]*);(?<memo_posted>[^;]*);(?<accu_splits>[^;]*)");
|
||||||
|
gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
|
||||||
|
}
|
||||||
|
void gnc_bi_import_gui_option4_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
|
||||||
|
return;
|
||||||
|
g_string_assign (gui->regexp, "^(?<id>[^!#+^;]*);(?<date_opened>[^;]*);(?<owner_id>[^;]*);(?<billingid>[^;]*);?(?<notes>[^;]*);?(?<date>[^;]*);?(?<desc>[^;]*);?(?<action>[^;]*);?(?<account>[^;]*);?(?<quantity>[^;]*);?(?<price>[^;]*);?(?<disc_type>[^;]*);?(?<disc_how>[^;]*);?(?<discount>[^;]*);?(?<taxable>[^;]*);?(?<taxincluded>[^;]*);?(?<tax_table>[^;]*);(?<date_posted>[^;]*);(?<due_date>[^;]*);(?<account_posted>[^;]*);(?<memo_posted>[^;]*);(?<accu_splits>[^;]*)");
|
||||||
|
gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
|
||||||
|
}
|
||||||
|
void gnc_bi_import_gui_option5_cb (GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
gchar *temp;
|
||||||
|
if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
|
||||||
|
return;
|
||||||
|
temp = gnc_input_dialog (0, _("Adjust regular expression used for import"), _("This regular expression is used to parse the import file. Modify according to your needs.\n"), gui->regexp->str);
|
||||||
|
if (temp) {
|
||||||
|
g_string_assign (gui->regexp,temp);
|
||||||
|
g_free (temp);
|
||||||
|
gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*****************************************************************
|
||||||
|
* Set whether we are importing a bi, invoice, Customer or Vendor
|
||||||
|
* ****************************************************************/
|
||||||
|
|
||||||
|
void gnc_import_gui_type(GtkWidget *widget, gpointer data)
|
||||||
|
{
|
||||||
|
BillImportGui *gui = data;
|
||||||
|
if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
|
||||||
|
return;
|
||||||
|
if (g_ascii_strcasecmp(widget->name,"radiobuttonInvoice") == 0)gui->type="INVOICE";
|
||||||
|
else if (g_ascii_strcasecmp(widget->name,"radiobuttonBill") == 0)gui->type="BILL";
|
||||||
|
//printf ("TYPE set to, %s\n",gui->type);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
* gnc_input_dialog *
|
||||||
|
* simple convenience dialog to get a single value from the user *
|
||||||
|
* user may choose between "Ok" and "Cancel" *
|
||||||
|
* *
|
||||||
|
* NOTE: This function does not return until the dialog is closed *
|
||||||
|
* *
|
||||||
|
* Args: parent - the parent window or NULL *
|
||||||
|
* title - the title of the dialog *
|
||||||
|
* msg - the message to display *
|
||||||
|
* default_input - will be displayed as default input *
|
||||||
|
* Return: the input (text) the user entered, if pressed "Ok" *
|
||||||
|
* NULL, if pressed "Cancel" *
|
||||||
|
\********************************************************************/
|
||||||
|
static gchar *
|
||||||
|
gnc_input_dialog (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input)
|
||||||
|
{
|
||||||
|
GtkWidget *dialog, *label, *content_area;
|
||||||
|
gint result;
|
||||||
|
GtkWidget *view;
|
||||||
|
GtkTextBuffer *buffer;
|
||||||
|
gchar *user_input;
|
||||||
|
GtkTextIter start, end;
|
||||||
|
|
||||||
|
/* Create the widgets */
|
||||||
|
dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
|
||||||
|
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
|
||||||
|
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
|
||||||
|
NULL);
|
||||||
|
#ifdef HAVE_GTK_2_14
|
||||||
|
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||||
|
#else
|
||||||
|
content_area = GTK_DIALOG (dialog)->vbox;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// add a label
|
||||||
|
label = gtk_label_new (msg);
|
||||||
|
gtk_container_add (GTK_CONTAINER (content_area), label);
|
||||||
|
|
||||||
|
// add a textview
|
||||||
|
view = gtk_text_view_new ();
|
||||||
|
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD_CHAR);
|
||||||
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||||
|
gtk_text_buffer_set_text (buffer, default_input, -1);
|
||||||
|
gtk_container_add (GTK_CONTAINER (content_area), view);
|
||||||
|
|
||||||
|
// run the dialog
|
||||||
|
gtk_widget_show_all (dialog);
|
||||||
|
result = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||||
|
|
||||||
|
if (result == GTK_RESPONSE_REJECT)
|
||||||
|
user_input = 0;
|
||||||
|
else {
|
||||||
|
gtk_text_buffer_get_start_iter (buffer, &start);
|
||||||
|
gtk_text_buffer_get_end_iter (buffer, &end);
|
||||||
|
user_input = gtk_text_buffer_get_text (buffer,
|
||||||
|
&start, &end, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy (dialog);
|
||||||
|
|
||||||
|
return user_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
* gnc_info2_dialog *
|
||||||
|
* displays an information dialog box (with scrollable text area) *
|
||||||
|
* *
|
||||||
|
* NOTE: This function does not return until the dialog is closed *
|
||||||
|
* *
|
||||||
|
* Args: parent - the parent window or NULL *
|
||||||
|
* title - the title of the dialog *
|
||||||
|
* msg - the message to display *
|
||||||
|
* Return: none *
|
||||||
|
\********************************************************************/
|
||||||
|
static void
|
||||||
|
gnc_info2_dialog (GtkWidget *parent, const gchar *title, const gchar *msg)
|
||||||
|
{
|
||||||
|
GtkWidget *dialog, *scrolledwindow, *content_area;
|
||||||
|
gint result;
|
||||||
|
GtkWidget *view;
|
||||||
|
GtkTextBuffer *buffer;
|
||||||
|
gchar *user_input;
|
||||||
|
GtkTextIter start, end;
|
||||||
|
gint width,height;
|
||||||
|
|
||||||
|
/* Create the widgets */
|
||||||
|
dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parent),
|
||||||
|
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
|
||||||
|
NULL);
|
||||||
|
#ifdef HAVE_GTK_2_14
|
||||||
|
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||||
|
#else
|
||||||
|
content_area = GTK_DIALOG (dialog)->vbox;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// add a scroll area
|
||||||
|
scrolledwindow = gtk_scrolled_window_new (NULL,NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (content_area), scrolledwindow);
|
||||||
|
|
||||||
|
// add a textview
|
||||||
|
view = gtk_text_view_new ();
|
||||||
|
// gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD_CHAR);
|
||||||
|
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
|
||||||
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||||
|
gtk_text_buffer_set_text (buffer, msg, -1);
|
||||||
|
gtk_container_add (GTK_CONTAINER (scrolledwindow), view);
|
||||||
|
|
||||||
|
// run the dialog
|
||||||
|
if (parent) {
|
||||||
|
gtk_window_get_size (GTK_WINDOW(parent), &width, &height);
|
||||||
|
gtk_window_set_default_size (GTK_WINDOW(dialog), width, height);
|
||||||
|
}
|
||||||
|
gtk_widget_show_all (dialog);
|
||||||
|
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||||
|
gtk_widget_destroy (dialog);
|
||||||
|
}
|
48
src/plugins/bi_import/gui.h
Normal file
48
src/plugins/bi_import/gui.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* gui.h --
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup Tools
|
||||||
|
* @{
|
||||||
|
* @file gui.h
|
||||||
|
* @brief GUI handling for bi import plugin
|
||||||
|
* @author Copyright (C) 2009 Sebastian Held <sebastian.held@gmx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GNC_PLUGIN_bi_import_gui_H
|
||||||
|
#define GNC_PLUGIN_bi_import_gui_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _bi_import_gui BillImportGui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File chooser
|
||||||
|
*/
|
||||||
|
BillImportGui *gnc_plugin_bi_import_showGUI(void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* GNC_PLUGIN_bi_import_gui_H */
|
||||||
|
|
||||||
|
/** @} */
|
80
src/plugins/bi_import/helpers.c
Normal file
80
src/plugins/bi_import/helpers.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* helpers.c --
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
//! \brief helper function
|
||||||
|
gboolean text2bool( const gchar *text )
|
||||||
|
{
|
||||||
|
gboolean erg = FALSE;
|
||||||
|
gchar *temp;
|
||||||
|
|
||||||
|
if (!text)
|
||||||
|
return erg;
|
||||||
|
|
||||||
|
temp = g_strdup( text );
|
||||||
|
g_strstrip( temp );
|
||||||
|
if ((g_ascii_strcasecmp( temp, "yes" ) == 0) || (g_ascii_strcasecmp( temp, "true" ) == 0) ||
|
||||||
|
(g_ascii_strcasecmp( temp, "1" ) == 0) || (g_ascii_strcasecmp( temp, "x" ) == 0))
|
||||||
|
erg = TRUE;
|
||||||
|
g_free( temp );
|
||||||
|
return erg;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \brief helper function
|
||||||
|
GncAmountType text2disc_type( const gchar *text )
|
||||||
|
{
|
||||||
|
GncAmountType type = GNC_AMT_TYPE_PERCENT;
|
||||||
|
gchar *temp;
|
||||||
|
|
||||||
|
if (!text)
|
||||||
|
return type;
|
||||||
|
|
||||||
|
temp = g_strdup( text );
|
||||||
|
g_strstrip( temp );
|
||||||
|
if ((strlen(temp) > 0) && (g_ascii_strcasecmp( temp, "%" ) != 0))
|
||||||
|
type = GNC_AMT_TYPE_VALUE;
|
||||||
|
g_free( temp );
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \brief helper function
|
||||||
|
GncDiscountHow text2disc_how( const gchar *text )
|
||||||
|
{
|
||||||
|
GncDiscountHow how = GNC_DISC_PRETAX;
|
||||||
|
gchar *temp;
|
||||||
|
|
||||||
|
if (!text)
|
||||||
|
return how;
|
||||||
|
|
||||||
|
temp = g_strdup( text );
|
||||||
|
g_strstrip( temp );
|
||||||
|
if (g_ascii_strcasecmp( temp, "=" ) == 0)
|
||||||
|
how = GNC_DISC_SAMETIME;
|
||||||
|
else if (g_ascii_strcasecmp( temp, ">" ) == 0)
|
||||||
|
how = GNC_DISC_POSTTAX;
|
||||||
|
g_free( temp );
|
||||||
|
return how;
|
||||||
|
}
|
32
src/plugins/bi_import/helpers.h
Normal file
32
src/plugins/bi_import/helpers.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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 <glib/gi18n.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
#include "gncEntry.h"
|
||||||
|
|
||||||
|
gboolean text2bool( const gchar *text );
|
||||||
|
GncAmountType text2disc_type( const gchar *text );
|
||||||
|
GncDiscountHow text2disc_how( const gchar *text );
|
1
src/plugins/bi_import/regex.txt
Normal file
1
src/plugins/bi_import/regex.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
^[#]*(?<id>[^,]*),(?<date_opened>[^,]*),(?<customer_id>[^,]*),(?<billing_id>[^,]*),?(?<notes>[^,]*),?(?<date>[^,]*),?(?<desc>[^,]*),?(?<action>[^,]*),?(?<account>[^,]*),?(?<quantity>[^,]*),?(?<price>[^,]*),?(?<disc_type>[^,]*),?(?<disc_how>[^,]*),?(?<discount>[^,]*),?(?<taxable>[^,]*),?(?<taxincluded>[^,]*),?(?<tax_table>[^,]*),(?<date_posted>[^,]*),(?<due_date>[^,]*),(?<account_posted>[^,]*),(?<memo_posted>[^,]*),(?<accu_splits>[^,]*)
|
5
src/plugins/bi_import/ui/Makefile.am
Normal file
5
src/plugins/bi_import/ui/Makefile.am
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
uidir = $(GNC_UI_DIR)
|
||||||
|
ui_DATA = \
|
||||||
|
gnc-plugin-bi_import-ui.xml
|
||||||
|
|
||||||
|
EXTRA_DIST = $(ui_DATA)
|
13
src/plugins/bi_import/ui/gnc-plugin-bi_import-ui.xml
Normal file
13
src/plugins/bi_import/ui/gnc-plugin-bi_import-ui.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<ui>
|
||||||
|
<menubar>
|
||||||
|
<placeholder name="AdditionalMenusPlaceholder">
|
||||||
|
<menu name="Business" action="BusinessAction">
|
||||||
|
<placeholder name="BusinessPlaceholderBottom">
|
||||||
|
<menu name="ImportMenu" action="ImportMenuAction">
|
||||||
|
<menuitem name="bi_import" action="bi_importAction"/>
|
||||||
|
</menu>
|
||||||
|
</placeholder>
|
||||||
|
</menu>
|
||||||
|
</placeholder>
|
||||||
|
</menubar>
|
||||||
|
</ui>
|
Loading…
Reference in New Issue
Block a user