Merge Roy Hansen's 'invoice-overview' into future.

This commit is contained in:
John Ralls committed 2026-10-20 14:13:05 -07:00
commit b9e70db1ce
19 files changed
+3452 -23

No files matched your search

+1
View File
@@ -72,6 +72,7 @@ set(gnucash_GRESOURCES
ui/gnc-plugin-page-account-tree.ui
ui/gnc-plugin-page-budget.ui
ui/gnc-plugin-page-invoice.ui
ui/gnc-plugin-page-invoices-owner.ui
ui/gnc-plugin-page-owner-tree.ui
ui/gnc-plugin-page-register.ui
ui/gnc-plugin-page-report.ui
+2
View File
@@ -46,6 +46,7 @@ set (gnome_utils_SOURCES
dialog-transfer.cpp
dialog-userpass.c
dialog-utils.c
dialog-filter-invoices.cpp
gnc-account-sel.c
gnc-amount-edit.c
gnc-autosave.c
@@ -133,6 +134,7 @@ set (gnome_utils_HEADERS
dialog-totd.h
dialog-transfer.h
dialog-utils.h
dialog-filter-invoices.h
gnc-account-sel.h
gnc-amount-edit.h
gnc-cell-renderer-label.h
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,51 @@
/*
* dialog-filter-invoices.h -- Filter dialog for invoices
* Copyright (C) 2026 Roy Hansen
* Author: Roy Hansen <roy@royhansen.no>
*
* 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, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef GNC_FILTER_INVOICES_DIALOG_H_
#define GNC_FILTER_INVOICES_DIALOG_H_
#include <memory>
#include <functional>
#include "gnc-plugin.h"
class GncFilterInvoicesDialogInternal;
class GncFilterInvoicesDialog {
std::unique_ptr<GncFilterInvoicesDialogInternal> m_filter;
public:
enum OwnerType {
TYPE_CUSTOMER,
TYPE_VENDOR,
TYPE_EMPLOYEE
};
GncFilterInvoicesDialog (GncPluginPage &plugin_page,
OwnerType owner_type,
std::function<void()> apply_cb);
~GncFilterInvoicesDialog ();
void dialog_open ();
QofQuery *create_qof_query (bool empty = false);
};
#endif /* GNC_FILTER_INVOICES_DIALOG_H_ */
+8
View File
@@ -23,6 +23,10 @@
#ifndef _GNCSEARCH_PARAM_H
#define _GNCSEARCH_PARAM_H
#ifdef __cplusplus
extern "C"
{
#endif
#define GNC_TYPE_SEARCH_PARAM (gnc_search_param_get_type ())
G_DECLARE_DERIVABLE_TYPE (GNCSearchParam, gnc_search_param, GNC, SEARCH_PARAM, GObject)
@@ -133,4 +137,8 @@ gboolean gnc_search_param_has_param_fcn (GNCSearchParamSimple *param);
gpointer gnc_search_param_compute_value (GNCSearchParamSimple *param,
gpointer object);
#ifdef __cplusplus
}
#endif
#endif /* _GNCSEARCH_PARAM_H */
+2
View File
@@ -52,6 +52,7 @@ set (gnc_gnome_noinst_HEADERS
gnc-plugin-page-report.h
gnc-plugin-page-sx-list.h
gnc-plugin-page-tracelog.h
gnc-plugin-page-invoices-owner.h
gnc-split-reg.h
reconcile-view.h
search-owner.h
@@ -122,6 +123,7 @@ set (gnc_gnome_SOURCES
gnc-plugin-page-report.cpp
gnc-plugin-page-sx-list.cpp
gnc-plugin-page-tracelog.cpp
gnc-plugin-page-invoices-owner.cpp
gnc-split-reg.c
reconcile-view.c
search-owner.c
+5 -10
View File
@@ -836,13 +836,8 @@ combo_changed_cb (GtkComboBox *widget, gpointer user_data)
g_source_remove_by_user_data (user_data);
}
/* This function will return the selected invoice report guid if
* the countdown times out or a selection is made and OK pressed.
*
* If cancel is pressed then it will return NULL
*/
static char*
use_default_report_template_or_change (GtkWindow *parent)
char*
gnc_invoice_window_use_default_report_template_or_change (GtkWindow *parent)
{
QofBook *book = gnc_get_current_book ();
GtkWidget *combo;
@@ -940,7 +935,7 @@ use_default_report_template_or_change (GtkWindow *parent)
return ret_guid;
}
static GncPluginPage *
GncPluginPage *
gnc_invoice_window_print_invoice (GtkWindow *parent, GncInvoice *invoice,
const gchar *report_guid)
{
@@ -1006,7 +1001,7 @@ gnc_invoice_window_printCB (GtkWindow* parent, gpointer data)
gnc_plugin_page_report_reload (GNC_PLUGIN_PAGE_REPORT (iw->reportPage));
else
{
gchar *report_guid = use_default_report_template_or_change (parent);
gchar *report_guid = gnc_invoice_window_use_default_report_template_or_change (parent);
if (!report_guid)
return;
@@ -3466,7 +3461,7 @@ multi_print_invoice_cb (GtkWindow *dialog, GList *invoice_list, gpointer user_da
if (!gnc_list_length_cmp (invoice_list, 0))
return;
report_guid = use_default_report_template_or_change (dialog);
report_guid = gnc_invoice_window_use_default_report_template_or_change (dialog);
if (!report_guid)
return;
+23
View File
@@ -34,6 +34,7 @@ typedef struct _invoice_window InvoiceWindow;
#include "gncOwner.h"
#include "dialog-search.h"
#include "dialog-query-view.h"
#include "gnc-plugin-page.h"
#ifdef __cplusplus
extern "C"
@@ -127,6 +128,28 @@ void gnc_invoice_window_duplicateCB (GtkWidget *widget, gpointer data);
void gnc_invoice_window_payment_cb (GtkWindow *parent, gpointer data);
void gnc_invoice_window_report_owner_cb (GtkWindow *parent, gpointer data);
/**
* Open av new tab displaying a printed view
* of the specified invoice.
*
* @param parent Parent window.
* @param invoice The invoice to be displayed.
* @param report_guid Report guid.
* @return Plugin page.
*/
GncPluginPage *gnc_invoice_window_print_invoice (GtkWindow *parent, GncInvoice *invoice, const gchar *report_guid);
/**
* This function will return the selected invoice report guid if
* the countdown times out or a selection is made and OK pressed.
*
* If cancel is pressed then it will return NULL
*
* @param parent Parent window.
* @return Invoice report guid or NULL.
*/
char *gnc_invoice_window_use_default_report_template_or_change (GtkWindow *parent);
void gnc_invoice_window_save_document_layout_to_user_state (InvoiceWindow *iw);
void gnc_invoice_window_reset_document_layout_and_clear_user_state (InvoiceWindow *iw);
gboolean gnc_invoice_window_document_has_user_state (InvoiceWindow *iw);
+53
View File
@@ -42,6 +42,7 @@
#include "gnc-plugin-business.h"
#include "gnc-plugin-page-invoice.h"
#include "gnc-plugin-page-owner-tree.h"
#include "gnc-plugin-page-invoices-owner.h"
#include "gncOwner.h"
#include "gnc-ui-util.h"
#include "gnc-date.h"
@@ -68,6 +69,8 @@ static void gnc_plugin_business_add_to_window (GncPlugin *plugin,
/* Command callbacks */
static void gnc_plugin_business_cmd_customer_page (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_customer_invoices_overview_page (
GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_customer_new_customer (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_customer_find_customer (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_customer_new_invoice (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
@@ -77,6 +80,8 @@ static void gnc_plugin_business_cmd_customer_find_job (GSimpleAction *simple, GV
static void gnc_plugin_business_cmd_customer_process_payment (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_vendor_page (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_vendor_bills_overview_page (
GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_vendor_new_vendor (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_vendor_find_vendor (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_vendor_new_bill (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
@@ -86,6 +91,8 @@ static void gnc_plugin_business_cmd_vendor_find_job (GSimpleAction *simple, GVar
static void gnc_plugin_business_cmd_vendor_process_payment (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_employee_page (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_employee_expenses_overview_page (
GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_employee_new_employee (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_employee_find_employee (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_employee_new_expense_voucher (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
@@ -103,6 +110,9 @@ static void gnc_plugin_business_cmd_test_init_data (GSimpleAction *simple, GVari
static void gnc_plugin_business_cmd_assign_payment (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
static void gnc_plugin_business_cmd_invoices_owner_page (
gpointer user_data, GncOwnerType owner_type);
static void update_inactive_actions (GncPluginPage *page);
static void bind_extra_toolbuttons_visibility (GncMainWindow *mainwindow);
@@ -122,6 +132,7 @@ static GncMainWindow *last_window = NULL;
static GActionEntry gnc_plugin_actions [] =
{
{ "CustomerOverviewPageAction", gnc_plugin_business_cmd_customer_page, NULL, NULL, NULL },
{ "CustomerInvoicesOverviewPageAction", gnc_plugin_business_cmd_customer_invoices_overview_page, NULL, NULL, NULL },
{ "CustomerNewCustomerOpenAction", gnc_plugin_business_cmd_customer_new_customer, NULL, NULL, NULL },
{ "CustomerFindCustomerOpenAction", gnc_plugin_business_cmd_customer_find_customer, NULL, NULL, NULL },
{ "CustomerNewInvoiceOpenAction", gnc_plugin_business_cmd_customer_new_invoice, NULL, NULL, NULL },
@@ -131,6 +142,7 @@ static GActionEntry gnc_plugin_actions [] =
{ "CustomerProcessPaymentAction", gnc_plugin_business_cmd_customer_process_payment, NULL, NULL, NULL },
{ "VendorOverviewPageAction", gnc_plugin_business_cmd_vendor_page, NULL, NULL, NULL },
{ "VendorBillsOverviewPageAction", gnc_plugin_business_cmd_vendor_bills_overview_page, NULL, NULL, NULL },
{ "VendorNewVendorOpenAction", gnc_plugin_business_cmd_vendor_new_vendor, NULL, NULL, NULL },
{ "VendorFindVendorOpenAction", gnc_plugin_business_cmd_vendor_find_vendor, NULL, NULL, NULL },
{ "VendorNewBillOpenAction", gnc_plugin_business_cmd_vendor_new_bill, NULL, NULL, NULL },
@@ -140,6 +152,7 @@ static GActionEntry gnc_plugin_actions [] =
{ "VendorProcessPaymentAction", gnc_plugin_business_cmd_vendor_process_payment, NULL, NULL, NULL },
{ "EmployeeOverviewPageAction", gnc_plugin_business_cmd_employee_page, NULL, NULL, NULL },
{ "EmployeeExpensesOverviewPageAction", gnc_plugin_business_cmd_employee_expenses_overview_page, NULL, NULL, NULL },
{ "EmployeeNewEmployeeOpenAction", gnc_plugin_business_cmd_employee_new_employee, NULL, NULL, NULL },
{ "EmployeeFindEmployeeOpenAction", gnc_plugin_business_cmd_employee_find_employee, NULL, NULL, NULL },
{ "EmployeeNewExpenseVoucherOpenAction", gnc_plugin_business_cmd_employee_new_expense_voucher, NULL, NULL, NULL },
@@ -278,6 +291,30 @@ gnc_plugin_business_cmd_customer_page (GSimpleAction *simple,
gnc_main_window_open_page (mw->window, page);
}
static void
gnc_plugin_business_cmd_customer_invoices_overview_page (GSimpleAction *simple,
GVariant *parameter,
gpointer user_data)
{
gnc_plugin_business_cmd_invoices_owner_page (user_data, GNC_OWNER_CUSTOMER);
}
static void
gnc_plugin_business_cmd_vendor_bills_overview_page (GSimpleAction *simple,
GVariant *parameter,
gpointer user_data)
{
gnc_plugin_business_cmd_invoices_owner_page (user_data, GNC_OWNER_VENDOR);
}
static void
gnc_plugin_business_cmd_employee_expenses_overview_page (GSimpleAction *simple,
GVariant *parameter,
gpointer user_data)
{
gnc_plugin_business_cmd_invoices_owner_page (user_data, GNC_OWNER_EMPLOYEE);
}
static void
gnc_plugin_business_cmd_customer_new_customer (GSimpleAction *simple,
GVariant *parameter,
@@ -735,6 +772,22 @@ gnc_plugin_business_cmd_assign_payment (GSimpleAction *simple,
trans, owner_p);
}
static void
gnc_plugin_business_cmd_invoices_owner_page (gpointer user_data,
GncOwnerType owner_type)
{
GncMainWindowActionData *mw = user_data;
g_return_if_fail (mw != NULL);
g_return_if_fail (GNC_IS_PLUGIN_BUSINESS (mw->data));
GncPluginPage *page = gnc_plugin_page_invoices_owner_new (owner_type);
g_return_if_fail (page);
gnc_main_window_open_page (mw->window, page);
}
static const gchar *register_txn_actions[] =
{
"RegisterAssignPayment",
@@ -0,0 +1,783 @@
/*
* plugin-page-invoices-owner.cpp -- Page for Invoices Overview
* Copyright (C) 2026 Roy Hansen
* Author: Roy Hansen <roy@royhansen.no>
*
* 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, see
* <https://www.gnu.org/licenses/>.
*/
#include <memory>
#include <string>
#include <iterator>
#include <config.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include "gnc-ui-util.h"
#include "gnc-query-view.h"
#include "dialog-utils.h"
#include <gnc-date-edit.h>
#include "dialog-invoice.h"
#include "search-param.h"
#include "gnc-icons.h"
#include "gnc-plugin.h"
#include "gnc-plugin-page-invoices-owner.h"
#include "gnc-gobject-utils.h"
#include "dialog-filter-invoices.h"
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = GNC_MOD_GUI;
static const char * const PLUGIN_NAME = "GncPluginPageInvoicesOwner";
static const char * const PLUGIN_ACTIONS_NAME = "GncPluginInvoicesOwnerActions";
static const char * const UI_FILE = "gnc-plugin-page-invoices-owner.ui";
namespace { // Isolate class-scope to this file.
class Page;
}
struct GncPluginPageInvoicesOwnerPrivate
{
Page *m_page = nullptr;
GncFilterInvoicesDialog::OwnerType m_owner_type;
};
G_DEFINE_TYPE_WITH_PRIVATE (GncPluginPageInvoicesOwner,
gnc_plugin_page_invoices_owner,
GNC_TYPE_PLUGIN_PAGE)
#define GNC_PLUGIN_PAGE_INVOICES_OWNER_GET_PRIVATE(o) \
((GncPluginPageInvoicesOwnerPrivate*) \
gnc_plugin_page_invoices_owner_get_instance_private ( \
(GncPluginPageInvoicesOwner*)o))
/************************************************************/
/* Helpers */
/************************************************************/
static GncPluginPageInvoicesOwnerPrivate *
get_private (GncPluginPage *plugin_page)
{
g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_INVOICES_OWNER (plugin_page),
nullptr);
return GNC_PLUGIN_PAGE_INVOICES_OWNER_GET_PRIVATE (
GNC_PLUGIN_PAGE_INVOICES_OWNER (plugin_page));
}
static GncPluginPageInvoicesOwnerPrivate *
get_private (GncPluginPageInvoicesOwner *plugin_page)
{
g_return_val_if_fail (GNC_IS_PLUGIN_PAGE_INVOICES_OWNER (plugin_page),
nullptr);
return GNC_PLUGIN_PAGE_INVOICES_OWNER_GET_PRIVATE (plugin_page);
}
static Page *
get_page (GncPluginPage *plugin_page)
{
auto *priv = get_private (plugin_page);
g_return_val_if_fail (priv, nullptr);
return priv->m_page;
}
static Page *
get_page (gpointer user_data)
{
auto *plugin_page = GNC_PLUGIN_PAGE (user_data);
g_return_val_if_fail (plugin_page, nullptr);
return get_page (plugin_page);
}
namespace { // Isolate class-scope to this file.
/************************************************************/
/* Forward-declare Command callbacks */
/************************************************************/
static void action_new_invoice (GSimpleAction *simple, GVariant *parameter,
gpointer user_data);
static void action_edit_invoice (GSimpleAction *simple, GVariant *parameter,
gpointer user_data);
static void action_duplicate_invoice (GSimpleAction *simple,
GVariant *parameter,
gpointer user_data);
static void action_print_invoice (GSimpleAction *simple, GVariant *parameter,
gpointer user_data);
static void action_open_filter_dialog (GSimpleAction *simple,
GVariant *parameter,
gpointer user_data);
/************************************************************/
/* Page Class */
/************************************************************/
class Page {
public:
GncPluginPageInvoicesOwner *m_plugin_page = nullptr;
private:
GncFilterInvoicesDialog::OwnerType m_owner_type;
std::unique_ptr<GncFilterInvoicesDialog> m_filter;
GtkWidget *m_query_view = nullptr; // Managed/freed by gtk
GList *m_columns = nullptr;
static constexpr GActionEntry k_plugin_actions [] = {
{ "NewInvoice", action_new_invoice, nullptr, nullptr, nullptr },
{ "EditInvoice", action_edit_invoice, nullptr, nullptr, nullptr },
{ "DuplicateInvoice", action_duplicate_invoice, nullptr, nullptr,
nullptr },
{ "PrintInvoice", action_print_invoice, nullptr, nullptr, nullptr },
{ "OpenFilterBy", action_open_filter_dialog, nullptr, nullptr,
nullptr }};
static constexpr guint k_plugin_n_actions = std::size(k_plugin_actions);
GncInvoice *get_selected ();
void create_table_columns ();
void setup_actions ();
public:
Page (GncPluginPageInvoicesOwner &p,
GncFilterInvoicesDialog::OwnerType owner);
~Page ()
{
gnc_plugin_page_disconnect_page_changed (
GNC_PLUGIN_PAGE (m_plugin_page));
g_list_free (m_columns);
}
GtkWindow *get_window ();
GtkWidget *create_widget ();
void double_click_entry (gpointer item);
void
button_press (GdkEventButton *event)
{
gnc_main_window_button_press_cb (m_query_view, event,
GNC_PLUGIN_PAGE (m_plugin_page));
}
void selection_changed ();
void focus_page ();
void new_invoice ();
void edit_invoice ();
void duplicate_invoice ();
void print_invoice ();
void apply_filter ();
void open_filter_dialog ();
};
/************************************************************/
/* Command callbacks */
/************************************************************/
static void
action_new_invoice (GSimpleAction *simple, GVariant *parameter,
gpointer user_data)
{
auto *page = get_page (user_data);
g_return_if_fail (page);
page->new_invoice ();
}
static void
action_edit_invoice (GSimpleAction *simple, GVariant *parameter,
gpointer user_data)
{
auto *page = get_page (user_data);
g_return_if_fail (page);
page->edit_invoice ();
}
static void
action_duplicate_invoice (GSimpleAction *simple, GVariant *parameter,
gpointer user_data)
{
auto *page = get_page (user_data);
g_return_if_fail (page);
page->duplicate_invoice ();
}
static void
action_print_invoice (GSimpleAction *simple, GVariant *parameter,
gpointer user_data)
{
auto *page = get_page (user_data);
g_return_if_fail (page);
page->print_invoice ();
}
static void
action_open_filter_dialog (GSimpleAction *simple, GVariant *parameter,
gpointer user_data)
{
auto *page = get_page (user_data);
g_return_if_fail (page);
page->open_filter_dialog ();
}
static void
action_double_click_entry (GNCQueryView *qview, gpointer item,
gpointer user_data)
{
auto *page = get_page (user_data);
g_return_if_fail (page);
page->double_click_entry (item);
}
static bool
action_button_press_event (GNCQueryView *qview, GdkEventButton *event,
gpointer user_data)
{
auto *page = get_page (user_data);
g_return_val_if_fail (page, false);
page->button_press (event);
return false;
}
static void
action_selection_changed (GtkTreeSelection *selection, gpointer user_data)
{
auto *page = get_page (user_data);
g_return_if_fail (page);
page->selection_changed ();
}
/************************************************************/
/* Page callbacks */
/************************************************************/
static GtkWidget *
page_create_widget (GncPluginPage *plugin_page)
{
auto *page = get_page (plugin_page);
g_return_val_if_fail (page, nullptr);
return page->create_widget ();
}
static void
page_destroy_widget (GncPluginPage *plugin_page)
{
auto *priv = get_private (plugin_page);
g_return_if_fail (priv);
delete priv->m_page;
priv->m_page = nullptr;
}
static gboolean
page_focus_function (GncPluginPage *plugin_page)
{
auto *page = get_page (plugin_page);
g_return_val_if_fail (page, false);
page->focus_page ();
return false;
}
/************************************************************/
/* Implementation */
/************************************************************/
GncInvoice *
Page::get_selected ()
{
auto *qv = GNC_QUERY_VIEW (m_query_view);
g_return_val_if_fail(qv, nullptr);
gpointer selected_entry = gnc_query_view_get_selected_entry (qv);
if (!selected_entry)
return nullptr;
auto *invoice = GNC_INVOICE (selected_entry);
g_return_val_if_fail(invoice, nullptr);
return invoice;
}
void
Page::create_table_columns ()
{
QofIdType type = GNC_INVOICE_MODULE_NAME;
const char *id_name;
switch (m_owner_type)
{
case GncFilterInvoicesDialog::TYPE_CUSTOMER:
id_name = _("Invoice ID");
break;
case GncFilterInvoicesDialog::TYPE_VENDOR:
id_name = _("Bill ID");
break;
case GncFilterInvoicesDialog::TYPE_EMPLOYEE:
id_name = _("Voucher ID");
break;
}
const char *owner_name =
m_owner_type == GncFilterInvoicesDialog::TYPE_EMPLOYEE ?
_("Employee") : _("Company");
m_columns = gnc_search_param_prepend (m_columns, _("Job"),
nullptr,
type,
INVOICE_OWNER,
OWNER_JOB,
JOB_NAME,
nullptr);
m_columns = gnc_search_param_prepend (m_columns, _("Billing ID"),
nullptr,
type,
INVOICE_BILLINGID,
nullptr);
m_columns = gnc_search_param_prepend (m_columns, _("Due"),
nullptr,
type,
INVOICE_DUE,
nullptr);
m_columns = gnc_search_param_prepend (m_columns, _("Paid"),
nullptr,
type,
INVOICE_IS_PAID,
nullptr);
m_columns = gnc_search_param_prepend (m_columns, _("Posted"),
nullptr,
type,
INVOICE_POSTED,
nullptr);
m_columns = gnc_search_param_prepend (m_columns, owner_name,
nullptr,
type,
INVOICE_OWNER,
OWNER_PARENT,
OWNER_NAME,
nullptr);
m_columns = gnc_search_param_prepend (m_columns, _("Total"),
nullptr,
type,
INVOICE_TOTAL,
nullptr);
m_columns = gnc_search_param_prepend (m_columns, _("Type"),
nullptr,
type,
INVOICE_TYPE_STRING,
nullptr);
m_columns = gnc_search_param_prepend (m_columns, id_name,
nullptr, type,
INVOICE_ID,
nullptr);
}
void
Page::setup_actions ()
{
switch (m_owner_type)
{
case GncFilterInvoicesDialog::TYPE_CUSTOMER:
gnc_plugin_page_set_menu_qualifier(
GNC_PLUGIN_PAGE (m_plugin_page), "c");
break;
case GncFilterInvoicesDialog::TYPE_VENDOR:
gnc_plugin_page_set_menu_qualifier(
GNC_PLUGIN_PAGE (m_plugin_page), "v");
break;
case GncFilterInvoicesDialog::TYPE_EMPLOYEE:
gnc_plugin_page_set_menu_qualifier(
GNC_PLUGIN_PAGE (m_plugin_page), "e");
break;
}
GSimpleActionGroup *simple_action_group;
simple_action_group = gnc_plugin_page_create_action_group (
GNC_PLUGIN_PAGE (m_plugin_page), PLUGIN_ACTIONS_NAME);
g_action_map_add_action_entries (G_ACTION_MAP (simple_action_group),
k_plugin_actions, k_plugin_n_actions,
m_plugin_page);
}
Page::Page (GncPluginPageInvoicesOwner &p,
GncFilterInvoicesDialog::OwnerType owner) : m_plugin_page (&p),
m_owner_type (owner)
{
const char *title;
switch (m_owner_type)
{
case GncFilterInvoicesDialog::TYPE_CUSTOMER:
title = _("Invoices");
break;
case GncFilterInvoicesDialog::TYPE_VENDOR:
title = _("Bills");
break;
case GncFilterInvoicesDialog::TYPE_EMPLOYEE:
title = _("Expense Vouchers");
break;
}
g_object_set (G_OBJECT (m_plugin_page), "page-name", title,
"ui-description", UI_FILE,
nullptr);
m_filter = std::make_unique<GncFilterInvoicesDialog> (
*GNC_PLUGIN_PAGE (m_plugin_page), m_owner_type,
[this]() {
this->apply_filter();
});
gnc_plugin_page_add_book (
GNC_PLUGIN_PAGE (m_plugin_page), gnc_get_current_book());
setup_actions ();
}
GtkWindow *
Page::get_window ()
{
auto *window =
GTK_WINDOW (gnc_plugin_page_get_window (
GNC_PLUGIN_PAGE (m_plugin_page)));
g_return_val_if_fail (window, nullptr);
return window;
}
GtkWidget *
Page::create_widget ()
{
ENTER ("page %p", m_plugin_page);
create_table_columns ();
// We initialize with an empty query because we dont
// want the query to delay initial page creation.
// We defer the actual query-creation to page-focus.
auto *empty_query = m_filter->create_qof_query (true);
g_return_val_if_fail (empty_query, nullptr);
m_query_view = gnc_query_view_new (m_columns, empty_query);
qof_query_destroy (empty_query);
auto *qview = GNC_QUERY_VIEW (m_query_view);
g_signal_connect (qview, "double_click_entry",
G_CALLBACK(action_double_click_entry),
m_plugin_page);
g_signal_connect (qview, "button-press-event",
G_CALLBACK (action_button_press_event),
m_plugin_page);
g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(qview)),
"changed", G_CALLBACK(action_selection_changed),
m_plugin_page);
auto *container = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
gtk_widget_set_name (GTK_WIDGET (container), "gnc-id-invoices-owner-page");
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (container),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
auto *scrolled = gtk_scrolled_window_new (nullptr, nullptr);
gtk_container_add (GTK_CONTAINER (scrolled), m_query_view);
gtk_box_pack_start(GTK_BOX (container), scrolled, true, true, 0);
gtk_widget_show_all (container);
g_signal_connect (G_OBJECT (m_plugin_page), "inserted",
G_CALLBACK (gnc_plugin_page_inserted_cb),
nullptr);
selection_changed ();
LEAVE ("");
return container;
}
void
Page::double_click_entry (gpointer item)
{
auto *invoice = GNC_INVOICE (item);
if (!invoice)
return;
auto *window = get_window ();
g_return_if_fail (window);
gnc_ui_invoice_edit (window, invoice);
}
void
Page::selection_changed ()
{
static const gchar *actions_requiring_owner_always[] =
{"EditInvoice", "DuplicateInvoice", "PrintInvoice", NULL};
bool has_selection = get_selected () != nullptr;
GSimpleActionGroup *simple_action_group =
gnc_plugin_page_get_action_group (GNC_PLUGIN_PAGE (m_plugin_page));
gnc_plugin_set_actions_enabled (G_ACTION_MAP(simple_action_group),
actions_requiring_owner_always,
has_selection);
}
void
Page::focus_page ()
{
static const gchar *load_ui [] = {"ViewPlaceholder1", "EditPlaceholder2",
"EditPlaceholder3", nullptr};
auto *window = get_window ();
g_return_if_fail (window);
gnc_main_window_update_menu_and_toolbar (GNC_MAIN_WINDOW (window),
GNC_PLUGIN_PAGE (m_plugin_page),
load_ui);
apply_filter ();
}
void
Page::new_invoice ()
{
GncOwner current_owner;
switch (m_owner_type)
{
case GncFilterInvoicesDialog::TYPE_VENDOR:
gncOwnerInitVendor(&current_owner, gncOwnerGetVendor (nullptr));
break;
case GncFilterInvoicesDialog::TYPE_EMPLOYEE:
gncOwnerInitEmployee(&current_owner, gncOwnerGetEmployee(nullptr));
break;
case GncFilterInvoicesDialog::TYPE_CUSTOMER:
gncOwnerInitCustomer (&current_owner, gncOwnerGetCustomer (nullptr));
}
auto *window = get_window ();
g_return_if_fail (window);
gnc_ui_invoice_new (window, &current_owner, gnc_get_current_book ());
}
void
Page::edit_invoice ()
{
auto *invoice = get_selected ();
if (!invoice)
return;
auto *window = get_window ();
g_return_if_fail (window);
gnc_ui_invoice_edit (window, invoice);
}
void
Page::duplicate_invoice ()
{
auto *invoice = get_selected ();
if (!invoice)
return;
auto *window = get_window ();
g_return_if_fail (window);
gnc_ui_invoice_duplicate (window, invoice, true, nullptr);
}
void
Page::print_invoice ()
{
auto *window = get_window ();
g_return_if_fail (window);
auto *invoice = get_selected ();
if (!invoice)
return;
gchar *report_guid =
gnc_invoice_window_use_default_report_template_or_change (window);
g_return_if_fail (report_guid);
auto *report_page =
gnc_invoice_window_print_invoice (window, invoice, report_guid);
g_free (report_guid);
g_return_if_fail (report_page);
gnc_main_window_open_page (GNC_MAIN_WINDOW (window), report_page);
}
void
Page::apply_filter ()
{
auto *query = m_filter->create_qof_query ();
g_return_if_fail (query);
gnc_query_view_reset_query (GNC_QUERY_VIEW (m_query_view), query);
qof_query_destroy (query);
}
void
Page::open_filter_dialog ()
{
m_filter->dialog_open();
}
} // End namespace
/************************************************************/
/* Plugin page */
/************************************************************/
GncPluginPage *
gnc_plugin_page_invoices_owner_new (GncOwnerType owner_type)
{
ENTER ("");
GncFilterInvoicesDialog::OwnerType owner;
switch (owner_type)
{
case GNC_OWNER_VENDOR:
owner = GncFilterInvoicesDialog::TYPE_VENDOR;
break;
case GNC_OWNER_EMPLOYEE:
owner = GncFilterInvoicesDialog::TYPE_EMPLOYEE;
break;
case GNC_OWNER_CUSTOMER:
owner = GncFilterInvoicesDialog::TYPE_CUSTOMER;
break;
default:
PERR ("Invalid Owner Type");
return nullptr;
}
/* Is there an existing page? */
for (auto *item = gnc_gobject_tracking_get_list (PLUGIN_NAME); item;
item = g_list_next (item))
{
auto *plugin_page =
GNC_PLUGIN_PAGE_INVOICES_OWNER (item->data);
g_return_val_if_fail (plugin_page, nullptr);
auto *priv = get_private (plugin_page);
g_return_val_if_fail (priv, nullptr);
if (priv->m_owner_type != owner)
continue;
LEAVE ("existing page %p", plugin_page);
return GNC_PLUGIN_PAGE (plugin_page);
}
auto *plugin_page = GNC_PLUGIN_PAGE_INVOICES_OWNER (
g_object_new (gnc_plugin_page_invoices_owner_get_type (), nullptr));
g_return_val_if_fail (plugin_page, nullptr);
auto *priv = get_private (plugin_page);
g_return_val_if_fail (priv, nullptr);
priv->m_owner_type = owner;
priv->m_page = new Page(*plugin_page, owner);
LEAVE ("new page %p", plugin_page);
return GNC_PLUGIN_PAGE (plugin_page);
}
static void
gnc_plugin_page_invoices_owner_class_init (
GncPluginPageInvoicesOwnerClass *klass)
{
auto *page_class = GNC_PLUGIN_PAGE_CLASS (klass);
page_class->plugin_name = PLUGIN_NAME;
page_class->tab_icon = GNC_ICON_INVOICE;
page_class->create_widget = page_create_widget;
page_class->destroy_widget = page_destroy_widget;
page_class->focus_page_function = page_focus_function;
}
static void
gnc_plugin_page_invoices_owner_init (GncPluginPageInvoicesOwner *plugin_page)
{
}
@@ -0,0 +1,62 @@
/*
* plugin-page-invoices-owner.h -- Page for Invoices Overview
* Copyright (C) 2026 Roy Hansen
* Author: Roy Hansen <roy@royhansen.no>
*
* 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, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef GNC_PLUGIN_PAGE_INVOICES_OWNER_H_
#define GNC_PLUGIN_PAGE_INVOICES_OWNER_H_
#include "gnc-plugin-page.h"
G_BEGIN_DECLS
#define GNC_TYPE_PLUGIN_PAGE_INVOICES_OWNER ( \
gnc_plugin_page_invoices_owner_get_type ())
#define GNC_PLUGIN_PAGE_INVOICES_OWNER(obj) ( \
G_TYPE_CHECK_INSTANCE_CAST ((obj), \
GNC_TYPE_PLUGIN_PAGE_INVOICES_OWNER, \
GncPluginPageInvoicesOwner))
#define GNC_IS_PLUGIN_PAGE_INVOICES_OWNER(obj) ( \
G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
GNC_TYPE_PLUGIN_PAGE_INVOICES_OWNER))
struct GncPluginPageInvoicesOwner {
GncPluginPage gnc_plugin_page;
};
struct GncPluginPageInvoicesOwnerClass {
GncPluginPageClass gnc_plugin_page;
};
GType gnc_plugin_page_invoices_owner_get_type ();
/**
* Create a new Invoices/Bill/Vouchers page.
* If a page of the requested type is already open, use that instead
* of creating a new one.
*
* @param owner_type The owner type (customer/vendor/employee).
* @return Returns a plugin page.
*/
GncPluginPage *gnc_plugin_page_invoices_owner_new (GncOwnerType owner_type);
G_END_DECLS
#endif /* GNC_PLUGIN_PAGE_INVOICES_OWNER_H_ */
+1
View File
@@ -60,6 +60,7 @@ set (gtkbuilder_SOURCES
gnc-plugin-page-register.glade
gnc-recurrence.glade
gnc-tree-view-owner.glade
dialog-filter-invoices.glade
window-autoclear.glade
window-reconcile.glade
)
@@ -0,0 +1,524 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.4"/>
<object class="GtkDialog" id="invoices-filters">
<property name="can-focus">False</property>
<property name="border-width">6</property>
<property name="title" translatable="yes">Filter By…</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox">
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="label">Presets</property>
<property name="shadow-type">in</property>
<property name="border-width">3</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<property name="border-width">6</property>
<child>
<object class="GtkRadioButton" id="preset-custom">
<property name="visible">True</property>
<property name="label" translatable="yes">Custom</property>
<property name="active">True</property>
</object>
</child>
<child>
<object class="GtkRadioButton" id="preset-overdue">
<property name="visible">True</property>
<property name="label" translatable="yes">Overdue Invoices</property>
<property name="group">preset-custom</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkFrame" id="custom-controls">
<property name="label">Custom</property>
<property name="shadow-type">in</property>
<property name="border-width">3</property>
<property name="visible">true</property>
<child>
<object class="GtkBox" id="dialog-vbox13">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<property name="border-width">6</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="spacing">20</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkCheckButton" id="show-paid">
<property name="label" translatable="yes">Show paid</property>
<property name="width-request">180</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="halign">center</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show-unpaid">
<property name="label" translatable="yes">Show unpaid</property>
<property name="width-request">180</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="halign">center</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkToolbar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkSeparatorToolItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="spacing">20</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkCheckButton" id="show-posted">
<property name="label" translatable="yes">Show posted</property>
<property name="width-request">180</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="halign">center</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show-unposted">
<property name="label" translatable="yes">Show unposted</property>
<property name="width-request">180</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="halign">center</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkToolbar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkSeparatorToolItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="spacing">20</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkCheckButton" id="show-invoices">
<property name="label" translatable="yes">Show Invoices</property>
<property name="width-request">180</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="halign">center</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show-creditnotes">
<property name="label" translatable="yes">Show Credit Notes</property>
<property name="width-request">180</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="halign">center</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkToolbar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkSeparatorToolItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<property name="hexpand">False</property>
<child>
<object class="GtkCheckButton" id="filter-by-start">
<property name="label" translatable="yes">Filter by start date:</property>
<property name="width-request">180</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
<property name="hexpand">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="start_date_box">
<property name="visible">True</property>
<property name="hexpand">False</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<property name="hexpand">False</property>
<child>
<object class="GtkCheckButton" id="filter-by-end">
<property name="label" translatable="yes">Filter by end date:</property>
<property name="width-request">180</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="draw-indicator">True</property>
<property name="hexpand">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="end_date_box">
<property name="visible">True</property>
<property name="hexpand">False</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<property name="hexpand">True</property>
<child>
<object class="GtkButton" id="apply-dates">
<property name="label" translatable="yes">Apply dates</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="halign">end</property>
<property name="valign">start</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkFrame" id="overdue-controls">
<property name="label">Overdue...</property>
<property name="shadow-type">in</property>
<property name="border-width">3</property>
<property name="visible">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<property name="border-width">6</property>
<child>
<object class="GtkRadioButton" id="overdue-days-0">
<property name="visible">True</property>
<property name="label" translatable="yes">0+ days</property>
<property name="active">True</property>
</object>
</child>
<child>
<object class="GtkRadioButton" id="overdue-days-7">
<property name="visible">True</property>
<property name="label" translatable="yes">7+ days</property>
<property name="group">overdue-days-0</property>
</object>
</child>
<child>
<object class="GtkRadioButton" id="overdue-days-14">
<property name="visible">True</property>
<property name="label" translatable="yes">14+ days</property>
<property name="group">overdue-days-0</property>
</object>
</child>
<child>
<object class="GtkRadioButton" id="overdue-days-30">
<property name="visible">True</property>
<property name="label" translatable="yes">30+ days</property>
<property name="group">overdue-days-0</property>
</object>
</child>
<child>
<object class="GtkRadioButton" id="overdue-days-60">
<property name="visible">True</property>
<property name="label" translatable="yes">60+ days</property>
<property name="group">overdue-days-0</property>
</object>
</child>
<child>
<object class="GtkRadioButton" id="overdue-days-90">
<property name="visible">True</property>
<property name="label" translatable="yes">90+ days</property>
<property name="group">overdue-days-0</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkFrame">
<property name="label">Search</property>
<property name="shadow-type">in</property>
<property name="border-width">3</property>
<property name="visible">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<property name="border-width">6</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkEntry" id="search">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="valign">start</property>
<property name="placeholder-text" translatable="yes">Type to search for Invoices...</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<property name="hexpand">True</property>
<child>
<object class="GtkButton" id="apply-search">
<property name="label" translatable="yes">Apply search</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="halign">end</property>
<property name="valign">start</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<property name="spacing">10</property>
<property name="border-width">10</property>
<property name="halign">end</property>
<child>
<object class="GtkButton" id="reset">
<property name="label" translatable="yes">Reset</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="halign">end</property>
<property name="valign">start</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">8</property>
</packing>
</child>
<child>
<object class="GtkButton" id="close">
<property name="label" translatable="yes">Close</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="halign">end</property>
<property name="valign">start</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">8</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
+15
View File
@@ -20,6 +20,11 @@
<attribute name="action">gnc-plugin-business-actions.CustomerFindCustomerOpenAction</attribute>
<attribute name="tooltip" translatable="yes">Open the Find Customer dialog</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Invoices Overview</attribute>
<attribute name="action">gnc-plugin-business-actions.CustomerInvoicesOverviewPageAction</attribute>
<attribute name="tooltip" translatable="yes">Open Invoices overview page</attribute>
</item>
<item>
<attribute name="label" translatable="yes">New _Invoice…</attribute>
<attribute name="action">gnc-plugin-business-actions.CustomerNewInvoiceOpenAction</attribute>
@@ -69,6 +74,11 @@
<attribute name="action">gnc-plugin-business-actions.VendorFindVendorOpenAction</attribute>
<attribute name="tooltip" translatable="yes">Open the Find Vendor dialog</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Bills Overview</attribute>
<attribute name="action">gnc-plugin-business-actions.VendorBillsOverviewPageAction</attribute>
<attribute name="tooltip" translatable="yes">Open Bills overview page</attribute>
</item>
<item>
<attribute name="label" translatable="yes">New _Bill…</attribute>
<attribute name="action">gnc-plugin-business-actions.VendorNewBillOpenAction</attribute>
@@ -118,6 +128,11 @@
<attribute name="action">gnc-plugin-business-actions.EmployeeFindEmployeeOpenAction</attribute>
<attribute name="tooltip" translatable="yes">Open the Find Employee dialog</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Expense vouchers Overview</attribute>
<attribute name="action">gnc-plugin-business-actions.EmployeeExpensesOverviewPageAction</attribute>
<attribute name="tooltip" translatable="yes">Open Expense vouchers overview page</attribute>
</item>
<item>
<attribute name="label" translatable="yes">New _Expense Voucher…</attribute>
<attribute name="action">gnc-plugin-business-actions.EmployeeNewExpenseVoucherOpenAction</attribute>
@@ -0,0 +1,521 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.4"/>
<object class="GtkToolbar" id="mainwin-toolbar-c">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkToolButton" id="but1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Save the current file</property>
<property name="action-name">gnc-plugin-basic-commands-actions.FileSaveAction</property>
<property name="label" translatable="yes">_Save</property>
<property name="use-underline">True</property>
<property name="icon-name">document-save</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but2">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Close the currently active page</property>
<property name="action-name">mainwin.FileCloseAction</property>
<property name="label" translatable="yes">_Close</property>
<property name="use-underline">True</property>
<property name="icon-name">window-close</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkSeparatorToolItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but3">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Create a new Invoice</property>
<property name="action-name">GncPluginInvoicesOwnerActions.NewInvoice</property>
<property name="label" translatable="yes">New</property>
<property name="use-underline">True</property>
<property name="icon-name">gnc-invoice-new</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but4">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Edit the selected Invoice</property>
<property name="action-name">GncPluginInvoicesOwnerActions.EditInvoice</property>
<property name="label" translatable="yes">Edit</property>
<property name="use-underline">True</property>
<property name="icon-name">gnc-invoice-edit</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but5">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Duplicate the selected Invoice</property>
<property name="action-name">GncPluginInvoicesOwnerActions.DuplicateInvoice</property>
<property name="label" translatable="yes">Duplicate</property>
<property name="use-underline">True</property>
<property name="icon-name">gnc-invoice-duplicate</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but6">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Print the selected Invoice</property>
<property name="action-name">GncPluginInvoicesOwnerActions.PrintInvoice</property>
<property name="label" translatable="yes">_Print</property>
<property name="use-underline">True</property>
<property name="icon-name">document-print</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<object class="GtkToolbar" id="mainwin-toolbar-v">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkToolButton" id="but1v">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Save the current file</property>
<property name="action-name">gnc-plugin-basic-commands-actions.FileSaveAction</property>
<property name="label" translatable="yes">_Save</property>
<property name="use-underline">True</property>
<property name="icon-name">document-save</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but2v">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Close the currently active page</property>
<property name="action-name">mainwin.FileCloseAction</property>
<property name="label" translatable="yes">_Close</property>
<property name="use-underline">True</property>
<property name="icon-name">window-close</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkSeparatorToolItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but3v">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Create a new Bill</property>
<property name="action-name">GncPluginInvoicesOwnerActions.NewInvoice</property>
<property name="label" translatable="yes">New</property>
<property name="use-underline">True</property>
<property name="icon-name">gnc-invoice-new</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but4v">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Edit the selected Bill</property>
<property name="action-name">GncPluginInvoicesOwnerActions.EditInvoice</property>
<property name="label" translatable="yes">Edit</property>
<property name="use-underline">True</property>
<property name="icon-name">gnc-invoice-edit</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but5v">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Duplicate the selected Bill</property>
<property name="action-name">GncPluginInvoicesOwnerActions.DuplicateInvoice</property>
<property name="label" translatable="yes">Duplicate</property>
<property name="use-underline">True</property>
<property name="icon-name">gnc-invoice-duplicate</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but6v">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Print the selected Bill</property>
<property name="action-name">GncPluginInvoicesOwnerActions.PrintInvoice</property>
<property name="label" translatable="yes">_Print</property>
<property name="use-underline">True</property>
<property name="icon-name">document-print</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<object class="GtkToolbar" id="mainwin-toolbar-e">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkToolButton" id="but1e">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Save the current file</property>
<property name="action-name">gnc-plugin-basic-commands-actions.FileSaveAction</property>
<property name="label" translatable="yes">_Save</property>
<property name="use-underline">True</property>
<property name="icon-name">document-save</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but2e">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Close the currently active page</property>
<property name="action-name">mainwin.FileCloseAction</property>
<property name="label" translatable="yes">_Close</property>
<property name="use-underline">True</property>
<property name="icon-name">window-close</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkSeparatorToolItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but3e">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Create a new Expense Voucher</property>
<property name="action-name">GncPluginInvoicesOwnerActions.NewInvoice</property>
<property name="label" translatable="yes">New</property>
<property name="use-underline">True</property>
<property name="icon-name">gnc-invoice-new</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but4e">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Edit the selected Expense Voucher</property>
<property name="action-name">GncPluginInvoicesOwnerActions.EditInvoice</property>
<property name="label" translatable="yes">Edit</property>
<property name="use-underline">True</property>
<property name="icon-name">gnc-invoice-edit</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but5e">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Duplicate the selected Expense Voucher</property>
<property name="action-name">GncPluginInvoicesOwnerActions.DuplicateInvoice</property>
<property name="label" translatable="yes">Duplicate</property>
<property name="use-underline">True</property>
<property name="icon-name">gnc-invoice-duplicate</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="but6e">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Print the selected Expense Voucher</property>
<property name="action-name">GncPluginInvoicesOwnerActions.PrintInvoice</property>
<property name="label" translatable="yes">_Print</property>
<property name="use-underline">True</property>
<property name="icon-name">document-print</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<menu id="ViewPlaceholder1">
<item>
<attribute name="label" translatable="yes">_Filter By…</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.OpenFilterBy</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
</menu>
<menu id="EditPlaceholder2-c">
<item>
<attribute name="label" translatable="yes">Edit Invoice</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.EditInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Duplicate Invoice</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.DuplicateInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Print Invoice</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.PrintInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
</menu>
<menu id="EditPlaceholder2-v">
<item>
<attribute name="label" translatable="yes">Edit Bill</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.EditInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Duplicate Bill</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.DuplicateInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Print Bill</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.PrintInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
</menu>
<menu id="EditPlaceholder2-e">
<item>
<attribute name="label" translatable="yes">Edit Expense Voucher</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.EditInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Duplicate Expense Voucher</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.DuplicateInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Print Expense Voucher</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.PrintInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
</menu>
<menu id="EditPlaceholder3-c">
<item>
<attribute name="label" translatable="yes">New Invoice</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.NewInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
</menu>
<menu id="EditPlaceholder3-v">
<item>
<attribute name="label" translatable="yes">New Bill</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.NewInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
</menu>
<menu id="EditPlaceholder3-e">
<item>
<attribute name="label" translatable="yes">New Expense Voucher</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.NewInvoice</attribute>
<attribute name="temp" translatable="no">yes</attribute>
</item>
</menu>
<menu id="mainwin-popup-c">
<section>
<item>
<attribute name="label" translatable="yes">_Filter By…</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.OpenFilterBy</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Re_name Page</attribute>
<attribute name="action">mainwin.ActionsRenamePageAction</attribute>
<attribute name="tooltip" translatable="yes">Rename this page</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Edit</attribute>
<attribute name="tooltip" translatable="yes">Edit the selected Invoice</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.EditInvoice</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Duplicate</attribute>
<attribute name="tooltip" translatable="yes">Duplicate the selected Invoice</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.DuplicateInvoice</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Print</attribute>
<attribute name="tooltip" translatable="yes">Print the selected Invoice</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.PrintInvoice</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">New</attribute>
<attribute name="tooltip" translatable="yes">Create a new Invoice</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.NewInvoice</attribute>
</item>
</section>
</menu>
<menu id="mainwin-popup-v">
<section>
<item>
<attribute name="label" translatable="yes">_Filter By…</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.OpenFilterBy</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Re_name Page</attribute>
<attribute name="action">mainwin.ActionsRenamePageAction</attribute>
<attribute name="tooltip" translatable="yes">Rename this page</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Edit</attribute>
<attribute name="tooltip" translatable="yes">Edit the selected Bill</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.EditInvoice</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Duplicate</attribute>
<attribute name="tooltip" translatable="yes">Duplicate the selected Bill</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.DuplicateInvoice</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Print</attribute>
<attribute name="tooltip" translatable="yes">Print the selected Bill</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.PrintInvoice</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">New</attribute>
<attribute name="tooltip" translatable="yes">Create a new Bill</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.NewInvoice</attribute>
</item>
</section>
</menu>
<menu id="mainwin-popup-e">
<section>
<item>
<attribute name="label" translatable="yes">_Filter By…</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.OpenFilterBy</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Re_name Page</attribute>
<attribute name="action">mainwin.ActionsRenamePageAction</attribute>
<attribute name="tooltip" translatable="yes">Rename this page</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Edit</attribute>
<attribute name="tooltip" translatable="yes">Edit the selected Expense Voucher</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.EditInvoice</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Duplicate</attribute>
<attribute name="tooltip" translatable="yes">Duplicate the selected Expense Voucher</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.DuplicateInvoice</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Print</attribute>
<attribute name="tooltip" translatable="yes">Print the selected Expense Voucher</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.PrintInvoice</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">New</attribute>
<attribute name="tooltip" translatable="yes">Create a new Expense Voucher</attribute>
<attribute name="action">GncPluginInvoicesOwnerActions.NewInvoice</attribute>
</item>
</section>
</menu>
</interface>
+26
View File
@@ -1011,6 +1011,30 @@ gnc_numeric gncInvoiceGetTotal (GncInvoice *invoice)
return gncInvoiceGetTotalInternal (invoice, TRUE, TRUE, FALSE, 0);
}
static gnc_numeric gncInvoiceGetTotalNegatedIfCreditNote(GncInvoice *invoice)
{
if (!invoice)
return gnc_numeric_zero ();
gnc_numeric total = gncInvoiceGetTotalInternal (invoice, TRUE, TRUE, FALSE,
0);
GncInvoiceType type = gncInvoiceGetType (invoice);
switch (type)
{
case GNC_INVOICE_CUST_CREDIT_NOTE:
case GNC_INVOICE_VEND_CREDIT_NOTE:
case GNC_INVOICE_EMPL_CREDIT_NOTE:
total = gnc_numeric_neg (total);
break;
default:
break;
}
return total;
}
gnc_numeric gncInvoiceGetTotalSubtotal (GncInvoice *invoice)
{
if (!invoice) return gnc_numeric_zero ();
@@ -2233,6 +2257,8 @@ gboolean gncInvoiceRegister (void)
{ INVOICE_JOB, GNC_ID_JOB, (QofAccessFunc)qofInvoiceGetJob, (QofSetterFunc)qofInvoiceSetJob },
{ QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncInvoiceGetActive, (QofSetterFunc)gncInvoiceSetActive },
{ INVOICE_IS_CN, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncInvoiceGetIsCreditNote, (QofSetterFunc)gncInvoiceSetIsCreditNote },
{ INVOICE_TOTAL, QOF_TYPE_NUMERIC,
(QofAccessFunc)gncInvoiceGetTotalNegatedIfCreditNote, NULL },
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
{ NULL },
+1
View File
@@ -304,6 +304,7 @@ gboolean gncInvoiceIsPaid (const GncInvoice *invoice);
#define INVOICE_TYPE_STRING "type_string"
#define INVOICE_BILLTO "bill-to"
#define INVOICE_JOB "invoice_job"
#define INVOICE_TOTAL "total"
#define INVOICE_FROM_LOT "invoice-from-lot"
#define INVOICE_FROM_TXN "invoice-from-txn"
+26 -13
View File
@@ -194,11 +194,15 @@ static int
string_compare_func (gpointer a, gpointer b, gint options,
QofParam *getter)
{
const char *s1, *s2;
g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR);
const char *s1 = "", *s2 = "";
s1 = ((query_string_getter)getter->param_getfcn) (a, getter);
s2 = ((query_string_getter)getter->param_getfcn) (b, getter);
g_return_val_if_fail (getter && getter->param_getfcn, COMPARE_ERROR);
if (a)
s1 = ((query_string_getter)getter->param_getfcn) (a, getter);
if (b)
s2 = ((query_string_getter)getter->param_getfcn) (b, getter);
if (options == QOF_STRING_MATCH_CASEINSENSITIVE)
return safe_strcasecmp (s1, s2);
@@ -235,24 +239,33 @@ int
qof_string_number_compare_func (gpointer a, gpointer b, gint options,
QofParam *getter)
{
const char *s1, *s2;
const char *s1 = nullptr, *s2 = nullptr;
char *sr1, *sr2;
long i1, i2;
g_return_val_if_fail (a && b && getter && getter->param_getfcn, COMPARE_ERROR);
s1 = ((query_string_getter)getter->param_getfcn) (a, getter);
s2 = ((query_string_getter)getter->param_getfcn) (b, getter);
g_return_val_if_fail (getter && getter->param_getfcn, COMPARE_ERROR);
if (a)
s1 = ((query_string_getter)getter->param_getfcn) (a, getter);
if (b)
s2 = ((query_string_getter)getter->param_getfcn) (b, getter);
// Deal with nullptr strings
if (s1 == s2) return 0;
if (!s1 && s2) return -1;
if (s1 && !s2) return 1;
if (s1 == s2)
return 0;
if (!s1 && s2)
return -1;
if (s1 && !s2)
return 1;
// Convert to integers and test
i1 = strtol(s1, &sr1, 10);
i2 = strtol(s2, &sr2, 10);
if (i1 < i2) return -1;
if (i1 > i2) return 1;
if (i1 < i2)
return -1;
if (i1 > i2)
return 1;
// If the integers match, then test the REST of the string as text.
if (options == QOF_STRING_MATCH_CASEINSENSITIVE)
+4
View File
@@ -98,6 +98,7 @@ gnucash/gnome/gnc-plugin-business.c
gnucash/gnome/gnc-plugin-page-account-tree.cpp
gnucash/gnome/gnc-plugin-page-budget.cpp
gnucash/gnome/gnc-plugin-page-invoice.cpp
gnucash/gnome/gnc-plugin-page-invoices-owner.cpp
gnucash/gnome/gnc-plugin-page-owner-tree.cpp
gnucash/gnome/gnc-plugin-page-register.cpp
gnucash/gnome/gnc-plugin-page-register-filter.cpp
@@ -138,6 +139,7 @@ gnucash/gnome-utils/dialog-commodity.cpp
gnucash/gnome-utils/dialog-doclink-utils.c
gnucash/gnome-utils/dialog-dup-trans.c
gnucash/gnome-utils/dialog-file-access.c
gnucash/gnome-utils/dialog-filter-invoices.cpp
gnucash/gnome-utils/dialog-object-references.c
gnucash/gnome-utils/dialog-options.cpp
gnucash/gnome-utils/dialog-preferences.c
@@ -259,6 +261,7 @@ gnucash/gtkbuilder/dialog-date-close.glade
gnucash/gtkbuilder/dialog-doclink.glade
gnucash/gtkbuilder/dialog-employee.glade
gnucash/gtkbuilder/dialog-file-access.glade
gnucash/gtkbuilder/dialog-filter-invoices.glade
gnucash/gtkbuilder/dialog-fincalc.glade
gnucash/gtkbuilder/dialog-find-account.glade
gnucash/gtkbuilder/dialog-imap-editor.glade
@@ -524,6 +527,7 @@ gnucash/ui/gnc-plugin-file-history.ui
gnucash/ui/gnc-plugin-log-replay.ui
gnucash/ui/gnc-plugin-page-account-tree.ui
gnucash/ui/gnc-plugin-page-budget.ui
gnucash/ui/gnc-plugin-page-invoices-owner.ui
gnucash/ui/gnc-plugin-page-invoice.ui
gnucash/ui/gnc-plugin-page-owner-tree.ui
gnucash/ui/gnc-plugin-page-register.ui