GnuCashew ~ Web Application compatible with GnuCash sql data files.
GCW
Loading...
Searching...
No Matches
Model.cpp
Go to the documentation of this file.
1#line 2 "src/Gui/AccountRegister/Model.cpp"
2
3#include <chrono>
4
5#include "../Glb/gcwglobal.h"
6#include "../Dbo/SessionGnuCash.h"
7#include "../Dbo/Splits/Splits.h"
8#include "../Dbo/Prefrences.h"
9#include "../Dbo/Vars/Vars.h"
10#include "../Glb/Core.h"
11#include "../Eng/TransactionManager.h"
12#include "Model.h"
13
15Model()
16: Wt::WStandardItemModel( 0, 8 ) // 8-columns
17{
18 /*
19 ** these are here for testing, so we can quickly enable the view and putz around on it
20 */
21// m_viewMode = ViewMode::BASIC_LEDGER ; // (default)
22// m_viewMode = ViewMode::AUTOSPLIT_LEDGER ;
23// m_viewMode = ViewMode::TRANSACTION_JOURNAL ;
24// m_viewMode = ViewMode::GENERAL_JOURNAL ;
25// m_doubleLine = true ;
26
27 /*
28 ** set the lastDate to match the todays date, so when first
29 ** opening the register, the date is automatically set.
30 */
33
34#ifdef NEVER
35 dataChanged().connect( [=]( Wt::WModelIndex _index1, Wt::WModelIndex _index2 )
36 {
37 std::cout << __FILE__ << ":" << __LINE__ << " model<signal>.dataChanged()"
38 << "\n tst:" << std::string( Wt::asString( _index1.data() ) == Wt::asString( _index2.data() )? "same":"different" )
39 << "\n r1:" << _index1.row()
40 << " c1:" << _index1.column()
41 << " v1:" << Wt::asString( _index1.data() )
42 << "\n r2:" << _index2.row()
43 << " c2:" << _index2.column()
44 << " v2:" << Wt::asString( _index2.data() )
45 << std::endl;
46
47 });
48#endif
49
50#ifdef NEVER
51 itemChanged().connect( [=]( Wt::WStandardItem * _item )
52 {
53 std::cout << __FILE__ << ":" << __LINE__ << " model<signal>.itemChanged()"
54 << "\n r:" << _item-> row()
55 << " c:" << _item-> column()
56 << "\n d:" << Wt::asString( _item-> data( Wt::ItemDataRole::Display ) )
57 << "\n t:" << Wt::asString( _item-> text() )
58 << std::endl;
59
60 });
61#endif
62
63} // endGCW::Gui::AccountRegisterModel::AccountRegisterModel( const std::string & _accountGuid )
64
65auto
67setAccountGuid( const std::string & _accountGuid )-> void
68{
69 m_accountGuid = _accountGuid;
70 refreshFromDisk();
71
72} // endsetAccountGuid( const std::string & _accountGuid )-> void
73
74auto
76setViewMode( ViewMode _viewMode )-> void
77{
78 m_viewMode = _viewMode;
79 refreshFromDisk();
80
81} // endsetViewMode( ViewMode _viewMode )-> void
82
83auto
85setDoubleLine( bool _doubleLine )-> void
86{
87 m_doubleLine = _doubleLine;
88 refreshFromDisk();
89
90} // endsetDoubleLine( bool _doubleLine )-> void
91
92auto
94splitCount()-> int
95{
96 return m_splitCount;
97
98} // endsplitCount()-> int
99
100auto
102isDeletable( const Wt::WModelIndex & _index )-> bool
103{
104 /*!
105 ** If this transaction split has no guid
106 ** then it's a new row, and cannot be deleted
107 */
108 if( getSplitGuid( _index ) == "" )
109 return false;
110
111 /*!
112 ** If this transaction split is reconciled, then it is
113 ** considered not deletable
114 */
115 auto split = Dbo::Splits::byGuid( getSplitGuid( _index ) );
116 if( split-> isReconciled() )
117 return false;
118
119 /*
120 ** deletable
121 */
122 return true;
123
124} // endisDeletable( const Wt::WModelIndex & _index )-> bool
125
126auto
128isJumpable( const Wt::WModelIndex & _index )-> bool
129{
130 /*!
131 ** If this transaction split has no guid
132 ** then it's a new row, and cannot be jumped
133 */
134 if( getSplitGuid( _index ) == "" )
135 return false;
136
137 // BUGBUG: use transman here to get the other split
138 /*!
139 ** Need to have another split to be jumpable
140 */
141// auto splits = Dbo::Splits::bySplitExcept( getSplitGuid( _index ) );
142// if(
143// if( !split || split-> guid() == "" )
144// return false;
145
146 /*
147 ** jumpable
148 */
149 return true;
150
151} // endisJumpable( const Wt::WModelIndex & _index )-> bool
152
153auto
155isReadOnly()-> bool
156{
157 return m_readOnly;
158}
159
160auto
162isReadOnly( const Wt::WModelIndex & _index )-> bool
163{
164 /*
165 ** if the whole model is read/only, return it
166 */
167 if( isReadOnly() )
168 return true;
169
170 /*
171 ** if the index isn't valid, we are read/only
172 */
173 if( !_index.isValid() )
174 return true;
175
176 /*!
177 ** If this transaction split has no guid
178 ** then it's a new row, and can be edited
179 */
180 if( getSplitGuid( _index ) == "" )
181 return false;
182
183 /*!
184 ** If this transaction split is reconciled, then it is
185 ** considered not editable.
186 **
187 ** We have to convert this _index in to the proper split
188 ** that represents it, and then query that split to see
189 ** if it is reconciled or not. We use the transaction
190 ** manager to get this done, as it encapsulates a bunch
191 ** of different tools for manipulating the data.
192 */
193// GCW::Gui::Transaction::Manager transMan( Dbo::Splits::byGuid( getSplitGuid( _index ) ) );
194// if( transMan.thisSplit()-> isReconciled() )
195// return true;
196
197 /*
198 ** readOnly == false == editable
199 */
200 return false;
201
202} // endReadOnly( const Wt::WModelIndex & _index )-> bool
203
204auto
206isReadOnly( int _row )-> bool
207{
208 return
209 isReadOnly( index( _row, 0 ) );
210}
211
212auto
214saveToDisk()-> void
215{
216 std::cout << FUNCTION_HEADER << " ~not implemented~ " << std::endl;
217
218} // endsaveToDisk()
219
220auto
222getString( const Wt::WModelIndex & _index, int column )-> std::string
223{
224 return
225 Wt::asString // convert the index.data() to a WString
226 (
227 index( _index.row(), column ) // get the index of the ACTION column
228 .data( Wt::ItemDataRole::Display ) // get the (string/display) data from it
229 )
230 .toUTF8(); // convert the WString to a std::string
231 //
232} // endgetString( const Wt::WModelIndex & _index, int column )-> std::string
233
234auto
236getDate( const Wt::WModelIndex & _index )-> Wt::WDateTime
237{
238 auto retVal =
239 Wt::WDateTime::fromString // convert the WString to a WDateTime
240 (
241 getString( _index, asInt( Col::DATE ) ),
242 GCW_DATE_FORMAT_DISPLAY // use this DATE format for the conversion
243 );
244
245 /*
246 ** set the default time-component
247 */
249
250 return retVal;
251
252} // endgetDate( const Wt::WModelIndex & _index )-> std::string
253
254auto
256getAction( const Wt::WModelIndex & _index )-> std::string
257{
258 return getString( _index, asInt( Col::ACTION ) );
259
260} // endgetAction( const Wt::WModelIndex & _index )-> std::string
261
262auto
264getDescription( const Wt::WModelIndex & _index )-> std::string
265{
266 return getString( _index, asInt( Col::DESCRIPTION ) );
267
268} // endgetDescription( const Wt::WModelIndex & _index )-> std::string
269
270auto
272getTransferText( const Wt::WModelIndex & _index )-> std::string
273{
274 return getString( _index, asInt( Col::TRANSFER ) );
275
276} // endgetTransferText( const Wt::WModelIndex & _index )-> std::string
277
278auto
280getTransferGuid( const Wt::WModelIndex & _index )-> std::string
281{
282 return
283 GCW::Dbo::Accounts::byFullName( getTransferText( _index ) )-> guid();
284
285} // endgetTransferGuid( const Wt::WModelIndex & _index )-> std::string
286
287auto
289getReconcile( const Wt::WModelIndex & _index )-> std::string
290{
291 return getString( _index, asInt( Col::RECONCILE ) );
292
293} // endgetReconcile( const Wt::WModelIndex & _index )-> std::string
294
295auto
297getNumeric( const Wt::WModelIndex & _index )-> GCW_NUMERIC
298{
299 GCW_NUMERIC retVal( 0 );
300
301 if( !_index.data( Wt::ItemDataRole::Display ).empty() )
302 retVal = GCW_NUMERIC( Wt::asString( _index.data( Wt::ItemDataRole::Display ) ).toUTF8() );
303
304 return retVal;
305
306} // endgetNumeric( const Wt::WModelIndex & _index )-> GCW_NUMERIC
307
308auto
310getDebit( const Wt::WModelIndex & _index )-> GCW_NUMERIC
311{
312 return
313 getNumeric( index( _index.row(), asInt( Col::DEBIT ) ) );
314
315} // endgetDebit( const Wt::WModelIndex & _index )-> GCW_NUMERIC
316
317auto
319getCredit( const Wt::WModelIndex & _index )-> GCW_NUMERIC
320{
321 return
322 getNumeric( index( _index.row(), asInt( Col::CREDIT ) ) );
323
324} // endgetCredit( const Wt::WModelIndex & _index )-> GCW_NUMERIC
325
326auto
328getValue( const Wt::WModelIndex & _index )-> GCW_NUMERIC
329{
330 GCW_NUMERIC retVal( 0 );
331
332 // get both values so we can determine (+) or (-)
333 auto debit = getDebit( _index );
334 auto credit = getCredit( _index );
335 retVal = debit - credit;
336
337 return retVal;
338
339} // endgetValue( const Wt::WModelIndex & _index )-> GCW_NUMERIC
340
341auto
343getSplitGuid( const Wt::WModelIndex & _index )-> std::string
344{
345 return
346 Wt::asString // convert the index.data() to a WString
347 (
348 index( _index.row(), asInt( Col::DATE ) ) // get the index of the DATE column
349 .data( Wt::ItemDataRole::User ) // get the (string/User) data from it
350 )
351 .toUTF8(); // convert the WString to a std::string
352
353} // endgetSplitGuid( const Wt::WModelIndex & _index )-> std::string
354
355auto
357getSplitGuid( int _row )-> std::string
358{
359 return getSplitGuid( index( _row, asInt( Col::DATE ) ) );
360
361} // endgetSplitGuid( int _row )-> std::string
362
363auto
365saveToDisk( const Wt::WModelIndex & _index )-> void
366{
367#ifdef NEVER
368 std::cout << __FILE__ << ":" << __LINE__ << " " << __FUNCTION__ << "(): "
369 << "\n row:" << _index.row()
370 << "\n col:" << _index.column()
371 << "\n gui:" << getSplitGuid( _index )
372 << std::endl;
373#endif
374
375 /*
376 ** Prepare to update everything
377 */
378 GCW::Eng::Transaction::Manager transMan( this );
379
380 /*
381 ** If we don't have a split guid, then this is a new row. It also
382 ** means we don't have a transaction, either. So, build up a whole
383 ** set of transaction-items that we'll be needing to set in these
384 ** new values.
385 */
386 auto splitGuid = getSplitGuid( _index );
387 if( splitGuid == "" )
388 {
389 /*
390 ** Create a new transaction
391 **
392 */
393 transMan.newTransaction( m_accountGuid, getTransferGuid( _index ) );
394
395 } // endif( ..no split.. )
396
397 /*
398 ** We have a split item, so load up the transaction associated with it as
399 ** well as the split-pair item, we will poke changes in to it accordingly below.
400 */
401 else
402 {
403 transMan.loadSplit( splitGuid );
404 }
405
406 /*
407 ** write out the data that changed
408 */
409 switch( _index.column() )
410 {
411 case asInt( Col::DATE ):
412 {
413 transMan.setDate( getDate( _index ) );
414 break;
415 }
416
417 case asInt( Col::ACTION ):
418 {
419 transMan.setAction( getAction( _index ) );
420 break;
421 }
422
423 case asInt( Col::DESCRIPTION ):
424 {
425 transMan.setDescription( getDescription( _index ) );
426 break;
427 }
428
429 case asInt( Col::TRANSFER ):
430 {
431 transMan.setTransferGuid( getTransferGuid( _index ) );
432 break;
433 }
434
435 case asInt( Col::RECONCILE ):
436 {
437 transMan.setReconcile( getReconcile( _index ) );
438 break;
439 }
440
441 case asInt( Col::DEBIT ):
442 {
443 transMan.setValue( getValue( _index ) );
444 break;
445 }
446
447 case asInt( Col::CREDIT ):
448 {
449 transMan.setValue( getValue( _index ) );
450 break;
451 }
452
453#ifdef NEVER
454 case asInt( Col::NOTES ):
455 {
456 transMan.setNotes( getNotes( _index ) );
457 break;
458 }
459#endif
460
461 } // endswitch( index.column() )
462
463} // endsaveToDisk( const Wt::WModelIndex & _index )-> void
464
465auto
467setData( const Wt::WModelIndex & _index, const Wt::cpp17::any & _value, Wt::ItemDataRole _role )-> bool
468{
469 /*
470 ** This is not an edit role - fast quit!
471 */
472 if( _role != Wt::ItemDataRole::Edit )
473 return false;
474
475 /*
476 ** Nothing happening constitutes a success
477 */
478 bool retVal = true;
479
480 /*
481 ** This compare function compares two _any_ values
482 */
483 auto _valuesMatch = []( const Wt::cpp17::any & _any1, const Wt::cpp17::any & _any2 )
484 {
485 /*
486 ** In any case, the two values must be of the same type.
487 */
488 if( _any1.type() == _any2.type() )
489 {
490#ifdef NEVER
491 std::cout << __FILE__ << ":" << __LINE__ << " " << __FUNCTION__
492 << "\n " << typeid(Wt::WString).name()
493 << "\n " << typeid(Wt::WString).hash_code()
494 << "\n " << _any1.type().name()
495 << "\n " << _any1.type().hash_code()
496 << std::endl;
497#endif
498
499 if( typeid(std::string) == _any1.type() )
500 {
501 auto v1 = Wt::cpp17::any_cast< std::string >( _any1 );
502 auto v2 = Wt::cpp17::any_cast< std::string >( _any2 );
503 return v1 == v2;
504 }
505
506 else
507 if( typeid(Wt::WString) == _any1.type() )
508 {
509 auto v1 = Wt::cpp17::any_cast< Wt::WString >( _any1 );
510 auto v2 = Wt::cpp17::any_cast< Wt::WString >( _any2 );
511 return v1 == v2;
512 }
513
514 else
515 if( typeid(int) == _any1.type() )
516 {
517 auto v1 = Wt::cpp17::any_cast< int >( _any1 );
518 auto v2 = Wt::cpp17::any_cast< int >( _any2 );
519 return v1 == v2;
520 }
521
522 else
523 if( typeid(Wt::WDate) == _any1.type() )
524 {
525 auto v1 = Wt::cpp17::any_cast< Wt::WDate >( _any1 );
526 auto v2 = Wt::cpp17::any_cast< Wt::WDate >( _any2 );
527 return v1 == v2;
528 }
529
530 else
531 if( typeid(Wt::WDateTime) == _any1.type() )
532 {
533 auto v1 = Wt::cpp17::any_cast< Wt::WDateTime >( _any1 );
534 auto v2 = Wt::cpp17::any_cast< Wt::WDateTime >( _any2 );
535 return v1 == v2;
536 }
537
538 else
539 {
540 std::cout << __FILE__ << ":" << __LINE__
541 << " unhandled type " << _any1.type().name()
542 << std::endl;
543 }
544
545 } // endif( _any1.type() == _any2.type() )
546
547 /*
548 ** not a match!
549 */
550 return false;
551
552 }; // endauto _valuesMatch = []( const Wt::cpp17::any & _any1, const Wt::cpp17::any & _any2 )
553
554 /*
555 ** Only updating if the data actually changed
556 */
557 if( !_valuesMatch( _index.data( _role ), _value ) )
558 {
559#ifdef NEVER
560 std::cout << BREAKHEADER
561 << "\n row:" << _index.row()
562 << "\n col:" << _index.column()
563 << "\n cur:" << Wt::asString( _index.data( _role ) )
564 << "\n new:" << Wt::asString( _value )
565 << std::endl;
566#endif
567
568 /*
569 ** saving to the model causes _index to be updated with the new value
570 */
571 retVal = Wt::WStandardItemModel::setData( _index, _value, _role );
572
573// saveToDisk( _index );
574
575// m_dirtyRows.insert( _index.row() );
576
577// m_goneDirty.emit( _index );
578
579// dataChanged().emit( index( _index.row(), COL_DATE ), index( _index.row(), COL_BALANCE ) );
580
581#ifdef NEVER
582 std::cout << BREAKFOOTER
583 << std::endl;
584#endif
585
586 } // endif( !_valuesMatch( _index.data( _role ), _value ) )
587
588 /*
589 ** Return success fail
590 */
591 return retVal;
592
593} // endsetData( const Wt::WModelIndex & _index, const Wt::cpp17::any & _value, Wt::ItemDataRole _role )-> bool
594
595/*!
596** \brief Refresh From Disk
597**
598** This procedure reads from the gnucash storage source (either postgres or sqlite) and loads all of the
599** transactions and their associated splits in to the model suitable for editing within an automatic
600** table view.
601*/
602auto
604refreshFromDisk()-> void
605{
606 const auto start = std::chrono::system_clock::now();
607
608 /*
609 ** this gets recomputed below
610 */
611 m_splitCount = 0;
612
613 /*
614 ** can't without an account
615 */
616 if( m_accountGuid == "" )
617 return;
618
619 /*
620 ** Signal the model is about to be reset.
621 */
622 layoutAboutToBeChanged().emit();
623
624 /*!
625 ** Before refreshing from disk, the entire contents of the
626 ** model are cleared, so it is important to make sure anything
627 ** to be saved from the model is done first.
628 */
629 clear();
630
631 /*
632 ** Get the prefrence item that can inform us about prefrences
633 ** to be applied to this model.
634 */
635 auto prefrenceItem = GCW::Dbo::Prefrences::get();
636
637 /*
638 ** Get an account item loaded. This is the account that _is_ this
639 ** register.
640 */
641 auto registerAccountItem = GCW::Dbo::Accounts::byGuid( m_accountGuid );
642
643 /*
644 ** use a transaction manager for accessing everything
645 */
646 GCW::Eng::Transaction::Manager transMan( this );
647
648#ifdef NEVER
649 std::cout << __FILE__ << ":" << __LINE__
650 << " guid:" << registerAccountItem-> guid()
651 << " name:" << registerAccountItem-> name()
652 << " dbcr:" << static_cast<int>( registerAccountItem-> accountDrCr() )
653 << " type:" << static_cast<int>( registerAccountItem-> accountType() )
654 << " typn:" << registerAccountItem-> accountTypeName()
655 << std::endl;
656#endif
657
658 /*!
659 ** In order to produce a proper 'register' of items, it is important
660 ** to load the data from the 'splits' side of the transaction rather
661 ** than the transaction itself.
662 **
663 ** Note that when the splits are loaded based on the account ID, they
664 ** are returned in a std::vector(sorted_by_date) that is sorted based on
665 ** the transction date. This chosen sort method insures that the
666 ** running balance can be accurately calculated on the fly, since each
667 ** item is pulled from the vector in a sorted order, and the running
668 ** balance is included in the model row. The user can sort the user
669 ** interface later and still have the line-item-balance remain accurate.
670 */
671 auto splitItems = GCW::Dbo::Splits::byAccount( m_accountGuid );
672
673 /*
674 ** remember the split count
675 */
676 m_splitCount = splitItems.size();
677
678 /*!
679 ** Each item is processed from the vector in sequential order.
680 ** In this process we grab the contents of the split, and
681 ** generate a model item row containing all of the column values.
682 ** Maintain a running balance as we go along to keep the balance
683 ** reflected within the view. The result is a multi-column row
684 ** item that is added to the model. This allows the model to be
685 ** subsequently re-sorted or subset-extracted without affecting
686 ** the running balances and so forth.
687 */
688 m_balance = GCW_NUMERIC( 0 );
689 for( auto splitItem : splitItems )
690 {
691 transMan.setSplitItem( splitItem );
692
693 /*
694 ** Start out read-only == true. We want to default read-only
695 ** and upgrade to read-write if the dataset calls for it.
696 */
697 bool readOnly = true;
698
699 /*
700 ** BUGBUG: Depending on the condition of the database, in the odd chance that something
701 ** has gone corrupted, this will more-or-less mask the issue, by simply
702 ** stepping over this split that appears to be in bad shape. Ideally we need
703 ** to generate some sort of report at this point, but for now we'll just step
704 ** over it.
705 */
706 if( !transMan.transactionItem() )
707 continue;
708
709 /*
710 ** If this model is editable, then check the reconciliation
711 ** state. If the split has already been reconciled then
712 ** we really don't want the user messing around with it.
713 */
714 if( !m_readOnly )
715 {
716 if( splitItem-> reconcile_state() == GCW_RECONCILE_YES )
717 {
718 readOnly = true;
719 }
720 else
721 {
722 readOnly = false;
723 }
724 }
725
726 transMan.setReadOnly( readOnly );
727
728 transMan.appendRow();
729
730 } // endfor( auto splitItem : splitItems )
731
732 /*!
733 ** After all the split items are loaded, an additional ~blank~ item
734 ** is included at the end of the vector, for coding new entries.
735 */
736#ifdef NEVER
737 if( !isReadOnly() )
738 {
739 /*
740 ** Create a row with blank values
741 */
742 RowItem columns;
743 auto post_date = _addColumn( columns, "" ); // Date
744 post_date-> setData( m_lastDate, Wt::ItemDataRole::Edit );
745 post_date-> setFlags( Wt::ItemFlag::Editable );
746
747 _addColumn( columns, "" )-> setFlags( Wt::ItemFlag::Editable ); // Num
748 _addColumn( columns, "" )-> setFlags( Wt::ItemFlag::Editable ); // Memo
749 _addColumn( columns, "" )-> setFlags( Wt::ItemFlag::Editable ); // Account
750 _addColumn( columns, "n" )-> setFlags( Wt::ItemFlag::Editable ); // R
751 _addColumn( columns, "" )-> setFlags( Wt::ItemFlag::Editable ); // Deposit
752 _addColumn( columns, "" )-> setFlags( Wt::ItemFlag::Editable ); // Withdrawal
753 _addColumn( columns, "" )-> setFlags( Wt::ItemFlag::Editable ); // Balance
754 appendRow( std::move( columns ) ) ;
755
756 } // endif( m_editable )
757#endif
758
759 /*!
760 ** poke all the header labels in. Note that some of the labels change
761 ** depending on the account debit/credit type. We get those from the
762 ** accountDef.
763 **
764 ** \bug Needs work
765 ** this is modified a bit to allow for a default account def.
766 ** this is necessary since it is possible to ask for an account
767 ** register that is not (yet) associated to an account... this
768 ** can happen in the BillPay module when setting up a new
769 ** account for bill-pay functions. (kind of sloppy doing it here)
770 ** The first item at(0) represents the default-register settings,
771 ** suitable for any register view.
772 */
774#ifdef NO_DRCR_YET
775 if( registerAccountItem )
776 accountDef = registerAccountItem-> accountDef();
777#endif
778
779 /*!
780 ** \anchor account_type_labels
781 */
782 int col = 0;
783 setHeaderData( col++, TR( "gcw.AccountRegister.column.date" ) );
784 setHeaderData( col++, TR( "gcw.AccountRegister.column.num" ) );
785 setHeaderData( col++, TR( "gcw.AccountRegister.column.memo" ) );
786 setHeaderData( col++, TR( "gcw.AccountRegister.column." + accountDef.colAccount ) );
787 setHeaderData( col++, TR( "gcw.AccountRegister.column.reconcile" ) );
788 setHeaderData( col++, TR( "gcw.AccountRegister.column." + accountDef.colDr ) );
789 setHeaderData( col++, TR( "gcw.AccountRegister.column." + accountDef.colCr ) );
790 setHeaderData( col++, TR( "gcw.AccountRegister.column.balance" ) );
791
792 /*
793 ** Let the rest of the world know the model changed.
794 */
795 layoutChanged().emit();
796
797 /*
798 ** load time
799 */
800 std::cout << __FILE__ << ":" << __LINE__
801 << " " << std::chrono::duration_cast< std::chrono::milliseconds >
802 ( std::chrono::system_clock::now() - start ).count()
803 << "mS load time for"
804 << " " << splitCount() << " items"
805 << std::endl;
806
807} // endrefreshFromDisk()-> void
808
809auto
811makeRow( const std::string & _splitGuid )-> GCW::Gui::AccountRegister::Model::RowItem
812{
813 RowItem rowItem;
814
815 return rowItem;
816
817} // endmakeRow( const std::string & _splitGuid )-> GCW::Gui::AccountRegisterModel::RowItem
818
819auto
821suggestionsFromColumn( int _column ) const-> std::set< std::string >
822{
823 /*
824 ** First, make a set of unique values.
825 */
826 std::set< std::string > retVal;
827 for( int row=0; row< rowCount(); row++ )
828 retVal.insert( Wt::asString( item( row, _column )-> text() ).toUTF8() );
829
830 return retVal;
831
832} // endsuggestionsFromColumn( int _column ) const-> std::set< std::string >
833
834auto
836setStyleClass( int _row, const std::string & _class )-> void
837{
838
839
840} // endsetStyleClass( int _row, const std::string & _class )-> void
841
842auto
844removeStyleClass( int _row, const std::string & _class )-> void
845{
846
847} // endremoveStyleClass( int _row, const std::string & _class )-> void
848
849
static std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
Definition Core.cpp:16
auto setTransferGuid(const std::string &_value) -> void
Set Transfer GUID.
auto newTransaction(const std::string &_accountGuid1, const std::string &_accountGuid2) -> void
New Transaction.
auto setReconcile(const std::string &_value) -> void
auto setSplitItem(GCW::Dbo::Splits::Item::Ptr _splitItem) -> void
auto transactionItem() const -> GCW::Dbo::Transactions::Item::Ptr
Transaction Item.
auto setDescription(const std::string &_value) -> void
auto setDate(const Wt::WDateTime &_value) -> void
auto loadSplit(const std::string &_splitGuid) -> void
Set Split.
auto setAction(const std::string &_value) -> void
Set Action.
auto setNotes(const std::string &_acctGuid, const std::string &_value) -> void
auto setReadOnly(bool _value) -> void
auto setValue(GCW_NUMERIC _value) -> void
auto isDeletable(const Wt::WModelIndex &_index) -> bool
Is Read Only.
Definition Model.cpp:102
auto getDate(const Wt::WModelIndex &_index) -> Wt::WDateTime
Get Date from the index.
Definition Model.cpp:236
auto setViewMode(ViewMode _viewMode) -> void
Definition Model.cpp:76
auto getValue(const Wt::WModelIndex &_index) -> GCW_NUMERIC
Get Value (positive or negative)
Definition Model.cpp:328
auto getReconcile(const Wt::WModelIndex &_index) -> std::string
Get Reconciliation.
Definition Model.cpp:289
auto setStyleClass(int _row, const std::string &_class) -> void
Definition Model.cpp:836
auto setAccountGuid(const std::string &_accountGuid) -> void
Definition Model.cpp:67
auto getDebit(const Wt::WModelIndex &_index) -> GCW_NUMERIC
Get Debit value.
Definition Model.cpp:310
auto getAction(const Wt::WModelIndex &_index) -> std::string
Get Action.
Definition Model.cpp:256
auto getCredit(const Wt::WModelIndex &_index) -> GCW_NUMERIC
Get Credit value.
Definition Model.cpp:319
auto getString(const Wt::WModelIndex &_index, int column) -> std::string
Definition Model.cpp:222
auto getNumeric(const Wt::WModelIndex &_index) -> GCW_NUMERIC
Get numeric value.
Definition Model.cpp:297
auto splitCount() -> int
Split Count.
Definition Model.cpp:94
auto getSplitGuid(const Wt::WModelIndex &_index) -> std::string
Get GUID from row.
Definition Model.cpp:343
auto removeStyleClass(int _row, const std::string &_class) -> void
Definition Model.cpp:844
auto refreshFromDisk() -> void
Refresh From Disk.
Definition Model.cpp:604
auto getDescription(const Wt::WModelIndex &_index) -> std::string
Get Description.
Definition Model.cpp:264
auto getTransferGuid(const Wt::WModelIndex &_index) -> std::string
Get Transfer Account GUID.
Definition Model.cpp:280
auto setDoubleLine(bool _doubleLine) -> void
Definition Model.cpp:85
auto isJumpable(const Wt::WModelIndex &_index) -> bool
Is Jumpable.
Definition Model.cpp:128
std::vector< std::unique_ptr< Wt::WStandardItem > > RowItem
Definition Model.h:31
auto setData(const Wt::WModelIndex &_index, const Wt::cpp17::any &_value, Wt::ItemDataRole _role) -> bool
Definition Model.cpp:467
auto makeRow(const std::string &_splitGuid) -> RowItem
Definition Model.cpp:811
auto suggestionsFromColumn(int _column) const -> std::set< std::string >
Column Suggestions.
Definition Model.cpp:821
auto getTransferText(const Wt::WModelIndex &_index) -> std::string
Get Transfer Account Text.
Definition Model.cpp:272
static constexpr const int User
static constexpr const int Edit
static constexpr const int Display
virtual Signal< WModelIndex, WModelIndex > & dataChanged()
virtual bool setData(const WModelIndex &index, const cpp17::any &value, ItemDataRole role=ItemDataRole::Edit)
virtual cpp17::any data(const WModelIndex &index, ItemDataRole role=ItemDataRole::Display) const=0
void setTime(const WTime &time)
static WDateTime fromString(const WString &s)
static WDateTime currentDateTime()
int row() const
int column() const
cpp17::any data(ItemDataRole role=ItemDataRole::Display) const
Signal< WStandardItem * > & itemChanged()
std::string toUTF8() const
#define TR(X)
Definition define.h:17
#define FUNCTION_HEADER
Definition gcwglobal.h:40
#define BREAKHEADER
Definition gcwglobal.h:43
#define BREAKFOOTER
Definition gcwglobal.h:44
#define GCW_DATE_DEFAULT_TIME
Default Time.
Definition gcwglobal.h:25
#define GCW_DATE_FORMAT_DISPLAY
Definition gcwglobal.h:14
#define GCW_RECONCILE_YES
Definition gcwglobal.h:28
#define GCW_NUMERIC
Internal Numeric Type.
Definition gcwglobal.h:38
WString asString(const cpp17::any &v, const WString &formatString=WString())
const std::vector< AccountDef_t > s_accountDefs
auto byFullName(const std::string &_fullName) -> Item::Ptr
Load Account by 'full name' with ':' account separator.
auto byGuid(const std::string &_guid) -> Item::Ptr
Load Account by GUID.
auto get() -> GCW::Dbo::Prefrences::Item
auto byAccount(const std::string &_accountGuid) -> Item::Vector
Load Splits by Account.
Definition Splits.cpp:165
auto byGuid(const std::string &_splitGuid) -> Item::Ptr
Load a single split.
Definition Splits.h:331
constexpr int asInt(Col col) noexcept
Definition ViewMode.h:67
std::string colAccount
a printable 'label' for the 'account' column in the registers
std::string colDr
a printable 'label' for the 'debit' column in the registers
std::string colCr
a printable 'label' for the 'credit' column in the registers