1 /*
2  * Copyright 2016-2018  Thomas Baumgart <tbaumgart@kde.org>
3  * Copyright 2017-2018  Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef LEDGERTRANSACTION_P_H
20 #define LEDGERTRANSACTION_P_H
21 
22 // ----------------------------------------------------------------------------
23 // QT Includes
24 
25 #include <QString>
26 
27 // ----------------------------------------------------------------------------
28 // KDE Includes
29 
30 #include <KLocalizedString>
31 
32 // ----------------------------------------------------------------------------
33 // Project Includes
34 
35 #include "mymoneysplit.h"
36 #include "mymoneytransaction.h"
37 #include "mymoneyfile.h"
38 #include "mymoneyaccount.h"
39 #include "mymoneypayee.h"
40 #include "mymoneymoney.h"
41 
42 class LedgerTransactionPrivate
43 {
44 public:
LedgerTransactionPrivate()45   LedgerTransactionPrivate() :
46     m_erroneous(false)
47   {
48   }
49 
~LedgerTransactionPrivate()50   virtual ~LedgerTransactionPrivate()
51   {
52   }
53 
init(const MyMoneyTransaction & t,const MyMoneySplit & s)54   void init(const MyMoneyTransaction& t, const MyMoneySplit& s)
55   {
56     m_transaction = t;
57     m_split = s;
58     // extract the payee id
59     auto payeeId = m_split.payeeId();
60     if(payeeId.isEmpty()) {
61       foreach (const auto split, m_transaction.splits()) {
62         if(!split.payeeId().isEmpty()) {
63           payeeId = split.payeeId();
64           break;
65         }
66       }
67     }
68     if(!payeeId.isEmpty()) {
69       m_payeeId = payeeId;
70       m_payeeName = MyMoneyFile::instance()->payee(payeeId).name();
71     }
72 
73     m_account = MyMoneyFile::instance()->accountToCategory(m_split.accountId());
74     m_costCenterId = m_split.costCenterId();
75 
76     // A transaction can have more than 2 splits ...
77     if(m_transaction.splitCount() > 2) {
78       m_counterAccount = i18n("Split transaction");
79 
80     // ... exactly two splits ...
81     } else if(m_transaction.splitCount() == 2) {
82       foreach (const auto split, m_transaction.splits()) {
83         if(split.id() != m_split.id()) {
84           m_counterAccountId = split.accountId();
85           m_counterAccount = MyMoneyFile::instance()->accountToCategory(m_counterAccountId);
86           // in case the own split does not have a costcenter, but the counter split does
87           // we use it nevertheless
88           if(m_costCenterId.isEmpty())
89             m_costCenterId = split.costCenterId();
90           break;
91         }
92       }
93 
94     // ... or a single split
95     } else if(!m_split.shares().isZero()) {
96       m_counterAccount = i18n("*** UNASSIGNED ***");
97     }
98 
99     // The transaction is erroneous in case it is not balanced
100     m_erroneous = !m_transaction.splitSum().isZero();
101 
102     // now take care of the values
103     setupValueDisplay();
104   }
105 
setupValueDisplay()106   void setupValueDisplay()
107   {
108     const auto file = MyMoneyFile::instance();
109     const auto acc = file->account(m_split.accountId());
110 
111     auto value = m_split.value(m_transaction.commodity(), acc.currencyId());
112     m_signedShares = value.formatMoney(acc.fraction());
113 
114     if(value.isNegative()) {
115       m_shares = m_payment = (-value).formatMoney(acc.fraction());
116     } else {
117       m_shares = m_deposit = m_signedShares;
118     }
119 
120     // figure out if it is a debit or credit split. s.a. https://en.wikipedia.org/wiki/Debits_and_credits#Aspects_of_transactions
121     if(m_split.shares().isNegative()) {
122       m_sharesSuffix = i18nc("Credit suffix", "Cr.");
123     } else {
124       m_sharesSuffix = i18nc("Debit suffix", "Dr.");
125     }
126   }
127 
128   MyMoneyTransaction  m_transaction;
129   MyMoneySplit        m_split;
130   QString             m_counterAccountId;
131   QString             m_counterAccount;
132   QString             m_account;
133   QString             m_costCenterId;
134   QString             m_payeeName;
135   QString             m_payeeId;
136   QString             m_shares;
137   QString             m_signedShares;
138   QString             m_payment;
139   QString             m_deposit;
140   QString             m_balance;
141   QString             m_sharesSuffix; // shows Cr or Dr
142   bool                m_erroneous;
143 };
144 
145 #endif // LEDGERTRANSACTION_P_H
146