GnuCash c935c2f+
Loading...
Searching...
No Matches
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.
 
#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.
 
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.
 
gboolean gncOwnerGetOwnerFromLot (GNCLot *lot, GncOwner *owner)
 Get the owner from the lot.
 
gboolean gncOwnerGetOwnerFromTxn (Transaction *txn, GncOwner *owner)
 Convenience function to get the owner from a transaction.
 
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.
 
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.
 
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.
 
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.
 
gboolean gncOwnerReduceSplitTo (Split *split, gnc_numeric target_amount)
 Helper function to reduce the amount of a split to target_amount.
 
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.
 
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.
 
void gncOwnerFree (GncOwner *owner)
 
void gncOwnerBeginEdit (GncOwner *owner)
 These are convenience wrappers around gnc{Vendor,Customer,Job,Employee}* functions.
 
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.
 
const char * gncOwnerGetTypeString (const GncOwner *owner)
 return the type for the owner as an untranslated string.
 
QofInstanceqofOwnerGetOwner (const GncOwner *owner)
 return the owner itself as an entity.
 
void qofOwnerSetEntity (GncOwner *owner, QofInstance *ent)
 set the owner from the entity.
 
gboolean GNC_IS_OWNER (QofInstance *ent)
 Check if entity is an owner kind.
 
QofIdTypeConst gncOwnerTypeToQofIdType (GncOwnerType t)
 Returns the QofIdType of the given GncOwnerType, or NULL if no suitable one exists.
 
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.
 
gboolean gncOwnerIsValid (const GncOwner *owner)
 Returns TRUE if the given owner is one of the valid objects.
 
gpointer gncOwnerGetUndefined (const GncOwner *owner)
 If the given owner is of type GNC_OWNER_UNDEFINED, returns the undefined pointer, which is usually NULL.
 
GncCustomergncOwnerGetCustomer (const GncOwner *owner)
 If the given owner is of type GNC_OWNER_CUSTOMER, returns the pointer to the customer object.
 
GncJob * gncOwnerGetJob (const GncOwner *owner)
 If the given owner is of type GNC_OWNER_JOB, returns the pointer to the job object.
 
GncVendor * gncOwnerGetVendor (const GncOwner *owner)
 If the given owner is of type GNC_OWNER_VENDOR, returns the pointer to the vendor object.
 
GncEmployee * gncOwnerGetEmployee (const GncOwner *owner)
 If the given owner is of type GNC_OWNER_EMPLOYEE, returns the pointer to the employee object.
 
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.
 
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

◆ GNC_ID_OWNER

#define GNC_ID_OWNER   "gncOwner"

Definition at line 43 of file gncOwner.h.

◆ OWNER_CUSTOMER

#define OWNER_CUSTOMER   "customer"

Definition at line 326 of file gncOwner.h.

◆ OWNER_EMPLOYEE

#define OWNER_EMPLOYEE   "employee"

Definition at line 329 of file gncOwner.h.

◆ OWNER_FROM_LOT

#define OWNER_FROM_LOT   "owner-from-lot"

Definition at line 334 of file gncOwner.h.

◆ OWNER_JOB

#define OWNER_JOB   "job"

Definition at line 327 of file gncOwner.h.

◆ OWNER_NAME

#define OWNER_NAME   "name"

Definition at line 332 of file gncOwner.h.

◆ OWNER_PARENT

#define OWNER_PARENT   "parent"

Definition at line 330 of file gncOwner.h.

◆ OWNER_PARENTG

#define OWNER_PARENTG   "parent-guid"

Definition at line 331 of file gncOwner.h.

◆ OWNER_TYPE

#define OWNER_TYPE   "type"

Definition at line 324 of file gncOwner.h.

◆ OWNER_TYPE_STRING

#define OWNER_TYPE_STRING   "type-string"

Allows the type to be handled externally.

Definition at line 325 of file gncOwner.h.

◆ OWNER_VENDOR

#define OWNER_VENDOR   "vendor"

Definition at line 328 of file gncOwner.h.

