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  catch( std::exception & e )
151  {
152  std::cout << __FILE__ << ":" << __LINE__ << " " << e.what() << std::endl;
153  }
154  }
155 
156  return retVal;
157 
158 } // endload( const std::string & _guid )-> GCW::Dbo::Accounts::Item::Ptr
159 
160 auto
162 byGuid( const std::string & _guid )-> GCW::Dbo::Accounts::Item::Ptr
163 {
164  return load( _guid );
165 
166 } // endbyGuid( const std::string & _guid )-> GCW::Dbo::Accounts::Item::Ptr
167 
168 auto
170 byChildName( const std::string & _parentGuid, const std::string & _childName )-> GCW::Dbo::Accounts::Item::Ptr
171 {
173 
174  retVal =
175  GCW::app()-> gnucashew_session().find< GCW::Dbo::Accounts::Item >()
176  .where( "parent_guid = ? AND name = ?" )
177  .bind( _parentGuid )
178  .bind( _childName )
179  .resultValue()
180  ;
181 
182  return retVal;
183 
184 } // endbyChildName( const std::string & _parentGuid, const std::string & _childName )-> GCW::Dbo::Accounts::Item::Ptr
185 
186 auto
188 byFullName( const std::string & _fullName )-> GCW::Dbo::Accounts::Item::Ptr
189 {
191 
192  /*
193  ** Here we split the account full-name, so we can dive in
194  ** to the accounts table and lope our way up to this
195  ** account.
196  **
197  */
198  auto split = GCW::Core::split( _fullName, ':' );
199 
200  /*
201  ** Start at the root and lope on up. The return value
202  ** will be filled-in as we go. We should end on the final
203  ** account, which is the one we wanted.
204  **
205  */
206  Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
207  retVal = rootAccount();
208  for( int i=0; i< split.size(); i++ )
209  retVal = byChildName( retVal-> guid(), split.at(i) );
210 
211  return retVal;
212 
213 } // endbyFullName( const std::string & _fullName )-> GCW::Dbo::Accounts::Item::Ptr
214 
215 auto
218 {
220 
221  auto results =
222  GCW::app()-> gnucashew_session().find< GCW::Dbo::Accounts::Item >()
223  .resultList()
224  ;
225 
226  for( auto result : results )
227  retVal.push_back( result );
228 
229  sort( retVal );
230 
231  return retVal;
232 
233 } // endallAccounts()-> GCW::Dbo::Accounts::Item::Vector
234 
235 auto
238 {
240 
241  auto results =
242  GCW::app()-> gnucashew_session().find< GCW::Dbo::Accounts::Item >()
243  .resultList()
244  ;
245 
246  /*
247  ** push back all accounts that are
248  ** _not_ hidden, and
249  ** _not_ placeholder
250  **
251  */
252  for( auto & result : results )
253  if( !result-> hidden()
254  && !result-> placeHolder()
255  )
256  retVal.push_back( result );
257 
258  return retVal;
259 
260 } // endactiveAccounts()-> GCW::Dbo::Accounts::Item::Vector
261 
262 auto
264 vector( const std::string & _parentGuid )-> GCW::Dbo::Accounts::Item::Vector
265 {
267 
268 
269  return retVal;
270 
271 } // endvector( const std::string & _parentGuid )-> GCW::Dbo::Accounts::Item::Vector
272 
273 /*!
274 ** \brief Compute Account Full-Name from Heirarchy
275 **
276 ** This function will calculate the "full account name" from
277 ** the accountGuid up to the root parent.
278 **
279 */
280 auto
282 fullName( const std::string & _accountGuid )-> std::string
283 {
284  /*!
285  ** If the provided account guid is blank, then just return
286  ** an empty string.
287  **
288  */
289  if( _accountGuid == "" )
290  return "";
291 
292  /*
293  ** Fetch the account by Guid
294  **
295  */
296  auto accountItem = byGuid( _accountGuid );
297 
298  /*!
299  ** During the building process, even though the "root account"
300  ** is a valid account, it is ignored and not included in the
301  ** results.
302  **
303  */
304  if( accountItem == rootAccount() )
305  return "";
306 
307  /*
308  ** This is a recursive function that extracts the portions of
309  ** the account names and assembles them in to a contiguous
310  ** string with ':' color separator.
311  **
312  */
313  std::string retVal = fullName( accountItem-> parent_guid() );
314 
315  /*
316  ** If we got anything then we need a separator
317  **
318  */
319  if( retVal != "" )
320  retVal += ":";
321 
322  /*
323  ** And, finally the name of our account.
324  **
325  */
326  retVal += accountItem-> name();
327 
328  /*!
329  ** Recursively, this should generate a name such as;
330  ** "Assets:2023:Cash:FGB:OLB:2300-LSI"
331  **
332  */
333  return retVal;
334 
335 } // endfullName( const std::string & _accountGuid )-> std::string
336 
337 auto
339 fullName( Item::Ptr _item )-> std::string
340 {
341  return fullName( _item-> guid() );
342 
343 } // endfullName( Item::Ptr _item )-> std::string
344 
345 
346 
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:264
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:237
@ 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:217
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:188
auto byGuid(const std::string &_guid) -> Item::Ptr
Load Account by GUID.
Definition: Accounts.cpp:162
auto byChildName(const std::string &_parentGuid, const std::string &_childName) -> Item::Ptr
Load Account by 'child name' and 'parent id'.
Definition: Accounts.cpp:170
auto fullName(const std::string &_guid) -> std::string
Account Fullname via GUID.
Definition: Accounts.cpp:282
App * app()
Definition: App.cpp:67