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