mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Bug 754209 - Bills can be posted multiple times from "find bill" search results - follow up
This commit adds code to check & repair that removes the read only status of the bogus transactions so the user can go in the AP/AR account and delete these bad transactions. Translators: this commit introduces a new translatable string.
This commit is contained in:
parent
d45886f73b
commit
0f66e20005
@ -462,6 +462,50 @@ gncScrubBusinessLot (GNCLot *lot)
|
||||
return splits_deleted;
|
||||
}
|
||||
|
||||
void
|
||||
gncScrubBusinessSplit (Split *split)
|
||||
{
|
||||
const gchar *memo = _("Please delete this transaction. Explanation at http://wiki.gnucash.org/wiki/Business_Features_Issues#Double_Posting");
|
||||
Transaction *txn;
|
||||
|
||||
if (!split) return;
|
||||
ENTER ("(split=%p)", split);
|
||||
|
||||
txn = xaccSplitGetParent (split);
|
||||
if (txn)
|
||||
{
|
||||
gchar txntype = xaccTransGetTxnType (txn);
|
||||
const gchar *read_only = xaccTransGetReadOnly (txn);
|
||||
gboolean is_void = xaccTransGetVoidStatus (txn);
|
||||
GNCLot *lot = xaccSplitGetLot (split);
|
||||
|
||||
/* Look for transactions as a result of double posting an invoice or bill
|
||||
* Refer to https://bugzilla.gnome.org/show_bug.cgi?id=754209
|
||||
* to learn how this could have happened in the past.
|
||||
* Characteristics of such transaction are:
|
||||
* - read only
|
||||
* - not voided (to ensure read only is set by the business functions)
|
||||
* - transaction type is none (should be type invoice for proper post transactions)
|
||||
* - assigned to a lot
|
||||
*/
|
||||
if ((txntype == TXN_TYPE_NONE) && read_only && !is_void && lot)
|
||||
{
|
||||
gchar *txn_date = qof_print_date (xaccTransGetDateEntered (txn));
|
||||
xaccTransClearReadOnly (txn);
|
||||
xaccSplitSetMemo (split, memo);
|
||||
gnc_lot_remove_split (lot, split);
|
||||
PWARN("Cleared double post status of transaction \"%s\", dated %s. "
|
||||
"Please delete transaction and verify balance.",
|
||||
xaccTransGetDescription (txn),
|
||||
txn_date);
|
||||
g_free (txn_date);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LEAVE ("(split=%p)", split);
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
void
|
||||
@ -505,20 +549,72 @@ gncScrubBusinessAccountLots (Account *acc)
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
void
|
||||
gncScrubBusinessAccountSplits (Account *acc)
|
||||
{
|
||||
SplitList *splits, *node;
|
||||
gint split_count = 0;
|
||||
gint curr_split_no = 1;
|
||||
const gchar *str;
|
||||
|
||||
if (!acc) return;
|
||||
if (FALSE == xaccAccountIsAPARType (xaccAccountGetType (acc))) return;
|
||||
|
||||
str = xaccAccountGetName(acc);
|
||||
str = str ? str : "(null)";
|
||||
|
||||
ENTER ("(acc=%s)", str);
|
||||
PINFO ("Cleaning up superfluous lot links in account %s \n", str);
|
||||
xaccAccountBeginEdit(acc);
|
||||
|
||||
splits = xaccAccountGetSplitList(acc);
|
||||
split_count = g_list_length (splits);
|
||||
for (node = splits; node; node = node->next)
|
||||
{
|
||||
Split *split = node->data;
|
||||
|
||||
PINFO("Start processing split %d of %d",
|
||||
curr_split_no, split_count);
|
||||
|
||||
if (split)
|
||||
gncScrubBusinessSplit (split);
|
||||
|
||||
PINFO("Finished processing split %d of %d",
|
||||
curr_split_no, split_count);
|
||||
curr_split_no++;
|
||||
}
|
||||
xaccAccountCommitEdit(acc);
|
||||
LEAVE ("(acc=%s)", str);
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
void
|
||||
gncScrubBusinessAccount (Account *acc)
|
||||
{
|
||||
if (!acc) return;
|
||||
if (FALSE == xaccAccountIsAPARType (xaccAccountGetType (acc))) return;
|
||||
|
||||
gncScrubBusinessAccountLots (acc);
|
||||
gncScrubBusinessAccountSplits (acc);
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
static void
|
||||
lot_scrub_cb (Account *acc, gpointer data)
|
||||
{
|
||||
if (FALSE == xaccAccountIsAPARType (xaccAccountGetType (acc))) return;
|
||||
gncScrubBusinessAccountLots (acc);
|
||||
gncScrubBusinessAccount (acc);
|
||||
}
|
||||
|
||||
void
|
||||
gncScrubBusinessAccountTreeLots (Account *acc)
|
||||
gncScrubBusinessAccountTree (Account *acc)
|
||||
{
|
||||
if (!acc) return;
|
||||
|
||||
gnc_account_foreach_descendant(acc, lot_scrub_cb, NULL);
|
||||
gncScrubBusinessAccountLots (acc);
|
||||
gncScrubBusinessAccount (acc);
|
||||
}
|
||||
|
||||
/* ========================== END OF FILE ========================= */
|
||||
|
@ -54,6 +54,21 @@
|
||||
*/
|
||||
gboolean gncScrubBusinessLot (GNCLot *lot);
|
||||
|
||||
/** The gncScrubBusinessSplit() function will fix all issues found with
|
||||
* the given split.
|
||||
*
|
||||
* Currently this function only does one thing: check if the split is
|
||||
* part of a transaction that was generated as the result of a doubly
|
||||
* posted invoice/bill/credit note. Refer to
|
||||
* https://bugzilla.gnome.org/show_bug.cgi?id=754209 to learn how this
|
||||
* could have happened in the past.
|
||||
* If such a transaction is found, its read-only status is removed and
|
||||
* a warning is written to the trace file. Considering the user may
|
||||
* already have added a correcting transaction we leave it up to the user
|
||||
* to decide whether to also delete the transaction or not.
|
||||
*/
|
||||
void gncScrubBusinessSplit (Split *split);
|
||||
|
||||
/** The gncScrubBusinessAccountLots() function will call
|
||||
* gncScrubBusinessLot() on each lot in the given account.
|
||||
*
|
||||
@ -63,15 +78,26 @@ gboolean gncScrubBusinessLot (GNCLot *lot);
|
||||
*/
|
||||
void gncScrubBusinessAccountLots (Account *acc);
|
||||
|
||||
/** The gncScrubBusinessAccountTreeLots() function will call
|
||||
* gncScrubBusinessAccountLots() on each lot in the given account
|
||||
* and its sub accounts.
|
||||
*
|
||||
* This routine is the primary routine for ensuring that the
|
||||
* lot structure of every lot of a business account is in good
|
||||
* order.
|
||||
/** The gncScrubBusinessAccountSplits() function will call
|
||||
* gncScrubBusinessSplit() on each split in the given account.
|
||||
*/
|
||||
void gncScrubBusinessAccountTreeLots (Account *acc);
|
||||
void gncScrubBusinessAccountSplits (Account *acc);
|
||||
|
||||
/** The gncScrubBusinessAccount() function will call
|
||||
* all scrub functions relevant for a given account
|
||||
* on condition the account is a business related account
|
||||
* (Accounts Receivable or Accounts Payable type).
|
||||
*
|
||||
* This routine is the primary routine for fixing all
|
||||
* (known) issues in a business account.
|
||||
*/
|
||||
void gncScrubBusinessAccount (Account *acc);
|
||||
|
||||
/** The gncScrubBusinessAccountTreeLots() function will call
|
||||
* gncScrubBusinessAccount() on the given account
|
||||
* and its sub accounts.
|
||||
*/
|
||||
void gncScrubBusinessAccountTree (Account *acc);
|
||||
|
||||
/** @} */
|
||||
#endif /* GNC_SCRUBBUSINESS_H */
|
||||
|
@ -1573,7 +1573,7 @@ gnc_plugin_page_account_tree_cmd_scrub (GtkAction *action, GncPluginPageAccountT
|
||||
if (g_getenv("GNC_AUTO_SCRUB_LOTS") != NULL)
|
||||
xaccAccountScrubLots(account);
|
||||
|
||||
gncScrubBusinessAccountLots(account);
|
||||
gncScrubBusinessAccount(account);
|
||||
|
||||
|
||||
gnc_resume_gui_refresh ();
|
||||
@ -1595,7 +1595,7 @@ gnc_plugin_page_account_tree_cmd_scrub_sub (GtkAction *action, GncPluginPageAcco
|
||||
if (g_getenv("GNC_AUTO_SCRUB_LOTS") != NULL)
|
||||
xaccAccountTreeScrubLots(account);
|
||||
|
||||
gncScrubBusinessAccountTreeLots(account);
|
||||
gncScrubBusinessAccountTree(account);
|
||||
|
||||
gnc_resume_gui_refresh ();
|
||||
}
|
||||
@ -1613,7 +1613,7 @@ gnc_plugin_page_account_tree_cmd_scrub_all (GtkAction *action, GncPluginPageAcco
|
||||
if (g_getenv("GNC_AUTO_SCRUB_LOTS") != NULL)
|
||||
xaccAccountTreeScrubLots(root);
|
||||
|
||||
gncScrubBusinessAccountTreeLots(root);
|
||||
gncScrubBusinessAccountTree(root);
|
||||
|
||||
gnc_resume_gui_refresh ();
|
||||
}
|
||||
|
@ -3726,7 +3726,10 @@ gnc_plugin_page_register_cmd_scrub_current (GtkAction *action,
|
||||
split = gnc_split_register_get_current_split (reg);
|
||||
lot = xaccSplitGetLot (split);
|
||||
if (lot && xaccAccountIsAPARType (xaccAccountGetType (xaccSplitGetAccount (split))))
|
||||
{
|
||||
gncScrubBusinessLot (lot);
|
||||
gncScrubBusinessSplit (split);
|
||||
}
|
||||
gnc_resume_gui_refresh();
|
||||
LEAVE(" ");
|
||||
}
|
||||
@ -3773,7 +3776,10 @@ gnc_plugin_page_register_cmd_scrub_all (GtkAction *action,
|
||||
|
||||
lot = xaccSplitGetLot (split);
|
||||
if (lot && xaccAccountIsAPARType (xaccAccountGetType (xaccSplitGetAccount (split))))
|
||||
{
|
||||
gncScrubBusinessLot (lot);
|
||||
gncScrubBusinessSplit (split);
|
||||
}
|
||||
|
||||
PINFO("Finished processing split %d of %d",
|
||||
curr_split_no, split_count);
|
||||
|
Loading…
Reference in New Issue
Block a user