GnuCashew ~ GnuCash Enabled Web
GCW
Model.cpp
Go to the documentation of this file.
1 #line 2 "src/Gui/BillPay/Model.cpp"
2 
3 #include <Wt/WStandardItem.h>
4 
5 #include "../../App.h"
6 #include "../Dbo/Vars/Vars.h"
7 #include "BillPay.h"
8 
9 namespace {
10 
12 {
13 // name, width, alignment, toolTip
14  { "accountKey" , "120px", Wt::AlignmentFlag::Left, "Primary Account Identifier" },
15  { "last4" , "60px", Wt::AlignmentFlag::Center, "Last 4 digits of account number" },
16  { "Nickname" , "100px", Wt::AlignmentFlag::Left, "Friendly Nickname for the account" },
17  { "Gp" , "50px", Wt::AlignmentFlag::Center, "Grouping" },
18  { "Dy" , "50px", Wt::AlignmentFlag::Center, "Day that the payment is due" },
19  { "Min" , "50px", Wt::AlignmentFlag::Right, "Minimum Payment Due" },
20  { "Bgt" , "50px", Wt::AlignmentFlag::Right, "Payment Budget" },
21  { "Actual" , "75px", Wt::AlignmentFlag::Right, "Actual payment most recently made" },
22  { "Au" , "50px", Wt::AlignmentFlag::Center, "Automatic Payment Indicator" },
23  { "01" , "35px", Wt::AlignmentFlag::Center, "January" },
24  { "02" , "35px", Wt::AlignmentFlag::Center, "February" },
25  { "03" , "35px", Wt::AlignmentFlag::Center, "March" },
26  { "04" , "35px", Wt::AlignmentFlag::Center, "April" },
27  { "05" , "35px", Wt::AlignmentFlag::Center, "May" },
28  { "06" , "35px", Wt::AlignmentFlag::Center, "June" },
29  { "07" , "35px", Wt::AlignmentFlag::Center, "July" },
30  { "08" , "35px", Wt::AlignmentFlag::Center, "August" },
31  { "09" , "35px", Wt::AlignmentFlag::Center, "September" },
32  { "10" , "35px", Wt::AlignmentFlag::Center, "October" },
33  { "11" , "35px", Wt::AlignmentFlag::Center, "November" },
34  { "12" , "35px", Wt::AlignmentFlag::Center, "December" },
35 };
36 
37 #define COLUMN_COUNT (sizeof(columns)/sizeof(GCW::Gui::BillPay::ColumnDef_t))
38 
39 } // endnamespace {
40 
42 Model( int _selectedMonth, const Status _status )
43 : Wt::WStandardItemModel( 0, COLUMN_COUNT ),
44  m_status( _status )
45 {
46 
47  /*
48  ** Load the header _only_ on the 'unpaid' view.
49  **
50  ** The unpaid view is represented first in the widget so that
51  ** bills that are unpaid appear at the top of the browser
52  ** window. The unpaid view, therefore, is the only view
53  ** that includes the header. If the other two remaining
54  ** views (Paid, Disabled) also had a header the gui would
55  ** get too cluttered, so those headers are left blank.
56  */
58  {
59  for( int col = 1; col< COLUMN_COUNT; col++ )
60  {
61  setHeaderData( col, Wt::Orientation::Horizontal, columns[ col ].name , Wt::ItemDataRole::Display );
62  setHeaderData( col, Wt::Orientation::Horizontal, columns[ col ].toolTip , Wt::ItemDataRole::ToolTip );
63  }
64  }
65 
66  /*
67  ** Load the data based on the month selected.
68  */
69  loadData( _selectedMonth );
70 
71 } // endModel( const Status _status )
72 
73 auto
75 loadData( int _selectedMonth )-> void
76 {
77  /*!
78  ** On load, the first column-label is set to indicate the
79  ** model type as well as the month selected.
80  **
81  ** \code
82  ** Change the label on the column-0, example;
83  ** "03 Unpaid"
84  ** "06 Paid"
85  ** "12 Disabled"
86  ** \endcode
87  **
88  */
89  setHeaderData
90  (
91  0,
92  Wt::Orientation::Horizontal,
93  toString( _selectedMonth ) + " " + asString( m_status ),
94  Wt::ItemDataRole::Display
95  );
96 
97  /*!
98  ** On load, all existing data in the model is first dumped.
99  */
100  while( rowCount() > 0 )
101  takeRow( 0 );
102 
103  /*!
104  ** Get all the var items that are for the 'managed bill pay item' (mbpi)
105  ** in to a resultList that will then be used to load the
106  ** resulting model.
107  */
108  Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
109  auto items =
110  GCW::app()-> gnucashew_session().find< GCW::Dbo::Vars::Item >()
111  .where( "\"cfyField\" = '" GCW_GUI_BILLPAY_ITEM_CFY "'" )
112  .resultList()
113  ;
114 
115  /*
116  ** Calculate our yes/no status for grabbing items.
117  */
118  std::string yesNo = "yes";
119  if( m_status == GCW::Gui::BillPay::Status::Unpaid )
120  yesNo = "no";
121 
122  /*!
123  ** Run the resultList collection through an analyzer that will
124  ** extract billpay items that match the selection criteria of
125  ** paid/unpaid/disabled/yes/no accordingly.
126  */
127  std::vector< GCW::Gui::BillPay::Item > bpItems;
128  for( auto item : items )
129  {
130  auto bpItem = GCW::Gui::BillPay::Item( item );
131 
132  /*
133  ** Calculate these boolean.
134  */
135  auto isActive = bpItem.isActive () == "yes";
136  auto isVisible = bpItem.isVisible() == "yes";
137 
138  /*
139  ** This is for Paid and Unpaid (not Disabled).
140  */
141  if( m_status == GCW::Gui::BillPay::Status::Paid
142  || m_status == GCW::Gui::BillPay::Status::Unpaid
143  )
144  {
145  /*
146  ** The item ~must~ be active ~and~ visible.
147  */
148  if( isActive && isVisible )
149  {
150  /*
151  ** Get the .var. string that has the combo-box values for the monthly
152  ** indicators of what has been paid and what has not. Depending on the
153  ** value of that payment status, it must therefore match the yes/no clause
154  ** we calculated above. If it's a match, we grab it.
155  */
156  if( bpItem.cb( _selectedMonth ) == yesNo )
157 // if( i-> getVarString( "cb" + GCW::Gui::BillPay::toString( _selectedMonth ) ) == yesNo )
158  bpItems.push_back( bpItem );
159 
160  } // endif( isActive && isVisible )
161 
162  } // endif( ..is active.. )
163 
164  /*
165  ** This is for Disabled.
166  */
167  else
168  if( m_status == GCW::Gui::BillPay::Status::Disabled ) // capture disabled items here
169  {
170  /*
171  ** Disabled items are either notActive ~or~ notVisible.
172  */
173  if( !isActive || !isVisible )
174  bpItems.push_back( bpItem );
175 
176  } // endelseif( .disabled. )
177 
178  } // endfor( auto i : items )
179 
180  /*!
181  ** Sort all the items by the account group.dueDay. (The
182  ** user is not allowed to sort these views so we do it) This sorts the items
183  ** with the items that are due first, above those that are due next.
184  */
185  sort( bpItems );
186 
187  /*!
188  ** Each item is processed out of the sorted vector and placed
189  ** in to the item model.
190  */
191  for( auto bpItem : bpItems )
192  {
193  /*
194  ** Grab a few handles.
195  */
196  auto accountName = std::make_unique< Wt::WStandardItem >();
197  auto accountGuid = bpItem.accountGuid();
198 
199  if( accountGuid != "" )
200  {
201  auto accountItem = GCW::Dbo::Accounts::byGuid( accountGuid );
202 
203  /*
204  ** set the bpItem.guid so we can edit this row
205  */
206  accountName-> setData( bpItem.guid(), Wt::ItemDataRole::User );
207 
208  /*
209  ** sometimes the 'account' can get lost, so check first the
210  ** account still exists.
211  */
212  if( accountItem )
213  {
214  /*
215  ** build the account column to;
216  ** display the account name
217  ** carry the account-full-name as a toolTip,
218  ** carry the guid of the originating bpItem
219  */
220  accountName-> setData( accountItem-> name() , Wt::ItemDataRole::Display );
221  accountName-> setToolTip( GCW::Dbo::Accounts::fullName( accountGuid ) );
222  }
223 
224  } // endif( accountGuid != "" )
225 
226  /*
227  ** The columns are pushed in to .columns. variable.
228  */
229  std::vector< std::unique_ptr< Wt::WStandardItem > > columns;
230  columns.push_back( std::move( accountName ) );
231  columns.push_back( std::make_unique< Wt::WStandardItem >( bpItem.last4 () ) );
232  columns.push_back( std::make_unique< Wt::WStandardItem >( bpItem.nickname () ) );
233  columns.push_back( std::make_unique< Wt::WStandardItem >( bpItem.group () ) );
234  columns.push_back( std::make_unique< Wt::WStandardItem >( bpItem.dueDay () ) );
235  columns.push_back( std::make_unique< Wt::WStandardItem >( bpItem.minimum () ) );
236  columns.push_back( std::make_unique< Wt::WStandardItem >( bpItem.budget () ) );
237  columns.push_back( std::make_unique< Wt::WStandardItem >( bpItem.actual () ) );
238  columns.push_back( std::make_unique< Wt::WStandardItem >( bpItem.autoPay () ) );
239 
240  /*
241  ** Load 12-columns, one for each month.
242  */
243  for( int month=1; month<= 12; month++ )
244  {
245  auto cb = std::make_unique< Wt::WStandardItem >( bpItem.cb( month ) );
246 
247  /*!
248  ** While building the 'month columns', apply a style class to the
249  ** column of items according to the month selected. This causes
250  ** the current selected column to be highlighted within the table
251  ** view in the browser.
252  **
253  ** \image html BillPayColumnSelector.png
254  */
255  if( _selectedMonth == month )
256  cb-> setStyleClass( "colsel" );
257 
258  columns.push_back( std::move( cb ) );
259 
260  } // endfor( int i=1; i<= 12; i++ )
261 
262  /*
263  ** Push everything in to the model.
264  */
265  appendRow( std::move( columns ) );
266 
267  } // endfor( auto bpItem : bpItems )
268 
269 } // endloadData( int _selectedMonth )-> void
270 
271 auto
274 {
275  return columns[col];
276 }
277 
278 auto
280 sort( std::vector< GCW::Gui::BillPay::Item > & _bpItems )-> void
281 {
282  /*!
283  ** Sort the vector of bpItems by group.dueDay
284  */
285  std::sort
286  (
287  _bpItems.begin(),
288  _bpItems.end(),
289  []( const GCW::Gui::BillPay::Item item1,
290  const GCW::Gui::BillPay::Item item2
291  )
292  {
293 // auto account1 = GCW::Dbo::Accounts::byGuid( item1-> keyField() );
294 // auto account2 = GCW::Dbo::Accounts::byGuid( item2-> keyField() );
295 // auto name1 = account1-> name();
296 // auto name2 = account2-> name();
297 
298 // auto name1 = item1.nickname();
299 // auto name2 = item2.nickname();
300 
301  /*
302  ** return .bool. of the comparison
303  */
304  return item1.sortValue()
305  < item2.sortValue()
306  ;
307  }
308  );
309 
310 } // endsort( std::vector< GCW::Gui::BillPay::Item > & _bpItems )-> void
311 
312 
#define GCW_GUI_BILLPAY_ITEM_CFY
Definition: BillPay.h:40
#define COLUMN_COUNT
Definition: Model.cpp:37
Variables Item Class.
Definition: Vars.h:36
Status m_status
Model Status.
Definition: Model.h:123
auto sort(std::vector< GCW::Gui::BillPay::Item > &_bpItems) -> void
Sorter.
Definition: Model.cpp:280
auto loadData(int _selectedMonth) -> void
Reload the data based on the selected month.
Definition: Model.cpp:75
Model(int _selectedMonth, Status _status)
ctor
Definition: Model.cpp:42
auto columnDef(int _col) -> ColumnDef_t
Column Definition.
Definition: Model.cpp:273
const Wt::WFormModel::Field name
Definition: Accounts.cpp:47
auto byGuid(const std::string &_guid) -> Item::Ptr
Load Account by GUID.
Definition: Accounts.cpp:172
auto fullName(const std::string &_guid) -> std::string
Account Fullname via GUID.
Definition: Accounts.cpp:292
auto bpItem(const std::string &_guid) -> GCW::Gui::BillPay::Item
Bill Pay Item.
Definition: BillPay.cpp:19
std::string asString(Status _status)
Get Status as String.
Definition: Status.cpp:7
Status
Bill Status.
Definition: Status.h:21
@ Disabled
Disabled Status.
@ Unpaid
Unpaid Status.
auto toString(int _value) -> std::string
Convert Integer to String.
Definition: BillPay.cpp:41
App * app()
Definition: App.cpp:67
Definition: GncLock.h:6