mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge branch 'maint'
This commit is contained in:
commit
e4ac6b480f
File diff suppressed because it is too large
Load Diff
@ -60,16 +60,16 @@ GType gnc_budget_view_get_type (void);
|
||||
*
|
||||
* @return The newly created widget
|
||||
*/
|
||||
GncBudgetView *gnc_budget_view_new(GncBudget *budget, AccountFilterDialog* fd);
|
||||
void gnc_budget_view_save(GncBudgetView* view, GKeyFile *key_file, const gchar* group_name);
|
||||
void gnc_budget_view_refresh(GncBudgetView* view);
|
||||
void gnc_budget_view_delete_budget(GncBudgetView* view);
|
||||
void gnc_budget_view_save_account_filter(GncBudgetView *view);
|
||||
gboolean gnc_budget_view_restore(GncBudgetView* view, GKeyFile *key_file, const gchar* group_name);
|
||||
GtkTreeSelection* gnc_budget_view_get_selection(GncBudgetView* view);
|
||||
Account* gnc_budget_view_get_account_from_path(GncBudgetView* view, GtkTreePath* path);
|
||||
GList* gnc_budget_view_get_selected_accounts(GncBudgetView* view);
|
||||
GtkWidget *gnc_budget_view_get_account_tree_view (GncBudgetView* view);
|
||||
GncBudgetView *gnc_budget_view_new (GncBudget *budget, AccountFilterDialog* fd);
|
||||
void gnc_budget_view_save (GncBudgetView* budget_view, GKeyFile *key_file, const gchar* group_name);
|
||||
void gnc_budget_view_refresh (GncBudgetView* budget_view);
|
||||
void gnc_budget_view_delete_budget (GncBudgetView* budget_view);
|
||||
void gnc_budget_view_save_account_filter (GncBudgetView *budget_view);
|
||||
gboolean gnc_budget_view_restore (GncBudgetView* budget_view, GKeyFile *key_file, const gchar* group_name);
|
||||
GtkTreeSelection* gnc_budget_view_get_selection (GncBudgetView* budget_view);
|
||||
Account* gnc_budget_view_get_account_from_path (GncBudgetView* budget_view, GtkTreePath* path);
|
||||
GList* gnc_budget_view_get_selected_accounts (GncBudgetView* budget_view);
|
||||
GtkWidget *gnc_budget_view_get_account_tree_view (GncBudgetView* budget_view);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -60,19 +60,19 @@ static GtkActionEntry gnc_plugin_actions [] =
|
||||
{
|
||||
"NewBudgetAction", NULL, N_("New Budget"), NULL,
|
||||
N_("Create a new Budget"),
|
||||
G_CALLBACK (gnc_plugin_budget_cmd_new_budget)
|
||||
G_CALLBACK(gnc_plugin_budget_cmd_new_budget)
|
||||
},
|
||||
|
||||
{
|
||||
"OpenBudgetAction", NULL, N_("Open Budget"), NULL,
|
||||
N_("Open an existing Budget"),
|
||||
G_CALLBACK (gnc_plugin_budget_cmd_open_budget)
|
||||
G_CALLBACK(gnc_plugin_budget_cmd_open_budget)
|
||||
},
|
||||
|
||||
{
|
||||
"CopyBudgetAction", NULL, N_("Copy Budget"), NULL,
|
||||
N_("Copy an existing Budget"),
|
||||
G_CALLBACK (gnc_plugin_budget_cmd_copy_budget)
|
||||
G_CALLBACK(gnc_plugin_budget_cmd_copy_budget)
|
||||
},
|
||||
};
|
||||
static guint gnc_plugin_n_actions = G_N_ELEMENTS (gnc_plugin_actions);
|
||||
@ -83,7 +83,7 @@ typedef struct GncPluginBudgetPrivate
|
||||
} GncPluginBudgetPrivate;
|
||||
|
||||
#define GNC_PLUGIN_BUDGET_GET_PRIVATE(o) \
|
||||
((GncPluginBudgetPrivate*)g_type_instance_get_private((GTypeInstance*)o, GNC_TYPE_PLUGIN_BUDGET))
|
||||
((GncPluginBudgetPrivate*)g_type_instance_get_private ((GTypeInstance*)o, GNC_TYPE_PLUGIN_BUDGET))
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
@ -98,12 +98,13 @@ GncPlugin * gnc_plugin_budget_new (void)
|
||||
|
||||
plugin = g_object_new (GNC_TYPE_PLUGIN_BUDGET, NULL);
|
||||
LEAVE(" ");
|
||||
return GNC_PLUGIN (plugin);
|
||||
return GNC_PLUGIN(plugin);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_budget_main_window_page_changed (GncMainWindow *window,
|
||||
GncPluginPage *plugin_page, gpointer user_data)
|
||||
GncPluginPage *plugin_page,
|
||||
gpointer user_data)
|
||||
{
|
||||
// We continue only if the plugin_page is a valid
|
||||
if (!plugin_page || !GNC_IS_PLUGIN_PAGE(plugin_page))
|
||||
@ -116,9 +117,9 @@ gnc_plugin_budget_main_window_page_changed (GncMainWindow *window,
|
||||
|
||||
// The page changed signal is emitted multiple times so we need
|
||||
// to use an idle_add to change the focus to the tree view
|
||||
g_idle_remove_by_data (GNC_PLUGIN_PAGE_BUDGET (plugin_page));
|
||||
g_idle_remove_by_data (GNC_PLUGIN_PAGE_BUDGET(plugin_page));
|
||||
g_idle_add ((GSourceFunc)gnc_plugin_page_budget_focus,
|
||||
GNC_PLUGIN_PAGE_BUDGET (plugin_page));
|
||||
GNC_PLUGIN_PAGE_BUDGET(plugin_page));
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,8 +128,8 @@ G_DEFINE_TYPE_WITH_PRIVATE(GncPluginBudget, gnc_plugin_budget, GNC_TYPE_PLUGIN)
|
||||
static void
|
||||
gnc_plugin_budget_class_init (GncPluginBudgetClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GncPluginClass *plugin_class = GNC_PLUGIN_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
GncPluginClass *plugin_class = GNC_PLUGIN_CLASS(klass);
|
||||
|
||||
ENTER (" ");
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
@ -147,14 +148,14 @@ gnc_plugin_budget_class_init (GncPluginBudgetClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_budget_init(GncPluginBudget *plugin)
|
||||
gnc_plugin_budget_init (GncPluginBudget *plugin)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_plugin_budget_finalize(GObject *object)
|
||||
gnc_plugin_budget_finalize (GObject *object)
|
||||
{
|
||||
g_return_if_fail(GNC_IS_PLUGIN_BUDGET (object));
|
||||
g_return_if_fail (GNC_IS_PLUGIN_BUDGET(object));
|
||||
|
||||
ENTER(" ");
|
||||
(parent_class->finalize)(object);
|
||||
@ -168,12 +169,12 @@ gnc_plugin_budget_finalize(GObject *object)
|
||||
*
|
||||
*/
|
||||
static void gnc_plugin_budget_add_to_window (GncPlugin *plugin,
|
||||
GncMainWindow *mainwindow,
|
||||
GQuark type)
|
||||
GncMainWindow *mainwindow,
|
||||
GQuark type)
|
||||
{
|
||||
g_signal_connect(mainwindow, "page_changed",
|
||||
G_CALLBACK(gnc_plugin_budget_main_window_page_changed),
|
||||
plugin);
|
||||
g_signal_connect (mainwindow, "page_changed",
|
||||
G_CALLBACK(gnc_plugin_budget_main_window_page_changed),
|
||||
plugin);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
@ -183,95 +184,84 @@ static void gnc_plugin_budget_add_to_window (GncPlugin *plugin,
|
||||
/* Make a new budget; put it in a page; open the page. */
|
||||
static void
|
||||
gnc_plugin_budget_cmd_new_budget (GtkAction *action,
|
||||
GncMainWindowActionData *data)
|
||||
GncMainWindowActionData *user_data)
|
||||
{
|
||||
GncBudget *budget;
|
||||
GncPluginPage *page;
|
||||
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (user_data != NULL);
|
||||
|
||||
budget = gnc_budget_new(gnc_get_current_book());
|
||||
page = gnc_plugin_page_budget_new(budget);
|
||||
gnc_main_window_open_page (data->window, page);
|
||||
budget = gnc_budget_new (gnc_get_current_book());
|
||||
page = gnc_plugin_page_budget_new (budget);
|
||||
gnc_main_window_open_page (user_data->window, page);
|
||||
}
|
||||
|
||||
/* If only one budget exists, open it; otherwise user selects one to open */
|
||||
static void
|
||||
gnc_plugin_budget_cmd_open_budget (GtkAction *action,
|
||||
GncMainWindowActionData *data)
|
||||
GncMainWindowActionData *user_data)
|
||||
{
|
||||
guint count;
|
||||
QofBook *book;
|
||||
GncBudget *bgt = NULL;
|
||||
QofCollection *col;
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (user_data != NULL);
|
||||
|
||||
book = gnc_get_current_book();
|
||||
col = qof_book_get_collection(book, GNC_ID_BUDGET);
|
||||
count = qof_collection_count(col);
|
||||
book = gnc_get_current_book ();
|
||||
col = qof_book_get_collection (book, GNC_ID_BUDGET);
|
||||
count = qof_collection_count (col);
|
||||
if (count > 0)
|
||||
{
|
||||
if (count == 1)
|
||||
{
|
||||
bgt = gnc_budget_get_default(book);
|
||||
}
|
||||
bgt = gnc_budget_get_default (book);
|
||||
else
|
||||
{
|
||||
bgt = gnc_budget_gui_select_budget(GTK_WINDOW(data->window), book);
|
||||
}
|
||||
bgt = gnc_budget_gui_select_budget (GTK_WINDOW(user_data->window), book);
|
||||
|
||||
if (bgt) gnc_main_window_open_page(
|
||||
data->window, gnc_plugin_page_budget_new(bgt));
|
||||
if (bgt)
|
||||
gnc_main_window_open_page (user_data->window,
|
||||
gnc_plugin_page_budget_new (bgt));
|
||||
}
|
||||
else /* if no budgets exist yet, just open a new budget */
|
||||
{
|
||||
gnc_plugin_budget_cmd_new_budget(action, data);
|
||||
}
|
||||
gnc_plugin_budget_cmd_new_budget (action, user_data);
|
||||
}
|
||||
|
||||
/* If only one budget exists, create a copy of it; otherwise user selects one to copy */
|
||||
static void
|
||||
gnc_plugin_budget_cmd_copy_budget (GtkAction *action,
|
||||
GncMainWindowActionData *data)
|
||||
GncMainWindowActionData *user_data)
|
||||
{
|
||||
guint count;
|
||||
QofBook *book;
|
||||
GncBudget *bgt = NULL;
|
||||
QofCollection *col;
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (user_data != NULL);
|
||||
|
||||
book = gnc_get_current_book();
|
||||
col = qof_book_get_collection(book, GNC_ID_BUDGET);
|
||||
count = qof_collection_count(col);
|
||||
book = gnc_get_current_book ();
|
||||
col = qof_book_get_collection (book, GNC_ID_BUDGET);
|
||||
count = qof_collection_count (col);
|
||||
if (count > 0)
|
||||
{
|
||||
if (count == 1)
|
||||
{
|
||||
bgt = gnc_budget_get_default(book);
|
||||
}
|
||||
else
|
||||
{
|
||||
bgt = gnc_budget_gui_select_budget(GTK_WINDOW(data->window), book);
|
||||
}
|
||||
bgt = gnc_budget_gui_select_budget (GTK_WINDOW(user_data->window), book);
|
||||
|
||||
if (bgt)
|
||||
{
|
||||
GncBudget* copy;
|
||||
gchar* name;
|
||||
|
||||
copy = gnc_budget_clone(bgt);
|
||||
name = g_strdup_printf("Copy of %s", gnc_budget_get_name(bgt));
|
||||
gnc_budget_set_name(copy, name);
|
||||
g_free(name);
|
||||
copy = gnc_budget_clone (bgt);
|
||||
name = g_strdup_printf ("Copy of %s", gnc_budget_get_name (bgt));
|
||||
gnc_budget_set_name (copy, name);
|
||||
g_free (name);
|
||||
|
||||
gnc_main_window_open_page(
|
||||
data->window, gnc_plugin_page_budget_new(copy));
|
||||
gnc_main_window_open_page (user_data->window,
|
||||
gnc_plugin_page_budget_new (copy));
|
||||
}
|
||||
}
|
||||
else /* if no budgets exist yet, just open a new budget */
|
||||
{
|
||||
gnc_plugin_budget_cmd_new_budget(action, data);
|
||||
}
|
||||
gnc_plugin_budget_cmd_new_budget (action, user_data);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
@ -279,14 +269,14 @@ gnc_plugin_budget_cmd_copy_budget (GtkAction *action,
|
||||
************************************************************/
|
||||
|
||||
static void
|
||||
row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *column,
|
||||
gpointer data)
|
||||
row_activated_cb (GtkTreeView *tv, GtkTreePath *path,
|
||||
GtkTreeViewColumn *column, gpointer user_data)
|
||||
{
|
||||
gtk_dialog_response(GTK_DIALOG(data), GTK_RESPONSE_OK);
|
||||
gtk_dialog_response (GTK_DIALOG(user_data), GTK_RESPONSE_OK);
|
||||
}
|
||||
|
||||
GncBudget *
|
||||
gnc_budget_gui_select_budget(GtkWindow *parent, QofBook *book)
|
||||
gnc_budget_gui_select_budget (GtkWindow *parent, QofBook *book)
|
||||
{
|
||||
GncBudget *bgt;
|
||||
GtkDialog *dlg;
|
||||
@ -297,44 +287,41 @@ gnc_budget_gui_select_budget(GtkWindow *parent, QofBook *book)
|
||||
gint response;
|
||||
gboolean ok;
|
||||
|
||||
dlg = GTK_DIALOG(gtk_dialog_new_with_buttons(
|
||||
dlg = GTK_DIALOG(gtk_dialog_new_with_buttons (
|
||||
_("Select a Budget"), parent, GTK_DIALOG_MODAL,
|
||||
_("_OK"), GTK_RESPONSE_OK,
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL, NULL));
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
_("_OK"), GTK_RESPONSE_OK, NULL));
|
||||
|
||||
tv = GTK_TREE_VIEW(gtk_tree_view_new());
|
||||
sel = gtk_tree_view_get_selection(tv);
|
||||
gtk_tree_selection_set_mode(sel, GTK_SELECTION_BROWSE);
|
||||
g_signal_connect(tv, "row-activated", G_CALLBACK(row_activated_cb), dlg);
|
||||
tm = gnc_tree_model_budget_new(book);
|
||||
gnc_tree_view_budget_set_model(tv, tm);
|
||||
g_object_unref(tm);
|
||||
gtk_container_add(GTK_CONTAINER (gtk_dialog_get_content_area (dlg)), GTK_WIDGET(tv));
|
||||
gtk_widget_show_all(GTK_WIDGET(dlg));
|
||||
tv = GTK_TREE_VIEW(gtk_tree_view_new ());
|
||||
sel = gtk_tree_view_get_selection (tv);
|
||||
gtk_tree_selection_set_mode (sel, GTK_SELECTION_BROWSE);
|
||||
g_signal_connect (tv, "row-activated", G_CALLBACK(row_activated_cb), dlg);
|
||||
tm = gnc_tree_model_budget_new (book);
|
||||
gnc_tree_view_budget_set_model (tv, tm);
|
||||
g_object_unref (tm);
|
||||
gtk_container_add (GTK_CONTAINER(gtk_dialog_get_content_area (dlg)), GTK_WIDGET(tv));
|
||||
gtk_widget_show_all (GTK_WIDGET(dlg));
|
||||
|
||||
// Preselect the default budget
|
||||
bgt = gnc_budget_get_default(book);
|
||||
if (bgt && gnc_tree_model_budget_get_iter_for_budget(tm, &iter, bgt))
|
||||
{
|
||||
gtk_tree_view_set_cursor(tv, gtk_tree_model_get_path(tm, &iter), NULL,
|
||||
FALSE);
|
||||
}
|
||||
bgt = gnc_budget_get_default (book);
|
||||
|
||||
if (bgt && gnc_tree_model_budget_get_iter_for_budget (tm, &iter, bgt))
|
||||
gtk_tree_view_set_cursor (tv, gtk_tree_model_get_path (tm, &iter), NULL, FALSE);
|
||||
|
||||
bgt = NULL;
|
||||
response = gtk_dialog_run(dlg);
|
||||
response = gtk_dialog_run (dlg);
|
||||
switch (response)
|
||||
{
|
||||
case GTK_RESPONSE_OK:
|
||||
ok = gtk_tree_selection_get_selected(sel, &tm, &iter);
|
||||
ok = gtk_tree_selection_get_selected (sel, &tm, &iter);
|
||||
if (ok)
|
||||
{
|
||||
bgt = gnc_tree_model_budget_get_budget(tm, &iter);
|
||||
}
|
||||
bgt = gnc_tree_model_budget_get_budget (tm, &iter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_widget_destroy(GTK_WIDGET(dlg));
|
||||
gtk_widget_destroy (GTK_WIDGET(dlg));
|
||||
return bgt;
|
||||
}
|
||||
|
||||
|
@ -55,11 +55,11 @@ typedef struct
|
||||
} GncPluginBudgetClass;
|
||||
|
||||
/* function prototypes */
|
||||
GType gnc_plugin_budget_get_type(void);
|
||||
GncPlugin *gnc_plugin_budget_new(void);
|
||||
GType gnc_plugin_budget_get_type (void);
|
||||
GncPlugin *gnc_plugin_budget_new (void);
|
||||
|
||||
/* Launch the budget list dialog.*/
|
||||
GncBudget * gnc_budget_gui_select_budget(GtkWindow *parent, QofBook *book);
|
||||
GncBudget * gnc_budget_gui_select_budget (GtkWindow *parent, QofBook *book);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -66,9 +66,9 @@ GType gnc_plugin_page_budget_get_type (void);
|
||||
*
|
||||
* @return The newly created plugin page.
|
||||
*/
|
||||
GncPluginPage *gnc_plugin_page_budget_new (GncBudget *budget);
|
||||
GncPluginPage *gnc_plugin_page_budget_new (GncBudget *budget);
|
||||
|
||||
void gnc_budget_gui_delete_budget(GncBudget *budget);
|
||||
void gnc_budget_gui_delete_budget (GncBudget *budget);
|
||||
|
||||
/** Given a pointer to a budget plugin page, set the focus to
|
||||
* the Account GtkTreeView. This is used in a g_idle_add so
|
||||
|
@ -937,6 +937,7 @@ gnc_plugin_page_report_recreate_page (GtkWidget *window,
|
||||
g_warning("error reading group %s key %s: %s",
|
||||
group_name, keys[i], error->message);
|
||||
g_error_free(error);
|
||||
g_strfreev (keys);
|
||||
LEAVE("bad value");
|
||||
return NULL;
|
||||
}
|
||||
@ -946,6 +947,7 @@ gnc_plugin_page_report_recreate_page (GtkWidget *window,
|
||||
if (!scm_integer_p(scm_id))
|
||||
{
|
||||
DEBUG("report id not an integer for key %s", keys[i]);
|
||||
g_strfreev (keys);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -957,6 +959,7 @@ gnc_plugin_page_report_recreate_page (GtkWidget *window,
|
||||
}
|
||||
}
|
||||
}
|
||||
g_strfreev (keys);
|
||||
|
||||
if (final_id == SCM_BOOL_F)
|
||||
{
|
||||
|
@ -895,23 +895,21 @@
|
||||
to-date date-type receivable?)
|
||||
(gnc:msg "processing " (qof-print-date to-date) " date-type " date-type
|
||||
"receivable? " receivable?)
|
||||
(let ((bucket-dates (make-extended-interval-list to-date (- num-buckets 2)))
|
||||
(let ((bucket-dates (make-extended-interval-list to-date (- num-buckets 3)))
|
||||
(buckets (make-vector num-buckets 0)))
|
||||
(define (addbucket! idx amt)
|
||||
(vector-set! buckets idx (+ amt (vector-ref buckets idx))))
|
||||
(let lp ((splits splits)
|
||||
(invoices-and-splits '()))
|
||||
(let lp ((splits splits))
|
||||
(cond
|
||||
((null? splits)
|
||||
(vector->list buckets))
|
||||
|
||||
;; next split is an invoice posting split. add its balance to
|
||||
;; bucket, and add splits to invoices-and-splits for payments.
|
||||
;; bucket
|
||||
((eqv? (xaccTransGetTxnType (xaccSplitGetParent (car splits)))
|
||||
TXN-TYPE-INVOICE)
|
||||
(let* ((invoice (gncInvoiceGetInvoiceFromTxn
|
||||
(xaccSplitGetParent (car splits))))
|
||||
(inv-splits (gnc-lot-get-split-list (gncInvoiceGetPostedLot invoice)))
|
||||
(lot (gncInvoiceGetPostedLot invoice))
|
||||
(bal (gnc-lot-get-balance lot))
|
||||
(bal (if receivable? bal (- bal)))
|
||||
@ -924,33 +922,31 @@
|
||||
(if (< date (car bucket-dates))
|
||||
(addbucket! idx bal)
|
||||
(loop (1+ idx) (cdr bucket-dates))))
|
||||
(lp (cdr splits)
|
||||
(cons (cons invoice inv-splits) invoices-and-splits))))
|
||||
(lp (cdr splits))))
|
||||
|
||||
;; next split is a payment. find the associated invoices,
|
||||
;; deduct their totals. the remaining is an overpayment.
|
||||
;; next split is a payment. analyse its sister APAR splits. any
|
||||
;; split whose lot has no invoice is an overpayment.
|
||||
((eqv? (xaccTransGetTxnType (xaccSplitGetParent (car splits)))
|
||||
TXN-TYPE-PAYMENT)
|
||||
(let* ((txn (xaccSplitGetParent (car splits)))
|
||||
(payment (apply + (map xaccSplitGetAmount
|
||||
(xaccTransGetAPARAcctSplitList txn #f))))
|
||||
(splitlist (xaccTransGetAPARAcctSplitList txn #f))
|
||||
(payment (apply + (map xaccSplitGetAmount splitlist)))
|
||||
(overpayment
|
||||
(fold
|
||||
(lambda (inv-and-splits payment-left)
|
||||
(if (member txn (map xaccSplitGetParent (cdr inv-and-splits)))
|
||||
(- payment-left (gncInvoiceGetTotal (car inv-and-splits)))
|
||||
payment-left))
|
||||
(if receivable? (- payment) payment) invoices-and-splits)))
|
||||
(lambda (a b)
|
||||
(if (null? (gncInvoiceGetInvoiceFromLot (xaccSplitGetLot a)))
|
||||
(- b (xaccSplitGetAmount a))
|
||||
b))
|
||||
0 splitlist)))
|
||||
(gnc:msg "next " (gnc:strify (car splits)) " payment " payment
|
||||
" overpayment " overpayment)
|
||||
(when (positive? overpayment)
|
||||
(addbucket! (1- num-buckets) (- overpayment)))
|
||||
(lp (cdr splits) invoices-and-splits)))
|
||||
(addbucket! (1- num-buckets) (if receivable? (- overpayment) overpayment))
|
||||
(lp (cdr splits))))
|
||||
|
||||
;; not invoice/prepayment. regular or payment split.
|
||||
(else
|
||||
(gnc:msg "next " (gnc:strify (car splits)) " skipped")
|
||||
(lp (cdr splits) invoices-and-splits))))))
|
||||
(lp (cdr splits)))))))
|
||||
|
||||
;; ***************************************************************************
|
||||
|
||||
|
@ -1034,12 +1034,9 @@ also show overall period profit & loss."))
|
||||
(if (and common-currency
|
||||
(every has-price?
|
||||
(gnc:accounts-get-commodities income-expense #f)))
|
||||
(gnc:monetary-neg
|
||||
(monetaries->exchanged income-expense-balance
|
||||
common-currency price-source date))
|
||||
(map
|
||||
gnc:monetary-neg
|
||||
(income-expense-balance 'format gnc:make-gnc-monetary #f))))))
|
||||
(monetaries->exchanged income-expense-balance
|
||||
common-currency price-source date)
|
||||
(income-expense-balance 'format gnc:make-gnc-monetary #f)))))
|
||||
|
||||
(chart (and-let* (include-chart?
|
||||
incr
|
||||
|
@ -232,7 +232,7 @@ exist but have no suitable transactions."))
|
||||
|
||||
(else
|
||||
(setup-query query accounts report-date)
|
||||
(let* ((splits (qof-query-run query))
|
||||
(let* ((splits (xaccQueryGetSplitsUniqueTrans query))
|
||||
(accounts (sort-and-delete-duplicates (map xaccSplitGetAccount splits)
|
||||
gnc:account-path-less-p equal?)))
|
||||
(qof-query-destroy query)
|
||||
|
@ -357,24 +357,29 @@
|
||||
#f)))
|
||||
payment-splits)))))
|
||||
|
||||
(define (make-payment->invoices-table amount payment-splits currency)
|
||||
(define (make-payment->invoices-table txn payment-splits currency)
|
||||
(let lp ((payment-splits payment-splits)
|
||||
(amount (- amount))
|
||||
(result '()))
|
||||
(cond
|
||||
((null? payment-splits)
|
||||
(reverse
|
||||
(if (positive? amount)
|
||||
(cons (list (gnc:make-html-table-cell/size 1 2 (_ "Prepayments"))
|
||||
(make-cell (gnc:make-gnc-monetary currency amount)))
|
||||
result)
|
||||
result)))
|
||||
(let ((overpayment
|
||||
(fold
|
||||
(lambda (a b)
|
||||
(if (null? (gncInvoiceGetInvoiceFromLot (xaccSplitGetLot a)))
|
||||
(- b (xaccSplitGetAmount a))
|
||||
b))
|
||||
0 (xaccTransGetAPARAcctSplitList txn #f))))
|
||||
(reverse
|
||||
(if (positive? overpayment)
|
||||
(cons (list (gnc:make-html-table-cell/size 1 2 (_ "Prepayments"))
|
||||
(make-cell (gnc:make-gnc-monetary currency overpayment)))
|
||||
result)
|
||||
result))))
|
||||
(else
|
||||
(let* ((payment-split (car payment-splits))
|
||||
(inv (car payment-split))
|
||||
(inv-amount (gncInvoiceGetTotal inv)))
|
||||
(lp (cdr payment-splits)
|
||||
(- amount inv-amount)
|
||||
(cons (list
|
||||
(qof-print-date (gncInvoiceGetDatePosted inv))
|
||||
(gnc:make-html-text
|
||||
@ -508,7 +513,7 @@
|
||||
((and payment-splits (eq? link-option 'simple))
|
||||
(make-payment->invoices-list invoice payment-splits))
|
||||
((and payment-splits (eq? link-option 'detailed))
|
||||
(make-payment->invoices-table value payment-splits currency))
|
||||
(make-payment->invoices-table txn payment-splits currency))
|
||||
;; some error occurred, show 1 line containing empty-list
|
||||
(else '(()))))
|
||||
|
||||
@ -723,7 +728,7 @@ invoices and amounts.")))))
|
||||
(document (gnc:make-html-document))
|
||||
(table (gnc:make-html-table))
|
||||
(headings (make-heading-list used-columns link-option))
|
||||
(report-title (string-append (owner-string type) " " (_ "Report"))))
|
||||
(report-title (string-append (_ (owner-string type)) " " (_ "Report"))))
|
||||
|
||||
(cond
|
||||
((not (gncOwnerIsValid owner))
|
||||
@ -749,7 +754,7 @@ invoices and amounts.")))))
|
||||
|
||||
(gnc:html-document-set-headline!
|
||||
document (gnc:html-markup
|
||||
"span" (owner-string type) " " (_ "Report:") " "
|
||||
"span" report-title ": "
|
||||
(gnc:html-markup-anchor
|
||||
(if (eqv? GNC-OWNER-JOB type)
|
||||
(gnc:job-anchor-text (gncOwnerGetJob owner))
|
||||
|
@ -535,7 +535,22 @@
|
||||
"$320.00" "#200.00 " "$100,000.00" "$117,529.00" "$9,500.00" "$9,500.00"
|
||||
"$500.00" "$9,000.00" "$9,500.00" "$103,600.00" "$4,429.00" "$0.00"
|
||||
"$108,029.00" "1 FUNDS $350.00" "#1.00 $1.60")
|
||||
(sxml->table-row-col sxml 1 #f 4)))))
|
||||
(sxml->table-row-col sxml 1 #f 4)))
|
||||
|
||||
;; the following includes non-zero retained earnings of $1,270
|
||||
(set-option! multi-bs-options "General" "End Date"
|
||||
(cons 'absolute (gnc-dmy2time64 1 3 1980)))
|
||||
(set-option! multi-bs-options "General" "Period duration" #f)
|
||||
(let ((sxml (options->sxml multicol-balsheet-uuid multi-bs-options
|
||||
"multicol-balsheet-retained")))
|
||||
(test-equal "bal-1/3/80"
|
||||
'("$123,319.00" "$123,319.00" "$5,129.00" "$2,000.00" "$3,029.00"
|
||||
"$0.00" "$100.00" "$17,000.00" "$2,000.00" "$15,000.00" "30 FUNDS "
|
||||
"$1,190.00" "$1,190.00" "#700.00 " "$100,000.00" "$123,319.00"
|
||||
"$9,500.00" "$9,500.00" "$500.00" "$9,000.00" "$9,500.00"
|
||||
"$103,600.00" "$8,949.00" "$1,270.00" "$113,819.00" "1 FUNDS $500.00"
|
||||
"#1.00 $1.70")
|
||||
(sxml->table-row-col sxml 1 #f 2)))))
|
||||
|
||||
(define (multicol-pnl-tests)
|
||||
(define (default-testing-options)
|
||||
|
@ -18,6 +18,7 @@
|
||||
(list (cons 'employee "08ae9c2e884b4f9787144f47eacd7f44")
|
||||
(cons 'vendor "d7d1e53505ee4b1b82efad9eacedaea0")
|
||||
(cons 'customer "c146317be32e4948a561ec7fc89d15c1")
|
||||
(cons 'customer-new "c146317be32e4948a561ec7fc89d15c1-new")
|
||||
(cons 'job "5518ac227e474f47a34439f2d4d049de")))
|
||||
|
||||
(setlocale LC_ALL "C")
|
||||
@ -207,13 +208,18 @@
|
||||
(set-option! options "General"
|
||||
(case variant
|
||||
((customer) "Customer")
|
||||
((customer-new) "Customer")
|
||||
((job) "Job"))
|
||||
owner)
|
||||
(set-option! options "General" "From"
|
||||
(cons 'absolute (gnc-dmy2time64 1 1 1980)))
|
||||
(set-option! options "General" "To"
|
||||
(cons 'absolute (gnc-dmy2time64 1 7 1980)))
|
||||
(set-option! options "General" "Account" account)
|
||||
(cond
|
||||
((eq? variant 'customer-new)
|
||||
(set-option! options "Display Columns" "Links" 'detailed))
|
||||
(else
|
||||
(set-option! options "General" "Account" account)))
|
||||
options))
|
||||
|
||||
;; inv-1 $6, due 18.7.1980 after report-date i.e. "current"
|
||||
@ -322,6 +328,42 @@
|
||||
sxml)))
|
||||
(test-end "customer-report")
|
||||
|
||||
(test-begin "new-customer-report")
|
||||
(let* ((options (default-testing-options 'customer-new
|
||||
owner-1 (get-acct "AR-USD")))
|
||||
(sxml (options->sxml 'customer-new options "new-customer-report basic")))
|
||||
(test-equal "inv-descriptions"
|
||||
'("inv >90 $11.50" "inv 60-90 $7.50" "inv 30-60 $8.50"
|
||||
"inv >90 payment" "inv >90 payment" "inv <30days $4.00"
|
||||
"inv $200" "inv $200" "inv current $6.75" "inv $3 CN"
|
||||
"$31.75" "$7.50")
|
||||
((sxpath `(// (table 3) // tr (td 5) // *text*))
|
||||
sxml))
|
||||
(test-equal "credit-amounts"
|
||||
'("$11.50" "$7.50" "$8.50" "$4.00" "$200.00" "$6.75" "$8.00")
|
||||
((sxpath `(// (table 3) // tr (td 6) // *text*))
|
||||
sxml))
|
||||
(test-equal "debit-amounts"
|
||||
'("$1.50" "$2.00" "$200.00" "$3.00" "$31.75")
|
||||
((sxpath `(// (table 3) // tr (td 7) // *text*))
|
||||
sxml))
|
||||
(test-equal "balance-amounts"
|
||||
'("$11.50" "$19.00" "$27.50" "$26.00" "$24.00" "$28.00"
|
||||
"$228.00" "$28.00" "$34.75" "$31.75")
|
||||
((sxpath `(// (table 3) // tr (td 8) // *text*))
|
||||
sxml))
|
||||
(test-equal "link-amounts"
|
||||
'("$1.50" "$11.50" "$11.50" "$200.00" "$200.00")
|
||||
((sxpath `(// (table 3) // tr (td 11) // *text*))
|
||||
sxml))
|
||||
;; from the report, find the 3rd table, last row, find embedded
|
||||
;; table, retrieve tr contents
|
||||
(test-equal "aging-table"
|
||||
'("$0.00" "$6.75" "$1.00" "$8.50" "$7.50" "$8.00" "$31.75")
|
||||
((sxpath `(// (table 3) // (tr -1) // table // tbody // tr // *text*))
|
||||
sxml)))
|
||||
(test-end "new-customer-report")
|
||||
|
||||
(display "job-report tests:\n")
|
||||
;; inv for job
|
||||
(let ((inv-2-copy (gncInvoiceCopy inv-2)))
|
||||
|
@ -50,6 +50,7 @@ static gncFeature known_features[] =
|
||||
{ GNC_FEATURE_SQLITE3_ISO_DATES, "Use ISO formatted date-time strings in SQLite3 databases (requires at least GnuCash 2.6.20)"},
|
||||
{ GNC_FEATURE_REG_SORT_FILTER, "Store the register sort and filter settings in .gcm metadata file (requires at least GnuCash 3.3)"},
|
||||
{ GNC_FEATURE_BUDGET_UNREVERSED, "Store budget amounts unreversed (i.e. natural) signs (requires at least Gnucash 3.8)"},
|
||||
{ GNC_FEATURE_BUDGET_SHOW_EXTRA_ACCOUNT_COLS, "Show extra account columns in the Budget View (requires at least Gnucash 3.8)"},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
@ -54,6 +54,7 @@ extern "C" {
|
||||
#define GNC_FEATURE_SQLITE3_ISO_DATES "ISO-8601 formatted date strings in SQLite3 databases."
|
||||
#define GNC_FEATURE_REG_SORT_FILTER "Register sort and filter settings stored in .gcm file"
|
||||
#define GNC_FEATURE_BUDGET_UNREVERSED "Use natural signs in budget amounts"
|
||||
#define GNC_FEATURE_BUDGET_SHOW_EXTRA_ACCOUNT_COLS "Show extra account columns in the Budget View"
|
||||
|
||||
/** @} */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user