Enumeration Type Documentation

◆ GncOwnerType

enum GncOwnerType

Definition at line 45 of file gncOwner.h.

46{
47 GNC_OWNER_NONE ,
48 GNC_OWNER_UNDEFINED ,
49 GNC_OWNER_CUSTOMER ,
50 GNC_OWNER_JOB ,
51 GNC_OWNER_VENDOR ,
52 GNC_OWNER_EMPLOYEE ,
53} GncOwnerType;

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}
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:3982
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

◆ gncOwnerAttachToLot()

void gncOwnerAttachToLot ( const GncOwner owner,
GNCLot *  lot 
)

Attach an owner to a lot.

Definition at line 622 of file gncOwner.c.

623{
624 if (!owner || !lot)
625 return;
626
627 gnc_lot_begin_edit (lot);
628
629 qof_instance_set (QOF_INSTANCE (lot),
630 GNC_OWNER_TYPE, (gint64)gncOwnerGetType (owner),
631 GNC_OWNER_GUID, gncOwnerGetGUID (owner),
632 NULL);
633 gnc_lot_commit_edit (lot);
634}
void qof_instance_set(QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_set Group setting multiple parameters in a single begin/commit/rollback.
const GncGUID * gncOwnerGetGUID(const GncOwner *owner)
Get the GncGUID of the immediate owner.
Definition gncOwner.c:518
GncOwnerType gncOwnerGetType(const GncOwner *owner)
Returns the GncOwnerType of this owner.
Definition gncOwner.c:200

◆ 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}
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition Account.cpp:1516
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition Account.cpp:1475
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
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
Account * gnc_lot_get_account(const GNCLot *lot)
Returns the account with which this lot is associated.
Definition gnc-lot.cpp:377
gnc_numeric gnc_lot_get_balance(GNCLot *lot)
Returns the lot balance.
Definition gnc-lot.cpp:487
gboolean gnc_lot_is_closed(GNCLot *lot)
Returns closed status of the given lot.
Definition gnc-lot.cpp:367
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.
int gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
Returns 1 if a>b, -1 if b>a, 0 if a == b
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
STRUCTS.

◆ 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}

◆ gncOwnerCommitEdit()

void gncOwnerCommitEdit ( GncOwner owner)

Definition at line 103 of file gncOwner.c.

104{
105 if (!owner) return;
106 switch (owner->type)
107 {
108 case GNC_OWNER_NONE :
109 case GNC_OWNER_UNDEFINED :
110 break;
111 case GNC_OWNER_CUSTOMER :
112 {
113 gncCustomerCommitEdit(owner->owner.customer);
114 break;
115 }
116 case GNC_OWNER_JOB :
117 {
118 gncJobCommitEdit(owner->owner.job);
119 break;
120 }
121 case GNC_OWNER_VENDOR :
122 {
123 gncVendorCommitEdit(owner->owner.vendor);
124 break;
125 }
126 case GNC_OWNER_EMPLOYEE :
127 {
128 gncEmployeeCommitEdit(owner->owner.employee);
129 break;
130 }
131 }
132}

◆ gncOwnerCompare()

int gncOwnerCompare ( const GncOwner a,
const GncOwner b 
)

Sort on name.

Definition at line 590 of file gncOwner.c.

591{
592 if (!a && !b) return 0;
593 if (!a && b) return 1;
594 if (a && !b) return -1;
595
596 if (a->type != b->type)
597 return (a->type - b->type);
598
599 switch (a->type)
600 {
601 case GNC_OWNER_NONE:
602 case GNC_OWNER_UNDEFINED:
603 default:
604 return 0;
605 case GNC_OWNER_CUSTOMER:
606 return gncCustomerCompare (a->owner.customer, b->owner.customer);
607 case GNC_OWNER_VENDOR:
608 return gncVendorCompare (a->owner.vendor, b->owner.vendor);
609 case GNC_OWNER_EMPLOYEE:
610 return gncEmployeeCompare (a->owner.employee, b->owner.employee);
611 case GNC_OWNER_JOB:
612 return gncJobCompare (a->owner.job, b->owner.job);
613 }
614}
int gncVendorCompare(const GncVendor *a, const GncVendor *b)
XXX should be renamed to RetJobList to be consistent with other usage, since caller must free the cop...
Definition gncVendor.c:795

