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 1101 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 1215 of file assistant-stock-transaction.cpp.

1215 { return m_capgains_entry.get(); }

◆ cash_entry()

StockTransactionEntry* StockAssistantModel::cash_entry ( )
inline

Accessor.

Returns
the Cash entry.

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

1200 { 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 1436 of file assistant-stock-transaction.cpp.

1437 {
1438  if (!m_ready_to_create)
1439  {
1440  PERR ("errors exist. cannot create transaction.");
1441  m_list_of_splits.clear();
1442  return {false, nullptr};
1443  }
1444  auto book = qof_instance_get_book (m_acct);
1445  auto trans = xaccMallocTransaction (book);
1446  xaccTransBeginEdit (trans);
1447  xaccTransSetCurrency (trans, m_currency);
1448  xaccTransSetDescription (trans, m_transaction_description);
1449  xaccTransSetDatePostedSecsNormalized (trans, m_transaction_date);
1450  AccountVec accounts;
1451  std::for_each (m_list_of_splits.begin(), m_list_of_splits.end(),
1452  [&](auto& entry)
1453  {
1454  entry->create_split (trans, accounts);
1455  if (entry->get_kvp_tag() && entry->account())
1456  xaccAccountSetAssociatedAccount (m_acct, entry->get_kvp_tag(), entry->account());
1457  });
1458  add_price (book);
1459  xaccTransCommitEdit (trans);
1460  std::for_each (accounts.begin(), accounts.end(), xaccAccountCommitEdit);
1461  m_list_of_splits.clear();
1462  m_ready_to_create = false;
1463  return {true, trans};
1464 }
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:2620
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 1210 of file assistant-stock-transaction.cpp.

1210 { return m_dividend_entry.get(); }

◆ fees_entry()

StockTransactionEntry* StockAssistantModel::fees_entry ( )
inline

Accessor.

Returns
the Fees entry.

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

1205 { 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 1314 of file assistant-stock-transaction.cpp.

1314  {
1315  if (!m_txn_types || !m_txn_type)
1316  return { false, "Error: txn_type not initialized", {} };
1317 
1318  m_logger.clear();
1319  m_list_of_splits.clear();
1320 
1321  GncNumeric debit{};
1322  GncNumeric credit{};
1323 
1324  // check the stock transaction date. If there are existing stock
1325  // transactions dated after the date specified, it is very likely
1326  // the later stock transactions will be invalidated. warn the user
1327  // to review them.
1328  if (const auto& splits = xaccAccountGetSplits (m_acct); !splits.empty())
1329  check_txn_date(splits.back(), m_transaction_date, m_logger);
1330 
1331  if (m_stock_entry->enabled() || m_stock_entry->has_amount())
1332  {
1333  m_stock_entry->validate_amount(m_logger);
1334  m_list_of_splits.push_back(m_stock_entry.get());
1335 
1336  auto price{m_stock_entry->calculate_price()};
1337  if (!gnc_numeric_check(price))
1338  {
1339  // Translators: %s refer to: stock mnemonic, broker currency,
1340  // date of transaction.
1341  auto tmpl = N_("A price of 1 %s = %s on %s will be recorded.");
1342  auto date_str = qof_print_date (m_transaction_date);
1343  auto price_msg = g_strdup_printf
1344  (_(tmpl),
1346  m_stock_entry->print_price(), date_str);
1347  m_logger.info(price_msg);
1348  g_free (date_str);
1349  g_free (price_msg);
1350  }
1351  }
1352 
1353  if (m_stock_entry->marker_split())
1354  m_list_of_splits.push_back(m_stock_entry.get());
1355 
1356  if (m_cash_entry->enabled())
1357  {
1358  m_cash_entry->validate_amount(m_logger);
1359  m_list_of_splits.push_back (m_cash_entry.get());
1360  }
1361 
1362  if (m_fees_entry->enabled())
1363  {
1364  m_fees_entry->validate_amount(m_logger);
1365  if (m_fees_entry->do_capitalize())
1366  m_fees_entry->set_account(m_acct);
1367  m_list_of_splits.push_back (m_fees_entry.get());
1368  }
1369 
1370  if (m_dividend_entry->enabled())
1371  {
1372  m_dividend_entry->validate_amount(m_logger);
1373  m_list_of_splits.push_back (m_dividend_entry.get());
1374  }
1375 
1376  if (m_capgains_entry->enabled())
1377  {
1378  m_stock_cg_entry =
1379  std::make_unique<StockTransactionStockCapGainsEntry>(m_capgains_entry.get(),
1380  m_stock_entry.get());
1381  m_stock_cg_entry->validate_amount(m_logger);
1382  m_capgains_entry->validate_amount(m_logger);
1383  m_list_of_splits.push_back(m_stock_cg_entry.get());
1384  m_list_of_splits.push_back (m_capgains_entry.get());
1385  }
1386 
1387  std::for_each(m_list_of_splits.begin(), m_list_of_splits.end(),
1388  [&debit, &credit](auto& entry) {
1389  if (entry->debit_side())
1390  debit += entry->value();
1391  else
1392  credit += entry->value();
1393  });
1394 
1395  if (gnc_numeric_check(debit) || gnc_numeric_check(credit) ||!gnc_numeric_equal (debit, credit))
1396  {
1397  const char *err_act = NULL, *err_reason = NULL;
1398  if (gnc_numeric_check(debit))
1399  {
1400  err_act = "debit";
1402  }
1403  else if (gnc_numeric_check(credit))
1404  {
1405  err_act = "credit";
1406  err_reason = gnc_numeric_errorCode_to_string(gnc_numeric_check(credit));
1407  }
1408 
1409  if (err_act)
1410  {
1411  auto err_str = g_strdup_printf (N_("Transaction can't balance, %s is error value %s"), err_act, err_reason);
1412  m_logger.error(err_str);
1413  g_free (err_str);
1414  }
1415  else
1416  {
1417  auto imbalance_str = N_("Total Debits of %s does not balance with total Credits of %s.");
1418  auto pinfo{gnc_commodity_print_info (m_currency, true)};
1419  auto debit_str = g_strdup (xaccPrintAmount (debit, pinfo));
1420  auto credit_str = g_strdup (xaccPrintAmount (credit, pinfo));
1421  auto error_str = g_strdup_printf (_(imbalance_str), debit_str, credit_str);
1422  m_logger.error (error_str);
1423  g_free (error_str);
1424  g_free (credit_str);
1425  g_free (debit_str);
1426  }
1427  }
1428 
1429  // generate final summary message. Collates a header, the errors
1430  // and warnings. Then allow completion if errors is empty.
1431  m_ready_to_create = !m_logger.has_errors();
1432  return { m_ready_to_create, m_logger.report(), m_list_of_splits };
1433 }
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:609
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:3351
GNCNumericErrorCode gnc_numeric_check(gnc_numeric in)
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 1159 of file assistant-stock-transaction.cpp.

1159 { return m_txn_types; }

◆ logger()

Logger& StockAssistantModel::logger ( )
inline

Accessor.

Returns
the logger.

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

1220 { 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 1247 of file assistant-stock-transaction.cpp.

1248 {
1249  auto old_bal = m_stock_entry->get_balance();
1250  auto new_bal = xaccAccountGetBalanceAsOfDate
1251  (m_acct, gnc_time64_get_day_end (m_transaction_date));
1252  if (m_txn_types_date && m_txn_types_date == m_transaction_date &&
1253  gnc_numeric_equal (old_bal, new_bal))
1254  return false;
1255  m_stock_entry->set_balance(new_bal);
1256  m_txn_types_date = m_transaction_date;
1257  m_txn_types = gnc_numeric_zero_p (new_bal) ? starting_types
1258  : gnc_numeric_positive_p (new_bal) ? long_types
1259  : short_types;
1260  return true;
1261 };
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:3469
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:1316

◆ set_transaction_date()

void StockAssistantModel::set_transaction_date ( time64  date)
inline

Setter.

Parameters
time64for the transaction date.

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

1175 { 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 1180 of file assistant-stock-transaction.cpp.

1180 { 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 1264 of file assistant-stock-transaction.cpp.

1265 {
1266  if (!m_txn_types_date || m_txn_types_date != m_transaction_date)
1267  {
1268  PERR ("transaction_date has changed. rerun maybe_reset_txn_types!");
1269  return false;
1270  }
1271  try
1272  {
1273  m_txn_type = m_txn_types->at (type_idx);
1274  }
1275  catch (const std::out_of_range&)
1276  {
1277  PERR ("out of range type_idx=%d", type_idx);
1278  return false;
1279  }
1280 
1281  m_stock_entry->set_fieldmask(m_txn_type->stock_amount);
1282  m_fees_entry->set_fieldmask(m_txn_type->fees_value);
1283  m_capgains_entry->set_fieldmask(m_txn_type->capgains_value);
1284  m_dividend_entry->set_fieldmask(m_txn_type->dividend_value);
1285  m_cash_entry->set_fieldmask(m_txn_type->cash_value);
1286  return true;
1287 };
#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 1195 of file assistant-stock-transaction.cpp.

1195 { 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 1185 of file assistant-stock-transaction.cpp.

1185 { 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 1170 of file assistant-stock-transaction.cpp.

1170 { return m_txn_type.has_value(); }

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