Merge branch 'maint'

This commit is contained in:
Christopher Lam 2023-01-30 09:56:13 +08:00
commit 119356752f
11 changed files with 191 additions and 179 deletions

View File

@ -1826,7 +1826,7 @@ def gnc_numeric_from_decimal(decimal_value):
TEN = int(Decimal(0).radix()) # this is always 10
numerator_place_value = 1
# add each digit to the final value multiplied by the place value
# from least significant to most sigificant
# from least significant to most significant
for i in range(len(digits)-1,-1,-1):
numerator += digits[i] * numerator_place_value
numerator_place_value *= TEN

View File

@ -66,7 +66,7 @@ def gnc_numeric_from_decimal(decimal_value):
TEN = int(Decimal(0).radix()) # this is always 10
numerator_place_value = 1
# add each digit to the final value multiplied by the place value
# from least significant to most sigificant
# from least significant to most significant
for i in range(len(digits)-1,-1,-1):
numerator += digits[i] * numerator_place_value
numerator_place_value *= TEN

View File

@ -8,7 +8,7 @@ id,company,name,addr1,addr2,addr3,addr4,phone,fax,email,notes,shipname,shipaddr1
#company with the same ID will be UPDATED. This may not be what you want!
000099,Average Company,Accounts Dept,50 Poor Avenue,,,,,,,,,,,,,,,
,Academy,Academy,Some Street,,,,555-237-6959,,,,,,,,,,shipmail
,company,name,addr1,addr2,addr3,addr4,phone,fax,emai,lnotes,shipname,shipaddr1,shipaddr2,shipaddr3,shipaddr4,shipphone,shipfax,shipemail
,company,name,addr1,addr2,addr3,addr4,phone,fax,email,notes,shipname,shipaddr1,shipaddr2,shipaddr3,shipaddr4,shipphone,shipfax,shipemail
,No Address Company,Accounts,,,,,,,,,,,,,,,,
#Just another example after a blank line

Can't render this file because it has a wrong number of fields in line 2.

View File

@ -990,7 +990,7 @@ gnc_invoice_post(InvoiceWindow *iw, struct post_invoice_params *post_params)
gncInvoiceSetCurrency (invoice, gncOwnerGetCurrency (gncInvoiceGetOwner (invoice)));
/* Fill in the conversion prices with feedback from the user */
text = _("One or more of the entries are for accounts different from the invoice/bill currency. You will be asked a conversion rate for each.");
text = _("One or more of the entries are for accounts different from the invoice/bill currency. You will be asked to enter a conversion rate for each.");
/* Ask the user for conversion rates for all foreign currencies
* (relative to the invoice currency) */

View File