◆ gncOwnerCopy()

void gncOwnerCopy ( const GncOwner src,
GncOwner dest 
)

Definition at line 397 of file gncOwner.c.

398{
399 if (!src || !dest) return;
400 if (src == dest) return;
401 *dest = *src;
402}

◆ 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,
821 GNC_HOW_RND_ROUND_HALF_UP);
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,
827 GNC_HOW_RND_ROUND_HALF_UP);
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 */
882 if (preset_txn)
883 *preset_txn = txn;
884
885 return payment_lot;
886}
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity
Definition Account.cpp:3408
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
time64 gnc_time(time64 *tbuf)
get the current time
Definition gnc-date.cpp:262
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
void xaccTransSetNum(Transaction *trans, const char *xnum)
Sets the transaction Number (or ID) field; rather than use this function directly,...
#define xaccTransAppendSplit(t, s)
Add a split to the 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 xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction's split list.
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
void xaccTransSetDatePostedSecs(Transaction *trans, time64 secs)
The xaccTransSetDatePostedSecs() method will modify the posted date of the transaction,...
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
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.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account.
Definition Account.h:1069
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
void gnc_lot_add_split(GNCLot *lot, Split *split)
Adds a split to this lot.
Definition gnc-lot.cpp:579
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
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_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
void gncOwnerAttachToLot(const GncOwner *owner, GNCLot *lot)
Attach an owner to a lot.
Definition gncOwner.c:622
const GncOwner * gncOwnerGetEndOwner(const GncOwner *owner)
Get the "parent" Owner or GncGUID thereof.
Definition gncOwner.c:572
void xaccSplitSetReconcile(Split *split, char recn)
Set the reconcile flag.
gboolean xaccSplitDestroy(Split *split)
Destructor.
Definition Split.cpp:1506
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction's commodity.
Split * xaccMallocSplit(QofBook *book)
Constructor.
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity.
#define NREC
not reconciled or cleared
Definition Split.h:76
void xaccSplitSetAction(Split *split, const char *actn)
The Action is an arbitrary user-assigned string.
Definition Split.cpp:1786
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.
QofBook reference.
Definition qofbook-p.hpp:47

◆ gncOwnerDestroy()

void gncOwnerDestroy ( GncOwner owner)

Definition at line 134 of file gncOwner.c.

135{
136 if (!owner) return;
137 switch (owner->type)
138 {
139 case GNC_OWNER_NONE :
140 case GNC_OWNER_UNDEFINED :
141 break;
142 case GNC_OWNER_CUSTOMER :
143 {
144 gncCustomerDestroy(owner->owner.customer);
145 break;
146 }
147 case GNC_OWNER_JOB :
148 {
149 gncJobDestroy(owner->owner.job);
150 break;
151 }
152 case GNC_OWNER_VENDOR :
153 {
154 gncVendorDestroy(owner->owner.vendor);
155 break;
156 }
157 case GNC_OWNER_EMPLOYEE :
158 {
159 gncEmployeeDestroy(owner->owner.employee);
160 break;
161 }
162 }
163}

◆ 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}

◆ 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
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,...
GList SplitList
GList of Split.
Definition gnc-engine.h:207
#define TXN_TYPE_LINK
Transaction is a link between (invoice and payment) lots
#define PWARN(format, args...)
Log a warning.
Definition qoflog.h:250
SplitList * gnc_lot_get_split_list(const GNCLot *lot)
Returns a list of all the splits in this lot.
Definition gnc-lot.cpp:425
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.

◆ gncOwnerFree()

void gncOwnerFree ( GncOwner owner)

Definition at line 66 of file gncOwner.c.

67{
68 if (!owner) return;
69 g_free (owner);
70}

◆ gncOwnerGCompareFunc()

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.

