GnuCash  5.6-150-g038405b370+
Public Member Functions
StockAssistantModel Class Reference

available transaction types based on the state of the account, the collection and validation of input data from the StockAssistantView and conversion of the data into a GnuCash transaction. More...

Public Member Functions

 StockAssistantModel (Account *account)
 
bool maybe_reset_txn_types ()
 Selects a TxnTypevec for the user to pick from depending on whether the account has a positive, negative, or zero share balance on the selected transaction date. More...
 
const std::optional< TxnTypeVec > & get_txn_types ()
 Accessor function. More...
 
bool set_txn_type (guint type_idx)
 Setter. More...
 
bool txn_type_valid ()
 Accessor. More...
 
void set_transaction_date (time64 date)
 Setter. More...
 
void set_transaction_desc (const char *desc)
 Setter. More...
 
const std::optional< TxnTypeInfo > & txn_type ()
 Accessor. More...
 
std::string get_new_amount_str () const
 Accessor. More...
 
StockTransactionEntrystock_entry ()
 Accessor. More...
 
StockTransactionEntrycash_entry ()
 Accessor. More...
 
StockTransactionEntryfees_entry ()
 Accessor. More...
 
StockTransactionEntrydividend_entry ()
 Accessor. More...
 
StockTransactionEntrycapgains_entry ()
 Accessor. More...
 
Loggerlogger ()
 Accessor. More...
 
std::tuple< bool, std::string, EntryVec > generate_list_of_splits ()
 Generate the proposed list of splits. More...
 
std::tuple< bool, Transaction * > create_transaction ()
 Generate a GnuCash transaction from the active entries. More...
 
Accountaccount ()
 

Detailed Description

available transaction types based on the state of the account, the collection and validation of input data from the StockAssistantView and conversion of the data into a GnuCash transaction.

Definition at line 1104 of file assistant-stock-transaction.cpp.

Member Function Documentation

◆ capgains_entry()

StockTransactionEntry* StockAssistantModel::capgains_entry ( )
inline

Accessor.

Returns
the Capital Gains entry.

Definition at line 1218 of file assistant-stock-transaction.cpp.

1218 { return m_capgains_entry.get(); }

◆ cash_entry()

StockTransactionEntry* StockAssistantModel::cash_entry ( )
inline

Accessor.

Returns
the Cash entry.

Definition at line 1203 of file assistant-stock-transaction.cpp.

1203 { return m_cash_entry.get(); }

◆ create_transaction()

std::tuple< bool, Transaction * > StockAssistantModel::create_transaction ( )

Generate a GnuCash transaction from the active entries.

Returns
A tuple containing a boolean indicating that the transaction was created and a pointer to the new transaction.

Definition at line 1439 of file assistant-stock-transaction.cpp.

1440 {
1441  if (!m_ready_to_create)
1442  {
1443  PERR ("errors exist. cannot create transaction.");
1444  m_list_of_splits.clear();
1445  return {false, nullptr};
1446  }
1447  auto book = qof_instance_get_book (m_acct);
1448  auto trans = xaccMallocTransaction (book);
1449  xaccTransBeginEdit (trans);
1450  xaccTransSetCurrency (trans, m_currency);
1451  xaccTransSetDescription (trans, m_transaction_description);
1452  xaccTransSetDatePostedSecsNormalized (trans, m_transaction_date);
1453  AccountVec accounts;
1454  std::for_each (m_list_of_splits.begin(), m_list_of_splits.end(),
1455  [&](auto& entry)
1456  {
1457  entry->create_split (trans, accounts);
1458  if (entry->get_kvp_tag() && entry->account())
1459  xaccAccountSetAssociatedAccount (m_acct, entry->get_kvp_tag(), entry->account());
1460  });
1461  add_price (book);
1462  xaccTransCommitEdit (trans);
1463  std::for_each (accounts.begin(), accounts.end(), xaccAccountCommitEdit);
1464  m_list_of_splits.clear();
1465  m_ready_to_create = false;
1466  return {true, trans};
1467 }
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
void xaccAccountSetAssociatedAccount(Account *acc, const char *tag, const Account *assoc_acct)
Set the account&#39;s associated account e.g.
Definition: Account.cpp:2669
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
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...
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition: Account.cpp:1516

◆ dividend_entry()

StockTransactionEntry* StockAssistantModel::dividend_entry ( )
inline

Accessor.

Returns
the Dividend entry.

Definition at line 1213 of file assistant-stock-transaction.cpp.

1213 { return m_dividend_entry.get(); }

◆ fees_entry()

StockTransactionEntry* StockAssistantModel::fees_entry ( )
inline

Accessor.

Returns
the Fees entry.

Definition at line 1208 of file assistant-stock-transaction.cpp.

1208 { return m_fees_entry.get(); }

◆ generate_list_of_splits()

std::tuple< bool, std::string, EntryVec > StockAssistantModel::generate_list_of_splits ( )

Generate the proposed list of splits.

This is used to display the proposal to the user in the last page of the assistant and to select on which entries to call create_split.

Returns
A tuple containing a boolean indicating that the data passed validation, a string containing diagnostics, and a vector of the Entries to be used in the transacion.

