GnuCash  5.6-125-g579da58a10+
Files | Data Structures | Macros | Enumerations | Functions

Files

file  gncOwner.h
 Business Interface: Object OWNERs.
 

Data Structures

struct  GncOwner
 
struct  GncOwner
 

Macros

#define GNC_ID_OWNER   "gncOwner"
 
#define OWNER_TYPE   "type"
 
#define OWNER_TYPE_STRING   "type-string"
 Allows the type to be handled externally. More...
 
#define OWNER_CUSTOMER   "customer"
 
#define OWNER_JOB   "job"
 
#define OWNER_VENDOR   "vendor"
 
#define OWNER_EMPLOYEE   "employee"
 
#define OWNER_PARENT   "parent"
 
#define OWNER_PARENTG   "parent-guid"
 
#define OWNER_NAME   "name"
 
#define OWNER_FROM_LOT   "owner-from-lot"
 

Enumerations

enum  GncOwnerType {
  GNC_OWNER_NONE, GNC_OWNER_UNDEFINED, GNC_OWNER_CUSTOMER, GNC_OWNER_JOB,
  GNC_OWNER_VENDOR, GNC_OWNER_EMPLOYEE
}
 

Functions

void gncOwnerCopy (const GncOwner *src, GncOwner *dest)
 
const GncGUIDgncOwnerGetGUID (const GncOwner *owner)
 Get the GncGUID of the immediate owner.
 
GncGUID gncOwnerRetGUID (GncOwner *owner)
 
const GncOwnergncOwnerGetEndOwner (const GncOwner *owner)
 Get the "parent" Owner or GncGUID thereof. More...
 
const GncGUIDgncOwnerGetEndGUID (const GncOwner *owner)
 
void gncOwnerAttachToLot (const GncOwner *owner, GNCLot *lot)
 Attach an owner to a lot.
 
gboolean gncOwnerLotMatchOwnerFunc (GNCLot *lot, gpointer user_data)
 Helper function used to filter a list of lots by owner.
 
gint gncOwnerLotsSortFunc (GNCLot *lotA, GNCLot *lotB)
 Helper function used to sort lots by date. More...
 
gboolean gncOwnerGetOwnerFromLot (GNCLot *lot, GncOwner *owner)
 Get the owner from the lot. More...
 
gboolean gncOwnerGetOwnerFromTxn (Transaction *txn, GncOwner *owner)
 Convenience function to get the owner from a transaction. More...
 
gboolean gncOwnerGetOwnerFromTypeGuid (QofBook *book, GncOwner *owner, QofIdType type, GncGUID *guid)
 
GNCLot * gncOwnerCreatePaymentLotSecs (const GncOwner *owner, Transaction **preset_txn, Account *posted_acc, Account *xfer_acc, gnc_numeric amount, gnc_numeric exch, time64 date, const char *memo, const char *num)
 Create a lot for a payment to the owner using the other parameters passed in. More...
 
void gncOwnerAutoApplyPaymentsWithLots (const GncOwner *owner, GList *lots)
 Given a list of lots, try to balance as many of them as possible by creating balancing transactions between them. More...
 
void gncOwnerApplyPaymentSecs (const GncOwner *owner, Transaction **preset_txn, GList *lots, Account *posted_acc, Account *xfer_acc, gnc_numeric amount, gnc_numeric exch, time64 date, const char *memo, const char *num, gboolean auto_pay)
 A convenience function to apply a payment to the owner. More...
 
Split * gncOwnerFindOffsettingSplit (GNCLot *lot, gnc_numeric target_amount)
 Helper function to find a split in lot that best offsets target_amount Obviously it should be of opposite sign. More...
 
gboolean gncOwnerReduceSplitTo (Split *split, gnc_numeric target_amount)
 Helper function to reduce the amount of a split to target_amount. More...
 
void gncOwnerSetLotLinkMemo (Transaction *ll_txn)
 To help a user understand what a lot link transaction does, we set the memo to name all documents involved in the link. More...
 
GList * gncOwnerGetAccountTypesList (const GncOwner *owner)
 Returns a GList of account-types based on the owner type.
 
GList * gncOwnerGetCommoditiesList (const GncOwner *owner)
 Returns a GList of currencies associated with the owner.
 
gnc_numeric gncOwnerGetBalanceInCurrency (const GncOwner *owner, const gnc_commodity *report_currency)
 Given an owner, extract the open balance from the owner and then convert it to the desired currency.
 
GncOwnergncOwnerNew (void)
 These two functions are mainly for the convenience of scheme code. More...
 
void gncOwnerFree (GncOwner *owner)
 
void gncOwnerBeginEdit (GncOwner *owner)
 These are convenience wrappers around gnc{Vendor,Customer,Job,Employee}* functions. More...
 
void gncOwnerCommitEdit (GncOwner *owner)
 
void gncOwnerDestroy (GncOwner *owner)
 

QOF handling

Whilst GncOwner is not a formal QOF object, these functions are still expected to be useful in making GncOwner transparent to QOF as they can be used by objects like GncInvoice.

QofIdTypeConst qofOwnerGetType (const GncOwner *owner)
 return the type for the collection. More...
 
const char * gncOwnerGetTypeString (const GncOwner *owner)
 return the type for the owner as an untranslated string. More...
 
QofInstanceqofOwnerGetOwner (const GncOwner *owner)
 return the owner itself as an entity. More...
 
void qofOwnerSetEntity (GncOwner *owner, QofInstance *ent)
 set the owner from the entity. More...
 
gboolean GNC_IS_OWNER (QofInstance *ent)
 Check if entity is an owner kind. More...
 
QofIdTypeConst gncOwnerTypeToQofIdType (GncOwnerType t)
 Returns the QofIdType of the given GncOwnerType, or NULL if no suitable one exists. More...
 
gboolean gncOwnerRegister (void)
 

Setup routines

void gncOwnerInitUndefined (GncOwner *owner, gpointer obj)
 
void gncOwnerInitCustomer (GncOwner *owner, GncCustomer *customer)
 
void gncOwnerInitJob (GncOwner *owner, GncJob *job)
 
void gncOwnerInitVendor (GncOwner *owner, GncVendor *vendor)
 
void gncOwnerInitEmployee (GncOwner *owner, GncEmployee *employee)
 

Get routines.

GncOwnerType gncOwnerGetType (const GncOwner *owner)
 Returns the GncOwnerType of this owner. More...
 
gboolean gncOwnerIsValid (const GncOwner *owner)
 Returns TRUE if the given owner is one of the valid objects. More...
 
gpointer gncOwnerGetUndefined (const GncOwner *owner)
 If the given owner is of type GNC_OWNER_UNDEFINED, returns the undefined pointer, which is usually NULL. More...
 
GncCustomergncOwnerGetCustomer (const GncOwner *owner)
 If the given owner is of type GNC_OWNER_CUSTOMER, returns the pointer to the customer object. More...
 
GncJob * gncOwnerGetJob (const GncOwner *owner)
 If the given owner is of type GNC_OWNER_JOB, returns the pointer to the job object. More...
 
