Prepare internal post-to code to handle credit notes

At the same time clear up some confusing parameter names

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@21407 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Geert Janssens 2011-10-09 21:06:31 +00:00
parent 03db2c40b1
commit 1452956461
2 changed files with 69 additions and 25 deletions

View File

@ -778,7 +778,7 @@ const char * gncInvoiceGetNotes (const GncInvoice *invoice)
GncOwnerType gncInvoiceGetOwnerType (GncInvoice *invoice) GncOwnerType gncInvoiceGetOwnerType (GncInvoice *invoice)
{ {
GncOwner *owner; const GncOwner *owner;
g_return_val_if_fail (invoice, GNC_OWNER_NONE); g_return_val_if_fail (invoice, GNC_OWNER_NONE);
owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice)); owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
@ -1154,10 +1154,28 @@ gncInvoiceGetInvoiceFromTxn (const Transaction *txn)
return gncInvoiceLookup(book, guid); return gncInvoiceLookup(book, guid);
} }
gboolean gncInvoiceAmountPositive (GncInvoice *invoice)
{
switch (gncInvoiceGetType (invoice))
{
case GNC_INVOICE_CUST_INVOICE:
case GNC_INVOICE_VEND_CREDIT_NOTE:
case GNC_INVOICE_EMPL_CREDIT_NOTE:
return TRUE;
case GNC_INVOICE_CUST_CREDIT_NOTE:
case GNC_INVOICE_VEND_INVOICE:
case GNC_INVOICE_EMPL_INVOICE:
case GNC_INVOICE_UNDEFINED:
return FALSE;
default:
return FALSE;
}
}
struct lotmatch struct lotmatch
{ {
GncOwner *owner; GncOwner *owner;
gboolean reverse; gboolean positive_balance;
}; };
static gboolean static gboolean
@ -1168,7 +1186,7 @@ gnc_lot_match_owner_payment (GNCLot *lot, gpointer user_data)
gnc_numeric balance = gnc_lot_get_balance (lot); gnc_numeric balance = gnc_lot_get_balance (lot);
/* Is this a payment lot */ /* Is this a payment lot */
if (gnc_numeric_positive_p (lm->reverse ? balance : if (gnc_numeric_positive_p (lm->positive_balance ? balance :
gnc_numeric_neg (balance))) gnc_numeric_neg (balance)))
return FALSE; return FALSE;
@ -1194,7 +1212,8 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
GList *iter; GList *iter;
GList *splitinfo = NULL; GList *splitinfo = NULL;
gnc_numeric total; gnc_numeric total;
gboolean reverse; gboolean positive_balance;
gboolean is_cust_doc;
const char *name, *type; const char *name, *type;
char *lot_title; char *lot_title;
Account *ccard_acct = NULL; Account *ccard_acct = NULL;
@ -1210,8 +1229,13 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
gncInvoiceSetTerms (invoice, gncInvoiceSetTerms (invoice,
gncBillTermReturnChild (invoice->terms, TRUE)); gncBillTermReturnChild (invoice->terms, TRUE));
/* Figure out if we need to "reverse" the numbers. */ /* Does the invoice/credit note have a positive effect on the balance ? Note that
reverse = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER); * payments for such invoices by definition then have a negative effect on the balance.
* This is used to determine which open lots can be considered when posting the invoice. */
positive_balance = gncInvoiceAmountPositive (invoice);
/* GncEntry functions need to know if the invoice/credit note is for a customer or a vendor/employee. */
is_cust_doc = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER);
/* Figure out if we need to separate out "credit-card" items */ /* Figure out if we need to separate out "credit-card" items */
owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice)); owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
@ -1223,7 +1247,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
LotList *lot_list; LotList *lot_list;
struct lotmatch lm; struct lotmatch lm;
lm.reverse = reverse; lm.positive_balance = positive_balance;
lm.owner = owner; lm.owner = owner;
lot_list = xaccAccountFindOpenLots (acc, gnc_lot_match_owner_payment, lot_list = xaccAccountFindOpenLots (acc, gnc_lot_match_owner_payment,
@ -1281,7 +1305,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
/* Stabilize the TaxTable in this entry */ /* Stabilize the TaxTable in this entry */
gncEntryBeginEdit (entry); gncEntryBeginEdit (entry);
if (reverse) if (is_cust_doc)
gncEntrySetInvTaxTable gncEntrySetInvTaxTable
(entry, gncTaxTableReturnChild (gncEntryGetInvTaxTable (entry), TRUE)); (entry, gncTaxTableReturnChild (gncEntryGetInvTaxTable (entry), TRUE));
else else
@ -1296,10 +1320,10 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
gncEntryCommitEdit (entry); gncEntryCommitEdit (entry);
/* Obtain the Entry's Value and TaxValues */ /* Obtain the Entry's Value and TaxValues */
gncEntryGetValue (entry, reverse, &value, NULL, &tax, &taxes); gncEntryGetValue (entry, is_cust_doc, &value, NULL, &tax, &taxes);
/* add the value for the account split */ /* add the value for the account split */
this_acc = (reverse ? gncEntryGetInvAccount (entry) : this_acc = (is_cust_doc ? gncEntryGetInvAccount (entry) :
gncEntryGetBillAccount (entry)); gncEntryGetBillAccount (entry));
if (this_acc) if (this_acc)
{ {
@ -1328,9 +1352,19 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
xaccAccountCommitEdit (this_acc); xaccAccountCommitEdit (this_acc);
xaccTransAppendSplit (txn, split); xaccTransAppendSplit (txn, split);
/* General note on the split creations below:
* Invoice and bill amounts are always stored as positive values in entries
* So to convert them to proper splits, the amounts may have to be reverted
* to have the proper effect on the account balance.
* Credit notes have the opposite effect of invoices/bills, but their amounts
* are stored as negative values as well. So to convert them into splits
* they can be treated exactly the same as their invoice/bill counter parts.
* The net effect is that the owner type is sufficient to determine whether a
* value has to be reverted when converting an invoice/bill/cn amount to a split.
*/
if (gnc_commodity_equal(xaccAccountGetCommodity(this_acc), invoice->currency)) if (gnc_commodity_equal(xaccAccountGetCommodity(this_acc), invoice->currency))
{ {
xaccSplitSetBaseValue (split, (reverse ? gnc_numeric_neg (value) xaccSplitSetBaseValue (split, (is_cust_doc ? gnc_numeric_neg (value)
: value), : value),
invoice->currency); invoice->currency);
} }
@ -1350,10 +1384,10 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
else else
{ {
gnc_numeric converted_amount; gnc_numeric converted_amount;
xaccSplitSetValue(split, (reverse ? gnc_numeric_neg(value) : value)); xaccSplitSetValue(split, (is_cust_doc ? gnc_numeric_neg(value) : value));
converted_amount = gnc_numeric_div(value, gnc_price_get_value(price), GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP); converted_amount = gnc_numeric_div(value, gnc_price_get_value(price), GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP);
printf("converting from %f to %f\n", gnc_numeric_to_double(value), gnc_numeric_to_double(converted_amount)); printf("converting from %f to %f\n", gnc_numeric_to_double(value), gnc_numeric_to_double(converted_amount));
xaccSplitSetAmount(split, reverse ? gnc_numeric_neg(converted_amount) : converted_amount); xaccSplitSetAmount(split, is_cust_doc ? gnc_numeric_neg(converted_amount) : converted_amount);
} }
} }
} }
@ -1379,7 +1413,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
xaccAccountInsertSplit (ccard_acct, split); xaccAccountInsertSplit (ccard_acct, split);
xaccAccountCommitEdit (ccard_acct); xaccAccountCommitEdit (ccard_acct);
xaccTransAppendSplit (txn, split); xaccTransAppendSplit (txn, split);
xaccSplitSetBaseValue (split, (reverse ? value : gnc_numeric_neg (value)), xaccSplitSetBaseValue (split, (is_cust_doc ? value : gnc_numeric_neg (value)),
invoice->currency); invoice->currency);
} }
@ -1421,7 +1455,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
if (gnc_commodity_equal(xaccAccountGetCommodity(acc_val->account), invoice->currency)) if (gnc_commodity_equal(xaccAccountGetCommodity(acc_val->account), invoice->currency))
{ {
xaccSplitSetBaseValue (split, (reverse ? gnc_numeric_neg (acc_val->value) xaccSplitSetBaseValue (split, (is_cust_doc ? gnc_numeric_neg (acc_val->value)
: acc_val->value), : acc_val->value),
invoice->currency); invoice->currency);
} }
@ -1441,11 +1475,11 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
else else
{ {
gnc_numeric converted_amount; gnc_numeric converted_amount;
xaccSplitSetValue(split, (reverse ? gnc_numeric_neg(acc_val->value) : acc_val->value)); xaccSplitSetValue(split, (is_cust_doc ? gnc_numeric_neg(acc_val->value) : acc_val->value));
converted_amount = gnc_numeric_div(acc_val->value, gnc_price_get_value(price), GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP); converted_amount = gnc_numeric_div(acc_val->value, gnc_price_get_value(price), GNC_DENOM_AUTO, GNC_HOW_RND_ROUND_HALF_UP);
printf("converting from %f to %f\n", gnc_numeric_to_double(acc_val->value), gnc_numeric_to_double(converted_amount)); printf("converting from %f to %f\n", gnc_numeric_to_double(acc_val->value), gnc_numeric_to_double(converted_amount));
xaccSplitSetAmount(split, reverse ? gnc_numeric_neg(converted_amount) : converted_amount); xaccSplitSetAmount(split, is_cust_doc ? gnc_numeric_neg(converted_amount) : converted_amount);
} }
} }
} }
@ -1465,7 +1499,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
xaccAccountInsertSplit (ccard_acct, split); xaccAccountInsertSplit (ccard_acct, split);
xaccAccountCommitEdit (ccard_acct); xaccAccountCommitEdit (ccard_acct);
xaccTransAppendSplit (txn, split); xaccTransAppendSplit (txn, split);
xaccSplitSetBaseValue (split, (reverse ? invoice->to_charge_amount : xaccSplitSetBaseValue (split, (is_cust_doc ? invoice->to_charge_amount :
gnc_numeric_neg(invoice->to_charge_amount)), gnc_numeric_neg(invoice->to_charge_amount)),
invoice->currency); invoice->currency);
@ -1473,7 +1507,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD); GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
} }
/* Now create the Posted split (which is negative -- it's a credit) */ /* Now create the Posted split (which is the opposite sign of the above splits) */
{ {
Split *split = xaccMallocSplit (book); Split *split = xaccMallocSplit (book);
@ -1485,7 +1519,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
xaccAccountInsertSplit (acc, split); xaccAccountInsertSplit (acc, split);
xaccAccountCommitEdit (acc); xaccAccountCommitEdit (acc);
xaccTransAppendSplit (txn, split); xaccTransAppendSplit (txn, split);
xaccSplitSetBaseValue (split, (reverse ? total : gnc_numeric_neg (total)), xaccSplitSetBaseValue (split, (is_cust_doc ? total : gnc_numeric_neg (total)),
invoice->currency); invoice->currency);
/* add this split to the lot */ /* add this split to the lot */
@ -1513,8 +1547,8 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
*/ */
total = gnc_lot_get_balance (lot); total = gnc_lot_get_balance (lot);
if ( (gnc_numeric_negative_p (total) && reverse) || if ( (gnc_numeric_negative_p (total) && positive_balance) ||
(gnc_numeric_positive_p (total) && !reverse) ) (gnc_numeric_positive_p (total) && !positive_balance) )
{ {
Transaction *t2; Transaction *t2;
GNCLot *lot2; GNCLot *lot2;
@ -1613,7 +1647,7 @@ gncInvoiceUnpost (GncInvoice *invoice, gboolean reset_tax_tables)
/* if we've been asked to reset the tax tables, then do so */ /* if we've been asked to reset the tax tables, then do so */
if (reset_tax_tables) if (reset_tax_tables)
{ {
gboolean reverse = (gncInvoiceGetOwnerType(invoice) == GNC_OWNER_CUSTOMER); gboolean is_cust_doc = (gncInvoiceGetOwnerType(invoice) == GNC_OWNER_CUSTOMER);
GList *iter; GList *iter;
for (iter = gncInvoiceGetEntries(invoice); iter; iter = iter->next) for (iter = gncInvoiceGetEntries(invoice); iter; iter = iter->next)
@ -1621,7 +1655,7 @@ gncInvoiceUnpost (GncInvoice *invoice, gboolean reset_tax_tables)
GncEntry *entry = iter->data; GncEntry *entry = iter->data;
gncEntryBeginEdit(entry); gncEntryBeginEdit(entry);
if (reverse) if (is_cust_doc)
gncEntrySetInvTaxTable(entry, gncEntrySetInvTaxTable(entry,
gncTaxTableGetParent(gncEntryGetInvTaxTable(entry))); gncTaxTableGetParent(gncEntryGetInvTaxTable(entry)));
else else

View File

@ -137,7 +137,7 @@ GncBillTerm * gncInvoiceGetTerms (const GncInvoice *invoice);
const char * gncInvoiceGetBillingID (const GncInvoice *invoice); const char * gncInvoiceGetBillingID (const GncInvoice *invoice);
const char * gncInvoiceGetNotes (const GncInvoice *invoice); const char * gncInvoiceGetNotes (const GncInvoice *invoice);
GncOwnerType gncInvoiceGetOwnerType (GncInvoice *invoice); GncOwnerType gncInvoiceGetOwnerType (GncInvoice *invoice);
GList * gncInvoiceGetTypeListForOwnerType (GncOwnerType type); GList * gncInvoiceGetTypeListForOwnerType (const GncOwnerType type);
GncInvoiceType gncInvoiceGetType (GncInvoice *invoice); GncInvoiceType gncInvoiceGetType (GncInvoice *invoice);
const char * gncInvoiceGetTypeString (GncInvoice *invoice); const char * gncInvoiceGetTypeString (GncInvoice *invoice);
gnc_commodity * gncInvoiceGetCurrency (const GncInvoice *invoice); gnc_commodity * gncInvoiceGetCurrency (const GncInvoice *invoice);
@ -162,6 +162,16 @@ EntryList * gncInvoiceGetEntries (GncInvoice *invoice);
GList * gncInvoiceGetPrices(GncInvoice *invoice); GList * gncInvoiceGetPrices(GncInvoice *invoice);
GNCPrice * gncInvoiceGetPrice(GncInvoice *invoice, gnc_commodity* commodity); GNCPrice * gncInvoiceGetPrice(GncInvoice *invoice, gnc_commodity* commodity);
/** Depending on the invoice type, invoices have a different effect
* on the balance. Customer invoices increase the balance, while
* vendor bills decrease the balance. Credit notes have the opposite
* effect.
*
* Returns TRUE if the invoice will increase the balance or FALSE
* otherwise.
*/
gboolean gncInvoiceAmountPositive (GncInvoice *invoice);
/** Post this invoice to an account. Returns the new Transaction /** Post this invoice to an account. Returns the new Transaction
* that is tied to this invoice. The transaction is set with * that is tied to this invoice. The transaction is set with
* the supplied posted date, due date, and memo. The Transaction * the supplied posted date, due date, and memo. The Transaction