Definition at line 1317 of file assistant-stock-transaction.cpp.

1317  {
1318  if (!m_txn_types || !m_txn_type)
1319  return { false, "Error: txn_type not initialized", {} };
1320 
1321  m_logger.clear();
1322  m_list_of_splits.clear();
1323 
1324  GncNumeric debit{};
1325  GncNumeric credit{};
1326 
1327  // check the stock transaction date. If there are existing stock
1328  // transactions dated after the date specified, it is very likely
1329  // the later stock transactions will be invalidated. warn the user
1330  // to review them.
1331  if (const auto& splits = xaccAccountGetSplits (m_acct); !splits.empty())
1332  check_txn_date(splits.back(), m_transaction_date, m_logger);
1333 
1334  if (m_stock_entry->enabled() || m_stock_entry->has_amount())
1335  {
1336  m_stock_entry->validate_amount(m_logger);
1337  m_list_of_splits.push_back(m_stock_entry.get());
1338 
1339  auto price{m_stock_entry->calculate_price()};
1340  if (!gnc_numeric_check(price))
1341  {
1342  // Translators: %s refer to: stock mnemonic, broker currency,
1343  // date of transaction.
1344  auto tmpl = N_("A price of 1 %s = %s on %s will be recorded.");
1345  auto date_str = qof_print_date (m_transaction_date);
1346  auto price_msg = g_strdup_printf
1347  (_(tmpl),
1349  m_stock_entry->print_price(), date_str);
1350  m_logger.info(price_msg);
1351  g_free (date_str);
1352  g_free (price_msg);
1353  }
1354  }
1355 
1356  if (m_stock_entry->marker_split())
1357  m_list_of_splits.push_back(m_stock_entry.get());
1358 
1359  if (m_cash_entry->enabled())
1360  {
1361  m_cash_entry->validate_amount(m_logger);
1362  m_list_of_splits.push_back (m_cash_entry.get());
1363  }
1364 
1365  if (m_fees_entry->enabled())
1366  {
1367  m_fees_entry->validate_amount(m_logger);
1368  if (m_fees_entry->do_capitalize())
1369  m_fees_entry->set_account(m_acct);
1370  m_list_of_splits.push_back (m_fees_entry.get());
1371  }
1372 
1373  if (m_dividend_entry->enabled())
1374  {
1375  m_dividend_entry->validate_amount(m_logger);
1376  m_list_of_splits.push_back (m_dividend_entry.get());
1377  }
1378 
1379  if (m_capgains_entry->enabled())
1380  {
1381  m_stock_cg_entry =
1382  std::make_unique<StockTransactionStockCapGainsEntry>(m_capgains_entry.get(),
1383  m_stock_entry.get());
1384  m_stock_cg_entry->validate_amount(m_logger);
1385  m_capgains_entry->validate_amount(m_logger);
1386  m_list_of_splits.push_back(m_stock_cg_entry.get());
1387  m_list_of_splits.push_back (m_capgains_entry.get());
1388  }
1389 
1390  std::for_each(m_list_of_splits.begin(), m_list_of_splits.end(),
1391  [&debit, &credit](auto& entry) {
1392  if (entry->debit_side())
1393  debit += entry->value();
1394  else
1395  credit += entry->value();
1396  });
1397 
1398  if (gnc_numeric_check(debit) || gnc_numeric_check(credit) ||!gnc_numeric_equal (debit, credit))
1399  {
1400  const char *err_act = NULL, *err_reason = NULL;
1401  if (gnc_numeric_check(debit))
1402  {
1403  err_act = "debit";
1405  }
1406  else if (gnc_numeric_check(credit))
1407  {
1408  err_act = "credit";
1409  err_reason = gnc_numeric_errorCode_to_string(gnc_numeric_check(credit));
1410  }
1411 
1412  if (err_act)
1413  {
1414  auto err_str = g_strdup_printf (N_("Transaction can't balance, %s is error value %s"), err_act, err_reason);
1415  m_logger.error(err_str);
1416  g_free (err_str);
1417  }
1418  else
1419  {
1420  auto imbalance_str = N_("Total Debits of %s does not balance with total Credits of %s.");
1421  auto pinfo{gnc_commodity_print_info (m_currency, true)};
1422  auto debit_str = g_strdup (xaccPrintAmount (debit, pinfo));
1423  auto credit_str = g_strdup (xaccPrintAmount (credit, pinfo));
1424  auto error_str = g_strdup_printf (_(imbalance_str), debit_str, credit_str);
1425  m_logger.error (error_str);
1426  g_free (error_str);
1427  g_free (credit_str);
1428  g_free (debit_str);
1429  }
1430  }
1431 
1432  // generate final summary message. Collates a header, the errors
1433  // and warnings. Then allow completion if errors is empty.
1434  m_ready_to_create = !m_logger.has_errors();
1435  return { m_ready_to_create, m_logger.report(), m_list_of_splits };
1436 }
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
std::string report()
Compose all of the logged messages into a bullet list, errors first, then warnings, infos last.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
The primary numeric class for representing amounts and values.
Definition: gnc-numeric.hpp:60
char * qof_print_date(time64 secs)
Convenience; calls through to qof_print_date_dmy_buff().
Definition: gnc-date.cpp:610
const char * gnc_numeric_errorCode_to_string(GNCNumericErrorCode error_code)
Returns a string representation of the given GNCNumericErrorCode.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account&#39;s commodity.
Definition: Account.cpp:3408
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
Check for error signal in value.