Definition at line 411 of file gncOwner.c.

412{
413 if (gncOwnerEqual (a, b))
414 return 0;
415 else
416 return 1;
417}
gboolean gncOwnerEqual(const GncOwner *a, const GncOwner *b)
Assess equality by checking.
Definition gncOwner.c:404

◆ gncOwnerGetAccountTypesList()

GList * gncOwnerGetAccountTypesList ( const GncOwner owner)

Returns a GList of account-types based on the owner type.

Definition at line 1444 of file gncOwner.c.

1445{
1446 g_return_val_if_fail (owner, NULL);
1447
1448 switch (gncOwnerGetType (owner))
1449 {
1450 case GNC_OWNER_CUSTOMER:
1451 return (g_list_prepend (NULL, (gpointer)ACCT_TYPE_RECEIVABLE));
1452 case GNC_OWNER_VENDOR:
1453 case GNC_OWNER_EMPLOYEE:
1454 return (g_list_prepend (NULL, (gpointer)ACCT_TYPE_PAYABLE));
1455 break;
1456 default:
1457 return (g_list_prepend (NULL, (gpointer)ACCT_TYPE_NONE));
1458 }
1459}
@ ACCT_TYPE_NONE
Not a type.
Definition Account.h:105

◆ gncOwnerGetActive()

gboolean gncOwnerGetActive ( const GncOwner owner)

Definition at line 498 of file gncOwner.c.

499{
500 if (!owner) return FALSE;
501 switch (owner->type)
502 {
503 case GNC_OWNER_NONE:
504 case GNC_OWNER_UNDEFINED:
505 default:
506 return FALSE;
507 case GNC_OWNER_CUSTOMER:
508 return gncCustomerGetActive (owner->owner.customer);
509 case GNC_OWNER_VENDOR:
510 return gncVendorGetActive (owner->owner.vendor);
511 case GNC_OWNER_EMPLOYEE:
512 return gncEmployeeGetActive (owner->owner.employee);
513 case GNC_OWNER_JOB:
514 return gncJobGetActive (owner->owner.job);
515 }
516}

◆ gncOwnerGetAddr()

GncAddress * gncOwnerGetAddr ( const GncOwner owner)

Definition at line 459 of file gncOwner.c.

460{
461 if (!owner) return NULL;
462 switch (owner->type)
463 {
464 case GNC_OWNER_NONE:
465 case GNC_OWNER_UNDEFINED:
466 case GNC_OWNER_JOB:
467 default:
468 return NULL;
469 case GNC_OWNER_CUSTOMER:
470 return gncCustomerGetAddr (owner->owner.customer);
471 case GNC_OWNER_VENDOR:
472 return gncVendorGetAddr (owner->owner.vendor);
473 case GNC_OWNER_EMPLOYEE:
474 return gncEmployeeGetAddr (owner->owner.employee);
475 }
476}

◆ gncOwnerGetBalanceInCurrency()

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.

Definition at line 1478 of file gncOwner.c.