@ -1568,23 +1568,34 @@ gboolean gnc_ui_payment_is_customer_payment(const Transaction *txn)
// ///////////////
static char *gen_split_desc (Transaction *txn, Split *split)
{
gnc_numeric value = xaccSplitGetValue(split);
gnc_numeric value = xaccSplitGetAmount(split);
Account *xfer_acct = xaccSplitGetAccount(split);
char *acct_name = gnc_account_get_full_name (xfer_acct);
const char *action = gnc_get_action_num (txn, split);
const char *memo = xaccSplitGetMemo (split);
char rec_state = xaccSplitGetReconcile (split);
const char *print_amt = xaccPrintAmount(value, gnc_account_print_info (xfer_acct, TRUE));
char *split_str = NULL;
char *rec_str = NULL;
if (rec_state == CREC)
rec_str = g_strdup_printf("[%s] ", _("Cleared"));
else if (rec_state == YREC)
rec_str = g_strdup_printf("[%s] ", _("Reconciled"));
else
rec_str = g_strdup("");
if (action && *action && memo && *memo)
split_str = g_strdup_printf ("%s: %s (%s, %s)", acct_name, print_amt,
split_str = g_strdup_printf ("%s%s: %s (%s, %s)", rec_str, acct_name, print_amt,
action, memo);
else if((action && *action) || (memo && *memo))
split_str = g_strdup_printf ("%s: %s (%s)", acct_name, print_amt,
split_str = g_strdup_printf ("%s%s: %s (%s)", rec_str, acct_name, print_amt,
action ? action : memo);
else
split_str = g_strdup_printf ("%s: %s", acct_name, print_amt);
split_str = g_strdup_printf ("%s%s: %s", rec_str, acct_name, print_amt);
g_free (acct_name);
g_free (rec_str);
return split_str;
}
@ -1621,8 +1632,8 @@ static Split *select_payment_split (GtkWindow *parent, Transaction *txn)
GList *node;
GtkWidget *first_rb = NULL;
int answer = GTK_BUTTONS_OK;
const char *message = _("While this transaction has multiple splits that can be considered\nas 'the payment split', gnucash only knows how to handle one.\n"
"Please select one, the others will be ignored.\n\n");
const char *message = _("While this transaction has multiple splits that can be considered\nas 'the payment split', GnuCash only knows how to handle one.\n"
"Please select one, the others will be discarded.\n\n");
GtkDialog *dialog = GTK_DIALOG(
gtk_dialog_new_with_buttons (_("Warning"),
parent,
@ -1683,10 +1694,11 @@ static Split *select_payment_split (GtkWindow *parent, Transaction *txn)
static GList *select_txn_lots (GtkWindow *parent, Transaction *txn, Account **post_acct, gboolean *abort)
{
gboolean has_no_lot_apar_splits = FALSE;
SplitList *post_splits = NULL, *no_lot_post_splits = NULL;
SplitList *apar_splits = NULL; /* all spits in txn that are APAR type */
SplitList *apar_splits_no_lot = NULL; /* all splits in txn that are APAR type, but not tied to a lot */
SplitList *iter;
GList *txn_lots = NULL;
GList *unique_apar_accts = NULL;
/* There's no use in continuing if I can't set the post_acct or abort variables */
if (!post_acct || !abort)
@ -1695,11 +1707,20 @@ static GList *select_txn_lots (GtkWindow *parent, Transaction *txn, Account **po
*abort = FALSE;
*post_acct = NULL;
post_splits = xaccTransGetAPARAcctSplitList (txn, FALSE);
for (iter = post_splits; iter; iter = iter->next)
/* Start by filtering out all APAR splits that have lots. Those are the ones we can
display as invoices and pre-payments in the payment window. */
apar_splits = xaccTransGetAPARAcctSplitList (txn, FALSE);
for (iter = apar_splits; iter; iter = iter->next)
{
GNCLot *postlot = NULL;
Split *post_split = iter->data;
Account *apar_acct = xaccSplitGetAccount (post_split);
/* Store found apar_acct in our list of unique_apar_accts
* for later processing */
if (!g_list_find (unique_apar_accts, apar_acct))
unique_apar_accts = g_list_prepend (unique_apar_accts, apar_acct);
postlot = xaccSplitGetLot (post_split);
if (postlot)
{
@ -1707,59 +1728,55 @@ static GList *select_txn_lots (GtkWindow *parent, Transaction *txn, Account **po
lot_info->lot = postlot;
lot_info->amount = xaccSplitGetValue (post_split);
txn_lots = g_list_prepend (txn_lots, lot_info);
*post_acct = xaccSplitGetAccount (post_split);
*post_acct = apar_acct;
}
else
{
/* Make sure not to override post_acct if it was set above from a lot split */
if (!*post_acct)
*post_acct = xaccSplitGetAccount (post_split);
no_lot_post_splits = g_list_prepend (no_lot_post_splits, post_split);
has_no_lot_apar_splits = TRUE;
}
apar_splits_no_lot = g_list_prepend (apar_splits_no_lot, post_split);
}
g_list_free (apar_splits);
g_list_free (post_splits);
/* If no post_acct was selected from the postlots, fall back to the first apar split's
* account if there is one. */
if (!*post_acct && apar_splits_no_lot)
*post_acct = xaccSplitGetAccount (apar_splits_no_lot->data);
g_list_free (apar_splits_no_lot);
/* If the txn has both APAR splits linked to a business lot and
* splits that are not, issue a warning some will be discarded.
/* Abort if the txn has splits in more than one APAR account
* GnuCash can only handle one post account per payment transaction.
*/
if (has_no_lot_apar_splits && gnc_list_length_cmp (txn_lots, 0))
if (g_list_length (unique_apar_accts) > 1)
{
GtkWidget *dialog;
char *split_str = g_strdup ("");
for (iter = no_lot_post_splits; iter; iter = iter->next)
for (iter = unique_apar_accts; iter; iter = iter->next)
{
Split *post_split = iter->data;
char *tmp_str = gen_split_desc (txn, post_split);
char *tmp_str2 = g_strconcat(split_str, "", tmp_str, "\n", NULL);
g_free (tmp_str);
Account *acct = iter->data;
char *acct_name = gnc_account_get_full_name (acct);
char *tmp_str = g_strconcat(split_str, "", acct_name, "\n", NULL);
g_free (acct_name);
g_free (split_str);
split_str = tmp_str2;
split_str = tmp_str;
}
dialog = gtk_message_dialog_new (parent,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_CANCEL,
_("The transaction has at least one split in a business account that is not part of a business transaction.\n"
"If you continue these splits will be ignored:\n\n%s\n"
"Do you wish to continue and ignore these splits?"),
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
_("This transaction has splits in multiple business accounts:\n\n%s\n"
"GnuCash can only handle transactions that post to a single account.\n\n"
"Please correct this manually by editing the transaction directly and then try again."),
split_str);
gtk_dialog_add_buttons (GTK_DIALOG(dialog),
_("Continue"), GTK_BUTTONS_OK, NULL);
gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_BUTTONS_CANCEL);
if (gtk_dialog_run (GTK_DIALOG(dialog)) != GTK_BUTTONS_OK)
{
*abort = TRUE;
g_list_free_full (txn_lots, g_free);
txn_lots = NULL;
}
gtk_dialog_run (GTK_DIALOG(dialog));
gtk_widget_destroy (dialog);
PINFO("Multiple asset accounts in splits of txn \"%s\"; cannot use this for assigning a payment.",
xaccTransGetDescription(txn));
g_free (split_str);
}
g_list_free (no_lot_post_splits);
*abort = TRUE;
g_list_free_full (txn_lots, g_free);
txn_lots = NULL;
}
return txn_lots;
}
@ -1808,7 +1825,8 @@ PaymentWindow * gnc_ui_payment_new_with_txn (GtkWindow* parent, GncOwner *owner,
GDate txn_date = xaccTransGetDatePostedGDate (txn);
gnc_ui_payment_window_set_date(pw, &txn_date);
}
gnc_ui_payment_window_set_amount(pw, xaccSplitGetValue(payment_split));
gnc_ui_payment_window_set_amount(pw, xaccSplitConvertAmount (payment_split, post_acct));
if (payment_split)
gnc_ui_payment_window_set_xferaccount(pw, xaccSplitGetAccount(payment_split));
return pw;

View File

@ -666,7 +666,7 @@
;; function to count the total number of splits to be iterated
(define (gnc:accounts-count-splits accounts)
(apply + (map length (map xaccAccountGetSplitList accounts))))
(fold (lambda (a b) (+ b (length (xaccAccountGetSplitList a)))) 0 accounts))
;; Sums up any splits of a certain type affecting a set of accounts.
;; the type is an alist '((str "match me") (cased #f) (regexp #f))
@ -912,7 +912,7 @@
(define (not-APAR? s)
(not (xaccAccountIsAPARType (xaccAccountGetType (xaccSplitGetAccount s)))))
;; analyse a payment transaction and return a 3-element vector:
;; (vector invoices opposing-splits overpayment)
;; (vector invoices overpayment opposing-splits)
;;
;; invoices: a list of (cons invoice inv-APAR-split)
;; opposing-splits: a list of (list pmt-APAR-split partial-amount derived?)
@ -920,44 +920,49 @@
;; amount does not match the transaction amount
;; overpayment: a number indicating overpayment amount
(define (gnc:payment-txn->payment-info txn)
(let lp ((splits (xaccTransGetSplitList txn))
(invoices '())
(overpayment 0)
(opposing-splits '()))
(match splits
(() (vector invoices opposing-splits overpayment))
(((? not-APAR? split) . rest)
(lp rest invoices (+ overpayment (xaccSplitGetAmount split))
opposing-splits))
((split . rest)
(let* ((lot (xaccSplitGetLot split))
(lot-all-splits (gnc-lot-get-split-list lot)))
(define split=? (cut equal? <> split))
(match (gncInvoiceGetInvoiceFromLot lot)
(() (let lp1 ((lot-splits lot-all-splits)
(overpayment overpayment)
(opposing-splits opposing-splits))
(match lot-splits
(() (lp rest invoices overpayment opposing-splits))
(((? split=?) . tail) (lp1 tail overpayment opposing-splits))
((s . tail)
(let* ((lot-bal (gnc-lot-get-balance lot))
(lot-bal (if (sign-equal? lot-bal (xaccSplitGetAmount s))
0 lot-bal))
(derived? (not (zero? lot-bal)))
(partial-amount
(fold
(lambda (a b)
(if (equal? s a) b (+ b (xaccSplitGetAmount a))))
(- lot-bal) lot-all-splits)))
(lp1 tail (+ overpayment partial-amount)
(cons (list s partial-amount derived?)
opposing-splits)))))))
(inv
(lp rest
(cons (cons inv split) invoices)
(+ overpayment (xaccSplitGetAmount split))
opposing-splits))))))))
(let* ((apar-split (xaccTransGetFirstAPARAcctSplit txn #t))
(apar-acct (xaccSplitGetAccount apar-split)))
(let lp ((splits (xaccTransGetSplitList txn))
(invoices '())
(overpayment 0)
(opposing-splits '()))
(match splits
(() (vector invoices opposing-splits overpayment))
(((? not-APAR? split) . rest)
(gnc:msg "next " (gnc:strify split) " overpayment " (+ overpayment (xaccSplitConvertAmount split apar-acct)))
(lp rest invoices (+ overpayment (xaccSplitConvertAmount split apar-acct))
opposing-splits))
((split . rest)
(let* ((lot (xaccSplitGetLot split))
(lot-all-splits (gnc-lot-get-split-list lot)))
(define split=? (cut equal? <> split))
(match (gncInvoiceGetInvoiceFromLot lot)
(() (let lp1 ((lot-splits lot-all-splits)
(overpayment overpayment)
(opposing-splits opposing-splits))
(match lot-splits
(() (lp rest invoices overpayment opposing-splits))
(((? split=?) . tail) (lp1 tail overpayment opposing-splits))
((s . tail)
(let* ((lot-bal (gnc-lot-get-balance lot))
(lot-bal (if (sign-equal? lot-bal (xaccSplitConvertAmount s apar-acct))
0 lot-bal))
(derived? (not (zero? lot-bal)))
(partial-amount
(fold
(lambda (a b)
(if (equal? s a) b (+ b (xaccSplitConvertAmount a apar-acct))))
(- lot-bal) lot-all-splits)))
(gnc:msg "next " (gnc:strify s) " overpayment " (+ overpayment partial-amount))
(lp1 tail (+ overpayment partial-amount)
(cons (list s partial-amount derived?)
opposing-splits)))))))
(inv
(gnc:msg "next " (gnc:strify split) " overpayment " (+ overpayment (xaccSplitConvertAmount split apar-acct)))
(lp rest
(cons (cons inv split) invoices)
(+ overpayment (xaccSplitConvertAmount split apar-acct))
opposing-splits)))))))))
;; create a stepped list, then add a date in the infinite future for
;; the "current" bucket
@ -971,7 +976,7 @@
(define-public (gnc:owner-splits->aging-list splits num-buckets
to-date date-type receivable?)
(gnc:msg "processing " (qof-print-date to-date) " date-type " date-type
"receivable? " receivable?)
" receivable? " receivable?)
(let ((bucket-dates (make-extended-interval-list to-date (- num-buckets 3)))
(buckets (make-vector num-buckets 0)))
(define (addbucket! idx amt)
@ -989,10 +994,11 @@
(xaccSplitGetParent (car splits))))
(lot (gncInvoiceGetPostedLot invoice))
(lot-splits (gnc-lot-get-split-list lot))
(apar-acct (gncInvoiceGetPostedAcc invoice))
(bal (fold
(lambda (a b)
(if (<= (xaccTransGetDate (xaccSplitGetParent a)) to-date)
(+ (xaccSplitGetAmount a) b)
(+ (xaccSplitConvertAmount a apar-acct) b)
b))
0 lot-splits))
(bal (if receivable? bal (- bal)))

View File

@ -453,6 +453,10 @@
44
(gnc:accounts-count-splits (list expense income)))
(test-equal "gnc:accounts-count-splits null"
0
(gnc:accounts-count-splits '()))
(let ((account-balances (gnc:get-assoc-account-balances
(list bank gbp-bank)
(lambda (acct)

View File

@ -103,7 +103,7 @@
* interest only loan), or large enough to fully repay both the interest and
* principal during the term of the loan (a fully amoritized loan). Many loans
* fall somewhere between, with payments that do not fully cover repayment of
* both the principal and interst. These loans require a larger final payment
* both the principal and interest. These loans require a larger final payment
* (balloon) to complete their amortization. Payments may occur at the
* beginning or end of a payment period. If you and your friend had agreed on
* monthly repayment of the $800 loan at 12% NAR compounded monthly, twelve
@ -220,7 +220,7 @@
* compounding Frequency, CF, is simply the number of times per
* year, the monies in the financial transaction are compounded. In
* the U.S., monies are usually compounded daily on bank deposits,
* and monthly on loans. Somtimes Long term deposits are compounded
* and monthly on loans. Sometimes Long term deposits are compounded
* quarterly or weekly.
*
* The Payment Frequency, PF, is simply how often during a year
@ -596,7 +596,7 @@
* T[n] = -i*n*(PV + C) - i*C*n(n+1)/2
* T[n] = -i*n*(PV + (C*(n - 1)/2))
*
* Note: substituing for C = -PV/N, in the equations for PV[n], I[n],
* Note: substituting for C = -PV/N, in the equations for PV[n], I[n],
* P[n], and T[n] would give the following equations:
*
* PV[n] = PV*(1 - n/N)
@ -739,12 +739,12 @@
* 1. The payment *, interest paid, principal paid and remaining PV
* for each payment period are computed and displayed. At the end of
* each year a summary is computed and displayed and the total
* interest paid is diplayed at the end.
* interest paid is displayed at the end.
*
* 2. A summary is computed and displayed for each year. The
* interest paid during the year is computed and displayed as well
* as the remaining balance at years end. The total interest paid
* is diplayed at the end.
* is displayed at the end.
*
* 3. An amortization schedule is computed for a common method of
* advanced payment of principal is computed and displayed. In this
@ -1016,7 +1016,7 @@
* Example 6: Balloon Payment
* On long term loans, small changes in the periodic payments can generate
* large changes in the future value. If the monthly payment in example 5 is
* rounded down to $1125, how much addtional (balloon) payment will be due
* rounded down to $1125, how much additional (balloon) payment will be due
* with the final regular payment.
* <>pmt=-1125
* -1,125
@ -2035,7 +2035,7 @@ Amortization_Schedule (amort_sched_ptr amortsched)
else
{
/* remaining pv less than advanced principal payment reduce
* advanced pricipal payment to remaining pv and set
* advanced principal payment to remaining pv and set
* remaining pv to fv */
adv_pmt = -pv;
pv = fv;
@ -2138,7 +2138,7 @@ Amortization_Schedule (amort_sched_ptr amortsched)
case 'o':
/* Constant payment to principal use constant payment equal to
* original pv divided by number of periods. constant payment to
* pricipal could be amount specified by user. */
* principal could be amount specified by user. */
amortsched->schedule.first_yr =
amortyr = (amort_sched_yr_ptr) calloc (1, sizeof (amort_sched_yr));
amortsched->total_periods = n;

View File

@ -71,7 +71,7 @@ returned.
Simple/ad-hoc lazy evaluation works well when data dependencies are
simple, but it breaks down when there are too many/circular
relationships. It becomes all too easy to get trapped in inifinite
relationships. It becomes all too easy to get trapped in infinite
loops of corrections. The goal of moving to a formal constraint
system is to introduce specific, well-defined sync points where
constraint checking can be done, without incuring circular

View File

@ -756,10 +756,12 @@ gncOwnerCreatePaymentLotSecs (const GncOwner *owner, Transaction **preset_txn,
QofBook *book;
Split *split;
const char *name;
gnc_commodity *commodity;
gnc_commodity *post_comm, *xfer_comm;
Split *xfer_split = NULL;
Transaction *txn = NULL;
GNCLot *payment_lot;
gnc_numeric xfer_amount = gnc_numeric_zero();
gnc_numeric txn_value = gnc_numeric_zero();
/* Verify our arguments */
if (!owner || !posted_acc || !xfer_acc) return NULL;
@ -768,7 +770,9 @@ gncOwnerCreatePaymentLotSecs (const GncOwner *owner, Transaction **preset_txn,
/* Compute the ancillary data */
book = gnc_account_get_book (posted_acc);
name = gncOwnerGetName (gncOwnerGetEndOwner ((GncOwner*)owner));
commodity = gncOwnerGetCurrency (owner);
post_comm = xaccAccountGetCommodity (posted_acc);
xfer_comm = xaccAccountGetCommodity (xfer_acc);
// reverse = use_reversed_payment_amounts(owner);
if (preset_txn && *preset_txn)
@ -776,110 +780,90 @@ gncOwnerCreatePaymentLotSecs (const GncOwner *owner, Transaction **preset_txn,
if (txn)
{
xaccTransSetDescription (txn, name ? name : "");
int i = 0;
/* Pre-existing transaction was specified. We completely clear it,
* except for the split in the transfer account, unless the
* transaction can't be reused (wrong currency, wrong transfer account).
* In that case, the transaction is simply removed and an new
* one created. */
* except for a pre-existing transfer split. We're very conservative
* in preserving that one as it may have been reconciled already. */
xfer_split = xaccTransFindSplitByAccount(txn, xfer_acc);
if (xaccTransGetCurrency(txn) != gncOwnerGetCurrency (owner))
xaccTransBeginEdit (txn);
while (i < xaccTransCountSplits(txn))
{
PINFO("Uh oh, mismatching currency/commodity between selected transaction and owner. We fall back to manual creation of a new transaction.");
xfer_split = NULL;
}
if (!xfer_split)
{
PINFO("Huh? Asset account not found anymore. Fully deleting old txn and now creating a new one.");
xaccTransBeginEdit (txn);
xaccTransDestroy (txn);
xaccTransCommitEdit (txn);
txn = NULL;
}
else
{
int i = 0;
xaccTransBeginEdit (txn);
while (i < xaccTransCountSplits(txn))
{
Split *split = xaccTransGetSplit (txn, i);
if (split == xfer_split)
{
gnc_set_num_action (NULL, split, num, _("Payment"));
++i;
}
else
{
xaccSplitDestroy(split);
}
}
/* Note: don't commit transaction now - that would insert an imbalance split.*/
Split *split = xaccTransGetSplit (txn, i);
if (split == xfer_split)
++i;
else
xaccSplitDestroy(split);
}
/* Note: don't commit transaction now - that would insert an imbalance split.*/
}
/* Create the transaction if we don't have one yet */
if (!txn)
else
{
txn = xaccMallocTransaction (book);
xaccTransBeginEdit (txn);
}
/* Complete transaction setup */
xaccTransSetDescription (txn, name ? name : "");
if (!gnc_commodity_equal(xaccTransGetCurrency (txn), post_comm) &&
!gnc_commodity_equal (xaccTransGetCurrency (txn), xfer_comm))
xaccTransSetCurrency (txn, xfer_comm);
/* With all commodities involved known, define split amounts and txn value.
* - post amount (amount passed in as parameter) is always in post_acct commodity,
* - xfer amount requires conversion if the xfer account has a different
* commodity than the post account.
* - txn value requires conversion if the post account has a different
* commodity than the transaction */
if (gnc_commodity_equal(post_comm, xfer_comm))
xfer_amount = amount;
else
xfer_amount = gnc_numeric_mul (amount, exch, GNC_DENOM_AUTO,
GNC_HOW_RND_ROUND_HALF_UP);
if (gnc_commodity_equal(post_comm, xaccTransGetCurrency (txn)))
txn_value = amount;
else
txn_value = gnc_numeric_mul (amount, exch, GNC_DENOM_AUTO,
GNC_HOW_RND_ROUND_HALF_UP);
/* Insert a split for the transfer account if we don't have one yet */
if (!xfer_split)
{
/* Set up the transaction */
xaccTransSetDescription (txn, name ? name : "");
/* set per book option */
xaccTransSetCurrency (txn, commodity);
/* The split for the transfer account */
split = xaccMallocSplit (book);
xaccSplitSetMemo (split, memo);
xfer_split = xaccMallocSplit (book);
xaccSplitSetMemo (xfer_split, memo);
/* set per book option */
gnc_set_num_action (NULL, split, num, _("Payment"));
gnc_set_num_action (NULL, xfer_split, num, _("Payment"));
xaccAccountBeginEdit (xfer_acc);
xaccAccountInsertSplit (xfer_acc, split);
xaccAccountInsertSplit (xfer_acc, xfer_split);
xaccAccountCommitEdit (xfer_acc);
xaccTransAppendSplit (txn, split);
xaccTransAppendSplit (txn, xfer_split);
if (gnc_commodity_equal(xaccAccountGetCommodity(xfer_acc), commodity))
{
xaccSplitSetBaseValue (split, amount, commodity);
}
else
{
/* This will be a multi-currency transaction. The amount passed to this
* function is in the owner commodity (also used by the post account).
* For the xfer split we also need to value the payment in the xfer account's
* commodity.
* exch is from post account to xfer account so that can be used directly
* to calculate the equivalent amount in the xfer account's commodity. */
gnc_numeric xfer_amount = gnc_numeric_mul (amount, exch, GNC_DENOM_AUTO,
GNC_HOW_RND_ROUND_HALF_UP);
xaccSplitSetAmount(split, xfer_amount); /* Payment in xfer account currency */
xaccSplitSetValue(split, amount); /* Payment in transaction currency */
}
xaccSplitSetAmount(xfer_split, xfer_amount); /* Payment in xfer account currency */
xaccSplitSetValue(xfer_split, txn_value); /* Payment in transaction currency */
}
/* For a pre-existing xfer split, let's check if the amount and value
* have changed. If so, update them and unreconcile. */
else if (!gnc_numeric_equal (xaccSplitGetAmount (xfer_split), xfer_amount) ||
!gnc_numeric_equal (xaccSplitGetValue (xfer_split), txn_value))
{
xaccSplitSetAmount (xfer_split, xfer_amount);
xaccSplitSetValue (xfer_split, txn_value);
xaccSplitSetReconcile (xfer_split, NREC);
}
/* Add a split in the post account */
split = xaccMallocSplit (book);
xaccSplitSetMemo (split, memo);
/* set per book option */
gnc_set_num_action (NULL, split, num, _("Payment"));
xaccSplitSetAction (split, _("Payment"));
xaccAccountBeginEdit (posted_acc);
xaccAccountInsertSplit (posted_acc, split);
xaccAccountCommitEdit (posted_acc);
xaccTransAppendSplit (txn, split);
xaccSplitSetBaseValue (split, gnc_numeric_neg (amount), commodity);
xaccSplitSetAmount (split, gnc_numeric_neg (amount));
xaccSplitSetValue (split, gnc_numeric_neg (txn_value));
/* Create a new lot for the payment */
payment_lot = gnc_lot_new (book);
@ -887,7 +871,7 @@ gncOwnerCreatePaymentLotSecs (const GncOwner *owner, Transaction **preset_txn,
gnc_lot_add_split (payment_lot, split);
/* Mark the transaction as a payment */
gnc_set_num_action (txn, NULL, num, _("Payment"));
xaccTransSetNum (txn, num);
xaccTransSetTxnType (txn, TXN_TYPE_PAYMENT);
/* Set date for transaction */

View File

@ -173,7 +173,7 @@ static void qof_instance_class_init(QofInstanceClass *klass)
"Object Last Update",
"A pointer to the last time this object was "
"updated. This value is present for use by "
"backends and shouldnot be written by other "
"backends and shouldn't be written by other "
"code.",
G_PARAM_READWRITE));