mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Allow reconciliations to be postponed.
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3384 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
@@ -53,6 +53,8 @@ struct _xaccLedgerDisplay
|
||||
|
||||
SplitRegister *reg;
|
||||
|
||||
gboolean loading;
|
||||
|
||||
LedgerDisplayDestroy destroy;
|
||||
LedgerDisplayGetParent get_parent;
|
||||
LedgerDisplaySetHelp set_help;
|
||||
@@ -487,6 +489,9 @@ refresh_handler (GHashTable *changes, gpointer user_data)
|
||||
const EventInfo *info;
|
||||
gboolean has_leader;
|
||||
|
||||
if (ld->loading)
|
||||
return;
|
||||
|
||||
has_leader = (ld->ld_type == LD_SINGLE || ld->ld_type == LD_SUBACCOUNT);
|
||||
|
||||
if (has_leader)
|
||||
@@ -684,6 +689,7 @@ xaccLedgerDisplayInternal (Account *lead_account, Query *q,
|
||||
ld->leader = *xaccAccountGetGUID (lead_account);
|
||||
ld->query = NULL;
|
||||
ld->ld_type = ld_type;
|
||||
ld->loading = FALSE;
|
||||
ld->destroy = NULL;
|
||||
ld->get_parent = NULL;
|
||||
ld->set_help = NULL;
|
||||
@@ -707,6 +713,10 @@ xaccLedgerDisplayInternal (Account *lead_account, Query *q,
|
||||
GNC_ID_ACCOUNT,
|
||||
GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);
|
||||
|
||||
gnc_gui_component_watch_entity_type (ld->component_id,
|
||||
GNC_ID_TRANS,
|
||||
GNC_EVENT_MODIFY);
|
||||
|
||||
/******************************************************************\
|
||||
* The main register window itself *
|
||||
\******************************************************************/
|
||||
@@ -764,6 +774,11 @@ xaccLedgerDisplayRefresh (xaccLedgerDisplay *ld)
|
||||
if (!ld)
|
||||
return;
|
||||
|
||||
if (ld->loading)
|
||||
return;
|
||||
|
||||
ld->loading = TRUE;
|
||||
|
||||
/* The leader account is used by the register gui to
|
||||
* assign a default source account for a "blank split"
|
||||
* that is attached to the bottom of the register.
|
||||
@@ -772,6 +787,8 @@ xaccLedgerDisplayRefresh (xaccLedgerDisplay *ld)
|
||||
xaccSRLoadRegister (ld->reg,
|
||||
xaccQueryGetSplits (ld->query),
|
||||
xaccLedgerDisplayLeader (ld));
|
||||
|
||||
ld->loading = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -4163,9 +4163,9 @@ void
|
||||
xaccSRLoadRegister (SplitRegister *reg, GList * slist,
|
||||
Account *default_account)
|
||||
{
|
||||
SRInfo *info = xaccSRGetInfo(reg);
|
||||
Split *blank_split = xaccSplitLookup(&info->blank_split_guid);
|
||||
Transaction *pending_trans = xaccTransLookup(&info->pending_trans_guid);
|
||||
SRInfo *info = xaccSRGetInfo (reg);
|
||||
Split *blank_split = xaccSplitLookup (&info->blank_split_guid);
|
||||
Transaction *pending_trans = xaccTransLookup (&info->pending_trans_guid);
|
||||
SplitRegisterBuffer *reg_buffer;
|
||||
GHashTable *trans_table = NULL;
|
||||
CellBlock *lead_cursor;
|
||||
@@ -4641,7 +4641,7 @@ xaccSRCheckReconciled (SplitRegister *reg)
|
||||
void
|
||||
xaccSRShowPresentDivider (SplitRegister *reg, gboolean show_present)
|
||||
{
|
||||
SRInfo *info = xaccSRGetInfo(reg);
|
||||
SRInfo *info = xaccSRGetInfo (reg);
|
||||
|
||||
if (reg == NULL)
|
||||
return;
|
||||
|
||||
@@ -1527,76 +1527,18 @@ xaccAccountTypesCompatible (int parent_type, int child_type)
|
||||
return compatible;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
static kvp_frame *
|
||||
xaccAccountGetReconcileInfo (Account *account)
|
||||
{
|
||||
kvp_value *value;
|
||||
|
||||
if (!account)
|
||||
return NULL;
|
||||
|
||||
value = kvp_frame_get_slot (xaccAccountGetSlots (account), "reconcile-info");
|
||||
if (!value)
|
||||
return NULL;
|
||||
|
||||
return kvp_value_get_frame (value);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
static void
|
||||
xaccAccountMakeReconcileInfo (Account *account)
|
||||
{
|
||||
kvp_frame *slots;
|
||||
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
if (xaccAccountGetReconcileInfo (account))
|
||||
return;
|
||||
|
||||
slots = xaccAccountGetSlots (account);
|
||||
if (!slots)
|
||||
return;
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
kvp_frame *frame;
|
||||
kvp_value *value;
|
||||
|
||||
check_open (account);
|
||||
|
||||
frame = kvp_frame_new ();
|
||||
value = kvp_value_new_frame (frame);
|
||||
|
||||
kvp_frame_set_slot (slots, "reconcile-info", value);
|
||||
|
||||
kvp_value_delete (value);
|
||||
kvp_frame_delete (frame);
|
||||
|
||||
mark_account (account);
|
||||
}
|
||||
xaccAccountCommitEdit (account);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
gboolean
|
||||
xaccAccountGetReconcileLastDate (Account *account, time_t *last_date)
|
||||
{
|
||||
kvp_frame *recn_info;
|
||||
kvp_value *value;
|
||||
|
||||
if (!account)
|
||||
return FALSE;
|
||||
|
||||
recn_info = xaccAccountGetReconcileInfo (account);
|
||||
if (!recn_info)
|
||||
return FALSE;
|
||||
|
||||
value = kvp_frame_get_slot (recn_info, "last-date");
|
||||
value = kvp_frame_get_slot_path (xaccAccountGetSlots (account),
|
||||
"reconcile-info", "last-date", NULL);
|
||||
if (!value)
|
||||
return FALSE;
|
||||
|
||||
@@ -1616,23 +1558,9 @@ xaccAccountGetReconcileLastDate (Account *account, time_t *last_date)
|
||||
void
|
||||
xaccAccountSetReconcileLastDate (Account *account, time_t last_date)
|
||||
{
|
||||
kvp_frame *recn_info;
|
||||
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
recn_info = xaccAccountGetReconcileInfo (account);
|
||||
if (!recn_info)
|
||||
{
|
||||
xaccAccountMakeReconcileInfo (account);
|
||||
recn_info = xaccAccountGetReconcileInfo (account);
|
||||
if (!recn_info)
|
||||
{
|
||||
PERR ("Couldn't make reconcile info");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
kvp_value *value;
|
||||
@@ -1641,7 +1569,8 @@ xaccAccountSetReconcileLastDate (Account *account, time_t last_date)
|
||||
|
||||
value = kvp_value_new_gint64 (last_date);
|
||||
|
||||
kvp_frame_set_slot (recn_info, "last-date", value);
|
||||
kvp_frame_set_slot_path (xaccAccountGetSlots (account), value,
|
||||
"reconcile-info", "last-date", NULL);
|
||||
|
||||
kvp_value_delete (value);
|
||||
|
||||
@@ -1656,17 +1585,13 @@ gboolean
|
||||
xaccAccountGetReconcilePostponeDate (Account *account,
|
||||
time_t *postpone_date)
|
||||
{
|
||||
kvp_frame *recn_info;
|
||||
kvp_value *value;
|
||||
|
||||
if (!account)
|
||||
return FALSE;
|
||||
|
||||
recn_info = xaccAccountGetReconcileInfo (account);
|
||||
if (!recn_info)
|
||||
return FALSE;
|
||||
|
||||
value = kvp_frame_get_slot (recn_info, "postpone-date");
|
||||
value = kvp_frame_get_slot_path (xaccAccountGetSlots (account),
|
||||
"reconcile-info", "postpone", "date", NULL);
|
||||
if (!value)
|
||||
return FALSE;
|
||||
|
||||
@@ -1687,23 +1612,9 @@ void
|
||||
xaccAccountSetReconcilePostponeDate (Account *account,
|
||||
time_t postpone_date)
|
||||
{
|
||||
kvp_frame *recn_info;
|
||||
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
recn_info = xaccAccountGetReconcileInfo (account);
|
||||
if (!recn_info)
|
||||
{
|
||||
xaccAccountMakeReconcileInfo (account);
|
||||
recn_info = xaccAccountGetReconcileInfo (account);
|
||||
if (!recn_info)
|
||||
{
|
||||
PERR ("Couldn't make reconcile info");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
kvp_value *value;
|
||||
@@ -1712,7 +1623,8 @@ xaccAccountSetReconcilePostponeDate (Account *account,
|
||||
|
||||
value = kvp_value_new_gint64 (postpone_date);
|
||||
|
||||
kvp_frame_set_slot (recn_info, "postpone-date", value);
|
||||
kvp_frame_set_slot_path (xaccAccountGetSlots (account), value,
|
||||
"reconcile-info", "postpone", "date", NULL);
|
||||
|
||||
kvp_value_delete (value);
|
||||
|
||||
@@ -1727,21 +1639,18 @@ gboolean
|
||||
xaccAccountGetReconcilePostponeBalance (Account *account,
|
||||
gnc_numeric *balance)
|
||||
{
|
||||
kvp_frame *recn_info;
|
||||
kvp_value *value;
|
||||
|
||||
if (!account)
|
||||
return FALSE;
|
||||
|
||||
recn_info = xaccAccountGetReconcileInfo (account);
|
||||
if (!recn_info)
|
||||
return FALSE;
|
||||
|
||||
value = kvp_frame_get_slot (recn_info, "postpone-balance");
|
||||
value = kvp_frame_get_slot_path (xaccAccountGetSlots (account),
|
||||
"reconcile-info", "postpone", "balance",
|
||||
NULL);
|
||||
if (!value)
|
||||
return FALSE;
|
||||
|
||||
if (kvp_value_get_type (value) == KVP_TYPE_GINT64)
|
||||
if (kvp_value_get_type (value) == KVP_TYPE_NUMERIC)
|
||||
{
|
||||
if (balance)
|
||||
*balance = kvp_value_get_numeric (value);
|
||||
@@ -1758,23 +1667,9 @@ void
|
||||
xaccAccountSetReconcilePostponeBalance (Account *account,
|
||||
gnc_numeric balance)
|
||||
{
|
||||
kvp_frame *recn_info;
|
||||
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
recn_info = xaccAccountGetReconcileInfo (account);
|
||||
if (!recn_info)
|
||||
{
|
||||
xaccAccountMakeReconcileInfo (account);
|
||||
recn_info = xaccAccountGetReconcileInfo (account);
|
||||
if (!recn_info)
|
||||
{
|
||||
PERR ("Couldn't make reconcile info");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
kvp_value *value;
|
||||
@@ -1783,7 +1678,8 @@ xaccAccountSetReconcilePostponeBalance (Account *account,
|
||||
|
||||
value = kvp_value_new_numeric (balance);
|
||||
|
||||
kvp_frame_set_slot (recn_info, "postpone-balance", value);
|
||||
kvp_frame_set_slot_path (xaccAccountGetSlots (account), value,
|
||||
"reconcile-info", "postpone", "balance", NULL);
|
||||
|
||||
kvp_value_delete (value);
|
||||
|
||||
@@ -1797,21 +1693,15 @@ xaccAccountSetReconcilePostponeBalance (Account *account,
|
||||
void
|
||||
xaccAccountClearReconcilePostpone (Account *account)
|
||||
{
|
||||
kvp_frame *recn_info;
|
||||
|
||||
if (!account)
|
||||
return;
|
||||
|
||||
recn_info = xaccAccountGetReconcileInfo (account);
|
||||
if (!recn_info)
|
||||
return;
|
||||
|
||||
xaccAccountBeginEdit (account);
|
||||
{
|
||||
check_open (account);
|
||||
|
||||
kvp_frame_set_slot (recn_info, "postpone-date", NULL);
|
||||
kvp_frame_set_slot (recn_info, "postpone-balance", NULL);
|
||||
kvp_frame_set_slot_path (xaccAccountGetSlots (account), NULL,
|
||||
"reconcile-info", "postpone", NULL);
|
||||
|
||||
mark_account (account);
|
||||
}
|
||||
|
||||
@@ -81,12 +81,12 @@ Type: frame
|
||||
Entities: Account
|
||||
Use: store the statement date of the last reconciliation
|
||||
|
||||
Name: reconcile-info/postpone-date
|
||||
Name: reconcile-info/postpone/date
|
||||
Type: gint64
|
||||
Entities: Account
|
||||
Use: store the ending statement date of a postponed reconciliation
|
||||
|
||||
Name: reconcile-info/postpone-balance
|
||||
Name: reconcile-info/postpone/balance
|
||||
Type: numeric
|
||||
Entities: Account
|
||||
Use: store the ending balance of a postponed reconciliation
|
||||
|
||||
@@ -66,6 +66,7 @@ static gint next_component_id = 0;
|
||||
static GList *components = NULL;
|
||||
|
||||
static ComponentEventInfo changes = { 0, 0, NULL };
|
||||
static ComponentEventInfo changes_backup = { 0, 0, NULL };
|
||||
|
||||
|
||||
/* This static indicates the debugging module that this .o belongs to. */
|
||||
@@ -275,6 +276,10 @@ gnc_component_manager_init (void)
|
||||
changes.account_event_mask = 0;
|
||||
changes.entity_events = guid_hash_table_new ();
|
||||
|
||||
changes_backup.trans_event_mask = 0;
|
||||
changes_backup.account_event_mask = 0;
|
||||
changes_backup.entity_events = guid_hash_table_new ();
|
||||
|
||||
handler_id = gnc_engine_register_event_handler (gnc_cm_event_handler, NULL);
|
||||
}
|
||||
|
||||
@@ -291,6 +296,10 @@ gnc_component_manager_shutdown (void)
|
||||
destroy_event_hash (changes.entity_events);
|
||||
changes.entity_events = NULL;
|
||||
|
||||
clear_event_info (&changes_backup);
|
||||
destroy_event_hash (changes_backup.entity_events);
|
||||
changes_backup.entity_events = NULL;
|
||||
|
||||
gnc_engine_unregister_event_handler (handler_id);
|
||||
}
|
||||
|
||||
@@ -546,7 +555,7 @@ match_helper (gpointer key, gpointer value, gpointer user_data)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
changes_match (ComponentEventInfo *cei)
|
||||
changes_match (ComponentEventInfo *cei, ComponentEventInfo *changes)
|
||||
{
|
||||
ComponentEventInfo *big_cei;
|
||||
GHashTable *small;
|
||||
@@ -556,21 +565,21 @@ changes_match (ComponentEventInfo *cei)
|
||||
|
||||
/* check types first, for efficiency */
|
||||
|
||||
if (cei->trans_event_mask & changes.trans_event_mask)
|
||||
if (cei->trans_event_mask & changes->trans_event_mask)
|
||||
return TRUE;
|
||||
|
||||
if (cei->account_event_mask & changes.account_event_mask)
|
||||
if (cei->account_event_mask & changes->account_event_mask)
|
||||
return TRUE;
|
||||
|
||||
if (g_hash_table_size (cei->entity_events) <=
|
||||
g_hash_table_size (changes.entity_events))
|
||||
g_hash_table_size (changes->entity_events))
|
||||
{
|
||||
small = cei->entity_events;
|
||||
big_cei = &changes;
|
||||
big_cei = changes;
|
||||
}
|
||||
else
|
||||
{
|
||||
small = changes.entity_events;
|
||||
small = changes->entity_events;
|
||||
big_cei = cei;
|
||||
}
|
||||
|
||||
@@ -590,6 +599,19 @@ gnc_gui_refresh_internal (gboolean force)
|
||||
if (!got_events && !force)
|
||||
return;
|
||||
|
||||
gnc_suspend_gui_refresh ();
|
||||
|
||||
{
|
||||
GHashTable *table;
|
||||
|
||||
changes_backup.trans_event_mask = changes.trans_event_mask;
|
||||
changes_backup.account_event_mask = changes.account_event_mask;
|
||||
|
||||
table = changes_backup.entity_events;
|
||||
changes_backup.entity_events = changes.entity_events;
|
||||
changes.entity_events = table;
|
||||
}
|
||||
|
||||
#if CM_DEBUG
|
||||
fprintf (stderr, "refresh!\n");
|
||||
#endif
|
||||
@@ -613,14 +635,16 @@ gnc_gui_refresh_internal (gboolean force)
|
||||
|
||||
if (force)
|
||||
ci->refresh_handler (NULL, ci->user_data);
|
||||
else if (changes_match (&ci->watch_info))
|
||||
ci->refresh_handler (changes.entity_events, ci->user_data);
|
||||
else if (changes_match (&ci->watch_info, &changes_backup))
|
||||
ci->refresh_handler (changes_backup.entity_events, ci->user_data);
|
||||
}
|
||||
|
||||
clear_event_info (&changes);
|
||||
clear_event_info (&changes_backup);
|
||||
got_events = FALSE;
|
||||
|
||||
g_list_free (list);
|
||||
|
||||
gnc_resume_gui_refresh ();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -116,8 +116,9 @@ struct _RecnWindow
|
||||
static gnc_numeric recnRecalculateBalance (RecnWindow *recnData);
|
||||
|
||||
static void recn_destroy_cb (GtkWidget *w, gpointer data);
|
||||
static void recnFinishCB(GtkWidget *w, gpointer data);
|
||||
static void recnCancelCB(GtkWidget *w, gpointer data);
|
||||
static void recnFinishCB (GtkWidget *w, gpointer data);
|
||||
static void recnPostponeCB (GtkWidget *w, gpointer data);
|
||||
static void recnCancelCB (GtkWidget *w, gpointer data);
|
||||
|
||||
static void gnc_reconcile_window_set_sensitivity(RecnWindow *recnData);
|
||||
static char * gnc_recn_make_window_name(Account *account);
|
||||
@@ -973,6 +974,14 @@ gnc_recn_create_menu_bar(RecnWindow *recnData, GtkWidget *statusbar)
|
||||
GNOME_APP_PIXMAP_NONE, NULL,
|
||||
'f', GDK_CONTROL_MASK, NULL
|
||||
},
|
||||
{
|
||||
GNOME_APP_UI_ITEM,
|
||||
N_("_Postpone"),
|
||||
N_("Postpone the reconciliation of this account"),
|
||||
recnPostponeCB, NULL, NULL,
|
||||
GNOME_APP_PIXMAP_NONE, NULL,
|
||||
'p', GDK_CONTROL_MASK, NULL
|
||||
},
|
||||
{
|
||||
GNOME_APP_UI_ITEM,
|
||||
N_("_Cancel"),
|
||||
@@ -1385,6 +1394,10 @@ recnWindow (GtkWidget *parent, Account *account)
|
||||
xaccAccountGetGUID (account),
|
||||
GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);
|
||||
|
||||
gnc_gui_component_watch_entity_type (component_id,
|
||||
GNC_ID_TRANS,
|
||||
GNC_EVENT_MODIFY);
|
||||
|
||||
type = xaccAccountGetType(account);
|
||||
recnData->use_shares = ((type == STOCK) || (type == MUTUAL) ||
|
||||
(type == CURRENCY));
|
||||
@@ -1755,7 +1768,7 @@ recnFinishCB (GtkWidget *w, gpointer data)
|
||||
{
|
||||
const char *message = _("The account is not balanced.\n"
|
||||
"Are you sure you want to finish?");
|
||||
if (!gnc_verify_dialog_parented(recnData->window, message, FALSE))
|
||||
if (!gnc_verify_dialog_parented (recnData->window, message, FALSE))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1763,11 +1776,11 @@ recnFinishCB (GtkWidget *w, gpointer data)
|
||||
|
||||
gnc_suspend_gui_refresh ();
|
||||
|
||||
recnData->delete_refresh = TRUE;
|
||||
|
||||
gnc_reconcile_list_commit(GNC_RECONCILE_LIST(recnData->credit), date);
|
||||
gnc_reconcile_list_commit(GNC_RECONCILE_LIST(recnData->debit), date);
|
||||
|
||||
recnData->delete_refresh = TRUE;
|
||||
|
||||
auto_payment = gnc_lookup_boolean_option ("Reconcile",
|
||||
"Automatic credit card payments",
|
||||
TRUE);
|
||||
@@ -1796,6 +1809,42 @@ recnFinishCB (GtkWidget *w, gpointer data)
|
||||
gnc_close_gui_component_by_data (WINDOW_RECONCILE_CM_CLASS, recnData);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* recnPostponeCB *
|
||||
* saves reconcile information for later use *
|
||||
* *
|
||||
* Args: w - the widget that called us *
|
||||
* data - the data struct for this window *
|
||||
* Return: none *
|
||||
\********************************************************************/
|
||||
static void
|
||||
recnPostponeCB (GtkWidget *w, gpointer data)
|
||||
{
|
||||
RecnWindow *recnData = data;
|
||||
Account *account;
|
||||
|
||||
{
|
||||
const char *message = _("Do you want to postpone this reconciliation "
|
||||
"and finish it later?");
|
||||
if (!gnc_verify_dialog_parented (recnData->window, message, FALSE))
|
||||
return;
|
||||
}
|
||||
|
||||
gnc_suspend_gui_refresh ();
|
||||
|
||||
recnData->delete_refresh = TRUE;
|
||||
|
||||
gnc_reconcile_list_postpone (GNC_RECONCILE_LIST(recnData->credit));
|
||||
gnc_reconcile_list_postpone (GNC_RECONCILE_LIST(recnData->debit));
|
||||
|
||||
account = recn_get_account (recnData);
|
||||
|
||||
xaccAccountSetReconcilePostponeDate (account, recnData->statement_date);
|
||||
xaccAccountSetReconcilePostponeBalance (account, recnData->new_ending);
|
||||
|
||||
gnc_close_gui_component_by_data (WINDOW_RECONCILE_CM_CLASS, recnData);
|
||||
}
|
||||
|
||||
static void
|
||||
recnCancelCB (GtkWidget *w, gpointer data)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user