GnuCashew ~ GnuCash Enabled Web
GCW
Accounts.cpp
Go to the documentation of this file.
1 #line 2 "src/Dbo/Accounts/Accounts.cpp"
2 
3 #include "../Glb/Core.h"
4 #include "../App.h"
5 #include "Accounts.h"
6 
7 const char * GCW::Dbo::Accounts::s_tableName = "accounts";
8 
9 /*!
10 ** \code
11 ** ; type drcr name colAccount colDr colCr parentType
12 ** \endcode
13 **
14 ** These are the account-types, debit/credit types, and register column labels for said accounts.
15 **
16 ** \ref GCW::Eng::AccountRegisterModel::refreshFromDisk() "refreshFromDisk()"
17 **
18 ** \sa \ref account_type_labels Account Type Labels
19 */
20 const std::vector< GCW::Dbo::Accounts::AccountDef_t > GCW::Dbo::Accounts::s_accountDefs =
21 {// type drcr backendName colAccount colDr colCr parentType
22  { GCW::Dbo::Accounts::Type::INVALID , GCW::Dbo::Accounts::DrCr::NONE , "INVALID" , "account" , "fundsin" , "fundsout" , },
23  { GCW::Dbo::Accounts::Type::NONE , GCW::Dbo::Accounts::DrCr::NONE , "NONE" , "account" , "fundsin" , "fundsout" , },
24  { GCW::Dbo::Accounts::Type::BANK , GCW::Dbo::Accounts::DrCr::DEBIT , "BANK" , "transfer" , "deposit" , "withdrawal" , Type::ASSET },
25  { GCW::Dbo::Accounts::Type::CASH , GCW::Dbo::Accounts::DrCr::DEBIT , "CASH" , "transfer" , "receive" , "spend" , Type::ASSET },
26  { GCW::Dbo::Accounts::Type::CREDIT , GCW::Dbo::Accounts::DrCr::CREDIT , "CREDIT" , "blank" , "payment" , "charge" , Type::LIABILITY },
27  { GCW::Dbo::Accounts::Type::ASSET , GCW::Dbo::Accounts::DrCr::DEBIT , "ASSET" , "transfer" , "increase" , "decrease" , Type::ASSET },
28  { GCW::Dbo::Accounts::Type::LIABILITY , GCW::Dbo::Accounts::DrCr::CREDIT , "LIABILITY" , "account" , "decrease" , "increase" , Type::LIABILITY },
29  { GCW::Dbo::Accounts::Type::STOCK , GCW::Dbo::Accounts::DrCr::DEBIT , "STOCK" , "account" , "buy" , "sell" , },
30  { GCW::Dbo::Accounts::Type::MUTUAL , GCW::Dbo::Accounts::DrCr::DEBIT , "MUTUAL" , "account" , "buy" , "sell" , },
31  { GCW::Dbo::Accounts::Type::CURRENCY , GCW::Dbo::Accounts::DrCr::DEBIT , "CURRENCY" , "account" , "buy" , "sell" , Type::ASSET },
32  { GCW::Dbo::Accounts::Type::INCOME , GCW::Dbo::Accounts::DrCr::CREDIT , "INCOME" , "account" , "charge" , "income" , Type::INCOME },
33  { GCW::Dbo::Accounts::Type::EXPENSE , GCW::Dbo::Accounts::DrCr::DEBIT , "EXPENSE" , "transfer" , "expense" , "rebate" , Type::EXPENSE },
34  { GCW::Dbo::Accounts::Type::EQUITY , GCW::Dbo::Accounts::DrCr::CREDIT , "EQUITY" , "transfer" , "decrease" , "increase" , Type::EQUITY },
35  { GCW::Dbo::Accounts::Type::RECEIVABLE , GCW::Dbo::Accounts::DrCr::DEBIT , "RECEIVABLE" , "transfer" , "invoice" , "payment" , },
36  { GCW::Dbo::Accounts::Type::PAYABLE , GCW::Dbo::Accounts::DrCr::CREDIT , "PAYABLE" , "account" , "payment" , "bill" , Type::LIABILITY },
37  { GCW::Dbo::Accounts::Type::ROOT , GCW::Dbo::Accounts::DrCr::NONE , "ROOT" , "account" , "debit" , "credit" , },
38  { GCW::Dbo::Accounts::Type::TRADING , GCW::Dbo::Accounts::DrCr::DEBIT , "TRADING" , "account" , "decrease" , "increase" , },
39  { GCW::Dbo::Accounts::Type::CHECKING , GCW::Dbo::Accounts::DrCr::DEBIT , "CHECKING" , "account" , "debit" , "credit" , Type::ASSET },
40  { GCW::Dbo::Accounts::Type::SAVINGS , GCW::Dbo::Accounts::DrCr::DEBIT , "SAVINGS" , "account" , "debit" , "credit" , Type::ASSET },
41  { GCW::Dbo::Accounts::Type::MONEYMRKT , GCW::Dbo::Accounts::DrCr::DEBIT , "MONEYMRKT" , "account" , "debit" , "credit" , },
42  { GCW::Dbo::Accounts::Type::CREDITLINE , GCW::Dbo::Accounts::DrCr::CREDIT , "CREDITLINE" , "account" , "decrease" , "increase" , Type::LIABILITY },
43 
44 }; // endGCW::Dbo::Accounts::s_accountDefs
45 
46 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::guid = "guid" ; // text(32) PRIMARY KEY NOT NULL
47 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::name = "name" ; // text(2048) NOT NULL
48 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::account_typeName = "account_type" ; // text(2048) NOT NULL
49 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::commodity_guid = "commodity_guid" ; // text(32)
50 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::commodity_scu = "commodity_scu" ; // integer NOT NULL
51 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::non_std_scu = "non_std_scu" ; // integer NOT NULL
52 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::parent_guid = "parent_guid" ; // text(32)
53 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::code = "code" ; // text(2048)
54 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::description = "description" ; // text(2048)
55 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::hidden = "hidden" ; // integer
56 const Wt::WFormModel::Field GCW::Dbo::Accounts::Field::placeHolder = "placeholder" ; // integer
57 
58 namespace {
59 
60 /*!
61 ** \brief Accounts Sorter
62 **
63 **
64 */
65 auto sort( GCW::Dbo::Accounts::Item::Vector & _accountItems )-> void
66 {
67  /*!
68  ** Sort the vector of accounts by fullname so that they can be loaded
69  ** in to the model in proper sequential order.
70  **
71  */
72  std::sort
73  (
74  _accountItems.begin(),
75  _accountItems.end(),
76  []( const GCW::Dbo::Accounts::Item::Ptr item1,
78  )
79  {
80  auto fullName1 = GCW::Dbo::Accounts::fullName( item1-> guid() );
81  auto fullName2 = GCW::Dbo::Accounts::fullName( item2-> guid() );
82 
83  /*
84  ** return .bool. if the .fullName1. is .less than. the .fullName2. date
85  **
86  */
87  return fullName1
88  < fullName2;
89  }
90  );
91 
92 } // endvoid sort( GCW::Dbo::Splits::Item::Vector & _splitItems )
93 
94 auto
96 {
98 
99  Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
100 
101  /*
102  ** Get a handle on the root account. The root account is the only
103  ** account that has no parent, and has a name == "Root Account".
104  ** There should only be one of these.
105  **
106  */
107  auto results =
108  GCW::app()-> gnucashew_session().find< GCW::Dbo::Accounts::Item >()
109  .where( "(parent_guid = '' OR parent_guid IS NULL) AND name = 'Root Account'" )
110  .resultList()
111  ;
112 
113  if( results.size() == 1 )
114  {
115  retVal = *results.begin();
116  }
117 
118  return retVal;
119 
120 } // endrootSql()-> GCW::Dbo::Accounts::Item::Ptr
121 
122 } // endnamespace {
123 
124 auto
127 {
128  return rootSql();
129 // return rootGnc();
130 
131 } // endroot()-> GCW::Dbo::Accounts::Item::Ptr
132 
133 auto
135 load( const std::string & _guid )-> GCW::Dbo::Accounts::Item::Ptr
136 {
138 
139  if( _guid != "" )
140  {
141 
142  Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
143 
144  try
145  {
146  retVal =
147  GCW::app()-> gnucashew_session().load< GCW::Dbo::Accounts::Item >( _guid )
148  ;
149  }
150 
151  /*
152  ** It is possible to provide a guid that doesn't exist. This can happen
153  ** in the bill-pay modules, since the bill-pay is somewhat loosely linked
154  ** to the actual gnucash items, if a gnucash account gets deleted and the
155  ** bill pay doesn't know about it, it can have a bad guid.
156  **
157  ** We don't care, we just return an .empty. item.
158  */
159  catch( std::exception & e )
160  {
161 // std::cout << __FILE__ << ":" << __LINE__ << " " << e.what() << std::endl;
162  }
163 
164  } // endif( _guid != "" )
165 
166  return retVal;
167 
168 } // endload( const std::string & _guid )-> GCW::Dbo::Accounts::Item::Ptr
169 
170 auto
172 byGuid( const std::string & _guid )-> GCW::Dbo::Accounts::Item::Ptr
173 {
174  return load( _guid );
175 
176 } // endbyGuid( const std::string & _guid )-> GCW::Dbo::Accounts::Item::Ptr
177 
178 auto
180 byChildName( const std::string & _parentGuid, const std::string & _childName )-> GCW::Dbo::Accounts::Item::Ptr
181 {
183 
184  retVal =
185  GCW::app()-> gnucashew_session().find< GCW::Dbo::Accounts::Item >()
186  .where( "parent_guid = ? AND name = ?" )
187  .bind( _parentGuid )
188  .bind( _childName )
189  .resultValue()
190  ;
191 
192  return retVal;
193 
194 } // endbyChildName( const std::string & _parentGuid, const std::string & _childName )-> GCW::Dbo::Accounts::Item::Ptr
195 
196 auto
198 byFullName( const std::string & _fullName )-> GCW::Dbo::Accounts::Item::Ptr
199 {
201 
202  /*
203  ** Here we split the account full-name, so we can dive in
204  ** to the accounts table and lope our way up to this
205  ** account.
206  **
207  */
208  auto split = GCW::Core::split( _fullName, ':' );
209 
210  /*
211  ** Start at the root and lope on up. The return value
212  ** will be filled-in as we go. We should end on the final
213  ** account, which is the one we wanted.
214  **
215  */
216  Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
217  retVal = rootAccount();
218  for( int i=0; i< split.size(); i++ )
219  retVal = byChildName( retVal-> guid(), split.at(i) );
220 
221  return retVal;
222 
223 } // endbyFullName( const std::string & _fullName )-> GCW::Dbo::Accounts::Item::Ptr
224 
225 auto
228 {
230 
231  auto results =
232  GCW::app()-> gnucashew_session().find< GCW::Dbo::Accounts::Item >()
233  .resultList()
234  ;
235 
236  for( auto result : results )
237  retVal.push_back( result );
238 
239  sort( retVal );
240 
241  return retVal;
242 
243 } // endallAccounts()-> GCW::Dbo::Accounts::Item::Vector
244 
245 auto
248 {
250 
251  auto results =
252  GCW::app()-> gnucashew_session().find< GCW::Dbo::Accounts::Item >()
253  .resultList()
254  ;
255 
256  /*
257  ** push back all accounts that are
258  ** _not_ hidden, and
259  ** _not_ placeholder
260  **
261  */
262  for( auto & result : results )
263  if( !result-> hidden()
264  && !result-> placeHolder()
265  )
266  retVal.push_back( result );
267 
268  return retVal;
269 
270 } // endactiveAccounts()-> GCW::Dbo::Accounts::Item::Vector
271 
272 auto
274 vector( const std::string & _parentGuid )-> GCW::Dbo::Accounts::Item::Vector
275 {
277 
278 
279  return retVal;
280 
281 } // endvector( const std::string & _parentGuid )-> GCW::Dbo::Accounts::Item::Vector
282 
283 /*!
284 ** \brief Compute Account Full-Name from Heirarchy
285 **
286 ** This function will calculate the "full account name" from
287 ** the accountGuid up to the root parent.
288 **
289 */
290 auto
292 fullName( const std::string & _accountGuid )-> std::string
293 {
294  /*!
295  ** If the provided account guid is blank, then just return
296  ** an empty string.
297  **
298  */
299  if( _accountGuid == "" )
300  return "";
301 
302  std::string retVal;
303 
304  /*
305  ** Fetch the account by Guid
306  **
307  */
308  auto accountItem = byGuid( _accountGuid );
309 
310  if( accountItem )
311  {
312  /*!
313  ** During the building process, even though the "root account"
314  ** is a valid account, it is ignored and not included in the
315  ** results.
316  **
317  */
318  if( accountItem == rootAccount() )
319  return "";
320 
321  /*
322  ** This is a recursive function that extracts the portions of
323  ** the account names and assembles them in to a contiguous
324  ** string with ':' color separator.
325  **
326  */
327  retVal = fullName( accountItem-> parent_guid() );
328 
329  /*
330  ** If we got anything then we need a separator
331  **
332  */
333  if( retVal != "" )
334  retVal += ":";
335 
336  /*
337  ** And, finally the name of our account.
338  **
339  */
340  retVal += accountItem-> name();
341 
342  } // endif( accountItem )
343 
344  /*!
345  ** Recursively, this should generate a name such as;
346  ** "Assets:2023:Cash:FGB:OLB:2300-LSI"
347  **
348  */
349  return retVal;
350 
351 } // endfullName( const std::string & _accountGuid )-> std::string
352 
353 auto
355 fullName( Item::Ptr _item )-> std::string
356 {
357  return fullName( _item-> guid() );
358 
359 } // endfullName( Item::Ptr _item )-> std::string
360 
361 
362 
static std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
Definition: Core.cpp:16
Account Item Class.
Definition: Item.h:89
std::vector< Ptr > Vector
Definition: BaseItem.h:41
Wt::Dbo::ptr< Item > Ptr
Definition: BaseItem.h:39
std::vector< std::string > split(const std::string &value, char delim)
Definition: Core.cpp:30
auto vector(const std::string &_parentGuid) -> Item::Vector
Child Accounts via parent.
Definition: Accounts.cpp:274
const Wt::WFormModel::Field name
Definition: Accounts.cpp:47
const Wt::WFormModel::Field guid
Definition: Accounts.cpp:46
const Wt::WFormModel::Field description
Definition: Accounts.cpp:54
const Wt::WFormModel::Field commodity_scu
Definition: Accounts.cpp:50
const Wt::WFormModel::Field account_typeName
Definition: Accounts.cpp:48
const Wt::WFormModel::Field code
Definition: Accounts.cpp:53
const Wt::WFormModel::Field non_std_scu
Definition: Accounts.cpp:51
const Wt::WFormModel::Field commodity_guid
Definition: Accounts.cpp:49
const Wt::WFormModel::Field placeHolder
Definition: Accounts.cpp:56
const Wt::WFormModel::Field hidden
Definition: Accounts.cpp:55
const Wt::WFormModel::Field parent_guid
Definition: Accounts.cpp:52
auto rootAccount() -> Item::Ptr
Load Root Account.
Definition: Accounts.cpp:126
@ CREDITLINE
18 ~ do not use
@ CURRENCY
07 ~ currency trading account (DEPRECATED)
@ EXPENSE
09 ~ expense tracking account
@ CHECKING
15 ~ do not use
@ ASSET
02 ~ generic generalized asset account
@ INCOME
08 ~ income tracking account
@ BANK
00 ~ bank institutionally held monies, can be interest bearing
@ MUTUAL
06 ~ similar to stock, shows: price, # shares, value
@ LIABILITY
04 ~ generic generalized liability account
@ SAVINGS
16 ~ do not use
@ NONE
-1 ~ not a type
@ EQUITY
10 ~ used to balance the balance sheet
@ INVALID
-1 ~ not a type
@ TRADING
14 ~ used to record multiple commodify transactions
@ CASH
01 ~ pure cash (shoebox)
@ CREDIT
03 ~ AMEX / VISA / DISCOVER type of credit cards
@ MONEYMRKT
17 ~ do not use
@ ROOT
13 ~ hidden root account for the account tree
@ PAYABLE
12 ~ A/R payable account
@ RECEIVABLE
11 ~ A/R receivable account
@ STOCK
05 ~ stock account show as three-column registers: price, # shares, value
auto load(const std::string &_guid) -> Item::Ptr
Load Account by GUID.
Definition: Accounts.cpp:135
auto activeAccounts() -> Item::Vector
Load accounts as; if( !hidden() && !placeHolder() )
Definition: Accounts.cpp:247
@ DEBIT
0x01 ~ DEBIT type account
@ NONE
0x00 ~ invalid - should not happen
@ CREDIT
0x02 ~ CREDIT type account
const std::vector< AccountDef_t > s_accountDefs
Definition: Accounts.cpp:20
auto allAccounts() -> Item::Vector
Load all accounts.
Definition: Accounts.cpp:227
const char * s_tableName
Definition: Accounts.cpp:7
auto byFullName(const std::string &_fullName) -> Item::Ptr
Load Account by 'full name' with ':' account separator.
Definition: Accounts.cpp:198
auto byGuid(const std::string &_guid) -> Item::Ptr
Load Account by GUID.
Definition: Accounts.cpp:172
auto byChildName(const std::string &_parentGuid, const std::string &_childName) -> Item::Ptr
Load Account by 'child name' and 'parent id'.
Definition: Accounts.cpp:180
auto fullName(const std::string &_guid) -> std::string
Account Fullname via GUID.
Definition: Accounts.cpp:292
App * app()
Definition: App.cpp:67