1480{
1481 gnc_numeric balance = gnc_numeric_zero ();
1482 QofBook *book;
1483 gnc_commodity *owner_currency;
1484 GNCPriceDB *pdb;
1485 const gnc_numeric *cached_balance = NULL;
1486
1487 g_return_val_if_fail (owner, gnc_numeric_zero ());
1488
1489 book = qof_instance_get_book (qofOwnerGetOwner (owner));
1490 owner_currency = gncOwnerGetCurrency (owner);
1491
1492 cached_balance = gncOwnerGetCachedBalance (owner);
1493 if (cached_balance)
1494 balance = *cached_balance;
1495 else
1496 {
1497 /* No valid cache value found for balance. Let's recalculate */
1498 GList *acct_list = gnc_account_get_descendants (gnc_book_get_root_account (book));
1499 GList *acct_types = gncOwnerGetAccountTypesList (owner);
1500 GList *acct_node;
1501
1502 /* For each account */
1503 for (acct_node = acct_list; acct_node; acct_node = acct_node->next)
1504 {
1505 Account *account = acct_node->data;
1506 GList *lot_list = NULL, *lot_node;
1507
1508 /* Check if this account can have lots for the owner, otherwise skip to next */
1509 if (g_list_index (acct_types, (gpointer)xaccAccountGetType (account))
1510 == -1)
1511 continue;
1512
1513
1514 if (!gnc_commodity_equal (owner_currency, xaccAccountGetCommodity (account)))
1515 continue;
1516
1517 /* Get a list of open lots for this owner and account */
1519 (gpointer)owner, NULL);
1520 /* For each lot */
1521 for (lot_node = lot_list; lot_node; lot_node = lot_node->next)
1522 {
1523 GNCLot *lot = lot_node->data;
1524 gnc_numeric lot_balance = gnc_lot_get_balance (lot);
1525 GncInvoice *invoice = gncInvoiceGetInvoiceFromLot(lot);
1526 if (invoice)
1527 balance = gnc_numeric_add (balance, lot_balance,
1528 gnc_commodity_get_fraction (owner_currency), GNC_HOW_RND_ROUND_HALF_UP);
1529 }
1530 g_list_free (lot_list);
1531 }
1532 g_list_free (acct_list);
1533 g_list_free (acct_types);
1534
1535 gncOwnerSetCachedBalance (owner, &balance);
1536 }
1537
1538 pdb = gnc_pricedb_get_db (book);
1539
1540 if (report_currency)
1542 pdb, balance, owner_currency, report_currency);
1543
1544 return balance;
1545}
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
Definition Account.cpp:3267
GList * gnc_account_get_descendants(const Account *account)
This routine returns a flat list of all of the accounts that are descendants of the specified account...
Definition Account.cpp:3044
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
GList * gncOwnerGetAccountTypesList(const GncOwner *owner)
Returns a GList of account-types based on the owner type.
Definition gncOwner.c:1444
QofInstance * qofOwnerGetOwner(const GncOwner *owner)
return the owner itself as an entity.
Definition gncOwner.c:275
gnc_numeric gnc_pricedb_convert_balance_latest_price(GNCPriceDB *pdb, gnc_numeric balance, const gnc_commodity *balance_currency, const gnc_commodity *new_currency)
Convert a balance from one currency to another using the most recent price between the two.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.

◆ gncOwnerGetCommoditiesList()

GList * gncOwnerGetCommoditiesList ( const GncOwner owner)

Returns a GList of currencies associated with the owner.

Definition at line 1462 of file gncOwner.c.

1463{
1464 g_return_val_if_fail (owner, NULL);
1465 g_return_val_if_fail (gncOwnerGetCurrency(owner), NULL);
1466
1467 return (g_list_prepend (NULL, gncOwnerGetCurrency(owner)));
1468}

◆ gncOwnerGetCurrency()

gnc_commodity * gncOwnerGetCurrency ( const GncOwner owner)

Definition at line 478 of file gncOwner.c.

479{
480 if (!owner) return NULL;
481 switch (owner->type)
482 {
483 case GNC_OWNER_NONE:
484 case GNC_OWNER_UNDEFINED:
485 default:
486 return NULL;
487 case GNC_OWNER_CUSTOMER:
488 return gncCustomerGetCurrency (owner->owner.customer);
489 case GNC_OWNER_VENDOR:
490 return gncVendorGetCurrency (owner->owner.vendor);
491 case GNC_OWNER_EMPLOYEE:
492 return gncEmployeeGetCurrency (owner->owner.employee);
493 case GNC_OWNER_JOB:
494 return gncOwnerGetCurrency (gncJobGetOwner (owner->owner.job));
495 }
496}

◆ 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}

◆ gncOwnerGetEndGUID()

const GncGUID * gncOwnerGetEndGUID ( const GncOwner owner)

Definition at line 616 of file gncOwner.c.

617{
618 if (!owner) return NULL;
619 return gncOwnerGetGUID (gncOwnerGetEndOwner (owner));
620}

◆ 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}

◆ gncOwnerGetGUID()

