GnuCashew ~ Web Application compatible with GnuCash sql data files.
GCW
Loading...
Searching...
No Matches
Splits.cpp
Go to the documentation of this file.
1#line 2 "src/Dbo/Splits.cpp"
2
3#include "../App.h"
4
5#include "Splits.h"
6#include "../Transactions/Transactions.h"
7
8const char * GCW::Dbo::Splits::s_tableName = "splits";
9
10namespace {
11
12/*!
13** \brief Splits Sorter
14**
15** This is a little (private) vector sorter used to sort the items pulled from the
16** database. The database can produce items in random order, and the 'date' is
17** contained on the 'transaction' so sorting by date requires a lookup in to the
18** transaction.
19**
20** The sorted_vector_of_splits is used in the Account Register editor, whereby the
21** items need to be in correct chronological order so as to be able to calculate
22** a running balance.
23*/
24void sort( GCW::Dbo::Splits::Item::Vector & _splitItems )
25{
26 /*!
27 ** Sort the vector of splits by 'transaction date' + 'value' so that they can be loaded
28 ** in to the model in proper sequential order.
29 */
30 std::sort
31 (
32 _splitItems.begin(),
33 _splitItems.end(),
34 []
35 ( const GCW::Dbo::Splits::Item::Ptr splitItem1,
36 const GCW::Dbo::Splits::Item::Ptr splitItem2
37 )
38 {
39 /*
40 ** get the transactions
41 */
42 auto trans1 = GCW::Dbo::Transactions::byGuid( splitItem1-> tx_guid() );
43 auto trans2 = GCW::Dbo::Transactions::byGuid( splitItem2-> tx_guid() );
44
45 /*
46 ** if we got transactions, analyze them!
47 */
48 if( trans1
49 && trans2
50 )
51 {
52 /*
53 ** return .bool. if the .trans1. date is .less than. the .trans2. date
54 **
55 ** Also, return .bool. if the trans1-split-value is greater than the
56 ** trans2-split-value, if the dates are the same. This way, debits
57 ** (positive values) are shown first in the register, and credits
58 ** follow, in value-descending order. This resolves one issue that
59 ** has always driven me mental which is the register showing negative
60 ** balance values because the withdrawals are computed prior to the
61 ** deposits... for that same day. This totally fixes that and lists
62 ** the deposits first, followed by the withdrawals. neat!
63 **
64 ** note: it is possible to string-compare these date values, as they are
65 ** represented as ISO dates (YYYY-mm-DD HH:MM:ss) which is
66 ** sortable. Alternatively, we can convert this string to an
67 ** internal WDate element, but that would be an unnecessary step.
68 **
69 ** return trans1-> post_date_as_date()
70 ** < trans2-> post_date_as_date();
71 */
72 if( trans1-> post_date()
73 == trans2-> post_date()
74 )
75 /*
76 ** dates are the same, so compare the values
77 */
78 return splitItem1-> value()
79 > splitItem2-> value()
80 ;
81
82 /*
83 ** the dates are different so just compare them
84 */
85 else
86 return trans1-> post_date()
87 < trans2-> post_date()
88 ;
89 }
90
91 return false;
92
93 } // endlambda( ..compare.. )
94
95 ); // endstd::sort
96
97} // endvoid sort( GCW::Dbo::Splits::Item::Vector & _splitItems )
98
99} // endnamespace {
100
101auto
103load( const std::string & _splitGuid )-> GCW::Dbo::Splits::Item::Ptr
104{
106
107 if( _splitGuid != "" )
108 {
109 Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
110
111 retVal =
112 GCW::app()-> gnucashew_session().load< GCW::Dbo::Splits::Item >( _splitGuid )
113 ;
114 }
115
116 return retVal;
117
118} // endload( const std::string & _splitGuid )
119
120auto
122find( const std::string & _splitGuid )-> GCW::Dbo::Splits::Item::Ptr
123{
125
126 if( _splitGuid != "" )
127 {
128 Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
129
130 /*
131 ** grab the raw data items out of the storage
132 */
133 auto results =
134 GCW::app()-> gnucashew_session().find< Item >()
135 .where( "guid = ?" )
136 .bind( _splitGuid )
137 .resultList()
138 ;
139
140 /*
141 ** We should find only one item
142 */
143 if( results.size() == 1 )
144 retVal = *results.begin();
145
146 } // endif( _splitGuid != "" )
147
148 return retVal;
149
150} // endfind( const std::string & _splitGuid )-> GCW::Dbo::Splits::Item::Ptr
151
152auto
154add( const std::string & _splitGuid )-> Item::Ptr
155{
156 Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
157
158 return
159 GCW::app()-> gnucashew_session().addNew< Item >( _splitGuid );
160
161} // endadd( const std::string & _splitGuid )-> Item::Ptr
162
163auto
165byAccount( const std::string & _accountGuid )-> GCW::Dbo::Splits::Item::Vector
166{
168
169 if( _accountGuid != "" )
170 {
171 Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
172
173 /*
174 ** grab the raw data items out of the storage
175 */
176 auto results =
177 GCW::app()-> gnucashew_session().find< GCW::Dbo::Splits::Item >()
178 .where( "account_guid = ?" )
179 .bind( _accountGuid )
180 .resultList()
181 ;
182
183 /*
184 ** vector everything
185 */
186 for( auto result : results )
187 retVal.push_back( result );
188
189 /*
190 ** sort the vector
191 */
192 sort( retVal );
193
194 } // endif( _accountGuid != "" )
195
196 return retVal;
197
198} // endbyAccount( const std::string & _accountGuid )-> GCW::Dbo::Splits::Item::Vector
199
200auto
202bySplitExcept( const std::string & _splitGuid )-> GCW::Dbo::Splits::Item::Vector
203{
205
206 auto splitItem = GCW::Dbo::Splits::load( _splitGuid );
207
208 /*
209 ** If we don't have a splitItem then we can't do nuthin.
210 */
211 if( splitItem )
212 {
213 Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
214
215 auto results =
216 GCW::app()-> gnucashew_session().find< GCW::Dbo::Splits::Item >()
217 .where( "tx_guid = ?" )
218 .bind( splitItem-> tx_guid() )
219 .resultList()
220 ;
221
222 /*
223 ** Load the vector, but skip the one that
224 ** matches our incoming split guid.
225 */
226 for( auto result : results )
227 if( result-> guid() != _splitGuid )
228 retVal.push_back( result );
229
230 /*
231 ** The vector is sorted by transction-date before
232 ** returning to the caller.
233 */
234 sort( retVal );
235
236 } // endif( GCW::app()-> gnucashew_session().isOpen() )
237
238 return retVal;
239
240} // endbySplit( const std::string & _splitGuid )-> GCW::Dbo::Splits::Item::Vector
241
242auto
244byTransaction( const std::string & _txGuid )-> GCW::Dbo::Splits::Item::Vector
245{
247
248 Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
249
250 auto results =
251 GCW::app()-> gnucashew_session().find< GCW::Dbo::Splits::Item >()
252 .where( "tx_guid = ?" )
253 .bind( _txGuid )
254 .resultList()
255 ;
256
257 for( auto result : results )
258 retVal.push_back( result );
259
260 /*
261 ** The vector is sorted by transction-date before
262 ** returning to the caller.
263 */
264 sort( retVal );
265
266 return retVal;
267
268} // endbyTransaction( const std::string & _txGuid )-> GCW::Dbo::Splits::Item::Vector
269
270auto
272set_value( GCW_NUMERIC _value )-> void
273{
274 m_value_num = (_value * 100).getAsInteger();
275 m_value_denom = 100;
276
277} // endset_value( GCW_NUMERIC _value )-> void
278
279auto
281set_quantity( GCW_NUMERIC _value )-> void
282{
283 m_quantity_num = (_value * 100).getAsInteger();
284 m_quantity_denom = 100;
285
286} // endset_quantity( GCW_NUMERIC _value )-> void
287
std::vector< Ptr > Vector
Definition BaseItem.h:41
Split Item Class.
Definition Splits.h:88
auto set_quantity(GCW_NUMERIC _value) -> void
Definition Splits.cpp:281
auto set_value(GCW_NUMERIC _value) -> void
Definition Splits.cpp:272
#define GCW_NUMERIC
Internal Numeric Type.
Definition gcwglobal.h:38
auto byTransaction(const std::string &_txGuid) -> Item::Vector
Load Splits by Transaction.
Definition Splits.cpp:244
auto byAccount(const std::string &_accountGuid) -> Item::Vector
Load Splits by Account.
Definition Splits.cpp:165
const char * s_tableName
Definition Splits.cpp:8
auto add(const std::string &_splitGuid) -> Item::Ptr
Add a single split.
Definition Splits.cpp:154
auto bySplitExcept(const std::string &_splitGuid) -> Item::Vector
Load Splits by Split.
Definition Splits.cpp:202
auto load(const std::string &_splitGuid) -> Item::Ptr
Load a single split.
Definition Splits.cpp:103
auto find(const std::string &_splitGuid) -> Item::Ptr
Find a single split.
Definition Splits.cpp:122
App * app()
Definition App.cpp:75