* src/engine/Account.[ch]: add an xaccAccountRemoveLot() function to allow

the LOT code to clear memory when you destroy a lot.  Fixes a crash
	  when you destroy a lot.
	* src/engine/Transaction.[ch]: add an xaccTransClearReadOnly() function
	  to let you clear the flag so you can then remove an transaction.  Only
	  for internal uses only!  This is used by the Invoice UnPost code.
	* src/engine/gnc-lot.c: remove the lot from the account's list of lots
	  when the last split is gone.

	* src/business/business-core/gncInvoice.[ch]: implement Unpost function
	* src/business/business-ledger/gncEntryLedger.[ch]: change the
	  set_readonly() function to let you toggle back and forth between
	  readonly and readwrite ledgers.
	* src/business/business-gnome/dialog-invoice.c: implement unpost; set back
	  to readwrite if the unpost succeeds
	* src/business/business-gnome/dialog-order.c: use new set_readonly() API
	FIXES BUG #101452


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7750 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Derek Atkins 2003-01-02 04:07:58 +00:00
parent 05809c5a38
commit 5c8944868d
12 changed files with 163 additions and 31 deletions

View File

@ -27,7 +27,24 @@
for logic to apply a payment. Moved logic from dialog-payment.
* src/business/business-gnome/dialog-payment.c: move logic to
apply payment to business-core.
* src/engine/Account.[ch]: add an xaccAccountRemoveLot() function to allow
the LOT code to clear memory when you destroy a lot. Fixes a crash
when you destroy a lot.
* src/engine/Transaction.[ch]: add an xaccTransClearReadOnly() function
to let you clear the flag so you can then remove an transaction. Only
for internal uses only! This is used by the Invoice UnPost code.
* src/engine/gnc-lot.c: remove the lot from the account's list of lots
when the last split is gone.
* src/business/business-core/gncInvoice.[ch]: implement Unpost function
* src/business/business-ledger/gncEntryLedger.[ch]: change the
set_readonly() function to let you toggle back and forth between
readonly and readwrite ledgers.
* src/business/business-gnome/dialog-invoice.c: implement unpost; set back
to readwrite if the unpost succeeds
* src/business/business-gnome/dialog-order.c: use new set_readonly() API
FIXES BUG #101452
2002-12-30 Benoit Grégoire <bock@step.polymtl.ca>
* src/import-export/hbci/druid-hbci-initial.c

View File