const GncGUID * gncOwnerGetGUID ( const GncOwner owner)

Get the GncGUID of the immediate owner.

Definition at line 518 of file gncOwner.c.

519{
520 if (!owner) return NULL;
521
522 switch (owner->type)
523 {
524 case GNC_OWNER_NONE:
525 case GNC_OWNER_UNDEFINED:
526 default:
527 return NULL;
528 case GNC_OWNER_CUSTOMER:
529 return qof_instance_get_guid (QOF_INSTANCE(owner->owner.customer));
530 case GNC_OWNER_JOB:
531 return qof_instance_get_guid (QOF_INSTANCE(owner->owner.job));
532 case GNC_OWNER_VENDOR:
533 return qof_instance_get_guid (QOF_INSTANCE(owner->owner.vendor));
534 case GNC_OWNER_EMPLOYEE:
535 return qof_instance_get_guid (QOF_INSTANCE(owner->owner.employee));
536 }
537}
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.

◆ gncOwnerGetID()

const char * gncOwnerGetID ( const GncOwner owner)

Definition at line 419 of file gncOwner.c.

420{
421 if (!owner) return NULL;
422 switch (owner->type)
423 {
424 case GNC_OWNER_NONE:
425 case GNC_OWNER_UNDEFINED:
426 default:
427 return NULL;
428 case GNC_OWNER_CUSTOMER:
429 return gncCustomerGetID (owner->owner.customer);
430 case GNC_OWNER_JOB:
431 return gncJobGetID (owner->owner.job);
432 case GNC_OWNER_VENDOR:
433 return gncVendorGetID (owner->owner.vendor);
434 case GNC_OWNER_EMPLOYEE:
435 return gncEmployeeGetID (owner->owner.employee);
436 }
437}

◆ 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}

◆ gncOwnerGetName()

const char * gncOwnerGetName ( const GncOwner owner)

Definition at line 439 of file gncOwner.c.

440{
441 if (!owner) return NULL;
442 switch (owner->type)
443 {
444 case GNC_OWNER_NONE:
445 case GNC_OWNER_UNDEFINED:
446 default:
447 return NULL;
448 case GNC_OWNER_CUSTOMER:
449 return gncCustomerGetName (owner->owner.customer);
450 case GNC_OWNER_JOB:
451 return gncJobGetName (owner->owner.job);
452 case GNC_OWNER_VENDOR:
453 return gncVendorGetName (owner->owner.vendor);
454 case GNC_OWNER_EMPLOYEE:
455 return gncEmployeeGetName (owner->owner.employee);
456 }
457}

◆ 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
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}
#define TXN_TYPE_NONE
No transaction type
Split * xaccTransGetFirstAPARAcctSplit(const Transaction *trans, gboolean strict)
The xaccTransGetFirstPaymentAcctSplit() method returns a pointer to the first split in this transacti...
gboolean gncOwnerGetOwnerFromLot(GNCLot *lot, GncOwner *owner)
Get the owner from the lot.
Definition gncOwner.c:636
GNCLot * xaccSplitGetLot(const Split *split)
Returns the pointer to the debited/credited Lot where this split belongs to, or NULL if it doesn't be...
Definition Split.cpp:1920

◆ gncOwnerGetOwnerFromTypeGuid()

gboolean gncOwnerGetOwnerFromTypeGuid ( QofBook book,
GncOwner owner,
QofIdType  type,
GncGUID guid 
)

Definition at line 1575 of file gncOwner.c.

