Merge branch 'maint'

This commit is contained in:
Robert Fewell 2019-12-12 16:33:34 +00:00
commit e4ac6b480f
15 changed files with 940 additions and 879 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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)))))))
;; ***************************************************************************

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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)))

View File

@ -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 },
};

View File

@ -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"
/** @} */