GncVendor * gncOwnerGetVendor (const GncOwner *owner)
 If the given owner is of type GNC_OWNER_VENDOR, returns the pointer to the vendor object. More...
 
GncEmployee * gncOwnerGetEmployee (const GncOwner *owner)
 If the given owner is of type GNC_OWNER_EMPLOYEE, returns the pointer to the employee object. More...
 
const char * gncOwnerGetID (const GncOwner *owner)
 
const char * gncOwnerGetName (const GncOwner *owner)
 
GncAddressgncOwnerGetAddr (const GncOwner *owner)
 
gboolean gncOwnerGetActive (const GncOwner *owner)
 
gnc_commodity * gncOwnerGetCurrency (const GncOwner *owner)
 

Set routines.

void gncOwnerSetActive (const GncOwner *owner, gboolean active)
 

Comparison routines.

gboolean gncOwnerEqual (const GncOwner *a, const GncOwner *b)
 Assess equality by checking. More...
 
int gncOwnerGCompareFunc (const GncOwner *a, const GncOwner *b)
 Same as gncOwnerEqual, but returns 0 if equal to be used as a GList custom compare function.
 
int gncOwnerCompare (const GncOwner *a, const GncOwner *b)
 Sort on name.
 

Detailed Description

Macro Definition Documentation

◆ OWNER_TYPE_STRING

#define OWNER_TYPE_STRING   "type-string"

Allows the type to be handled externally.

Definition at line 325 of file gncOwner.h.

Function Documentation

◆ GNC_IS_OWNER()

gboolean GNC_IS_OWNER ( QofInstance ent)

Check if entity is an owner kind.

This function conveniently imitates the various GNC_IS_ checks on the other gnucash objects even though an owner is not really a true object.

Definition at line 352 of file gncOwner.c.

353 {
354  if (!ent)
355  return FALSE;
356 
357  return (GNC_IS_VENDOR(ent) ||
358  GNC_IS_CUSTOMER(ent) ||
359  GNC_IS_EMPLOYEE(ent) ||
360  GNC_IS_JOB(ent));
361 }

◆ gncOwnerApplyPaymentSecs()

void gncOwnerApplyPaymentSecs ( const GncOwner owner,
Transaction **  preset_txn,
GList *  lots,
Account posted_acc,
Account xfer_acc,
gnc_numeric  amount,
gnc_numeric  exch,
time64  date,
const char *  memo,
const char *  num,
gboolean  auto_pay 
)

A convenience function to apply a payment to the owner.

It creates a lot for a payment, optionally based on an existing transaction and then tries to balance it with the list of document/payment lots passed in. If not lots were given, all open lots for the owner are considered.

This code is actually a convenience wrapper around gncOwnerCreatePaymentLot and gncOwnerAutoApplyPaymentsWithLots. See their descriptions for more details on what happens exactly.

Definition at line 1405 of file gncOwner.c.

1409 {
1410  GNCLot *payment_lot = NULL;
1411  GList *selected_lots = NULL;
1412 
1413  /* Verify our arguments */
1414  if (!owner || !posted_acc
1415  || (!xfer_acc && !gnc_numeric_zero_p (amount)) ) return;
1416  g_return_if_fail (owner->owner.undefined);
1417 
1418  if (lots)
1419  selected_lots = lots;
1420  else if (auto_pay)
1421  selected_lots = xaccAccountFindOpenLots (posted_acc, gncOwnerLotMatchOwnerFunc,
1422  (gpointer)owner, NULL);
1423 
1424  /* If there's a real amount to transfer create a lot for this payment */
1425  if (!gnc_numeric_zero_p (amount))
1426  payment_lot = gncOwnerCreatePaymentLotSecs (owner, preset_txn,
1427  posted_acc, xfer_acc,
1428  amount, exch, date, memo,
1429  num);
1430 
1431  /* And link the selected lots and the payment lot together as well
1432  * as possible. If the payment was bigger than the selected
1433  * documents/overpayments, only part of the payment will be
1434  * used. Similarly if more documents were selected than the
1435  * payment value set, not all documents will be marked as paid. */
1436  if (payment_lot)
1437  selected_lots = g_list_prepend (selected_lots, payment_lot);
1438 
1439  gncOwnerAutoApplyPaymentsWithLots (owner, selected_lots);
1440  g_list_free (selected_lots);
1441 }
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
void gncOwnerAutoApplyPaymentsWithLots(const GncOwner *owner, GList *lots)
Given a list of lots, try to balance as many of them as possible by creating balancing transactions b...
Definition: gncOwner.c:1256
GNCLot * gncOwnerCreatePaymentLotSecs(const GncOwner *owner, Transaction **preset_txn, Account *posted_acc, Account *xfer_acc, gnc_numeric amount, gnc_numeric exch, time64 date, const char *memo, const char *num)
Create a lot for a payment to the owner using the other parameters passed in.
Definition: gncOwner.c:750
gboolean gncOwnerLotMatchOwnerFunc(GNCLot *lot, gpointer user_data)
Helper function used to filter a list of lots by owner.
Definition: gncOwner.c:706
LotList * xaccAccountFindOpenLots(const Account *acc, gboolean(*match_func)(GNCLot *lot, gpointer user_data), gpointer user_data, GCompareFunc sort_func)
Find a list of open lots that match the match_func.
Definition: Account.cpp:4054

◆ gncOwnerAutoApplyPaymentsWithLots()

void gncOwnerAutoApplyPaymentsWithLots ( const GncOwner owner,
GList *  lots 
)

Given a list of lots, try to balance as many of them as possible by creating balancing transactions between them.

This can be used to automatically link invoices to payments (to "mark" invoices as paid) or to credit notes or the other way around.

The function starts with the first lot in the list and tries to create balancing transactions to the remainder of the lots in the list. If it reaches the end of the list, it will find the next still open lot in the list and tries to balance it with all lots that follow it (the ones that precede it are either already closed or not suitable or they would have been processed in a previous iteration).

By intelligently sorting the list of lots, you can play with the order of precedence in which the lots should be processed. For example, by sorting the oldest invoice lots first, the code will attempt to balance these first.

Some restrictions:

  • the algorithm is lazy: it will create the smallest balancing transaction(s) possible, not the largest ones. Since the process is iterative, you will have balanced the maximum amount possible in the end, but it may be done in several transactions instead of only one big one.
  • the balancing transactions only work within one account. If a balancing lot is from another account than the lot currently being balanced, it will be skipped during balance evaluation. However if there is a mix of lots from two different accounts, the algorithm will still attempt to match all lots per account.
  • the calling function is responsible for the memory management of the lots list. If it created the list, it should properly free it as well.

Definition at line 1256 of file gncOwner.c.