1576{
1577 if (!book || !owner || !type || !guid) return FALSE;
1578
1579 if (0 == g_strcmp0(type, GNC_ID_CUSTOMER))
1580 {
1581 GncCustomer *customer = gncCustomerLookup(book, guid);
1582 gncOwnerInitCustomer(owner, customer);
1583 return (NULL != customer);
1584 }
1585 else if (0 == g_strcmp0(type, GNC_ID_JOB))
1586 {
1587 GncJob *job = gncJobLookup(book, guid);
1588 gncOwnerInitJob(owner, job);
1589 return (NULL != job);
1590 }
1591 else if (0 == g_strcmp0(type, GNC_ID_VENDOR))
1592 {
1593 GncVendor *vendor = gncVendorLookup(book, guid);
1594 gncOwnerInitVendor(owner, vendor);
1595 return (NULL != vendor);
1596 }
1597 else if (0 == g_strcmp0(type, GNC_ID_EMPLOYEE))
1598 {
1599 GncEmployee *employee = gncEmployeeLookup(book, guid);
1600 gncOwnerInitEmployee(owner, employee);
1601 return (NULL != employee);
1602 }
1603 return 0;
1604}
credit, discount and shipaddr are unique to GncCustomer id, name, notes, terms, addr,...

◆ 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}

◆ 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}

◆ gncOwnerInitCustomer()

void gncOwnerInitCustomer ( GncOwner owner,
GncCustomer customer 
)

Definition at line 172 of file gncOwner.c.

173{
174 if (!owner) return;
175 owner->type = GNC_OWNER_CUSTOMER;
176 owner->owner.customer = customer;
177}

◆ gncOwnerInitEmployee()

void gncOwnerInitEmployee ( GncOwner owner,
GncEmployee *  employee 
)

Definition at line 193 of file gncOwner.c.

194{
195 if (!owner) return;
196 owner->type = GNC_OWNER_EMPLOYEE;
197 owner->owner.employee = employee;
198}

◆ gncOwnerInitJob()

void gncOwnerInitJob ( GncOwner owner,
GncJob *  job 
)

Definition at line 179 of file gncOwner.c.

180{
181 if (!owner) return;
182 owner->type = GNC_OWNER_JOB;
183 owner->owner.job = job;
184}

◆ gncOwnerInitUndefined()

void gncOwnerInitUndefined ( GncOwner owner,
gpointer  obj 
)

Definition at line 165 of file gncOwner.c.

166{
167 if (!owner) return;
168 owner->type = GNC_OWNER_UNDEFINED;
169 owner->owner.undefined = obj;
170}

◆ gncOwnerInitVendor()

void gncOwnerInitVendor ( GncOwner owner,
GncVendor *  vendor 
)

Definition at line 186 of file gncOwner.c.

187{
188 if (!owner) return;
189 owner->type = GNC_OWNER_VENDOR;
190 owner->owner.vendor = vendor;
191}

◆ 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}

◆ gncOwnerLotMatchOwnerFunc()

gboolean gncOwnerLotMatchOwnerFunc ( GNCLot *  lot,
gpointer  user_data 
)

Helper function used to filter a list of lots by owner.

Definition at line 706 of file gncOwner.c.

707{
708 const GncOwner *req_owner = user_data;
709 GncOwner lot_owner;
710 const GncOwner *end_owner;
711 GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
712
713 /* Determine the owner associated to the lot */
714 if (invoice)
715 /* Invoice lots */
716 end_owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
717 else if (gncOwnerGetOwnerFromLot (lot, &lot_owner))
718 /* Pre-payment lots */
719 end_owner = gncOwnerGetEndOwner (&lot_owner);
720 else
721 return FALSE;
722
723 /* Is this a lot for the requested owner ? */
724 return gncOwnerEqual (end_owner, req_owner);
725}

◆ 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}
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition gnc-date.h:87
time64 xaccTransRetDatePosted(const Transaction *trans)
Retrieve the posted date of the transaction.
Split * gnc_lot_get_earliest_split(GNCLot *lot)
Convenience routine to identify the earliest date in the lot.
Definition gnc-lot.cpp:658

◆ 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,
979 GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
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,
984 GNC_HOW_RND_ROUND_HALF_UP);
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}
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a-b.
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
void xaccSplitCopyOnto(const Split *from_split, Split *to_split)
This is really a helper for xaccTransCopyOnto.
Definition Split.cpp:648
QofBook * xaccSplitGetBook(const Split *split)
Returns the book of this split, i.e.

◆ gncOwnerRegister()

gboolean gncOwnerRegister ( void  )

