GnuCash  4.8a-176-g88ecf8dd1
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 *pay_lot, gnc_numeric target_value)
 Helper function to find a split in lot that best offsets target_value Obviously it should be of opposite sign. More...
 
gboolean gncOwnerReduceSplitTo (Split *split, gnc_numeric target_value)
 Helper function to reduce the value of a split to target_value. 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...
 
QofInstance * qofOwnerGetOwner (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 320 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 353 of file gncOwner.c.

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

◆ 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 1408 of file gncOwner.c.

1412 {
1413  GNCLot *payment_lot = NULL;
1414  GList *selected_lots = NULL;
1415 
1416  /* Verify our arguments */
1417  if (!owner || !posted_acc
1418  || (!xfer_acc && !gnc_numeric_zero_p (amount)) ) return;
1419  g_return_if_fail (owner->owner.undefined);
1420 
1421  /* If there's a real amount to transfer create a lot for this payment */
1422  if (!gnc_numeric_zero_p (amount))
1423  payment_lot = gncOwnerCreatePaymentLotSecs (owner, preset_txn,
1424  posted_acc, xfer_acc,
1425  amount, exch, date, memo,
1426  num);
1427 
1428  if (lots)
1429  selected_lots = lots;
1430  else if (auto_pay)
1431  selected_lots = xaccAccountFindOpenLots (posted_acc, gncOwnerLotMatchOwnerFunc,
1432  (gpointer)owner, NULL);
1433 
1434  /* And link the selected lots and the payment lot together as well as possible.
1435  * If the payment was bigger than the selected documents/overpayments, only
1436  * part of the payment will be used. Similarly if more documents were selected
1437  * than the payment value set, not all documents will be marked as paid. */
1438  if (payment_lot)
1439  selected_lots = g_list_prepend (selected_lots, payment_lot);
1440  gncOwnerAutoApplyPaymentsWithLots (owner, selected_lots);
1441  g_list_free (selected_lots);
1442 }
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:1259
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:751
gboolean gncOwnerLotMatchOwnerFunc(GNCLot *lot, gpointer user_data)
Helper function used to filter a list of lots by owner.
Definition: gncOwner.c:707
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:3994

◆ 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 1259 of file gncOwner.c.

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

◆ 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 73 of file gncOwner.c.

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

◆ 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 751 of file gncOwner.c.

755 {
756  QofBook *book;
757  Split *split;
758  const char *name;
759  gnc_commodity *commodity;
760  Split *xfer_split = NULL;
761  Transaction *txn = NULL;
762  GNCLot *payment_lot;
763 
764  /* Verify our arguments */
765  if (!owner || !posted_acc || !xfer_acc) return NULL;
766  g_return_val_if_fail (owner->owner.undefined != NULL, NULL);
767 
768  /* Compute the ancillary data */
769  book = gnc_account_get_book (posted_acc);
770  name = gncOwnerGetName (gncOwnerGetEndOwner ((GncOwner*)owner));
771  commodity = gncOwnerGetCurrency (owner);
772 // reverse = use_reversed_payment_amounts(owner);
773 
774  if (preset_txn && *preset_txn)
775  txn = *preset_txn;
776 
777  if (txn)
778  {
779  xaccTransSetDescription (txn, name ? name : "");
780 
781  /* Pre-existing transaction was specified. We completely clear it,
782  * except for the split in the transfer account, unless the
783  * transaction can't be reused (wrong currency, wrong transfer account).
784  * In that case, the transaction is simply removed and an new
785  * one created. */
786 
787  xfer_split = xaccTransFindSplitByAccount(txn, xfer_acc);
788 
789  if (xaccTransGetCurrency(txn) != gncOwnerGetCurrency (owner))
790  {
791  PINFO("Uh oh, mismatching currency/commodity between selected transaction and owner. We fall back to manual creation of a new transaction.");
792  xfer_split = NULL;
793  }
794 
795  if (!xfer_split)
796  {
797  PINFO("Huh? Asset account not found anymore. Fully deleting old txn and now creating a new one.");
798 
799  xaccTransBeginEdit (txn);
800  xaccTransDestroy (txn);
801  xaccTransCommitEdit (txn);
802 
803  txn = NULL;
804  }
805  else
806  {
807  int i = 0;
808  xaccTransBeginEdit (txn);
809  while (i < xaccTransCountSplits(txn))
810  {
811  Split *split = xaccTransGetSplit (txn, i);
812  if (split == xfer_split)
813  {
814  gnc_set_num_action (NULL, split, num, _("Payment"));
815  ++i;
816  }
817  else
818  {
819  xaccSplitDestroy(split);
820  }
821  }
822  /* Note: don't commit transaction now - that would insert an imbalance split.*/
823  }
824  }
825 
826  /* Create the transaction if we don't have one yet */
827  if (!txn)
828  {
829  txn = xaccMallocTransaction (book);
830  xaccTransBeginEdit (txn);
831  }
832 
833  /* Insert a split for the transfer account if we don't have one yet */
834  if (!xfer_split)
835  {
836 
837  /* Set up the transaction */
838  xaccTransSetDescription (txn, name ? name : "");
839  /* set per book option */
840  xaccTransSetCurrency (txn, commodity);
841 
842 
843  /* The split for the transfer account */
844  split = xaccMallocSplit (book);
845  xaccSplitSetMemo (split, memo);
846  /* set per book option */
847  gnc_set_num_action (NULL, split, num, _("Payment"));
848  xaccAccountBeginEdit (xfer_acc);
849  xaccAccountInsertSplit (xfer_acc, split);
850  xaccAccountCommitEdit (xfer_acc);
851  xaccTransAppendSplit (txn, split);
852 
853  if (gnc_commodity_equal(xaccAccountGetCommodity(xfer_acc), commodity))
854  {
855  xaccSplitSetBaseValue (split, amount, commodity);
856  }
857  else
858  {
859  /* This will be a multi-currency transaction. The amount passed to this
860  * function is in the owner commodity (also used by the post account).
861  * For the xfer split we also need to value the payment in the xfer account's
862  * commodity.
863  * exch is from post account to xfer account so that can be used directly
864  * to calculate the equivalent amount in the xfer account's commodity. */
865  gnc_numeric xfer_amount = gnc_numeric_mul (amount, exch, GNC_DENOM_AUTO,
867 
868  xaccSplitSetAmount(split, xfer_amount); /* Payment in xfer account currency */
869  xaccSplitSetValue(split, amount); /* Payment in transaction currency */
870  }
871  }
872 
873  /* Add a split in the post account */
874  split = xaccMallocSplit (book);
875  xaccSplitSetMemo (split, memo);
876  /* set per book option */
877  gnc_set_num_action (NULL, split, num, _("Payment"));
878  xaccAccountBeginEdit (posted_acc);
879  xaccAccountInsertSplit (posted_acc, split);
880  xaccAccountCommitEdit (posted_acc);
881  xaccTransAppendSplit (txn, split);
882  xaccSplitSetBaseValue (split, gnc_numeric_neg (amount), commodity);
883 
884  /* Create a new lot for the payment */
885  payment_lot = gnc_lot_new (book);
886  gncOwnerAttachToLot (owner, payment_lot);
887  gnc_lot_add_split (payment_lot, split);
888 
889  /* Mark the transaction as a payment */
890  gnc_set_num_action (txn, NULL, num, _("Payment"));
892 
893  /* Set date for transaction */
895  xaccTransSetDatePostedSecs (txn, date);
896 
897  /* Commit this new transaction */
898  xaccTransCommitEdit (txn);
899  if (preset_txn)
900  *preset_txn = txn;
901 
902  return payment_lot;
903 }
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:362
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
Definition: Transaction.c:510
void xaccSplitSetBaseValue(Split *s, gnc_numeric value, const gnc_commodity *base_currency)
Depending on the base_currency, set either the value or the amount of this split or both: If the base...
Definition: Split.c:1319
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction&#39;s split list.
#define PINFO(format, args...)
Print an informational note.
Definition: qoflog.h:256
gboolean xaccSplitDestroy(Split *split)
Destructor.
Definition: Split.c:1470
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.c:622
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
Definition: gnc-numeric.h:166
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
Definition: Transaction.c:1425
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
int xaccTransCountSplits(const Transaction *trans)
Returns the number of splits in this transaction.
Definition: Transaction.c:2396
void xaccTransSetTxnType(Transaction *trans, char type)
Set the Transaction Type.
Definition: Transaction.c:2109
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.
Definition: Split.c:1728
void gncOwnerAttachToLot(const GncOwner *owner, GNCLot *lot)
Attach an owner to a lot.
Definition: gncOwner.c:623
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:126
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:573
void xaccTransSetDatePostedSecs(Transaction *trans, time64 secs)
The xaccTransSetDatePostedSecs() method will modify the posted date of the transaction, specified by a time64 (see ctime(3)).
Definition: Transaction.c:2017
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition: Account.cpp:1430
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account&#39;s commodity.
Definition: Account.cpp:3405
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
Definition: Transaction.c:1366
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
Definition: Account.h:1038
time64 gnc_time(time64 *tbuf)
get the current local time
Definition: gnc-date.cpp:273
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
Definition: Transaction.c:2052
#define GNC_DENOM_AUTO
Values that can be passed as the &#39;denom&#39; argument.
Definition: gnc-numeric.h:246
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition: Account.cpp:1471

◆ 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 405 of file gncOwner.c.

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

◆ gncOwnerFindOffsettingSplit()

Split* gncOwnerFindOffsettingSplit ( GNCLot *  pay_lot,
gnc_numeric  target_value 
)

Helper function to find a split in lot that best offsets target_value 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 value is preferred over larger abs value
  2. larger abs value is preferred over smaller abs value
  3. if previous and new candidate are in the same value category, prefer real payment splits over lot link splits
  4. if previous and new candidate are of same split type prefer biggest abs value.

Definition at line 913 of file gncOwner.c.

914 {
915  SplitList *ls_iter = NULL;
916  Split *best_split = NULL;
917  gnc_numeric best_val = { 0, 1};
918  gint best_flags = 0;
919 
920  if (!lot)
921  return NULL;
922 
923  for (ls_iter = gnc_lot_get_split_list (lot); ls_iter; ls_iter = ls_iter->next)
924  {
925  Split *split = ls_iter->data;
926  Transaction *txn;
927  gnc_numeric split_value;
928  gint new_flags = 0;
929  gint val_cmp = 0;
930 
931  if (!split)
932  continue;
933 
934 
935  txn = xaccSplitGetParent (split);
936  if (!txn)
937  {
938  // Ooops - the split doesn't belong to any transaction !
939  // This is not expected so issue a warning and continue with next split
940  PWARN("Encountered a split in a payment lot that's not part of any transaction. "
941  "This is unexpected! Skipping split %p.", split);
942  continue;
943  }
944 
945  // Check if this split has the opposite sign of the target value we want to offset
946  split_value = xaccSplitGetValue (split);
947  if (gnc_numeric_positive_p (target_value) == gnc_numeric_positive_p (split_value))
948  continue;
949 
950  // Ok we have found a split that potentially can offset the target value
951  // Let's see if it's better than what we have found already.
952  val_cmp = gnc_numeric_compare (gnc_numeric_abs (split_value),
953  gnc_numeric_abs (target_value));
954  if (val_cmp == 0)
955  new_flags += is_equal;
956  else if (val_cmp > 0)
957  new_flags += is_more;
958  else
959  new_flags += is_less;
960 
961  if (xaccTransGetTxnType (txn) != TXN_TYPE_LINK)
962  new_flags += is_pay_split;
963 
964  if ((new_flags >= best_flags) &&
965  (gnc_numeric_compare (gnc_numeric_abs (split_value),
966  gnc_numeric_abs (best_val)) > 0))
967  {
968  // The new split is a better match than what we found so far
969  best_split = split;
970  best_flags = new_flags;
971  best_val = split_value;
972  }
973  }
974 
975  return best_split;
976 }
char xaccTransGetTxnType(const Transaction *trans)
Returns the Transaction Type.
Definition: Transaction.c:2548
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:211
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.c:436
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:127
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction&#39;s commodity.
Definition: gmock-Split.cpp:84

◆ 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 370 of file gncOwner.c.

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

◆ 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 391 of file gncOwner.c.

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

◆ 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 573 of file gncOwner.c.

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

◆ 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 377 of file gncOwner.c.

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

◆ 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 637 of file gncOwner.c.

638 {
639  GncGUID *guid = NULL;
640  QofBook *book;
641  GncOwnerType type = GNC_OWNER_NONE;
642  guint64 type64 = 0;
643 
644  if (!lot || !owner) return FALSE;
645 
646  book = gnc_lot_get_book (lot);
647  qof_instance_get (QOF_INSTANCE (lot),
648  GNC_OWNER_TYPE, &type64,
649  GNC_OWNER_GUID, &guid,
650  NULL);
651  type = (GncOwnerType) type64;
652  switch (type)
653  {
654  case GNC_OWNER_CUSTOMER:
655  gncOwnerInitCustomer (owner, gncCustomerLookup (book, guid));
656  break;
657  case GNC_OWNER_VENDOR:
658  gncOwnerInitVendor (owner, gncVendorLookup (book, guid));
659  break;
660  case GNC_OWNER_EMPLOYEE:
661  gncOwnerInitEmployee (owner, gncEmployeeLookup (book, guid));
662  break;
663  case GNC_OWNER_JOB:
664  gncOwnerInitJob (owner, gncJobLookup (book, guid));
665  break;
666  default:
667  guid_free (guid);
668  return FALSE;
669  }
670 
671  guid_free (guid);
672  return (owner->owner.undefined != NULL);
673 }
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 675 of file gncOwner.c.

676 {
677  Split *apar_split = NULL;
678 
679  if (!txn || !owner) return FALSE;
680 
681  if (xaccTransGetTxnType (txn) == TXN_TYPE_NONE)
682  return FALSE;
683 
684  apar_split = xaccTransGetFirstAPARAcctSplit (txn, TRUE);
685  if (apar_split)
686  {
687  GNCLot *lot = xaccSplitGetLot (apar_split);
688  GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
689  if (invoice)
690  gncOwnerCopy (gncInvoiceGetOwner (invoice), owner);
691  else if (!gncOwnerGetOwnerFromLot (lot, owner))
692  return FALSE;
693 
694  return TRUE; // Got owner from either invoice or lot
695  }
696 
697  return FALSE;
698 }
char xaccTransGetTxnType(const Transaction *trans)
Returns the Transaction Type.
Definition: Transaction.c:2548
#define TXN_TYPE_NONE
No transaction type.
Definition: Transaction.h:124
gboolean gncOwnerGetOwnerFromLot(GNCLot *lot, GncOwner *owner)
Get the owner from the lot.
Definition: gncOwner.c:637
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
Definition: gncInvoice.c:1301
Split * xaccTransGetFirstAPARAcctSplit(const Transaction *trans, gboolean strict)
The xaccTransGetFirstPaymentAcctSplit() method returns a pointer to the first split in this transacti...
Definition: Transaction.c:2372
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.c:1881

◆ gncOwnerGetType()

GncOwnerType gncOwnerGetType ( const GncOwner owner)

Returns the GncOwnerType of this owner.

(Not to be confused with qofOwnerGetType().)

Definition at line 201 of file gncOwner.c.

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

◆ gncOwnerGetTypeString()

const char* gncOwnerGetTypeString ( const GncOwner owner)

return the type for the owner as an untranslated string.

Definition at line 207 of file gncOwner.c.

208 {
209  GncOwnerType type = gncOwnerGetType(owner);
210  switch (type)
211  {
212  case GNC_OWNER_NONE:
213  return N_("None");
214  case GNC_OWNER_UNDEFINED:
215  return N_("Undefined");
216  case GNC_OWNER_CUSTOMER:
217  return N_("Customer");
218  case GNC_OWNER_JOB:
219  return N_("Job");
220  case GNC_OWNER_VENDOR:
221  return N_("Vendor");
222  case GNC_OWNER_EMPLOYEE:
223  return N_("Employee");
224  default:
225  PWARN ("Unknown owner type");
226  return NULL;
227  }
228 }
#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:201

◆ 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 363 of file gncOwner.c.

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

◆ 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 384 of file gncOwner.c.

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

◆ 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 700 of file gncOwner.c.

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

◆ 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 729 of file gncOwner.c.

730 {
731  GncInvoice *ia, *ib;
732  time64 da, db;
733 
734  ia = gncInvoiceGetInvoiceFromLot (lotA);
735  ib = gncInvoiceGetInvoiceFromLot (lotB);
736 
737  if (ia)
738  da = gncInvoiceGetDateDue (ia);
739  else
741 
742  if (ib)
743  db = gncInvoiceGetDateDue (ib);
744  else
746 
747  return (da > db) - (da < db);
748 }
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.c:701
time64 xaccTransRetDatePosted(const Transaction *trans)
Retrieve the posted date of the transaction.
Definition: Transaction.c:2484
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
Definition: gncInvoice.c:1301
gint64 time64
Many systems, including Microsoft Windows and BSD-derived Unixes like Darwin, are retaining the int-3...
Definition: gnc-date.h:93

◆ 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 58 of file gncOwner.c.

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

◆ gncOwnerReduceSplitTo()

gboolean gncOwnerReduceSplitTo ( Split *  split,
gnc_numeric  target_value 
)

Helper function to reduce the value of a split to target_value.

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 979 of file gncOwner.c.

980 {
981  gnc_numeric split_val = xaccSplitGetValue (split);
982  gnc_numeric rem_val;
983  Split *rem_split;
984  Transaction *txn;
985  GNCLot *lot;
986 
987  if (gnc_numeric_positive_p (split_val) != gnc_numeric_positive_p (target_value))
988  return FALSE; // Split and target value have to be of the same sign
989 
990  if (gnc_numeric_equal (split_val, target_value))
991  return FALSE; // Split already has the target value
992 
993  rem_val = gnc_numeric_sub (split_val, target_value, GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD); // note: values are of opposite sign
994  rem_split = xaccMallocSplit (xaccSplitGetBook (split));
995  xaccSplitCopyOnto (split, rem_split);
996  xaccSplitSetAmount (rem_split, rem_val);
997  xaccSplitSetValue (rem_split, rem_val);
998 
999  txn = xaccSplitGetParent (split);
1000  xaccTransBeginEdit (txn);
1001  xaccSplitSetAmount (split, target_value);
1002  xaccSplitSetValue (split, target_value);
1003  xaccSplitSetParent (rem_split, txn);
1004  xaccTransCommitEdit (txn);
1005 
1006  lot = xaccSplitGetLot (split);
1007  gnc_lot_add_split (lot, rem_split);
1008 
1009  return TRUE;
1010 }
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.
void xaccSplitCopyOnto(const Split *from_split, Split *to_split)
This is really a helper for xaccTransCopyOnto.
Definition: Split.c:639
void gnc_lot_add_split(GNCLot *lot, Split *split)
The gnc_lot_add_split() routine adds a split to this lot.
Definition: gnc-lot.c:622
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:201
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...
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
#define GNC_DENOM_AUTO
Values that can be passed as the &#39;denom&#39; argument.
Definition: gnc-numeric.h:246
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.c:1881

◆ 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 1013 of file gncOwner.c.

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

◆ gncOwnerTypeToQofIdType()

QofIdTypeConst gncOwnerTypeToQofIdType ( GncOwnerType  t)

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

Definition at line 236 of file gncOwner.c.

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

◆ qofOwnerGetOwner()

QofInstance* qofOwnerGetOwner ( const GncOwner owner)

return the owner itself as an entity.

Definition at line 276 of file gncOwner.c.

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

◆ qofOwnerGetType()

QofIdTypeConst qofOwnerGetType ( const GncOwner owner)

return the type for the collection.

Definition at line 231 of file gncOwner.c.

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

◆ qofOwnerSetEntity()

void qofOwnerSetEntity ( GncOwner owner,
QofInstance *  ent 
)

set the owner from the entity.

Definition at line 320 of file gncOwner.c.

321 {
322  if (!owner || !ent)
323  {
324  return;
325  }
326  if (0 == g_strcmp0(ent->e_type, GNC_ID_CUSTOMER))
327  {
328  owner->type = GNC_OWNER_CUSTOMER;
329  gncOwnerInitCustomer(owner, (GncCustomer*)ent);
330  }
331  else if (0 == g_strcmp0(ent->e_type, GNC_ID_JOB))
332  {
333  owner->type = GNC_OWNER_JOB;
334  gncOwnerInitJob(owner, (GncJob*)ent);
335  }
336  else if (0 == g_strcmp0(ent->e_type, GNC_ID_VENDOR))
337  {
338  owner->type = GNC_OWNER_VENDOR;
339  gncOwnerInitVendor(owner, (GncVendor*)ent);
340  }
341  else if (0 == g_strcmp0(ent->e_type, GNC_ID_EMPLOYEE))
342  {
343  owner->type = GNC_OWNER_EMPLOYEE;
344  gncOwnerInitEmployee(owner, (GncEmployee*)ent);
345  }
346  else
347  {
348  owner->type = GNC_OWNER_NONE;
349  owner->owner.undefined = NULL;
350  }
351 }
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.