1257 {
1258  GList *left_iter;
1259 
1260  /* General note: in the code below the term "payment" can
1261  * both mean a true payment or a document of
1262  * the opposite sign (invoice vs credit note) relative to
1263  * the lot being processed. In general this function will
1264  * perform a balancing action on a set of lots, so you
1265  * will also find frequent references to balancing instead. */
1266 
1267  /* Payments can only be applied when at least an owner
1268  * and a list of lots to use are given */
1269  if (!owner) return;
1270  if (!lots) return;
1271 
1272  for (left_iter = lots; left_iter; left_iter = left_iter->next)
1273  {
1274  GNCLot *left_lot = left_iter->data;
1275  gnc_numeric left_lot_bal;
1276  gboolean left_lot_has_doc;
1277  gboolean left_modified = FALSE;
1278  Account *acct;
1279  GList *right_iter;
1280 
1281  /* Only attempt to apply payments to open lots.
1282  * Note that due to the iterative nature of this function lots
1283  * in the list may become empty/closed before they are evaluated as
1284  * base lot, so we should check this for each lot. */
1285  if (!left_lot)
1286  continue;
1287  if (gnc_lot_count_splits (left_lot) == 0)
1288  {
1289  gnc_lot_destroy (left_lot);
1290  left_iter->data = NULL;
1291  continue;
1292  }
1293  if (gnc_lot_is_closed (left_lot))
1294  continue;
1295 
1296  acct = gnc_lot_get_account (left_lot);
1297  xaccAccountBeginEdit (acct);
1298 
1299  left_lot_bal = gnc_lot_get_balance (left_lot);
1300  left_lot_has_doc = (gncInvoiceGetInvoiceFromLot (left_lot) != NULL);
1301 
1302  /* Attempt to offset left_lot with any of the remaining lots. To do so
1303  * iterate over the remaining lots adding lot links or moving payments
1304  * around.
1305  */
1306  for (right_iter = left_iter->next; right_iter; right_iter = right_iter->next)
1307  {
1308  GNCLot *right_lot = right_iter->data;
1309  gnc_numeric right_lot_bal;
1310  gboolean right_lot_has_doc;
1311 
1312  /* Only attempt to use open lots to balance the base lot.
1313  * Note that due to the iterative nature of this function lots
1314  * in the list may become empty/closed before they are evaluated as
1315  * base lot, so we should check this for each lot. */
1316  if (!right_lot)
1317  continue;
1318  if (gnc_lot_count_splits (right_lot) == 0)
1319  {
1320  gnc_lot_destroy (right_lot);
1321  right_iter->data = NULL;
1322  continue;
1323  }
1324  if (gnc_lot_is_closed (right_lot))
1325  continue;
1326 
1327  /* Balancing transactions for invoice/payments can only happen
1328  * in the same account. */
1329  if (acct != gnc_lot_get_account (right_lot))
1330  continue;
1331 
1332 
1333  /* Only attempt to balance if the base lot and balancing lot are
1334  * of the opposite sign. (Otherwise we would increase the balance
1335  * of the lot - Duh */
1336  right_lot_bal = gnc_lot_get_balance (right_lot);
1337  if (gnc_numeric_positive_p (left_lot_bal) == gnc_numeric_positive_p (right_lot_bal))
1338  continue;
1339 
1340  /* Ok we found two lots than can (partly) offset each other.
1341  * Depending on the lot types, a different action is needed to accomplish this.
1342  * 1. Both lots are document lots (invoices/credit notes)
1343  * -> Create a lot linking transaction between the lots
1344  * 2. Both lots are payment lots (lots without a document attached)
1345  * -> Use part of the bigger lot to the close the smaller lot
1346  * 3. One document lot with one payment lot
1347  * -> Use (part of) the payment to offset (part of) the document lot,
1348  * Which one will be closed depends on which is the bigger one
1349  */
1350  right_lot_has_doc = (gncInvoiceGetInvoiceFromLot (right_lot) != NULL);
1351  if (left_lot_has_doc && right_lot_has_doc)
1352  gncOwnerCreateLotLink (left_lot, right_lot, owner);
1353  else if (!left_lot_has_doc && !right_lot_has_doc)
1354  {
1355  gint cmp = gnc_numeric_compare (gnc_numeric_abs (left_lot_bal),
1356  gnc_numeric_abs (right_lot_bal));
1357  if (cmp >= 0)
1358  gncOwnerOffsetLots (left_lot, right_lot, owner);
1359  else
1360  gncOwnerOffsetLots (right_lot, left_lot, owner);
1361  }
1362  else
1363  {
1364  GNCLot *doc_lot = left_lot_has_doc ? left_lot : right_lot;
1365  GNCLot *pay_lot = left_lot_has_doc ? right_lot : left_lot;
1366  // Ok, let's try to move a payment from pay_lot to doc_lot
1367  gncOwnerOffsetLots (pay_lot, doc_lot, owner);
1368  }
1369 
1370  /* If we get here, then right_lot was modified
1371  * If the lot has a document, send an event for send an event for it as well
1372  * so it gets potentially updated as paid */
1373 
1374  {
1375  GncInvoice *this_invoice = gncInvoiceGetInvoiceFromLot(right_lot);
1376  if (this_invoice)
1377  qof_event_gen (QOF_INSTANCE(this_invoice), QOF_EVENT_MODIFY, NULL);
1378  }
1379  left_modified = TRUE;
1380  }
1381 
1382  /* If left_lot was modified and the lot has a document,
1383  * send an event for send an event for it as well
1384  * so it gets potentially updated as paid */
1385  if (left_modified)
1386  {
1387  GncInvoice *this_invoice = gncInvoiceGetInvoiceFromLot(left_lot);
1388  if (this_invoice)
1389  qof_event_gen (QOF_INSTANCE(this_invoice), QOF_EVENT_MODIFY, NULL);
1390  }
1391  xaccAccountCommitEdit (acct);
1392 
1393  }
1394 }
STRUCTS.
int gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
Returns 1 if a>b, -1 if b>a, 0 if a == b.
gnc_numeric gnc_numeric_abs(gnc_numeric a)
Returns a newly created gnc_numeric that is the absolute value of the given gnc_numeric value...
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
Definition: gncInvoice.c:1289
gboolean gnc_lot_is_closed(GNCLot *lot)
The gnc_lot_is_closed() routine returns a boolean flag: is this lot closed? A lot is closed if its ba...
Definition: gnc-lot.cpp:367
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition: Account.cpp:1483
Account * gnc_lot_get_account(const GNCLot *lot)
The gnc_lot_get_account() routine returns the account with which this lot is associated.
Definition: gnc-lot.cpp:377
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
Definition: qofevent.cpp:231
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition: Account.cpp:1524
gnc_numeric gnc_lot_get_balance(GNCLot *lot)
The gnc_lot_get_balance() routine returns the balance of the lot.
Definition: gnc-lot.cpp:502

◆ gncOwnerBeginEdit()

void gncOwnerBeginEdit ( GncOwner owner)

These are convenience wrappers around gnc{Vendor,Customer,Job,Employee}* functions.

This allows you to begin edit, destroy commit edit an owner without knowing its type.

Definition at line 72 of file gncOwner.c.

73 {
74  if (!owner) return;
75  switch (owner->type)
76  {
77  case GNC_OWNER_NONE :
78  case GNC_OWNER_UNDEFINED :
79  break;
80  case GNC_OWNER_CUSTOMER :
81  {
82  gncCustomerBeginEdit(owner->owner.customer);
83  break;
84  }
85  case GNC_OWNER_JOB :
86  {
87  gncJobBeginEdit(owner->owner.job);
88  break;
89  }
90  case GNC_OWNER_VENDOR :
91  {
92  gncVendorBeginEdit(owner->owner.vendor);
93  break;
94  }
95  case GNC_OWNER_EMPLOYEE :
96  {
97  gncEmployeeBeginEdit(owner->owner.employee);
98  break;
99  }
100  }
101 }

◆ gncOwnerCreatePaymentLotSecs()

GNCLot* gncOwnerCreatePaymentLotSecs ( const GncOwner owner,
Transaction **  preset_txn,
Account posted_acc,
Account xfer_acc,
gnc_numeric  amount,
gnc_numeric  exch,
time64  date,
const char *  memo,
const char *  num 
)

Create a lot for a payment to the owner using the other parameters passed in.

If a transaction is set, this transaction will be reused if possible (meaning, if the transaction currency matches the owner's currency and if the transaction has (at least?) one split in the transfer account).

Definition at line 750 of file gncOwner.c.

754 {
755  QofBook *book;
756  Split *split;
757  const char *name;
758  gnc_commodity *post_comm, *xfer_comm;
759  Split *xfer_split = NULL;
760  Transaction *txn = NULL;
761  GNCLot *payment_lot;
762  gnc_numeric xfer_amount = gnc_numeric_zero();
763  gnc_numeric txn_value = gnc_numeric_zero();
764 
765  /* Verify our arguments */
766  if (!owner || !posted_acc || !xfer_acc) return NULL;
767  g_return_val_if_fail (owner->owner.undefined != NULL, NULL);
768 
769  /* Compute the ancillary data */
770  book = gnc_account_get_book (posted_acc);
771  name = gncOwnerGetName (gncOwnerGetEndOwner ((GncOwner*)owner));
772  post_comm = xaccAccountGetCommodity (posted_acc);
773  xfer_comm = xaccAccountGetCommodity (xfer_acc);
774 
775 // reverse = use_reversed_payment_amounts(owner);
776 
777  if (preset_txn && *preset_txn)
778  txn = *preset_txn;
779 
780  if (txn)
781  {
782  int i = 0;
783 
784  /* Pre-existing transaction was specified. We completely clear it,
785  * except for a pre-existing transfer split. We're very conservative
786  * in preserving that one as it may have been reconciled already. */
787  xfer_split = xaccTransFindSplitByAccount(txn, xfer_acc);
788  xaccTransBeginEdit (txn);
789  while (i < xaccTransCountSplits(txn))
790  {
791  Split *split = xaccTransGetSplit (txn, i);
792  if (split == xfer_split)
793  ++i;
794  else
795  xaccSplitDestroy(split);
796  }
797  /* Note: don't commit transaction now - that would insert an imbalance split.*/
798  }
799  else
800  {
801  txn = xaccMallocTransaction (book);
802  xaccTransBeginEdit (txn);
803  }
804 
805  /* Complete transaction setup */
806  xaccTransSetDescription (txn, name ? name : "");
807  if (!gnc_commodity_equal(xaccTransGetCurrency (txn), post_comm) &&
808  !gnc_commodity_equal (xaccTransGetCurrency (txn), xfer_comm))
809  xaccTransSetCurrency (txn, xfer_comm);
810 
811  /* With all commodities involved known, define split amounts and txn value.
812  * - post amount (amount passed in as parameter) is always in post_acct commodity,
813  * - xfer amount requires conversion if the xfer account has a different
814  * commodity than the post account.
815  * - txn value requires conversion if the post account has a different
816  * commodity than the transaction */
817  if (gnc_commodity_equal(post_comm, xfer_comm))
818  xfer_amount = amount;
819  else
820  xfer_amount = gnc_numeric_mul (amount, exch, GNC_DENOM_AUTO,
822 
823  if (gnc_commodity_equal(post_comm, xaccTransGetCurrency (txn)))
824  txn_value = amount;
825  else
826  txn_value = gnc_numeric_mul (amount, exch, GNC_DENOM_AUTO,
828 
829  /* Insert a split for the transfer account if we don't have one yet */
830  if (!xfer_split)
831  {
832  /* The split for the transfer account */
833  xfer_split = xaccMallocSplit (book);
834  xaccSplitSetMemo (xfer_split, memo);
835  /* set per book option */
836  gnc_set_num_action (NULL, xfer_split, num, _("Payment"));
837  xaccAccountBeginEdit (xfer_acc);
838  xaccAccountInsertSplit (xfer_acc, xfer_split);
839  xaccAccountCommitEdit (xfer_acc);
840  xaccTransAppendSplit (txn, xfer_split);
841 
842  xaccSplitSetAmount(xfer_split, xfer_amount); /* Payment in xfer account currency */
843  xaccSplitSetValue(xfer_split, txn_value); /* Payment in transaction currency */
844  }
845  /* For a pre-existing xfer split, let's check if the amount and value
846  * have changed. If so, update them and unreconcile. */
847  else if (!gnc_numeric_equal (xaccSplitGetAmount (xfer_split), xfer_amount) ||
848  !gnc_numeric_equal (xaccSplitGetValue (xfer_split), txn_value))
849  {
850  xaccSplitSetAmount (xfer_split, xfer_amount);
851  xaccSplitSetValue (xfer_split, txn_value);
852  xaccSplitSetReconcile (xfer_split, NREC);
853  }
854 
855  /* Add a split in the post account */
856  split = xaccMallocSplit (book);
857  xaccSplitSetMemo (split, memo);
858  /* set per book option */
859  xaccSplitSetAction (split, _("Payment"));
860  xaccAccountBeginEdit (posted_acc);
861  xaccAccountInsertSplit (posted_acc, split);
862  xaccAccountCommitEdit (posted_acc);
863  xaccTransAppendSplit (txn, split);
864  xaccSplitSetAmount (split, gnc_numeric_neg (amount));
865  xaccSplitSetValue (split, gnc_numeric_neg (txn_value));
866 
867  /* Create a new lot for the payment */
868  payment_lot = gnc_lot_new (book);
869  gncOwnerAttachToLot (owner, payment_lot);
870  gnc_lot_add_split (payment_lot, split);
871 
872  /* Mark the transaction as a payment */
873  xaccTransSetNum (txn, num);
875 
876  /* Set date for transaction */
878  xaccTransSetDatePostedSecs (txn, date);
879 
880  /* Commit this new transaction */
881  xaccTransCommitEdit (txn);
882  if (preset_txn)
883  *preset_txn = txn;
884 
885  return payment_lot;
886 }
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction&#39;s commodity.
Definition: gmock-Split.cpp:92
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
Definition: Transaction.h:381
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
void xaccSplitSetAction(Split *split, const char *actn)
The Action is an arbitrary user-assigned string.
Definition: Split.cpp:1781
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction&#39;s split list.
gboolean xaccSplitDestroy(Split *split)
Destructor.
Definition: Split.cpp:1504
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
void gnc_lot_add_split(GNCLot *lot, Split *split)
The gnc_lot_add_split() routine adds a split to this lot.
Definition: gnc-lot.cpp:594
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
void xaccTransSetNum(Transaction *trans, const char *xnum)
Sets the transaction Number (or ID) field; rather than use this function directly, see &#39;gnc_set_num_action&#39; in engine/engine-helpers.c & .h which takes a user-set book option for selecting the source for the num-cell (the transaction-number or the split-action field) in registers/reports into account automatically.
void xaccSplitSetReconcile(Split *split, char recn)
Set the reconcile flag.
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
int xaccTransCountSplits(const Transaction *trans)
Returns the number of splits in this transaction.
void xaccTransSetTxnType(Transaction *trans, char type)
Set the Transaction Type: note the type will be saved into the Transaction kvp property as a backward...
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account&#39;s commodity that the split should have...
Definition: gmock-Split.cpp:77
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
void gncOwnerAttachToLot(const GncOwner *owner, GNCLot *lot)
Attach an owner to a lot.
Definition: gncOwner.c:622
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
#define TXN_TYPE_PAYMENT
Transaction is a payment.
Definition: Transaction.h:127
Split * xaccMallocSplit(QofBook *book)
Constructor.
Definition: gmock-Split.cpp:37
const GncOwner * gncOwnerGetEndOwner(const GncOwner *owner)
Get the "parent" Owner or GncGUID thereof.
Definition: gncOwner.c:572
void xaccTransSetDatePostedSecs(Transaction *trans, time64 secs)
The xaccTransSetDatePostedSecs() method will modify the posted date of the transaction, specified by a time64 (see ctime(3)).
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction&#39;s commodity.
Definition: gmock-Split.cpp:84
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition: Account.cpp:1483
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account&#39;s commodity.
Definition: Account.cpp:3465
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
Definition: Account.h:1048
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
Definition: gnc-numeric.h:167
time64 gnc_time(time64 *tbuf)
get the current time
Definition: gnc-date.cpp:261
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
#define GNC_DENOM_AUTO
Values that can be passed as the &#39;denom&#39; argument.
Definition: gnc-numeric.h:247
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition: Account.cpp:1524
#define NREC
not reconciled or cleared
Definition: Split.h:74
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account&#39;s commodity.
Definition: gmock-Split.cpp:69

◆ gncOwnerEqual()

gboolean gncOwnerEqual ( const GncOwner a,
const GncOwner b 
)

Assess equality by checking.

  • if both owner objects refer to the same owner type
  • and if the owner reference points to the same {vendor/customer/employee} in memory

Definition at line 404 of file gncOwner.c.

405 {
406  if (!a || !b) return FALSE;
407  if (gncOwnerGetType (a) != gncOwnerGetType (b)) return FALSE;
408  return (a->owner.undefined == b->owner.undefined);
409 }
GncOwnerType gncOwnerGetType(const GncOwner *owner)
Returns the GncOwnerType of this owner.
Definition: gncOwner.c:200

◆ gncOwnerFindOffsettingSplit()

Split* gncOwnerFindOffsettingSplit ( GNCLot *  lot,
gnc_numeric  target_amount 
)

Helper function to find a split in lot that best offsets target_amount Obviously it should be of opposite sign.

If there are more splits of opposite sign the following criteria are used in order of preference:

  1. exact match in abs amount is preferred over larger abs amount
  2. larger abs amount is preferred over smaller abs amount
  3. if previous and new candidate are in the same amount category, prefer real payment splits over lot link splits
  4. if previous and new candidate are of same split type prefer biggest abs amount.

Definition at line 896 of file gncOwner.c.

897 {
898  SplitList *ls_iter = NULL;
899  Split *best_split = NULL;
900  gnc_numeric best_amt = { 0, 1};
901  gint best_flags = 0;
902 
903  if (!lot)
904  return NULL;
905 
906  for (ls_iter = gnc_lot_get_split_list (lot); ls_iter; ls_iter = ls_iter->next)
907  {
908  Split *split = ls_iter->data;
909 
910  if (!split)
911  continue;
912 
913 
914  Transaction *txn = xaccSplitGetParent (split);
915  if (!txn)
916  {
917  // Ooops - the split doesn't belong to any transaction !
918  // This is not expected so issue a warning and continue with next split
919  PWARN("Encountered a split in a payment lot that's not part of any transaction. "
920  "This is unexpected! Skipping split %p.", split);
921  continue;
922  }
923 
924  // Check if this split has the opposite sign of the target amount we want to offset
925  gnc_numeric split_amount = xaccSplitGetAmount (split);
926  if (gnc_numeric_positive_p (target_amount) == gnc_numeric_positive_p (split_amount))
927  continue;
928 
929  // Ok we have found a split that potentially can offset the target value
930  // Let's see if it's better than what we have found already.
931  gint amt_cmp = gnc_numeric_compare (gnc_numeric_abs (split_amount),
932  gnc_numeric_abs (target_amount));
933  gint new_flags = 0;
934  if (amt_cmp == 0)
935  new_flags += is_equal;
936  else if (amt_cmp > 0)
937  new_flags += is_more;
938  else
939  new_flags += is_less;
940 
941  if (xaccTransGetTxnType (txn) != TXN_TYPE_LINK)
942  new_flags += is_pay_split;
943 
944  if ((new_flags >= best_flags) &&
945  (gnc_numeric_compare (gnc_numeric_abs (split_amount),
946  gnc_numeric_abs (best_amt)) > 0))
947  {
948  // The new split is a better match than what we found so far
949  best_split = split;
950  best_flags = new_flags;
951  best_amt = split_amount;
952  }
953  }
954 
955  return best_split;
956 }
char xaccTransGetTxnType(Transaction *trans)
Returns the Transaction Type: note this type will be derived from the transaction splits...
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
int gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
Returns 1 if a>b, -1 if b>a, 0 if a == b.
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
GList SplitList
GList of Split.
Definition: gnc-engine.h:207
SplitList * gnc_lot_get_split_list(const GNCLot *lot)
The gnc_lot_get_split_list() routine returns a GList of all the splits in this lot.
Definition: gnc-lot.cpp:425
gnc_numeric gnc_numeric_abs(gnc_numeric a)
Returns a newly created gnc_numeric that is the absolute value of the given gnc_numeric value...
#define TXN_TYPE_LINK
Transaction is a link between (invoice and payment) lots.
Definition: Transaction.h:128
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account&#39;s commodity.
Definition: gmock-Split.cpp:69

◆ gncOwnerGetCustomer()

GncCustomer* gncOwnerGetCustomer ( const GncOwner owner)

If the given owner is of type GNC_OWNER_CUSTOMER, returns the pointer to the customer object.

Otherwise returns NULL.

Definition at line 369 of file gncOwner.c.

370 {
371  if (!owner) return NULL;
372  if (owner->type != GNC_OWNER_CUSTOMER) return NULL;
373  return owner->owner.customer;
374 }

◆ gncOwnerGetEmployee()

GncEmployee* gncOwnerGetEmployee ( const GncOwner owner)

If the given owner is of type GNC_OWNER_EMPLOYEE, returns the pointer to the employee object.

Otherwise returns NULL.

Definition at line 390 of file gncOwner.c.

391 {
392  if (!owner) return NULL;
393  if (owner->type != GNC_OWNER_EMPLOYEE) return NULL;
394  return owner->owner.employee;
395 }

◆ gncOwnerGetEndOwner()

const GncOwner* gncOwnerGetEndOwner ( const GncOwner owner)

Get the "parent" Owner or GncGUID thereof.

The "parent" owner is the Customer or Vendor, or the Owner of a Job

Definition at line 572 of file gncOwner.c.

573 {
574  if (!owner) return NULL;
575  switch (owner->type)
576  {
577  case GNC_OWNER_NONE:
578  case GNC_OWNER_UNDEFINED:
579  default:
580  return NULL;
581  case GNC_OWNER_CUSTOMER:
582  case GNC_OWNER_VENDOR:
583  case GNC_OWNER_EMPLOYEE:
584  return owner;
585  case GNC_OWNER_JOB:
586  return gncJobGetOwner (owner->owner.job);
587  }
588 }

◆ gncOwnerGetJob()

GncJob* gncOwnerGetJob ( const GncOwner owner)

If the given owner is of type GNC_OWNER_JOB, returns the pointer to the job object.

Otherwise returns NULL.

Definition at line 376 of file gncOwner.c.

377 {
378  if (!owner) return NULL;
379  if (owner->type != GNC_OWNER_JOB) return NULL;
380  return owner->owner.job;
381 }

◆ gncOwnerGetOwnerFromLot()

gboolean gncOwnerGetOwnerFromLot ( GNCLot *  lot,
GncOwner owner 
)

Get the owner from the lot.

If an owner is found in the lot, fill in "owner" and return TRUE. Otherwise return FALSE.

Definition at line 636 of file gncOwner.c.

637 {
638  GncGUID *guid = NULL;
639  QofBook *book;
640  GncOwnerType type = GNC_OWNER_NONE;
641  guint64 type64 = 0;
642 
643  if (!lot || !owner) return FALSE;
644 
645  book = gnc_lot_get_book (lot);
646  qof_instance_get (QOF_INSTANCE (lot),
647  GNC_OWNER_TYPE, &type64,
648  GNC_OWNER_GUID, &guid,
649  NULL);
650  type = (GncOwnerType) type64;
651  switch (type)
652  {
653  case GNC_OWNER_CUSTOMER:
654  gncOwnerInitCustomer (owner, gncCustomerLookup (book, guid));
655  break;
656  case GNC_OWNER_VENDOR:
657  gncOwnerInitVendor (owner, gncVendorLookup (book, guid));
658  break;
659  case GNC_OWNER_EMPLOYEE:
660  gncOwnerInitEmployee (owner, gncEmployeeLookup (book, guid));
661  break;
662  case GNC_OWNER_JOB:
663  gncOwnerInitJob (owner, gncJobLookup (book, guid));
664  break;
665  default:
666  guid_free (guid);
667  return FALSE;
668  }
669 
670  guid_free (guid);
671  return (owner->owner.undefined != NULL);
672 }
void qof_instance_get(const QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_get.
The type used to store guids in C.
Definition: guid.h:75

◆ gncOwnerGetOwnerFromTxn()

gboolean gncOwnerGetOwnerFromTxn ( Transaction *  txn,
GncOwner owner 
)

Convenience function to get the owner from a transaction.

Transactions don't really have an owner. What this function will do it figure out whether the transaction is part of a business transaction (either a posted invoice/bill/voucher/credit note or a payment transaction) and use the business object behind it to extract owner information.

Definition at line 674 of file gncOwner.c.

675 {
676  Split *apar_split = NULL;
677 
678  if (!txn || !owner) return FALSE;
679 
680  if (xaccTransGetTxnType (txn) == TXN_TYPE_NONE)
681  return FALSE;
682 
683  apar_split = xaccTransGetFirstAPARAcctSplit (txn, TRUE);
684  if (apar_split)
685  {
686  GNCLot *lot = xaccSplitGetLot (apar_split);
687  GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
688  if (invoice)
689  gncOwnerCopy (gncInvoiceGetOwner (invoice), owner);
690  else if (!gncOwnerGetOwnerFromLot (lot, owner))
691  return FALSE;
692 
693  return TRUE; // Got owner from either invoice or lot
694  }
695 
696  return FALSE;
697 }
char xaccTransGetTxnType(Transaction *trans)
Returns the Transaction Type: note this type will be derived from the transaction splits...
#define TXN_TYPE_NONE
No transaction type.
Definition: Transaction.h:125
gboolean gncOwnerGetOwnerFromLot(GNCLot *lot, GncOwner *owner)
Get the owner from the lot.
Definition: gncOwner.c:636
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
Definition: gncInvoice.c:1289
Split * xaccTransGetFirstAPARAcctSplit(const Transaction *trans, gboolean strict)
The xaccTransGetFirstPaymentAcctSplit() method returns a pointer to the first split in this transacti...
GNCLot * xaccSplitGetLot(const Split *split)
Returns the pointer to the debited/credited Lot where this split belongs to, or NULL if it doesn&#39;t be...
Definition: Split.cpp:1915

◆ gncOwnerGetType()

GncOwnerType gncOwnerGetType ( const GncOwner owner)

Returns the GncOwnerType of this owner.

(Not to be confused with qofOwnerGetType().)

Definition at line 200 of file gncOwner.c.

201 {
202  if (!owner) return GNC_OWNER_NONE;
203  return owner->type;
204 }

◆ gncOwnerGetTypeString()

const char* gncOwnerGetTypeString ( const GncOwner owner)

return the type for the owner as an untranslated string.

Definition at line 206 of file gncOwner.c.

207 {
208  GncOwnerType type = gncOwnerGetType(owner);
209  switch (type)
210  {
211  case GNC_OWNER_NONE:
212  return N_("None");
213  case GNC_OWNER_UNDEFINED:
214  return N_("Undefined");
215  case GNC_OWNER_CUSTOMER:
216  return N_("Customer");
217  case GNC_OWNER_JOB:
218  return N_("Job");
219  case GNC_OWNER_VENDOR:
220  return N_("Vendor");
221  case GNC_OWNER_EMPLOYEE:
222  return N_("Employee");
223  default:
224  PWARN ("Unknown owner type");
225  return NULL;
226  }
227 }
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
GncOwnerType gncOwnerGetType(const GncOwner *owner)
Returns the GncOwnerType of this owner.
Definition: gncOwner.c:200

◆ gncOwnerGetUndefined()

gpointer gncOwnerGetUndefined ( const GncOwner owner)

If the given owner is of type GNC_OWNER_UNDEFINED, returns the undefined pointer, which is usually NULL.

Otherwise returns NULL.

Definition at line 362 of file gncOwner.c.

363 {
364  if (!owner) return NULL;
365  if (owner->type != GNC_OWNER_UNDEFINED) return NULL;
366  return owner->owner.undefined;
367 }

◆ gncOwnerGetVendor()

GncVendor* gncOwnerGetVendor ( const GncOwner owner)

If the given owner is of type GNC_OWNER_VENDOR, returns the pointer to the vendor object.

Otherwise returns NULL.

Definition at line 383 of file gncOwner.c.

384 {
385  if (!owner) return NULL;
386  if (owner->type != GNC_OWNER_VENDOR) return NULL;
387  return owner->owner.vendor;
388 }

◆ gncOwnerIsValid()

gboolean gncOwnerIsValid ( const GncOwner owner)

Returns TRUE if the given owner is one of the valid objects.

Returns FALSE if the owner is (still) undefined, or if it is NULL.

Definition at line 699 of file gncOwner.c.

700 {
701  if (!owner) return FALSE;
702  return (owner->owner.undefined != NULL);
703 }

◆ gncOwnerLotsSortFunc()

gint gncOwnerLotsSortFunc ( GNCLot *  lotA,
GNCLot *  lotB 
)

Helper function used to sort lots by date.

If the lot is linked to an invoice, use the invoice posted date, otherwise use the lot's opened date.

Definition at line 728 of file gncOwner.c.

729 {
730  GncInvoice *ia, *ib;
731  time64 da, db;
732 
733  ia = gncInvoiceGetInvoiceFromLot (lotA);
734  ib = gncInvoiceGetInvoiceFromLot (lotB);
735 
736  if (ia)
737  da = gncInvoiceGetDateDue (ia);
738  else
740 
741  if (ib)
742  db = gncInvoiceGetDateDue (ib);
743  else
745 
746  return (da > db) - (da < db);
747 }
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
Split * gnc_lot_get_earliest_split(GNCLot *lot)
The gnc_lot_get_earliest_split() routine is a convenience routine that helps identify the earliest da...
Definition: gnc-lot.cpp:673
time64 xaccTransRetDatePosted(const Transaction *trans)
Retrieve the posted date of the transaction.
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
Definition: gncInvoice.c:1289
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition: gnc-date.h:87

◆ gncOwnerNew()

GncOwner* gncOwnerNew ( void  )

These two functions are mainly for the convenience of scheme code.

Normal C code has no need to ever use these two functions, and rather can just use a GncOwner directly and just pass around a pointer to it.

Definition at line 57 of file gncOwner.c.

58 {
59  GncOwner *o;
60 
61  o = g_new0 (GncOwner, 1);
62  o->type = GNC_OWNER_NONE;
63  return o;
64 }

◆ gncOwnerReduceSplitTo()

gboolean gncOwnerReduceSplitTo ( Split *  split,
gnc_numeric  target_amount 
)

Helper function to reduce the amount of a split to target_amount.

To make sure the split's parent transaction remains balanced a second split will be created with the remainder. Similarly if the split was part of a (business) lot, the remainder split will be added to the same lot to keep the lot's balance unchanged.

Definition at line 959 of file gncOwner.c.

960 {
961  gnc_numeric split_amt = xaccSplitGetAmount (split);
962  if (gnc_numeric_positive_p (split_amt) != gnc_numeric_positive_p (target_amount))
963  return FALSE; // Split and target amount have to be of the same sign
964 
965  if (gnc_numeric_equal (split_amt, target_amount))
966  return FALSE; // Split already has the target amount
967 
968  if (gnc_numeric_zero_p (split_amt))
969  return FALSE; // We can't reduce a split that already has zero amount
970 
971  Transaction *txn = xaccSplitGetParent (split);
972  xaccTransBeginEdit (txn);
973 
974  /* Calculate new value for reduced split. This can be different from
975  * the reduced split's new amount (when account and transaction
976  * commodity differ) */
977  gnc_numeric split_val = xaccSplitGetValue (split);
978  gnc_numeric exch = gnc_numeric_div (split_val, split_amt,
980 
981  gint64 txn_comm_fraction = gnc_commodity_get_fraction (xaccTransGetCurrency (txn));
982  gnc_numeric target_val = gnc_numeric_mul (target_amount, exch,
983  txn_comm_fraction,
985  xaccSplitSetAmount (split, target_amount);
986  xaccSplitSetValue (split, target_val);
987 
988  /* Calculate amount and value for remainder split.
989  * Note we calculate the remaining value by subtracting the new target value
990  * from the original split's value rather than multiplying the remaining
991  * amount with the exchange rate to avoid imbalances due to rounding errors. */
992  gnc_numeric rem_amt = gnc_numeric_sub (split_amt, target_amount, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
993  gnc_numeric rem_val = gnc_numeric_sub (split_val, target_val, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
994 
995  Split *rem_split = xaccMallocSplit (xaccSplitGetBook (split));
996  xaccSplitCopyOnto (split, rem_split);
997  xaccSplitSetAmount (rem_split, rem_amt);
998  xaccSplitSetValue (rem_split, rem_val);
999  xaccSplitSetParent (rem_split, txn);
1000 
1001  xaccTransCommitEdit (txn);
1002 
1003  GNCLot *lot = xaccSplitGetLot (split);
1004  gnc_lot_add_split (lot, rem_split);
1005 
1006  return TRUE;
1007 }
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction&#39;s commodity.
Definition: gmock-Split.cpp:92
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
All arguments are required to have the same denominator, that denominator is to be used in the output...
Definition: gnc-numeric.h:208
void xaccSplitCopyOnto(const Split *from_split, Split *to_split)
This is really a helper for xaccTransCopyOnto.
Definition: Split.cpp:638
void gnc_lot_add_split(GNCLot *lot, Split *split)
The gnc_lot_add_split() routine adds a split to this lot.
Definition: gnc-lot.cpp:594
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
QofBook * xaccSplitGetBook(const Split *split)
Returns the book of this split, i.e.
Definition: gmock-Split.cpp:45
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account&#39;s commodity that the split should have...
Definition: gmock-Split.cpp:77
Find the least common multiple of the arguments&#39; denominators and use that as the denominator of the ...
Definition: gnc-numeric.h:202
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
Split * xaccMallocSplit(QofBook *book)
Constructor.
Definition: gmock-Split.cpp:37
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a-b.
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction&#39;s commodity.
Definition: gmock-Split.cpp:84
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
Definition: gnc-numeric.h:167
#define GNC_DENOM_AUTO
Values that can be passed as the &#39;denom&#39; argument.
Definition: gnc-numeric.h:247
GNCLot * xaccSplitGetLot(const Split *split)
Returns the pointer to the debited/credited Lot where this split belongs to, or NULL if it doesn&#39;t be...
Definition: Split.cpp:1915
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account&#39;s commodity.
Definition: gmock-Split.cpp:69

◆ gncOwnerSetLotLinkMemo()

void gncOwnerSetLotLinkMemo ( Transaction *  ll_txn)

To help a user understand what a lot link transaction does, we set the memo to name all documents involved in the link.

The function below calculates this memo and sets it for all splits in the lot link transaction.

Definition at line 1010 of file gncOwner.c.

1011 {
1012  gchar *memo_prefix = _("Offset between documents: ");
1013  gchar *new_memo;
1014  SplitList *lts_iter;
1015  SplitList *splits = NULL, *siter;
1016  GList *titles = NULL, *titer;
1017 
1018  if (!ll_txn)
1019  return;
1020 
1021  if (xaccTransGetTxnType (ll_txn) != TXN_TYPE_LINK)
1022  return;
1023 
1024  // Find all splits in the lot link transaction that are also in a document lot
1025  for (lts_iter = xaccTransGetSplitList (ll_txn); lts_iter; lts_iter = lts_iter->next)
1026  {
1027  Split *split = lts_iter->data;
1028  GNCLot *lot;
1029  GncInvoice *invoice;
1030  gchar *title;
1031 
1032  if (!split)
1033  continue;
1034 
1035  lot = xaccSplitGetLot (split);
1036  if (!lot)
1037  continue;
1038 
1039  invoice = gncInvoiceGetInvoiceFromLot (lot);
1040  if (!invoice)
1041  continue;
1042 
1043  title = g_strdup_printf ("%s %s", gncInvoiceGetTypeString (invoice), gncInvoiceGetID (invoice));
1044 
1045  titles = g_list_prepend (titles, title);
1046  splits = g_list_prepend (splits, split); // splits don't need to be sorted
1047  }
1048 
1049  if (!titles)
1050  return; // We didn't find document lots
1051 
1052  titles = g_list_sort (titles, (GCompareFunc)g_strcmp0);
1053 
1054  // Create the memo as we'd want it to be
1055  new_memo = g_strconcat (memo_prefix, titles->data, NULL);
1056  for (titer = titles->next; titer; titer = titer->next)
1057  {
1058  gchar *tmp_memo = g_strconcat (new_memo, " - ", titer->data, NULL);
1059  g_free (new_memo);
1060  new_memo = tmp_memo;
1061  }
1062  g_list_free_full (titles, g_free);
1063 
1064  // Update the memos of all the splits we found previously (if needed)
1065  for (siter = splits; siter; siter = siter->next)
1066  {
1067  if (g_strcmp0 (xaccSplitGetMemo (siter->data), new_memo) != 0)
1068  xaccSplitSetMemo (siter->data, new_memo);
1069  }
1070 
1071  g_list_free (splits);
1072  g_free (new_memo);
1073 }
char xaccTransGetTxnType(Transaction *trans)
Returns the Transaction Type: note this type will be derived from the transaction splits...
GList SplitList
GList of Split.
Definition: gnc-engine.h:207
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
#define TXN_TYPE_LINK
Transaction is a link between (invoice and payment) lots.
Definition: Transaction.h:128
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
Definition: gncInvoice.c:1289
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
Definition: gmock-Split.cpp:99
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
GNCLot * xaccSplitGetLot(const Split *split)
Returns the pointer to the debited/credited Lot where this split belongs to, or NULL if it doesn&#39;t be...
Definition: Split.cpp:1915

◆ gncOwnerTypeToQofIdType()

QofIdTypeConst gncOwnerTypeToQofIdType ( GncOwnerType  t)

Returns the QofIdType of the given GncOwnerType, or NULL if no suitable one exists.

Definition at line 235 of file gncOwner.c.

236 {
237  QofIdTypeConst type = NULL;
238  switch (t)
239  {
240  case GNC_OWNER_NONE :
241  {
242  type = NULL;
243  break;
244  }
245  case GNC_OWNER_UNDEFINED :
246  {
247  type = NULL;
248  break;
249  }
250  case GNC_OWNER_CUSTOMER :
251  {
252  type = GNC_ID_CUSTOMER;
253  break;
254  }
255  case GNC_OWNER_JOB :
256  {
257  type = GNC_ID_JOB;
258  break;
259  }
260  case GNC_OWNER_VENDOR :
261  {
262  type = GNC_ID_VENDOR;
263  break;
264  }
265  case GNC_OWNER_EMPLOYEE :
266  {
267  type = GNC_ID_EMPLOYEE;
268  break;
269  }
270  }
271  return type;
272 }
const gchar * QofIdTypeConst
QofIdTypeConst declaration.
Definition: qofid.h:82

◆ qofOwnerGetOwner()

QofInstance* qofOwnerGetOwner ( const GncOwner owner)

return the owner itself as an entity.

Definition at line 275 of file gncOwner.c.

276 {
277  QofInstance *ent;
278 
279  if (!owner)
280  {
281  return NULL;
282  }
283  ent = NULL;
284  switch (owner->type)
285  {
286  case GNC_OWNER_NONE :
287  {
288  break;
289  }
290  case GNC_OWNER_UNDEFINED :
291  {
292  break;
293  }
294  case GNC_OWNER_CUSTOMER :
295  {
296  ent = QOF_INSTANCE(owner->owner.customer);
297  break;
298  }
299  case GNC_OWNER_JOB :
300  {
301  ent = QOF_INSTANCE(owner->owner.job);
302  break;
303  }
304  case GNC_OWNER_VENDOR :
305  {
306  ent = QOF_INSTANCE(owner->owner.vendor);
307  break;
308  }
309  case GNC_OWNER_EMPLOYEE :
310  {
311  ent = QOF_INSTANCE(owner->owner.employee);
312  break;
313  }
314  }
315  return ent;
316 }

◆ qofOwnerGetType()

QofIdTypeConst qofOwnerGetType ( const GncOwner owner)

return the type for the collection.

Definition at line 230 of file gncOwner.c.

231 {
232  return gncOwnerTypeToQofIdType(owner->type);
233 }
QofIdTypeConst gncOwnerTypeToQofIdType(GncOwnerType t)
Returns the QofIdType of the given GncOwnerType, or NULL if no suitable one exists.
Definition: gncOwner.c:235

◆ qofOwnerSetEntity()

void qofOwnerSetEntity ( GncOwner owner,
QofInstance ent 
)

set the owner from the entity.

Definition at line 319 of file gncOwner.c.

320 {
321  if (!owner || !ent)
322  {
323  return;
324  }
325  if (0 == g_strcmp0(ent->e_type, GNC_ID_CUSTOMER))
326  {
327  owner->type = GNC_OWNER_CUSTOMER;
328  gncOwnerInitCustomer(owner, (GncCustomer*)ent);
329  }
330  else if (0 == g_strcmp0(ent->e_type, GNC_ID_JOB))
331  {
332  owner->type = GNC_OWNER_JOB;
333  gncOwnerInitJob(owner, (GncJob*)ent);
334  }
335  else if (0 == g_strcmp0(ent->e_type, GNC_ID_VENDOR))
336  {
337  owner->type = GNC_OWNER_VENDOR;
338  gncOwnerInitVendor(owner, (GncVendor*)ent);
339  }
340  else if (0 == g_strcmp0(ent->e_type, GNC_ID_EMPLOYEE))
341  {
342  owner->type = GNC_OWNER_EMPLOYEE;
343  gncOwnerInitEmployee(owner, (GncEmployee*)ent);
344  }
345  else
346  {
347  owner->type = GNC_OWNER_NONE;
348  owner->owner.undefined = NULL;
349  }
350 }
credit, discount and shipaddr are unique to GncCustomer id, name, notes, terms, addr, currency, taxtable, taxtable_override taxincluded, active and jobs are identical to ::GncVendor.
QofIdType e_type
Entity type.
Definition: qofinstance.h:75