@ -514,7 +514,18 @@ gboolean gncInvoiceIsDirty (GncInvoice *invoice)
}
static void
gncInvoiceAttachInvoiceToLot (GncInvoice *invoice, GNCLot *lot)
gncInvoiceDetachFromLot (GNCLot *lot)
{
kvp_frame *kvp;
if (!lot) return;
kvp = gnc_lot_get_slots (lot);
kvp_frame_set_slot_path (kvp, NULL, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL);
}
static void
gncInvoiceAttachToLot (GncInvoice *invoice, GNCLot *lot)
{
kvp_frame *kvp;
kvp_value *value;
@ -552,7 +563,7 @@ GncInvoice * gncInvoiceGetInvoiceFromLot (GNCLot *lot)
}
static void
gncInvoiceAttachInvoiceToTxn (GncInvoice *invoice, Transaction *txn)
gncInvoiceAttachToTxn (GncInvoice *invoice, Transaction *txn)
{
kvp_frame *kvp;
kvp_value *value;
@ -775,8 +786,8 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
}
/* Now attach this invoice to the txn, lot, and account */
gncInvoiceAttachInvoiceToLot (invoice, lot);
gncInvoiceAttachInvoiceToTxn (invoice, txn);
gncInvoiceAttachToLot (invoice, lot);
gncInvoiceAttachToTxn (invoice, txn);
gncInvoiceSetPostedAcc (invoice, acc);
xaccTransSetReadOnly (txn, _("Generated from an invoice. Try unposting the invoice."));
@ -843,6 +854,49 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
return txn;
}
gboolean
gncInvoiceUnpost (GncInvoice *invoice)
{
Transaction *txn;
GNCLot *lot;
if (!invoice) return FALSE;
if (!gncInvoiceIsPosted (invoice)) return FALSE;
txn = gncInvoiceGetPostedTxn (invoice);
g_return_val_if_fail (txn, FALSE);
lot = gncInvoiceGetPostedLot (invoice);
g_return_val_if_fail (lot, FALSE);
/* Destroy the Posted Transaction */
xaccTransClearReadOnly (txn);
xaccTransBeginEdit (txn);
xaccTransDestroy (txn);
xaccTransCommitEdit (txn);
/* Disconnect the lot from the invoice; re-attach to the invoice owner */
gncInvoiceDetachFromLot (lot);
gncOwnerAttachToLot (&invoice->owner, lot);
/* If the lot has no splits, then destroy it */
if (!gnc_lot_count_splits (lot))
gnc_lot_destroy (lot);
/* Clear out the invoice posted information */
gncInvoiceBeginEdit (invoice);
invoice->posted_acc = NULL;
invoice->posted_txn = NULL;
invoice->posted_lot = NULL;
invoice->date_posted.tv_sec = invoice->date_posted.tv_nsec = 0;
mark_invoice (invoice);
gncInvoiceCommitEdit (invoice);
return TRUE;
}
static gboolean
gnc_lot_match_invoice_owner (GNCLot *lot, gpointer user_data)
{

View File

@ -78,6 +78,16 @@ gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
Timespec *posted_date, Timespec *due_date,
const char *memo);
/*
* UNpost this invoice. This will destroy the posted transaction
* and return the invoice to its unposted state. It may leave empty
* lots out there.
*
* Returns TRUE if successful, FALSE if there is a problem.
*/
gboolean
gncInvoiceUnpost (GncInvoice *invoice);
/*
* Apply a payment of "amount" for the owner, between the xfer_account
* (bank or other asset) and the posted_account (A/R or A/P).

View File

@ -572,11 +572,11 @@ gnc_invoice_window_postCB (GtkWidget *widget, gpointer data)
/* Reset the type; change to read-only! */
iw->dialog_type = VIEW_INVOICE;
gnc_entry_ledger_set_readonly (iw->ledger);
gnc_entry_ledger_set_readonly (iw->ledger, TRUE);
/* ... and redisplay here. */
gnc_invoice_update_window (iw);
gnc_table_refresh_gui (gnc_entry_ledger_get_table (iw->ledger), TRUE);
gnc_table_refresh_gui (gnc_entry_ledger_get_table (iw->ledger), FALSE);
}
void
@ -598,7 +598,17 @@ gnc_invoice_window_unpostCB (GtkWidget *widget, gpointer data)
if (!result) return;
/* Attempt to unpost the invoice */
gnc_suspend_gui_refresh ();
result = gncInvoiceUnpost (invoice);
gnc_resume_gui_refresh ();
if (!result) return;
/* if we get here, we succeeded in unposting -- reset the ledger and redisplay */
iw->dialog_type = EDIT_INVOICE;
gnc_entry_ledger_set_readonly (iw->ledger, FALSE);
gnc_invoice_update_window (iw);
gnc_table_refresh_gui (gnc_entry_ledger_get_table (iw->ledger), FALSE);
}
void gnc_invoice_window_cut_cb (GtkWidget *widget, gpointer data)
@ -1469,7 +1479,7 @@ gnc_invoice_update_window (InvoiceWindow *iw)
* XXX: right now we always can, but there
* may be times in the future when we cannot.
*/
//can_unpost = TRUE;
can_unpost = TRUE;
ts = gncInvoiceGetDatePosted (invoice);
gnc_date_edit_set_time_ts (GNC_DATE_EDIT (iw->posted_date), ts);

View File

@ -277,7 +277,7 @@ gnc_order_window_close_order_cb (GtkWidget *widget, gpointer data)
/* Reset the type; change to read-only */
ow->dialog_type = VIEW_ORDER;
gnc_entry_ledger_set_readonly (ow->ledger);
gnc_entry_ledger_set_readonly (ow->ledger, TRUE);
/* And redisplay the window */
gnc_order_update_window (ow);

View File

