| #define gncInvoiceGetGUID | ( | x | ) | qof_instance_get_guid(QOF_INSTANCE(x)) |
deprecated functions
Definition at line 212 of file gncInvoice.h.
| #define gncInvoiceLookup | ( | book, | |||
| guid | ) | QOF_BOOK_LOOKUP_ENTITY((book),(guid),GNC_ID_INVOICE, GncInvoice) |
Return a pointer to the instance gncInvoice that is identified by the guid, and is residing in the book. Returns NULL if the instance can't be found. Equivalent function prototype is GncInvoice * gncInvoiceLookup (QofBook *book, const GUID *guid);
Definition at line 179 of file gncInvoice.h.
| void gncBillAddEntry | ( | GncInvoice * | bill, | |
| GncEntry * | entry | |||
| ) |
Call this function when adding an entry to a bill instead of an invoice
Definition at line 436 of file gncInvoice.c.
00437 { 00438 GncInvoice *old; 00439 00440 if (!bill || !entry) return; 00441 00442 old = gncEntryGetBill (entry); 00443 if (old == bill) return; /* I already own this one */ 00444 if (old) gncBillRemoveEntry (old, entry); 00445 00446 gncEntrySetBill (entry, bill); 00447 bill->entries = g_list_insert_sorted (bill->entries, entry, 00448 (GCompareFunc)gncEntryCompare); 00449 mark_invoice (bill); 00450 }
| GncInvoice* gncInvoiceGetInvoiceFromLot | ( | GNCLot * | lot | ) |
Given a LOT, find and return the Invoice attached to the lot
Definition at line 769 of file gncInvoice.c.
00770 { 00771 KvpFrame *kvp; 00772 KvpValue *value; 00773 GUID *guid; 00774 QofBook *book; 00775 00776 if (!lot) return NULL; 00777 00778 book = gnc_lot_get_book (lot); 00779 kvp = gnc_lot_get_slots (lot); 00780 value = kvp_frame_get_slot_path (kvp, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL); 00781 if (!value) return NULL; 00782 00783 guid = kvp_value_get_guid (value); 00784 return gncInvoiceLookup(book, guid); 00785 }
| GncInvoice* gncInvoiceGetInvoiceFromTxn | ( | Transaction * | txn | ) |
Given a transaction, find and return the Invoice
Definition at line 809 of file gncInvoice.c.
00810 { 00811 KvpFrame *kvp; 00812 KvpValue *value; 00813 GUID *guid; 00814 QofBook *book; 00815 00816 if (!txn) return NULL; 00817 00818 book = xaccTransGetBook (txn); 00819 kvp = xaccTransGetSlots (txn); 00820 value = kvp_frame_get_slot_path (kvp, GNC_INVOICE_ID, GNC_INVOICE_GUID, NULL); 00821 if (!value) return NULL; 00822 00823 guid = kvp_value_get_guid (value); 00824 return gncInvoiceLookup(book,guid); 00825 }
| gnc_numeric gncInvoiceGetTotal | ( | GncInvoice * | invoice | ) |
return the "total" amount of the invoice
Definition at line 592 of file gncInvoice.c.
00593 { 00594 if (!invoice) return gnc_numeric_zero(); 00595 return gncInvoiceGetTotalInternal(invoice, TRUE, TRUE, FALSE, 0); 00596 }
| Transaction* gncInvoicePostToAccount | ( | GncInvoice * | invoice, | |
| Account * | acc, | |||
| Timespec * | posted_date, | |||
| Timespec * | due_date, | |||
| const char * | memo, | |||
| gboolean | accumulatesplits | |||
| ) |
Post this invoice to an account. Returns the new Transaction that is tied to this invoice. The transaction is set with the supplied posted date, due date, and memo. The Transaction description is set to the name of the company.
Definition at line 856 of file gncInvoice.c.
00859 { 00860 Transaction *txn; 00861 QofBook *book; 00862 GNCLot *lot = NULL; 00863 GList *iter; 00864 GList *splitinfo = NULL; 00865 gnc_numeric total; 00866 gboolean reverse; 00867 const char *name, *type; 00868 char *lot_title; 00869 Account *ccard_acct = NULL; 00870 GncOwner *owner; 00871 00872 if (!invoice || !acc) return NULL; 00873 00874 gncInvoiceBeginEdit (invoice); 00875 book = qof_instance_get_book(invoice); 00876 00877 /* Stabilize the Billing Terms of this invoice */ 00878 if (invoice->terms) 00879 gncInvoiceSetTerms (invoice, 00880 gncBillTermReturnChild (invoice->terms, TRUE)); 00881 00882 /* Figure out if we need to "reverse" the numbers. */ 00883 reverse = (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_CUSTOMER); 00884 00885 /* Figure out if we need to separate out "credit-card" items */ 00886 owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice)); 00887 if (gncInvoiceGetOwnerType (invoice) == GNC_OWNER_EMPLOYEE) 00888 ccard_acct = gncEmployeeGetCCard (gncOwnerGetEmployee (owner)); 00889 00890 /* Find an existing payment-lot for this owner */ 00891 { 00892 LotList *lot_list; 00893 struct lotmatch lm; 00894 00895 lm.reverse = reverse; 00896 lm.owner = owner; 00897 00898 lot_list = xaccAccountFindOpenLots (acc, gnc_lot_match_owner_payment, 00899 &lm, NULL); 00900 if (lot_list) 00901 lot = lot_list->data; 00902 00903 g_list_free (lot_list); 00904 } 00905 00906 /* Create a new lot for this invoice, if we need to do so */ 00907 if (!lot) 00908 lot = gnc_lot_new (book); 00909 00910 type = gncInvoiceGetType (invoice); 00911 00912 /* Set the lot title */ 00913 lot_title = g_strdup_printf ("%s %s", type, gncInvoiceGetID (invoice)); 00914 gnc_lot_set_title (lot, lot_title); 00915 g_free (lot_title); 00916 00917 /* Create a new transaction */ 00918 txn = xaccMallocTransaction (book); 00919 xaccTransBeginEdit (txn); 00920 00921 name = gncOwnerGetName (gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice))); 00922 00923 /* Set Transaction Description (Owner Name) , Num (invoice ID), Currency */ 00924 xaccTransSetDescription (txn, name ? name : ""); 00925 xaccTransSetNum (txn, gncInvoiceGetID (invoice)); 00926 xaccTransSetCurrency (txn, invoice->currency); 00927 00928 /* Entered and Posted at date */ 00929 xaccTransSetDateEnteredSecs (txn, time(NULL)); 00930 if (post_date) { 00931 xaccTransSetDatePostedTS (txn, post_date); 00932 gncInvoiceSetDatePosted (invoice, *post_date); 00933 } 00934 00935 if (due_date) 00936 xaccTransSetDateDueTS (txn, due_date); 00937 00938 /* Iterate through the entries; sum up everything for each account. 00939 * then create the appropriate splits in this txn. 00940 */ 00941 total = gnc_numeric_zero(); 00942 for (iter = gncInvoiceGetEntries(invoice); iter; iter = iter->next) { 00943 gnc_numeric value, tax; 00944 GList *taxes; 00945 GncEntry * entry = iter->data; 00946 Account *this_acc; 00947 00948 /* Stabilize the TaxTable in this entry */ 00949 gncEntryBeginEdit (entry); 00950 if (reverse) 00951 gncEntrySetInvTaxTable 00952 (entry, gncTaxTableReturnChild (gncEntryGetInvTaxTable (entry), TRUE)); 00953 else { 00954 gncEntrySetBillTaxTable 00955 (entry, gncTaxTableReturnChild (gncEntryGetBillTaxTable (entry), TRUE)); 00956 00957 /* If this is a bill, and the entry is billable, copy the price */ 00958 if (gncEntryGetBillable (entry)) 00959 gncEntrySetInvPrice (entry, gncEntryGetBillPrice (entry)); 00960 } 00961 gncEntryCommitEdit (entry); 00962 00963 /* Obtain the Entry's Value and TaxValues */ 00964 gncEntryGetValue (entry, reverse, &value, NULL, &tax, &taxes); 00965 00966 /* add the value for the account split */ 00967 this_acc = (reverse ? gncEntryGetInvAccount (entry) : 00968 gncEntryGetBillAccount (entry)); 00969 if (this_acc) { 00970 if (gnc_numeric_check (value) == GNC_ERROR_OK) { 00971 if (accumulatesplits) { 00972 splitinfo = gncAccountValueAdd (splitinfo, this_acc, value); 00973 } else { 00974 Split *split; 00975 00976 split = xaccMallocSplit (book); 00977 /* set action and memo? */ 00978 00979 xaccSplitSetMemo (split, gncEntryGetDescription (entry)); 00980 xaccSplitSetAction (split, type); 00981 00982 /* Need to insert this split into the account AND txn before 00983 * we set the Base Value. Otherwise SetBaseValue complains 00984 * that we don't have an account and fails to set the value. 00985 */ 00986 xaccAccountBeginEdit (this_acc); 00987 xaccAccountInsertSplit (this_acc, split); 00988 xaccAccountCommitEdit (this_acc); 00989 xaccTransAppendSplit (txn, split); 00990 xaccSplitSetBaseValue (split, (reverse ? gnc_numeric_neg (value) 00991 : value), 00992 invoice->currency); 00993 } 00994 00995 /* If there is a credit-card account, and this is a CCard 00996 * payment type, the don't add it to the total, and instead 00997 * create a split to the CC Acct with a memo of the entry 00998 * description instead of the provided memo. Note that the 00999 * value reversal is the same as the post account. 01000 * 01001 * Note: we don't have to worry about the tax values -- 01002 * expense vouchers don't have them. 01003 */ 01004 if (ccard_acct && gncEntryGetBillPayment (entry) == GNC_PAYMENT_CARD) { 01005 Split *split; 01006 01007 split = xaccMallocSplit (book); 01008 /* set action? */ 01009 xaccSplitSetMemo (split, gncEntryGetDescription (entry)); 01010 xaccSplitSetAction (split, type); 01011 xaccAccountBeginEdit (ccard_acct); 01012 xaccAccountInsertSplit (ccard_acct, split); 01013 xaccAccountCommitEdit (ccard_acct); 01014 xaccTransAppendSplit (txn, split); 01015 xaccSplitSetBaseValue (split, (reverse ? value : gnc_numeric_neg (value)), 01016 invoice->currency); 01017 01018 } else 01019 total = gnc_numeric_add (total, value, GNC_DENOM_AUTO, GNC_DENOM_LCD); 01020 01021 } else 01022 g_warning ("bad value in our entry"); 01023 } 01024 01025 /* now merge in the TaxValues */ 01026 splitinfo = gncAccountValueAddList (splitinfo, taxes); 01027 01028 /* ... and add the tax total */ 01029 if (gnc_numeric_check (tax) == GNC_ERROR_OK) 01030 total = gnc_numeric_add (total, tax, GNC_DENOM_AUTO, GNC_DENOM_LCD); 01031 else 01032 g_warning ("bad tax in our entry"); 01033 01034 } /* for */ 01035 01036 /* Iterate through the splitinfo list and generate the splits */ 01037 for (iter = splitinfo; iter; iter = iter->next) { 01038 Split *split; 01039 GncAccountValue *acc_val = iter->data; 01040 01041 split = xaccMallocSplit (book); 01042 /* set action and memo? */ 01043 01044 xaccSplitSetMemo (split, memo); 01045 xaccSplitSetAction (split, type); 01046 01047 xaccAccountBeginEdit (acc_val->account); 01048 xaccAccountInsertSplit (acc_val->account, split); 01049 xaccAccountCommitEdit (acc_val->account); 01050 xaccTransAppendSplit (txn, split); 01051 xaccSplitSetBaseValue (split, (reverse ? gnc_numeric_neg (acc_val->value) 01052 : acc_val->value), 01053 invoice->currency); 01054 } 01055 01056 /* If there is a ccard account, we may have an additional "to_card" payment. 01057 * we should make that now.. 01058 */ 01059 if (ccard_acct && !gnc_numeric_zero_p (invoice->to_charge_amount)) { 01060 Split *split = xaccMallocSplit (book); 01061 01062 /* Set memo. action? */ 01063 xaccSplitSetMemo (split, _("Extra to Charge Card")); 01064 xaccSplitSetAction (split, type); 01065 01066 xaccAccountBeginEdit (ccard_acct); 01067 xaccAccountInsertSplit (ccard_acct, split); 01068 xaccAccountCommitEdit (ccard_acct); 01069 xaccTransAppendSplit (txn, split); 01070 xaccSplitSetBaseValue (split, (reverse ? invoice->to_charge_amount : 01071 gnc_numeric_neg(invoice->to_charge_amount)), 01072 invoice->currency); 01073 01074 total = gnc_numeric_sub (total, invoice->to_charge_amount, 01075 GNC_DENOM_AUTO, GNC_DENOM_LCD); 01076 } 01077 01078 /* Now create the Posted split (which is negative -- it's a credit) */ 01079 { 01080 Split *split = xaccMallocSplit (book); 01081 01082 /* Set action/memo */ 01083 xaccSplitSetMemo (split, memo); 01084 xaccSplitSetAction (split, type); 01085 01086 xaccAccountBeginEdit (acc); 01087 xaccAccountInsertSplit (acc, split); 01088 xaccAccountCommitEdit (acc); 01089 xaccTransAppendSplit (txn, split); 01090 xaccSplitSetBaseValue (split, (reverse ? total : gnc_numeric_neg (total)), 01091 invoice->currency); 01092 01093 /* add this split to the lot */ 01094 gnc_lot_add_split (lot, split); 01095 } 01096 01097 /* Now attach this invoice to the txn, lot, and account */ 01098 gncInvoiceAttachToLot (invoice, lot); 01099 gncInvoiceAttachToTxn (invoice, txn); 01100 gncInvoiceSetPostedAcc (invoice, acc); 01101 01102 xaccTransSetReadOnly (txn, _("Generated from an invoice. Try unposting the invoice.")); 01103 xaccTransCommitEdit (txn); 01104 01105 gncAccountValueDestroy (splitinfo); 01106 01107 /* check the lot -- if we still look like a payment lot, then that 01108 * means we need to create a balancing split and create a new payment 01109 * lot for the next invoice 01110 * 01111 * we're looking for a positive balance for bill/AP, and a negative balance 01112 * for invoice/AR. 01113 * (because bill payments debit AP accounts and invoice payments 01114 * credit AR accounts) 01115 */ 01116 total = gnc_lot_get_balance (lot); 01117 01118 if ( (gnc_numeric_negative_p (total) && reverse) || 01119 (gnc_numeric_positive_p (total) && !reverse) ) { 01120 Transaction *t2; 01121 GNCLot *lot2; 01122 Split *split; 01123 /* Translators: This is the memo of an auto-created split */ 01124 char *memo2 = _("Automatic Payment Forward"); 01125 char *action2 = _("Auto Split"); 01126 01127 t2 = xaccMallocTransaction (book); 01128 lot2 = gnc_lot_new (book); 01129 gncOwnerAttachToLot (gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice)), 01130 lot2); 01131 01132 xaccTransBeginEdit (t2); 01133 xaccAccountBeginEdit (acc); 01134 01135 /* Set Transaction Description (Owner Name), Currency */ 01136 xaccTransSetDescription (t2, name ? name : ""); 01137 xaccTransSetCurrency (t2, invoice->currency); 01138 01139 /* Entered and Posted at date */ 01140 xaccTransSetDateEnteredSecs (t2, time(NULL)); 01141 if (post_date) 01142 xaccTransSetDatePostedTS (t2, post_date); 01143 01144 /* Balance out this lot */ 01145 split = xaccMallocSplit (book); 01146 xaccSplitSetMemo (split, memo2); 01147 xaccSplitSetAction (split, action2); 01148 xaccAccountInsertSplit (acc, split); 01149 xaccTransAppendSplit (t2, split); 01150 // the value of total used here is correct for both bill/AP and 01151 // invoice/AR. See the comment before this if block 01152 xaccSplitSetBaseValue (split, gnc_numeric_neg (total), 01153 invoice->currency); 01154 gnc_lot_add_split (lot, split); 01155 01156 /* And apply the pre-payment to a new lot */ 01157 split = xaccMallocSplit (book); 01158 xaccSplitSetMemo (split, memo2); 01159 xaccSplitSetAction (split, action2); 01160 xaccAccountInsertSplit (acc, split); 01161 xaccTransAppendSplit (t2, split); 01162 xaccSplitSetBaseValue (split, total, invoice->currency); 01163 gnc_lot_add_split (lot2, split); 01164 01165 xaccTransCommitEdit (t2); 01166 xaccAccountCommitEdit (acc); 01167 } 01168 01169 gncInvoiceCommitEdit (invoice); 01170 01171 return txn; 01172 }
| void gncInvoiceSortEntries | ( | GncInvoice * | invoice | ) |
Call this function when an Entry is changed and you want to re-sort the list of entries
Definition at line 461 of file gncInvoice.c.
00462 { 00463 if (!invoice) return; 00464 invoice->entries = g_list_sort(invoice->entries, 00465 (GCompareFunc)gncEntryCompare); 00466 mark_invoice(invoice); 00467 }
| gboolean gncInvoiceUnpost | ( | GncInvoice * | invoice, | |
| gboolean | reset_tax_tables | |||
| ) |
UNpost this invoice. This will destroy the posted transaction and return the invoice to its unposted state. It may leave empty lots out there. If reset_tax_tables is TRUE, then it will also revert all the Tax Tables to the parent, which will potentially change the total value of the invoice. It may also leave some orphaned Tax Table children.
Returns TRUE if successful, FALSE if there is a problem.
Definition at line 1175 of file gncInvoice.c.
01176 { 01177 Transaction *txn; 01178 GNCLot *lot; 01179 01180 if (!invoice) return FALSE; 01181 if (!gncInvoiceIsPosted (invoice)) return FALSE; 01182 01183 txn = gncInvoiceGetPostedTxn (invoice); 01184 g_return_val_if_fail (txn, FALSE); 01185 01186 lot = gncInvoiceGetPostedLot (invoice); 01187 g_return_val_if_fail (lot, FALSE); 01188 01189 /* Destroy the Posted Transaction */ 01190 xaccTransClearReadOnly (txn); 01191 xaccTransBeginEdit (txn); 01192 xaccTransDestroy (txn); 01193 xaccTransCommitEdit (txn); 01194 01195 /* Disconnect the lot from the invoice; re-attach to the invoice owner */ 01196 gncInvoiceDetachFromLot (lot); 01197 gncOwnerAttachToLot (&invoice->owner, lot); 01198 01199 /* If the lot has no splits, then destroy it */ 01200 if (!gnc_lot_count_splits (lot)) 01201 gnc_lot_destroy (lot); 01202 01203 /* Clear out the invoice posted information */ 01204 gncInvoiceBeginEdit (invoice); 01205 01206 invoice->posted_acc = NULL; 01207 invoice->posted_txn = NULL; 01208 invoice->posted_lot = NULL; 01209 invoice->date_posted.tv_sec = invoice->date_posted.tv_nsec = 0; 01210 01211 /* if we've been asked to reset the tax tables, then do so */ 01212 if (reset_tax_tables) { 01213 gboolean reverse = (gncInvoiceGetOwnerType(invoice) == GNC_OWNER_CUSTOMER); 01214 GList *iter; 01215 01216 for (iter = gncInvoiceGetEntries(invoice); iter; iter = iter->next) { 01217 GncEntry *entry = iter->data; 01218 01219 gncEntryBeginEdit(entry); 01220 if (reverse) 01221 gncEntrySetInvTaxTable(entry, 01222 gncTaxTableGetParent(gncEntryGetInvTaxTable(entry))); 01223 else 01224 gncEntrySetBillTaxTable(entry, 01225 gncTaxTableGetParent(gncEntryGetBillTaxTable(entry))); 01226 gncEntryCommitEdit(entry); 01227 } 01228 } 01229 01230 mark_invoice (invoice); 01231 gncInvoiceCommitEdit (invoice); 01232 01233 return TRUE; 01234 }
| Transaction* gncOwnerApplyPayment | ( | GncOwner * | owner, | |
| GncInvoice * | invoice, | |||
| Account * | posted_acc, | |||
| Account * | xfer_acc, | |||
| gnc_numeric | amount, | |||
| Timespec | date, | |||
| const char * | memo, | |||
| const char * | num | |||
| ) |
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). If the caller supplies an (optional) invoice argument, then apply the payment to that invoice first before any other invoice.
XXX: yes, this should be in gncOwner, but all the other logic is in gncInvoice...
Definition at line 1279 of file gncInvoice.c.
01283 { 01284 QofBook *book; 01285 Account *inv_posted_acc; 01286 Transaction *txn; 01287 Split *split; 01288 GList *lot_list, *fifo = NULL; 01289 GNCLot *lot, *inv_posted_lot = NULL, *prepay_lot = NULL; 01290 GncInvoice *this_invoice; 01291 const char *name; 01292 gnc_commodity *commodity; 01293 gnc_numeric split_amt; 01294 gboolean reverse, inv_passed = TRUE; 01295 01296 /* Verify our arguments */ 01297 if (!owner || !posted_acc || !xfer_acc) return NULL; 01298 g_return_val_if_fail (owner->owner.undefined != NULL, NULL); 01299 01300 /* Compute the ancillary data */ 01301 book = gnc_account_get_book (posted_acc); 01302 name = gncOwnerGetName (gncOwnerGetEndOwner (owner)); 01303 commodity = gncOwnerGetCurrency (owner); 01304 reverse = (gncOwnerGetType (owner) == GNC_OWNER_CUSTOMER); 01305 01306 txn = xaccMallocTransaction (book); 01307 xaccTransBeginEdit (txn); 01308 01309 /* Set up the transaction */ 01310 xaccTransSetDescription (txn, name ? name : ""); 01311 xaccTransSetNum (txn, num); 01312 xaccTransSetCurrency (txn, commodity); 01313 xaccTransSetDateEnteredSecs (txn, time(NULL)); 01314 xaccTransSetDatePostedTS (txn, &date); 01315 xaccTransSetTxnType (txn, TXN_TYPE_PAYMENT); 01316 01317 /* The split for the transfer account */ 01318 split = xaccMallocSplit (book); 01319 xaccSplitSetMemo (split, memo); 01320 xaccSplitSetAction (split, _("Payment")); 01321 xaccAccountBeginEdit (xfer_acc); 01322 xaccAccountInsertSplit (xfer_acc, split); 01323 xaccAccountCommitEdit (xfer_acc); 01324 xaccTransAppendSplit (txn, split); 01325 xaccSplitSetBaseValue (split, reverse ? amount : 01326 gnc_numeric_neg (amount), commodity); 01327 01328 /* Now, find all "open" lots in the posting account for this 01329 * company and apply the payment on a FIFO basis. Create 01330 * a new split for each open lot until the payment is gone. 01331 */ 01332 01333 fifo = xaccAccountFindOpenLots (posted_acc, gnc_lot_match_invoice_owner, 01334 owner, 01335 (GCompareFunc)gnc_lot_sort_func); 01336 01337 /* Check if an invoice was passed in, and if so, does it match the 01338 * account, and is it an open lot? If so, put it at the beginning 01339 * of the lot list fifo so we post to this invoice's lot first. 01340 */ 01341 if (invoice) { 01342 inv_posted_acc = gncInvoiceGetPostedAcc(invoice); 01343 inv_posted_lot = gncInvoiceGetPostedLot(invoice); 01344 if (inv_posted_acc && inv_posted_lot && 01345 guid_equal(xaccAccountGetGUID(inv_posted_acc), 01346 xaccAccountGetGUID(posted_acc)) && 01347 !gnc_lot_is_closed(inv_posted_lot)) { 01348 /* Put this invoice at the beginning of the FIFO */ 01349 fifo = g_list_prepend (fifo, inv_posted_lot); 01350 inv_passed = FALSE; 01351 } 01352 } 01353 01354 xaccAccountBeginEdit (posted_acc); 01355 01356 /* Now iterate over the fifo until the payment is fully applied 01357 * (or all the lots are paid) 01358 */ 01359 for (lot_list = fifo; lot_list; lot_list = lot_list->next) { 01360 gnc_numeric balance; 01361 01362 lot = lot_list->data; 01363 01364 /* Skip this lot if it matches the invoice that was passed in and 01365 * we've seen it already. This way we post to it the first time 01366 * (from the beginning of the lot-list) but not when we reach it 01367 * the second time. 01368 */ 01369 if (inv_posted_lot && 01370 guid_equal(qof_instance_get_guid(QOF_INSTANCE(lot)), 01371 qof_instance_get_guid(QOF_INSTANCE(inv_posted_lot)))) { 01372 if (inv_passed) 01373 continue; 01374 else 01375 inv_passed = TRUE; 01376 } 01377 01378 balance = gnc_lot_get_balance (lot); 01379 01380 if (!reverse) 01381 balance = gnc_numeric_neg (balance); 01382 01383 /* If the balance is "negative" then skip this lot. 01384 * (just save the pre-payment lot for later) 01385 */ 01386 if (gnc_numeric_negative_p (balance)) { 01387 if (prepay_lot) { 01388 g_warning ("Multiple pre-payment lots are found. Skipping."); 01389 } else { 01390 prepay_lot = lot; 01391 } 01392 continue; 01393 } 01394 01395 /* 01396 * If the amount <= the balance; we're done -- apply the amount. 01397 * Otherwise, apply the balance, subtract that from the amount, 01398 * and move on to the next one. 01399 */ 01400 if (gnc_numeric_compare (amount, balance) <= 0) { 01401 /* amount <= balance */ 01402 split_amt = amount; 01403 } else { 01404 /* amount > balance */ 01405 split_amt = balance; 01406 } 01407 01408 /* reduce the amount by split_amt */ 01409 amount = gnc_numeric_sub (amount, split_amt, GNC_DENOM_AUTO, GNC_DENOM_LCD); 01410 01411 /* Create the split for this lot in the post account */ 01412 split = xaccMallocSplit (book); 01413 xaccSplitSetMemo (split, memo); 01414 xaccSplitSetAction (split, _("Payment")); 01415 xaccAccountInsertSplit (posted_acc, split); 01416 xaccTransAppendSplit (txn, split); 01417 xaccSplitSetBaseValue (split, reverse ? gnc_numeric_neg (split_amt) : 01418 split_amt, commodity); 01419 gnc_lot_add_split (lot, split); 01420 01421 /* Now send an event for the invoice so it gets updated as paid */ 01422 this_invoice = gncInvoiceGetInvoiceFromLot(lot); 01423 if (this_invoice) 01424 qof_event_gen (&this_invoice->inst, QOF_EVENT_MODIFY, NULL); 01425 01426 if (gnc_numeric_zero_p (amount)) 01427 break; 01428 } 01429 01430 g_list_free (fifo); 01431 01432 /* If there is still money left here, then create a pre-payment lot */ 01433 if (gnc_numeric_positive_p (amount)) { 01434 if (prepay_lot == NULL) { 01435 prepay_lot = gnc_lot_new (book); 01436 gncOwnerAttachToLot (owner, prepay_lot); 01437 } 01438 01439 split = xaccMallocSplit (book); 01440 xaccSplitSetMemo (split, memo); 01441 xaccSplitSetAction (split, _("Pre-Payment")); 01442 xaccAccountInsertSplit (posted_acc, split); 01443 xaccTransAppendSplit (txn, split); 01444 xaccSplitSetBaseValue (split, reverse ? gnc_numeric_neg (amount) : 01445 amount, commodity); 01446 gnc_lot_add_split (prepay_lot, split); 01447 } 01448 01449 xaccAccountCommitEdit (posted_acc); 01450 01451 /* Commit this new transaction */ 01452 xaccTransCommitEdit (txn); 01453 01454 return txn; 01455 }
1.5.2