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
363
364auto
366getSplitRow( const std::string & _guid )-> int
367{
368 for( int row = 0; row< rowCount(); row++ )
369 if( getSplitGuid( row ) == _guid )
370 return row;
371
372 return -1;
373
374} // endgetSplitRow( const std::string & _guid )-> int
375
376
377auto
379saveToDisk( const Wt::WModelIndex & _index )-> void
380{
381#ifdef NEVER
382 std::cout << __FILE__ << ":" << __LINE__ << " " << __FUNCTION__ << "(): "
383 << "\n row:" << _index.row()
384 << "\n col:" << _index.column()
385 << "\n gui:" << getSplitGuid( _index )
386 << std::endl;
387#endif
388
389 /*
390 ** Prepare to update everything
391 */
392 GCW::Eng::Transaction::Manager transMan( this );
393
394 /*
395 ** If we don't have a split guid, then this is a new row. It also
396 ** means we don't have a transaction, either. So, build up a whole
397 ** set of transaction-items that we'll be needing to set in these
398 ** new values.
399 */
400 auto splitGuid = getSplitGuid( _index );
401 if( splitGuid == "" )
402 {
403 /*
404 ** Create a new transaction
405 **
406 */
407 transMan.newTransaction( m_accountGuid, getTransferGuid( _index ) );
408
409 } // endif( ..no split.. )
410
411 /*
412 ** We have a split item, so load up the transaction associated with it as
413 ** well as the split-pair item, we will poke changes in to it accordingly below.
414 */
415 else
416 {
417 transMan.loadSplit( splitGuid );
418 }
419
420 /*
421 ** write out the data that changed
422 */
423 switch( _index.column() )
424 {
425 case asInt( Col::DATE ):
426 {
427 transMan.setDate( getDate( _index ) );
428 break;
429 }
430
431 case asInt( Col::ACTION ):
432 {
433 transMan.setAction( getAction( _index ) );
434 break;
435 }
436
437 case asInt( Col::DESCRIPTION ):
438 {
439 transMan.setDescription( getDescription( _index ) );
440 break;
441 }
442
443 case asInt( Col::TRANSFER ):
444 {
445 transMan.setTransferGuid( getTransferGuid( _index ) );
446 break;
447 }
448
449 case asInt( Col::RECONCILE ):
450 {
451 transMan.setReconcile( getReconcile( _index ) );
452 break;
453 }
454
455 case asInt( Col::DEBIT ):
456 {
457 transMan.setValue( getValue( _index ) );
458 break;
459 }
460
461 case asInt( Col::CREDIT ):
462 {
463 transMan.setValue( getValue( _index ) );
464 break;
465 }
466
467#ifdef NEVER
468 case asInt( Col::NOTES ):
469 {
470 transMan.setNotes( getNotes( _index ) );
471 break;
472 }
473#endif
474
475 } // endswitch( index.column() )
476
477} // endsaveToDisk( const Wt::WModelIndex & _index )-> void
478
479auto
481setData( const Wt::WModelIndex & _index, const Wt::cpp17::any & _value, Wt::ItemDataRole _role )-> bool
482{
483 /*
484 ** This is not an edit role - fast quit!
485 */
486 if( _role != Wt::ItemDataRole::Edit )
487 return false;
488
489 /*
490 ** Nothing happening constitutes a success
491 */
492 bool retVal = true;
493
494 /*
495 ** This compare function compares two _any_ values
496 */
497 auto _valuesMatch = []( const Wt::cpp17::any & _any1, const Wt::cpp17::any & _any2 )
498 {
499 /*
500 ** In any case, the two values must be of the same type.
501 */
502 if( _any1.type() == _any2.type() )
503 {
504#ifdef NEVER
505 std::cout << __FILE__ << ":" << __LINE__ << " " << __FUNCTION__
506 << "\n " << typeid(Wt::WString).name()
507 << "\n " << typeid(Wt::WString).hash_code()
508 << "\n " << _any1.type().name()
509 << "\n " << _any1.type().hash_code()
510 << std::endl;
511#endif
512
513 if( typeid(std::string) == _any1.type() )
514 {
515 auto v1 = Wt::cpp17::any_cast< std::string >( _any1 );
516 auto v2 = Wt::cpp17::any_cast< std::string >( _any2 );
517 return v1 == v2;
518 }
519
520 else
521 if( typeid(Wt::WString) == _any1.type() )
522 {
523 auto v1 = Wt::cpp17::any_cast< Wt::WString >( _any1 );
524 auto v2 = Wt::cpp17::any_cast< Wt::WString >( _any2 );
525 return v1 == v2;
526 }
527
528 else
529 if( typeid(int) == _any1.type() )
530 {
531 auto v1 = Wt::cpp17::any_cast< int >( _any1 );
532 auto v2 = Wt::cpp17::any_cast< int >( _any2 );
533 return v1 == v2;
534 }
535
536 else
537 if( typeid(Wt::WDate) == _any1.type() )
538 {
539 auto v1 = Wt::cpp17::any_cast< Wt::WDate >( _any1 );
540 auto v2 = Wt::cpp17::any_cast< Wt::WDate >( _any2 );
541 return v1 == v2;
542 }
543
544 else
545 if( typeid(Wt::WDateTime) == _any1.type() )
546 {
547 auto v1 = Wt::cpp17::any_cast< Wt::WDateTime >( _any1 );
548 auto v2 = Wt::cpp17::any_cast< Wt::WDateTime >( _any2 );
549 return v1 == v2;
550 }
551
552 else
553 {
554 std::cout << __FILE__ << ":" << __LINE__ << " setData:_valuesMatch"
555 << " unhandled type " << _any1.type().name()
556 << std::endl;
557 }
558
559 } // endif( _any1.type() == _any2.type() )
560
561 /*
562 ** not a match!
563 */
564 return false;
565
566 }; // endauto _valuesMatch = []( const Wt::cpp17::any & _any1, const Wt::cpp17::any & _any2 )
567
568 /*
569 ** Only updating if the data actually changed
570 */
571 if( !_valuesMatch( _index.data( _role ), _value ) )
572 {
573#ifdef NEVER
574 std::cout << BREAKHEADER
575 << "\n row:" << _index.row()
576 << "\n col:" << _index.column()
577 << "\n cur:" << Wt::asString( _index.data( _role ) )
578 << "\n new:" << Wt::asString( _value )
579 << std::endl;
580#endif
581
582 /*
583 ** saving to the model causes _index to be updated with the new value
584 */
585 retVal = Wt::WStandardItemModel::setData( _index, _value, _role );
586
587// saveToDisk( _index );
588
589// m_dirtyRows.insert( _index.row() );
590
591// m_goneDirty.emit( _index );
592
593// dataChanged().emit( index( _index.row(), COL_DATE ), index( _index.row(), COL_BALANCE ) );
594
595#ifdef NEVER
596 std::cout << BREAKFOOTER
597 << std::endl;
598#endif
599
600 } // endif( !_valuesMatch( _index.data( _role ), _value ) )
601
602 /*
603 ** Return success fail
604 */
605 return retVal;
606
607} // endsetData( const Wt::WModelIndex & _index, const Wt::cpp17::any & _value, Wt::ItemDataRole _role )-> bool
608
609/*!
610** \brief Refresh From Disk
611**
612** This procedure reads from the gnucash storage source (either postgres or sqlite) and loads all of the
613** transactions and their associated splits in to the model suitable for editing within an automatic
614** table view.
615*/
616auto
618refreshFromDisk()-> void
619{
620 const auto start = std::chrono::system_clock::now();
621
622 /*
623 ** this gets recomputed below
624 */
625 m_splitCount = 0;
626
627 /*
628 ** can't without an account
629 */
630 if( m_accountGuid == "" )
631 return;
632
633 /*
634 ** Signal the model is about to be reset.
635 */
636 layoutAboutToBeChanged().emit();
637
638 /*!
639 ** Before refreshing from disk, the entire contents of the
640 ** model are cleared, so it is important to make sure anything
641 ** to be saved from the model is done first.
642 */
643 clear();
644
645 /*
646 ** Get the prefrence item that can inform us about prefrences
647 ** to be applied to this model.
648 */
649 auto prefrenceItem = GCW::Dbo::Prefrences::get();
650
651 /*
652 ** Get an account item loaded. This is the account that _is_ this
653 ** register.
654 */
655 auto registerAccountItem = GCW::Dbo::Accounts::byGuid( m_accountGuid );
656
657 /*
658 ** use a transaction manager for accessing everything
659 */
660 GCW::Eng::Transaction::Manager transMan( this );
661
662#ifdef NEVER
663 std::cout << __FILE__ << ":" << __LINE__
664 << " guid:" << registerAccountItem-> guid()
665 << " name:" << registerAccountItem-> name()
666 << " dbcr:" << static_cast<int>( registerAccountItem-> accountDrCr() )
667 << " type:" << static_cast<int>( registerAccountItem-> accountType() )
668 << " typn:" << registerAccountItem-> accountTypeName()
669 << std::endl;
670#endif
671
672 /*!
673 ** In order to produce a proper 'register' of items, it is important
674 ** to load the data from the 'splits' side of the transaction rather
675 ** than the transaction itself.
676 **
677 ** Note that when the splits are loaded based on the account ID, they
678 ** are returned in a std::vector(sorted_by_date) that is sorted based on
679 ** the transction date. This chosen sort method insures that the
680 ** running balance can be accurately calculated on the fly, since each
681 ** item is pulled from the vector in a sorted order, and the running
682 ** balance is included in the model row. The user can sort the user
683 ** interface later and still have the line-item-balance remain accurate.
684 */
685 auto splitItems = GCW::Dbo::Splits::byAccount( m_accountGuid );
686
687 /*
688 ** remember the split count
689 */
690 m_splitCount = splitItems.size();
691
692 /*!
693 ** Each item is processed from the vector in sequential order.
694 ** In this process we grab the contents of the split, and
695 ** generate a model item row containing all of the column values.
696 ** Maintain a running balance as we go along to keep the balance
697 ** reflected within the view. The result is a multi-column row
698 ** item that is added to the model. This allows the model to be
699 ** subsequently re-sorted or subset-extracted without affecting
700 ** the running balances and so forth.
701 */
702 m_balance = GCW_NUMERIC( 0 );
703 for( auto splitItem : splitItems )
704 {
705 transMan.setSplitItem( splitItem );
706
707 /*
708 ** BUGBUG: Depending on the condition of the database, in the odd chance that something
709 ** has gone corrupted, this will more-or-less mask the issue, by simply
710 ** stepping over this split that appears to be in bad shape. Ideally we need
711 ** to generate some sort of report at this point, but for now we'll just step
712 ** over it.
713 */
714 if( !transMan.transactionItem() )
715 continue;
716
717 transMan.appendRow( true );
718
719 } // endfor( auto splitItem : splitItems )
720
721 /*!
722 ** After all the split items are loaded, an additional ~blank~ item
723 ** is included at the end of the vector, for coding new entries.
724 */
725 if( !isReadOnly() )
726 {
727 transMan.appendEmptyRow( true );
728
729 } // endif( m_editable )
730
731 /*!
732 ** poke all the header labels in. Note that some of the labels change
733 ** depending on the account debit/credit type. We get those from the
734 ** accountDef.
735 **
736 ** \bug Needs work
737 ** this is modified a bit to allow for a default account def.
738 ** this is necessary since it is possible to ask for an account
739 ** register that is not (yet) associated to an account... this
740 ** can happen in the BillPay module when setting up a new
741 ** account for bill-pay functions. (kind of sloppy doing it here)
742 ** The first item at(0) represents the default-register settings,
743 ** suitable for any register view.
744 */
746#ifdef NO_DRCR_YET
747 if( registerAccountItem )
748 accountDef = registerAccountItem-> accountDef();
749#endif
750
751 /*!
752 ** \anchor account_type_labels
753 */
754 int col = 0;
755 setHeaderData( col++, TR( "gcw.AccountRegister.column.date" ) );
756 setHeaderData( col++, TR( "gcw.AccountRegister.column.num" ) );
757 setHeaderData( col++, TR( "gcw.AccountRegister.column.memo" ) );
758 setHeaderData( col++, TR( "gcw.AccountRegister.column." + accountDef.colAccount ) );
759 setHeaderData( col++, TR( "gcw.AccountRegister.column.reconcile" ) );
760 setHeaderData( col++, TR( "gcw.AccountRegister.column." + accountDef.colDr ) );
761 setHeaderData( col++, TR( "gcw.AccountRegister.column." + accountDef.colCr ) );
762 setHeaderData( col++, TR( "gcw.AccountRegister.column.balance" ) );
763
764 /*
765 ** Let the rest of the world know the model changed.
766 */
767 layoutChanged().emit();
768
769 /*
770 ** load time
771 */
772 std::cout << __FILE__ << ":" << __LINE__
773 << " " << std::chrono::duration_cast< std::chrono::milliseconds >
774 ( std::chrono::system_clock::now() - start ).count()
775 << "mS load time for"
776 << " " << splitCount() << " items"
777 << std::endl;
778
779} // endrefreshFromDisk()-> void
780
781auto
783makeRow( const std::string & _splitGuid )-> GCW::Gui::AccountRegister::Model::RowItem
784{
785 RowItem rowItem;
786
787 return rowItem;
788
789} // endmakeRow( const std::string & _splitGuid )-> GCW::Gui::AccountRegisterModel::RowItem
790
791auto
793suggestionsFromColumn( int _column ) const-> std::set< std::string >
794{
795 /*
796 ** First, make a set of unique values.
797 */
798 std::set< std::string > retVal;
799 for( int row=0; row< rowCount(); row++ )
800 retVal.insert( Wt::asString( item( row, _column )-> text() ).toUTF8() );
801
802 return retVal;
803
804} // endsuggestionsFromColumn( int _column ) const-> std::set< std::string >
805
806auto
808setStyleClass( int _row, const std::string & _class )-> void
809{
810
811
812} // endsetStyleClass( int _row, const std::string & _class )-> void
813
814auto
816removeStyleClass( int _row, const std::string & _class )-> void
817{
818
819} // endremoveStyleClass( int _row, const std::string & _class )-> void
820
821
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 appendRow(bool _editable) -> 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 setValue(GCW_NUMERIC _value) -> void
auto appendEmptyRow(bool _editable) -> 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:808
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:816
auto refreshFromDisk() -> void
Refresh From Disk.
Definition Model.cpp:618
auto getDescription(const Wt::WModelIndex &_index) -> std::string
Get Description.
Definition Model.cpp:264
auto getSplitRow(const std::string &_guid) -> int
Definition Model.cpp:366
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:481
auto makeRow(const std::string &_splitGuid) -> RowItem
Definition Model.cpp:783
auto suggestionsFromColumn(int _column) const -> std::set< std::string >
Column Suggestions.
Definition Model.cpp:793
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_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:76
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