@ -511,32 +511,51 @@ gboolean gnc_entry_ledger_find_entry (GncEntryLedger *ledger, GncEntry *entry,
return FALSE;
}
void gnc_entry_ledger_set_readonly (GncEntryLedger *ledger)
void gnc_entry_ledger_set_readonly (GncEntryLedger *ledger, gboolean readonly)
{
if (!ledger) return;
/* reset the ledger type to a viewer */
switch (ledger->type) {
case GNCENTRY_ORDER_ENTRY:
ledger->type = GNCENTRY_ORDER_VIEWER;
break;
case GNCENTRY_INVOICE_ENTRY:
ledger->type = GNCENTRY_INVOICE_VIEWER;
create_invoice_query (ledger);
break;
case GNCENTRY_BILL_ENTRY:
ledger->type = GNCENTRY_BILL_VIEWER;
create_invoice_query (ledger);
break;
default:
return; /* Nothing to do */
/* reset the ledger type appropriately */
if (readonly) {
switch (ledger->type) {
case GNCENTRY_ORDER_ENTRY:
ledger->type = GNCENTRY_ORDER_VIEWER;
break;
case GNCENTRY_INVOICE_ENTRY:
ledger->type = GNCENTRY_INVOICE_VIEWER;
create_invoice_query (ledger);
break;
case GNCENTRY_BILL_ENTRY:
ledger->type = GNCENTRY_BILL_VIEWER;
create_invoice_query (ledger);
break;
default:
return; /* Nothing to do */
}
} else {
switch (ledger->type) {
case GNCENTRY_ORDER_VIEWER:
ledger->type = GNCENTRY_ORDER_ENTRY;
break;
case GNCENTRY_INVOICE_VIEWER:
ledger->type = GNCENTRY_INVOICE_ENTRY;
create_invoice_query (ledger);
break;
case GNCENTRY_BILL_VIEWER:
ledger->type = GNCENTRY_BILL_ENTRY;
create_invoice_query (ledger);
break;
default:
return; /* Nothing to do */
}
}
/* reset the model */
gnc_table_model_set_read_only (ledger->table->model, TRUE);
gnc_table_model_set_read_only (ledger->table->model, readonly);
/* get rid of the blank entry, if it exists */
gnc_entry_ledger_clear_blank_entry (ledger);
/* if readonly is TRUE, get rid of the blank entry. */
if (readonly)
gnc_entry_ledger_clear_blank_entry (ledger);
/* and refresh the display */
gnc_entry_ledger_display_refresh (ledger);

View File

@ -86,7 +86,7 @@ void gnc_entry_ledger_set_colors (GncEntryLedgerColors reg_colors_new);
void gnc_entry_ledger_set_parent (GncEntryLedger *ledger, gncUIWidget parent);
void gnc_entry_ledger_set_readonly (GncEntryLedger *ledger);
void gnc_entry_ledger_set_readonly (GncEntryLedger *ledger, gboolean readonly);
gboolean gnc_entry_ledger_changed (GncEntryLedger *ledger);

View File

@ -963,6 +963,18 @@ xaccClearMarkDownGr (AccountGroup *grp, short val)
/********************************************************************\
\********************************************************************/
void
xaccAccountRemoveLot (Account *acc, GNCLot *lot)
{
if (!acc || !lot) return;
ENTER ("(acc=%p, lot=%p)", acc, lot);
xaccAccountBeginEdit (acc);
acc->lots = g_list_remove (acc->lots, lot);
xaccAccountCommitEdit (acc);
LEAVE ("(acc=%p, lot=%p)", acc, lot);
}
void
xaccAccountInsertLot (Account *acc, GNCLot *lot)
{
@ -990,7 +1002,7 @@ xaccAccountInsertLot (Account *acc, GNCLot *lot)
lot->account = acc;
}
/* Move all slots over to the new account. At worst,
/* Move all splits over to the new account. At worst,
* this is a no-op. */
if (lot->splits)
{

View File

@ -203,6 +203,7 @@ gboolean xaccAccountEqual(Account *a, Account* b, gboolean check_guids);
* the lot, and all of the splits in it, will be moved from that
* account to this account. */
void xaccAccountInsertLot (Account *, GNCLot *);
void xaccAccountRemoveLot (Account *, GNCLot *);
/** The xaccAccountInsertSplit() method will insert the indicated
* split into the indicated account. If the split already

View File

@ -2578,6 +2578,13 @@ xaccTransSetTxnType (Transaction *trans, char type)
kvp_value_delete (value);
}
void xaccTransClearReadOnly (Transaction *trans)
{
if (!trans) return;
kvp_frame_set_slot_path (trans->kvp_data, NULL, TRANS_READ_ONLY_REASON, NULL);
}
void
xaccTransSetReadOnly (Transaction *trans, const char *reason)
{

View File

@ -232,6 +232,7 @@ SplitList * xaccTransGetSplitList (const Transaction *trans);
/** Set the transaction to be ReadOnly */
void xaccTransSetReadOnly (Transaction *trans, const char *reason);
void xaccTransClearReadOnly (Transaction *trans);
/** FIXME: document me */
const char * xaccTransGetReadOnly (const Transaction *trans);
/** FIXME: document me */

View File

@ -258,6 +258,7 @@ gnc_lot_remove_split (GNCLot *lot, Split *split)
if (NULL == lot->splits)
{
xaccAccountRemoveLot (lot->account, lot);
lot->account = NULL;
}
}