◆ get_new_amount_str()

std::string StockAssistantModel::get_new_amount_str ( ) const

Accessor.

return string representing the new balance in a split/reverse split transaction.

◆ get_txn_types()

const std::optional<TxnTypeVec>& StockAssistantModel::get_txn_types ( )
inline

Accessor function.

Returns
The currently available transaction types or std::nullopt if it's unset.

Definition at line 1162 of file assistant-stock-transaction.cpp.

1162 { return m_txn_types; }

◆ logger()

Logger& StockAssistantModel::logger ( )
inline

Accessor.

Returns
the logger.

Definition at line 1223 of file assistant-stock-transaction.cpp.

1223 { return m_logger; }

◆ maybe_reset_txn_types()

bool StockAssistantModel::maybe_reset_txn_types ( )

Selects a TxnTypevec for the user to pick from depending on whether the account has a positive, negative, or zero share balance on the selected transaction date.

Returns
true if the account balance had changed.

Definition at line 1250 of file assistant-stock-transaction.cpp.

1251 {
1252  auto old_bal = m_stock_entry->get_balance();
1253  auto new_bal = xaccAccountGetBalanceAsOfDate
1254  (m_acct, gnc_time64_get_day_end (m_transaction_date));
1255  if (m_txn_types_date && m_txn_types_date == m_transaction_date &&
1256  gnc_numeric_equal (old_bal, new_bal))
1257  return false;
1258  m_stock_entry->set_balance(new_bal);
1259  m_txn_types_date = m_transaction_date;
1260  m_txn_types = gnc_numeric_zero_p (new_bal) ? starting_types
1261  : gnc_numeric_positive_p (new_bal) ? long_types
1262  : short_types;
1263  return true;
1264 };
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
gnc_numeric xaccAccountGetBalanceAsOfDate(Account *acc, time64 date)
Get the balance of the account at the end of the day before the date specified.
Definition: Account.cpp:3533
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
time64 gnc_time64_get_day_end(time64 time_val)
The gnc_time64_get_day_end() routine will take the given time in seconds and adjust it to the last se...
Definition: gnc-date.cpp:1386

◆ set_transaction_date()

void StockAssistantModel::set_transaction_date ( time64  date)
inline

Setter.

Parameters
time64for the transaction date.

Definition at line 1178 of file assistant-stock-transaction.cpp.

1178 { m_transaction_date = date;}

◆ set_transaction_desc()

void StockAssistantModel::set_transaction_desc ( const char *  desc)
inline

Setter.

Parameters
null-terminatedstring containing the transaction description.

Definition at line 1183 of file assistant-stock-transaction.cpp.

1183 { m_transaction_description = desc; }

◆ set_txn_type()

bool StockAssistantModel::set_txn_type ( guint  type_idx)

Setter.

Parameters
theindex into the current Transaction Types indicating the selection.
Returns
true if the selection succeeded.

Definition at line 1267 of file assistant-stock-transaction.cpp.

1268 {
1269  if (!m_txn_types_date || m_txn_types_date != m_transaction_date)
1270  {
1271  PERR ("transaction_date has changed. rerun maybe_reset_txn_types!");
1272  return false;
1273  }
1274  try
1275  {
1276  m_txn_type = m_txn_types->at (type_idx);
1277  }
1278  catch (const std::out_of_range&)
1279  {
1280  PERR ("out of range type_idx=%d", type_idx);
1281  return false;
1282  }
1283 
1284  m_stock_entry->set_fieldmask(m_txn_type->stock_amount);
1285  m_fees_entry->set_fieldmask(m_txn_type->fees_value);
1286  m_capgains_entry->set_fieldmask(m_txn_type->capgains_value);
1287  m_dividend_entry->set_fieldmask(m_txn_type->dividend_value);
1288  m_cash_entry->set_fieldmask(m_txn_type->cash_value);
1289  return true;
1290 };
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244

◆ stock_entry()

StockTransactionEntry* StockAssistantModel::stock_entry ( )
inline

Accessor.

Returns
the Stock entry.

Definition at line 1198 of file assistant-stock-transaction.cpp.

1198 { return m_stock_entry.get(); }

◆ txn_type()

const std::optional<TxnTypeInfo>& StockAssistantModel::txn_type ( )
inline

Accessor.

Returns
the selected transaction type or std::nullopt if it hasn't been set.

Definition at line 1188 of file assistant-stock-transaction.cpp.

1188 { return m_txn_type; }

◆ txn_type_valid()

bool StockAssistantModel::txn_type_valid ( )
inline

Accessor.

Returns
true if the transaction type has been set.

Definition at line 1173 of file assistant-stock-transaction.cpp.

1173 { return m_txn_type.has_value(); }

The documentation for this class was generated from the following file: