GnuCashew ~ Web Application compatible with GnuCash sql data files.
GCW
Loading...
Searching...
No Matches
EditWidget.cpp
Go to the documentation of this file.
1#line 2 "src/Gui/BillPay/EditWidget.cpp"
2
3#include <Wt/WMenuItem.h>
4#include <Wt/WVBoxLayout.h>
5#include <Wt/WMessageBox.h>
6
7#include "../../Eng/AccountComboModel.h"
8#include "../../Glb/Core.h"
9#include "BillPay.h"
10
12EditWidget( const std::string & _bpGuid )
13: Wt::WContainerWidget(),
14 m_bpGuid( _bpGuid )
15{
16 addStyleClass( "EditWidget" );
17
18 /*
19 ** use a layout.
20 */
21 auto lw = setLayout( std::make_unique< Wt::WVBoxLayout >() );
22
23 /*
24 ** This is a complex widget, with a header area with a
25 ** handful of fields, then a tab widget with a couple
26 ** pages.
27 */
28 auto templtMain =
29 lw->
31 (
32 std::make_unique< Wt::WTemplate >( TR("gcw_gui.billpay.editwidget.form.main") )
33 );
34
35 /*
36 ** add all the widgets
37 */
38 m_pbSave = templtMain-> bindNew< Wt::WPushButton >( "save" , TR( "gcw.billPay.lbl.save" ) );
39 m_pbCancel = templtMain-> bindNew< Wt::WPushButton >( "cancel" , TR( "gcw.billPay.lbl.cancel" ) );
40 m_pbDelete = templtMain-> bindNew< Wt::WPushButton >( "delete" , TR( "gcw.billPay.lbl.delete" ) );
41 m_pbProcess = templtMain-> bindNew< Wt::WPushButton >( "process" , TR( "gcw.billPay.lbl.process" ) );
50 m_ap = templtMain-> bindNew< Wt::WCheckBox >( "ap" , TR( "gcw.billPay.lbl.ap" ) );
51 m_isActive = templtMain-> bindNew< Wt::WCheckBox >( "isActive" , TR( "gcw.billPay.lbl.isActive" ) );
52 m_isVisible = templtMain-> bindNew< Wt::WCheckBox >( "isVisible" , TR( "gcw.billPay.lbl.isVisible" ) );
53 m_autoPay = templtMain-> bindNew< Wt::WCheckBox >( "autoPay" , TR( "gcw.billPay.lbl.autoPay" ) );
54 m_payNow = templtMain-> bindNew< Wt::WCheckBox >( "payNow" , TR( "gcw.billPay.lbl.payNow" ) );
55
56 m_pbSave -> setStyleClass( "btn-xs" );
57 m_pbCancel -> setStyleClass( "btn-xs" );
58 m_pbDelete -> setStyleClass( "btn-xs" );
59 m_pbProcess -> setStyleClass( "btn-xs" );
60
61 m_account -> setToolTip( TR( "gcw.billPay.ttp.account" ) );
62 m_dueDay -> setToolTip( TR( "gcw.billPay.ttp.dueDay" ) );
63 m_minimum -> setToolTip( TR( "gcw.billPay.ttp.minimum" ) );
64 m_budget -> setToolTip( TR( "gcw.billPay.ttp.budget" ) );
65 m_nickname -> setToolTip( TR( "gcw.billPay.ttp.nickname" ) );
66 m_group -> setToolTip( TR( "gcw.billPay.ttp.group" ) );
67 m_limit -> setToolTip( TR( "gcw.billPay.ttp.limit" ) );
68 m_actual -> setToolTip( TR( "gcw.billPay.ttp.actual" ) );
69 m_ap -> setToolTip( TR( "gcw.billPay.ttp.ap" ) );
70 m_isActive -> setToolTip( TR( "gcw.billPay.ttp.isActive" ) );
71 m_isVisible -> setToolTip( TR( "gcw.billPay.ttp.isVisible" ) );
72 m_autoPay -> setToolTip( TR( "gcw.billPay.ttp.autoPay" ) );
73 m_payNow -> setToolTip( TR( "gcw.billPay.ttp.payNow" ) );
74
75 m_dueDay -> setRange( 1, 31 );
76 m_group -> setRange( 0, 30 );
77 m_group -> setSingleStep( 5 );
78
79 templtMain-> bindString( "accountLabel" , TR( "gcw.billPay.lbl.account" ) );
80 templtMain-> bindString( "dueDayLabel" , TR( "gcw.billPay.lbl.dueDay" ) );
81 templtMain-> bindString( "minimumLabel" , TR( "gcw.billPay.lbl.minimum" ) );
82 templtMain-> bindString( "budgetLabel" , TR( "gcw.billPay.lbl.budget" ) );
83 templtMain-> bindString( "nicknameLabel" , TR( "gcw.billPay.lbl.nickname" ) );
84 templtMain-> bindString( "groupLabel" , TR( "gcw.billPay.lbl.group" ) );
85 templtMain-> bindString( "limitLabel" , TR( "gcw.billPay.lbl.limit" ) );
86 templtMain-> bindString( "actualLabel" , TR( "gcw.billPay.lbl.actual" ) );
87
88 /*
89 ** this is the tab widget. It takes up the remaining bottom space
90 ** on the form.
91 */
92 m_tabWidget = lw-> addWidget( std::make_unique< Wt::WTabWidget >(), 1 );
93
94 /*
95 ** This is the payment template. It will get added to
96 ** the first page of the tab widget.
97 */
99 {
100 auto u_ = std::make_unique< Wt::WTemplate >( TR( "gcw_gui.billpayeditor.form.tab1" ) );
101 templtPayment = u_.get();
102 m_tabWidget-> addTab( std::move( u_ ), TR("gcw.billPay.tabName.payment") );
103
104 for( int cb = 0; cb < 12; cb++ )
105 {
106 auto cbx = std::make_unique< Wt::WCheckBox >( toString( cb+1 ) );
107 cbx-> setTristate( true );
108 cbx-> setPartialStateSelectable( true );
109
110 m_cbx.push_back( cbx.get() );
111
112 templtPayment-> bindWidget( "cb" + toString( cb+1 ), std::move( cbx ) );
113 }
114
115 /*
116 ** URL field
117 */
119 m_url-> doubleClicked().connect( this, &EditWidget::url_open );
120
121 /*
122 ** URL-> go button
123 */
124 templtPayment-> bindNew< Wt::WPushButton >( "urlgo", TR("gcw.billPay.lbl.go") )->
125 clicked().connect( this, &EditWidget::url_open );
126
129// m_note = templtPayment-> bindNew< Wt::WTextEdit >( "note" );
130 m_label = templtPayment-> bindNew< Wt::WLabel >( "image", "image" );
131 m_label-> setMinimumSize( "160px", "160px" );
132 m_label-> resize( "160px", "160px" );
133
134 m_note-> setRows( 10 );
135// m_note-> resize( Wt::WLength::Auto, Wt::WLength( 200 ) );
136
137 auto pbClear = templtPayment-> bindNew< Wt::WPushButton >( "clear", TR("gcw.billPay.lbl.clear") );
138 pbClear-> setStyleClass( "btn-xs" );
139 pbClear-> setToolTip( TR("gcw.billPay.ttp.clear") );
140 pbClear->
141 clicked().connect( [&]()
142 {
143 for( auto cb : m_cbx )
144 cb-> setValueText( "no" );
145 });
146
147 } // endWt::WTemplate * templtPayment;
148
149 /*
150 ** This is the history widget. It contains
151 ** a registry table for this widget. It gets added to
152 ** the second page of the tab widget.
153 **
154 */
156 {
157 /*
158 ** This does a better job of honoring the layout, but we still have
159 ** to set the widget height.
160 **
161 */
162 auto w_ = std::make_unique< GCW::Gui::AccountRegister::Widget >();
163 m_register = w_.get();
164 m_register-> setReadOnly( true );
165 auto tab = m_tabWidget-> addTab( std::move( w_ ), TR("gcw.billPay.tabName.history") );
166// tab-> contents()-> setMaximumSize( Wt::WLength::Auto, "300px" );
167
168 } // endWt::WTemplate * templtHistory;
169
170 m_pbSave -> clicked().connect( [&](){ saveData(); });
171 m_pbCancel -> clicked().connect( [&](){ m_canceled.emit(); });
172 m_pbDelete -> clicked().connect( [&](){ m_deleted.emit(); });
173 m_pbProcess -> clicked().connect( [&](){ processPayment(); });
174
175 /*
176 ** get all the data loaded
177 */
178 loadData();
179
180} // endEditWidget( const std::string & _accountGuid )
181
182auto
184loadData()-> void
185{
186 /*
187 ** beware of safety
188 */
189 if( m_bpGuid == "" )
190 return;
191
192 m_pbProcess -> setDisabled( false );
193 m_pbDelete -> setDisabled( false );
194
195 /*
196 ** Get the item that carries the bill-pay info
197 */
198 auto bpItem = GCW::Gui::BillPay::bpItem( m_bpGuid );
199
200 /*
201 ** format the 'name' to be something readable
202 */
203 auto fullName = GCW::Dbo::Accounts::fullName( bpItem.accountGuid() );
204
205 /*
206 ** If the account-name has been assigned, then don't allow it to
207 ** be re-assigned.
208 */
209 if( fullName != "" )
210 m_account -> setDisabled( true );
211
212 /*
213 ** populate the form
214 */
215 Wt::Dbo::Transaction t( GCW::app()-> gnucashew_session() );
216 m_account -> setValueText( fullName );
217 m_dueDay -> setValueText( bpItem.dueDay () );
218 m_minimum -> setValueText( bpItem.minimum () );
219 m_budget -> setValueText( bpItem.budget () );
220 m_nickname -> setValueText( bpItem.nickname () );
221 m_group -> setValueText( bpItem.group () );
222 m_limit -> setValueText( bpItem.limit () );
223 m_actual -> setValueText( bpItem.actual () );
224 m_url -> setValueText( bpItem.url () );
225 m_ap -> setValueText( bpItem.ap () );
226 m_isActive -> setValueText( bpItem.isActive () );
227 m_isVisible -> setValueText( bpItem.isVisible () );
228 m_autoPay -> setValueText( bpItem.autoPay () );
229 m_payNow -> setValueText( bpItem.payNow () );
230 m_last4 -> setValueText( bpItem.last4 () );
231 m_note -> setValueText( bpItem.note () );
232
233 int i = 1;
234 for( auto cb : m_cbx )
235 cb-> setValueText( bpItem.cb( i++ ) );
236
237 m_register -> setAccountGuid( bpItem.accountGuid() );
238
239} // endloadData()-> void
240
241auto
243url_open()-> void
244{
245 wApp-> doJavaScript( "window.open( '" + m_url-> valueText().toUTF8() + "', '_blank' )" );
246
247} // endurl_open()-> void
248
249
250auto
252accountIsDuplicated()-> bool
253{
254 auto accountGuid = m_account-> valueGuid();
255
257
258 for( auto & itm : items )
259 {
260 Item item(itm);
261
262 /*
263 ** if the account is the same but the bpItem is different
264 ** then this must be a duplicate. The accountGuid and
265 ** bpItemGuid must match in order for this to not be a
266 ** duplicate. When they match, it means we're saving
267 ** the same (correct) bp item.
268 */
269 if( item.accountGuid() == accountGuid
270 && item.guid() != m_bpGuid
271 )
272 return true;
273 }
274
275 return false;
276
277} // endduplicateAccount()-> bool
278
279auto
281saveData()-> void
282{
283 /*
284 ** This needs to be set before we can save
285 */
286 if( m_account-> valueText() == "" )
287 {
288 Wt::WMessageBox::show( TR("gcw.billPay.lbl.billPay"), TR("gcw.billPay.save.needaccount"), Wt::StandardButton::Ok );
289 return;
290 }
291
292#ifdef DUPLICATES_ARE_ALLOWED_SINCE_INTERNET_EXPENSES_ARE_PAID_TO_FRONTIER_AND_HOSTGATOR_AND_SO_ON_SO_THERE_CAN_BE_MULTIPLE_INTERNET_BILLS
293 /*
294 ** If the account is already in a bill-pay, then disallow
295 ** another duplicate
296 */
297 if( accountIsDuplicated() )
298 {
299 Wt::WMessageBox::show( TR("gcw.billPay.lbl.billPay"), TR("gcw.billPay.save.duplicate"), Wt::StandardButton::Ok );
300 return;
301 }
302#endif
303
304 /*
305 ** little bit of housekeeping before we begin
306 */
307 if( m_bpGuid == "" )
308 m_bpGuid = GCW::Core::newGuid();
309
310 /*
311 ** load the bpItem, if we had to create a new guid above,
312 ** then we'll end up with a 'new' bpItem.
313 **
314 */
315 auto bpItem = GCW::Gui::BillPay::bpItem( m_bpGuid );
316
317 /*
318 ** save everything
319 */
320 Wt::Dbo::Transaction t ( GCW::app() -> gnucashew_session() );
321 bpItem.set_accountGuid ( m_account -> valueGuid() );
322 bpItem.set_dueDay ( m_dueDay -> valueText() );
323 bpItem.set_minimum ( m_minimum -> valueText() );
324 bpItem.set_budget ( m_budget -> valueText() );
325 bpItem.set_nickname ( m_nickname -> valueText() );
326 bpItem.set_group ( m_group -> valueText() );
327 bpItem.set_limit ( m_limit -> valueText() );
328 bpItem.set_actual ( m_actual -> valueText() );
329 bpItem.set_url ( m_url -> valueText() );
330 bpItem.set_ap ( m_ap -> valueText() );
331 bpItem.set_isActive ( m_isActive -> valueText() );
332 bpItem.set_isVisible ( m_isVisible -> valueText() );
333 bpItem.set_autoPay ( m_autoPay -> valueText() );
334 bpItem.set_payNow ( m_payNow -> valueText() );
335 bpItem.set_last4 ( m_last4 -> valueText() );
336 bpItem.set_note ( m_note -> valueText() );
337
338 int i = 1;
339 for( auto cb : m_cbx )
340 bpItem.set_cb( i++, cb-> valueText() );
341
342 m_saved.emit();
343
344} // endsaveData()-> void
345
346
347
348auto
350processPayment()-> void
351{
352 /*
353 ** create a message box child to this object, so we can
354 ** properly destroy it later
355 */
356 auto msgBox = addChild( std::make_unique< BillPay::PaymentWidgetDialog >( m_bpGuid ) );
357 msgBox-> show();
358
359 /*
360 ** when the dialog is finished, we remove it from the
361 ** child object collection and properly destroy it - no leaks!
362 */
363 msgBox->
364 finished().connect( [this,msgBox]()
365 {
366 m_lastPaymentDate = msgBox-> paymentDate();
367 removeChild( msgBox );
368 });
369
370} // endprocessPayment()-> void
371
372
373
375EditWidgetDialog( const std::string & _bpGuid )
376{
377 addStyleClass( "EditWidgetDialog" );
378 setWindowTitle( "Bill Pay Account" );
379
380 setClosable( true );
381 rejectWhenEscapePressed( true );
382
383 auto editWidget = contents()-> addNew< EditWidget >( _bpGuid );
384
385 editWidget-> saved ().connect( [&](){ accept(); });
386 editWidget-> canceled ().connect( [&](){ reject(); });
387
388} // endEditWidgetDialog( const std::string & _accountGuid )
389
390
#define GCW_GUI_BILLPAY_ITEM_CFY
Definition BillPay.h:41
EditWidgetDialog(const std::string &_bpGuid)
Wt::WPushButton * m_pbDelete
Definition EditWidget.h:79
Wt::WPushButton * m_pbSave
Definition EditWidget.h:77
Wt::WPushButton * m_pbProcess
Definition EditWidget.h:80
std::vector< Wt::WCheckBox * > m_cbx
Definition EditWidget.h:101
Wt::WTabWidget * m_tabWidget
Definition EditWidget.h:100
GCW::Gui::AccountComboBox * m_account
Definition EditWidget.h:81
Wt::WCheckBox * m_isVisible
Definition EditWidget.h:92
Wt::WPushButton * m_pbCancel
Definition EditWidget.h:78
EditWidget(const std::string &_bpGuid)
auto url_open() -> void
Open URL field in browser.
GCW::Gui::AccountRegister::Widget * m_register
Definition EditWidget.h:76
auto guid() const -> std::string
Item GUID.
auto accountGuid() const -> std::string
Account GUID.
void emit(A... args) const
Widget * addNew(Args &&...args)
void setLayout(std::unique_ptr< WLayout > layout)
virtual void addWidget(std::unique_ptr< WWidget > widget)
EventSignal< WMouseEvent > & doubleClicked()
EventSignal< WMouseEvent > & clicked()
virtual void resize(const WLength &width, const WLength &height) override
virtual void setStyleClass(const WString &styleClass) override
virtual void setMinimumSize(const WLength &width, const WLength &height) override
virtual void addStyleClass(const WString &styleClass, bool force=false) override
virtual void setToolTip(const WString &text, TextFormat textFormat=TextFormat::Plain) override
#define TR(X)
Definition define.h:17
auto newGuid() -> std::string
Generate new GUID string value.
Definition Core.cpp:245
auto fullName(const std::string &_guid) -> std::string
Account Fullname via GUID.
auto getByCfy(const std::string &_cfyValue) -> GCW::Dbo::Vars::Item::Vector
Definition Vars.cpp:75
auto bpItem(const std::string &_guid) -> GCW::Gui::BillPay::Item
Bill Pay Item.
Definition BillPay.cpp:33
auto toString(int _value) -> std::string
Convert Integer to String.
Definition BillPay.cpp:55
App * app()
Definition App.cpp:75