Definition at line 1606 of file gncOwner.c.

1607{
1608 static QofParam params[] =
1609 {
1610 { OWNER_TYPE, QOF_TYPE_INT64, (QofAccessFunc)gncOwnerGetType, NULL },
1611 { OWNER_CUSTOMER, GNC_ID_CUSTOMER, (QofAccessFunc)gncOwnerGetCustomer, NULL },
1612 { OWNER_JOB, GNC_ID_JOB, (QofAccessFunc)gncOwnerGetJob, NULL },
1613 { OWNER_VENDOR, GNC_ID_VENDOR, (QofAccessFunc)gncOwnerGetVendor, NULL },
1614 { OWNER_EMPLOYEE, GNC_ID_EMPLOYEE, (QofAccessFunc)gncOwnerGetEmployee, NULL },
1615 { OWNER_PARENT, GNC_ID_OWNER, (QofAccessFunc)gncOwnerGetEndOwner, NULL },
1616 { OWNER_PARENTG, QOF_TYPE_GUID, (QofAccessFunc)gncOwnerGetEndGUID, NULL },
1617 { OWNER_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncOwnerGetName, NULL },
1618 { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)gncOwnerGetGUID, NULL },
1619 { NULL },
1620 };
1621
1622 qof_class_register (GNC_ID_OWNER, (QofSortFunc)gncOwnerCompare, params);
1623 reg_lot ();
1624
1625 return TRUE;
1626}
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
Definition qofclass.h:123
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_function, const QofParam *params)
This function registers a new object class with the Qof subsystem.
Definition qofclass.cpp:86
int(* QofSortFunc)(gconstpointer, gconstpointer)
This function is the default sort function for a particular object type.
Definition qofclass.h:168
GncCustomer * gncOwnerGetCustomer(const GncOwner *owner)
If the given owner is of type GNC_OWNER_CUSTOMER, returns the pointer to the customer object.
Definition gncOwner.c:369
GncEmployee * gncOwnerGetEmployee(const GncOwner *owner)
If the given owner is of type GNC_OWNER_EMPLOYEE, returns the pointer to the employee object.
Definition gncOwner.c:390
GncJob * gncOwnerGetJob(const GncOwner *owner)
If the given owner is of type GNC_OWNER_JOB, returns the pointer to the job object.
Definition gncOwner.c:376
int gncOwnerCompare(const GncOwner *a, const GncOwner *b)
Sort on name.
Definition gncOwner.c:590
GncVendor * gncOwnerGetVendor(const GncOwner *owner)
If the given owner is of type GNC_OWNER_VENDOR, returns the pointer to the vendor object.
Definition gncOwner.c:383

◆ gncOwnerRetGUID()

GncGUID gncOwnerRetGUID ( GncOwner owner)

Definition at line 564 of file gncOwner.c.

565{
566 const GncGUID *guid = gncOwnerGetGUID (owner);
567 if (guid)
568 return *guid;
569 return *guid_null ();
570}
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
Definition guid.cpp:165

◆ gncOwnerSetActive()

void gncOwnerSetActive ( const GncOwner owner,
gboolean  active 
)

Definition at line 540 of file gncOwner.c.

541{
542 if (!owner) return;
543 switch (owner->type)
544 {
545 case GNC_OWNER_CUSTOMER:
546 gncCustomerSetActive (owner->owner.customer, active);
547 break;
548 case GNC_OWNER_VENDOR:
549 gncVendorSetActive (owner->owner.vendor, active);
550 break;
551 case GNC_OWNER_EMPLOYEE:
552 gncEmployeeSetActive (owner->owner.employee, active);
553 break;
554 case GNC_OWNER_JOB:
555 gncJobSetActive (owner->owner.job, active);
556 break;
557 case GNC_OWNER_NONE:
558 case GNC_OWNER_UNDEFINED:
559 default:
560 break;
561 }
562}

◆ 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 business items: ");
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}
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.

◆ 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}
QofIdType e_type
Entity type.
Definition qofinstance.h:75