[report] Load all intermediate balances in transcript (bug 147)
[abstract.git] / report / aaTranscript.cpp
blobb909d5fe7c46b269a98a5b1ebaeeb7a825f3d48d
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent tw=79 ft=cpp: */
3 /*
4 * Copyright (C) 2007 Sergey Yanovich <ynvich@gmail.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include "xpcom-config.h"
24 #include "nsCOMPtr.h"
25 #include "nsComponentManagerUtils.h"
26 #include "nsIArray.h"
27 #include "nsStringAPI.h"
29 /* Unfrozen API */
30 #include "mozIStorageConnection.h"
32 /* Project includes */
33 #include "nsStringUtils.h"
34 #include "aaIFlow.h"
35 #include "aaIBalance.h"
36 #include "aaIFilter.h"
37 #include "aaIStateFilter.h"
38 #include "aaIDiffFilter.h"
39 #include "aaBaseLoaders.h"
40 #include "aaAccountLoaders.h"
41 #include "aaStorageUtils.h"
42 #include "aaTranscriptCounter.h"
43 #include "aaDiffCounter.h"
45 #include "aaTranscript.h"
47 aaTranscript::aaTranscript(nsISupports *aOuter)
49 nsCOMPtr<mozIStorageConnection> connection = do_QueryInterface(aOuter);
51 mOpeningBalance = do_CreateInstance(AA_LOADBALANCE_CONTRACT_ID, connection);
52 mOpeningIncome = do_CreateInstance(AA_LOADINCOME_CONTRACT_ID, connection);
53 mOpening = mOpeningBalance;
54 if (!mOpening)
55 return;
57 mClosingBalance = do_CreateInstance(AA_LOADBALANCE_CONTRACT_ID, connection);
58 mClosingIncome = do_CreateInstance(AA_LOADINCOME_CONTRACT_ID, connection);
59 mClosing = mClosingBalance;
60 if (!mClosing)
61 return;
63 mOpeningFilter = do_CreateInstance(AA_STATEFILTER_CONTRACT_ID);
64 if (!mOpeningFilter)
65 return;
67 mClosingFilter = do_CreateInstance(AA_STATEFILTER_CONTRACT_ID);
68 if (!mClosingFilter)
69 return;
71 mDiffFilter = do_CreateInstance(AA_DIFFFILTER_CONTRACT_ID);
72 if (!mDiffFilter)
73 return;
75 mList = do_CreateInstance(AA_LOADFACTLIST_CONTRACT_ID, connection);
76 mListInternal = do_QueryInterface(mList);
77 if (!mListInternal)
78 return;
80 mDiffList = do_CreateInstance(AA_LOADBALANCE_CONTRACT_ID, connection);
81 mDiffListInternal = do_QueryInterface(mDiffList);
82 if (!mDiffListInternal)
83 return;
85 mConnection = connection;
88 aaTranscript::~aaTranscript()
92 NS_IMPL_ISUPPORTS4(aaTranscript,
93 nsIArray,
94 aaILoadQuery,
95 aaIFilter,
96 aaITranscript)
98 /* aaILoadQuery */
99 NS_IMETHODIMP
100 aaTranscript::Load()
102 NS_ENSURE_TRUE(mFlow, NS_ERROR_NOT_INITIALIZED);
103 nsresult rv;
104 if (mFlow->PickId()) {
105 mOpening = mOpeningBalance;
106 mClosing = mClosingBalance;
107 } else {
108 mOpening = mOpeningIncome;
109 mClosing = mClosingIncome;
111 mOpeningFilter->SetFlow( mFlow );
112 mOpeningFilter->SetDate( mStart );
113 mOpening->SetFilter( mOpeningFilter );
115 mClosingFilter->SetFlow( mFlow );
116 mClosingFilter->SetDate( mEnd );
117 mClosing->SetFilter( mClosingFilter );
119 rv = mOpening->Load();
120 NS_ENSURE_SUCCESS(rv, rv);
122 rv = mClosing->Load();
123 NS_ENSURE_SUCCESS(rv, rv);
125 mDiffFilter->SetFlow(mFlow);
126 mDiffFilter->SetStartDate(mStart);
127 mDiffFilter->SetEndDate(mEnd);
128 mDiffList->SetFilter(mDiffFilter);
130 aaDiffCounter diffCounter;
131 mDiffListInternal->SetLoadObserver(&diffCounter);
132 rv = mDiffList->Load();
133 NS_ENSURE_SUCCESS(rv, rv);
135 aaTranscriptCounter counter(mFlow->PickId());
136 mListInternal->SetLoadObserver(&counter);
137 mList->SetFilter(this);
138 rv = mList->Load();
139 mList->SetFilter(nsnull);
140 NS_ENSURE_SUCCESS(rv, rv);
141 mTotalDebits = counter.GetDebits();
142 mTotalCredits = counter.GetCredits();
143 mTotalDebitsValue = counter.GetDebitsValue() + diffCounter.GetDebits();
144 mTotalCreditsValue = counter.GetCreditsValue() + diffCounter.GetCredits();
145 nsCOMPtr<aaIBalance> balance;
146 GetOpening(getter_AddRefs(balance));
147 if (balance && balance->PickSide()) {
148 mTotalDebitsValue -= balance->PickDiff();
149 } else if (balance) {
150 mTotalCredits -= balance->PickDiff();
152 if (balance && balance->PickSide()) {
153 mTotalDebitsValue += balance->PickDiff();
154 } else if (balance) {
155 mTotalCredits += balance->PickDiff();
158 mLoadedFlow = mFlow;
159 return NS_OK;
162 NS_IMETHODIMP
163 aaTranscript::GetFilter(aaIFilter * * aFilter)
165 return NS_ERROR_NOT_IMPLEMENTED;
167 NS_IMETHODIMP
168 aaTranscript::SetFilter(aaIFilter * aFilter)
170 return NS_ERROR_NOT_IMPLEMENTED;
172 aaIFilter *
173 aaTranscript::PickFilter()
175 return nsnull;
178 /* aaITranscript */
179 NS_IMETHODIMP
180 aaTranscript::GetFlow(aaIFlow * *aFlow)
182 NS_ENSURE_ARG_POINTER(aFlow);
183 NS_IF_ADDREF(*aFlow = mFlow);
184 return NS_OK;
186 NS_IMETHODIMP
187 aaTranscript::SetFlow(aaIFlow * aFlow)
189 mFlow = aFlow;
190 return NS_OK;
192 aaIFlow *
193 aaTranscript::PickLoadedFlow()
195 return mLoadedFlow;
198 NS_IMETHODIMP
199 aaTranscript::GetStart(PRTime *aStart)
201 NS_ENSURE_ARG_POINTER(aStart);
202 *aStart = mStart;
203 return NS_OK;
205 NS_IMETHODIMP
206 aaTranscript::SetStart(PRTime aStart)
208 mStart = aStart;
209 return NS_OK;
212 NS_IMETHODIMP
213 aaTranscript::GetEnd(PRTime *aEnd)
215 NS_ENSURE_ARG_POINTER(aEnd);
216 *aEnd = mEnd;
217 return NS_OK;
219 NS_IMETHODIMP
220 aaTranscript::SetEnd(PRTime aEnd)
222 mEnd = aEnd;
223 return NS_OK;
226 NS_IMETHODIMP
227 aaTranscript::GetOpening(aaIBalance * *aOpen)
229 nsresult rv;
230 NS_ENSURE_ARG_POINTER(aOpen);
231 NS_ENSURE_TRUE(mOpening, NS_ERROR_UNEXPECTED);
233 PRUint32 count;
234 rv = mOpening->GetLength(&count);
235 NS_ENSURE_SUCCESS(rv, rv);
236 if (count) {
237 return mOpening->QueryElementAt(0, NS_GET_IID(aaIBalance), (void **) aOpen);
240 *aOpen = nsnull;
241 return NS_OK;
244 NS_IMETHODIMP
245 aaTranscript::GetClosing(aaIBalance * *aClose)
247 nsresult rv;
248 NS_ENSURE_ARG_POINTER(aClose);
249 NS_ENSURE_TRUE(mClosing, NS_ERROR_UNEXPECTED);
251 PRUint32 count;
252 rv = mClosing->GetLength(&count);
253 NS_ENSURE_SUCCESS(rv, rv);
254 if (count) {
255 return mClosing->QueryElementAt(0, NS_GET_IID(aaIBalance), (void **) aClose);
258 *aClose = nsnull;
259 return NS_OK;
262 NS_IMETHODIMP
263 aaTranscript::GetTotalDebits(double *aTotalDebits)
265 NS_ENSURE_ARG_POINTER(aTotalDebits);
267 *aTotalDebits = mTotalDebits;
268 return NS_OK;
271 NS_IMETHODIMP
272 aaTranscript::GetTotalCredits(double *aTotalCredits)
274 NS_ENSURE_ARG_POINTER(aTotalCredits);
276 *aTotalCredits = mTotalCredits;
277 return NS_OK;
280 NS_IMETHODIMP
281 aaTranscript::GetTotalDebitsValue(double *aTotalDebitsValue)
283 NS_ENSURE_ARG_POINTER(aTotalDebitsValue);
285 *aTotalDebitsValue = mTotalDebitsValue;
286 return NS_OK;
289 NS_IMETHODIMP
290 aaTranscript::GetTotalCreditsValue(double *aTotalCreditsValue)
292 NS_ENSURE_ARG_POINTER(aTotalCreditsValue);
294 *aTotalCreditsValue = mTotalCreditsValue;
295 return NS_OK;
298 /* aaIFilter */
299 NS_IMETHODIMP
300 aaTranscript::GetExpression(nsACString & aExpression)
302 NS_ENSURE_TRUE(mFlow, NS_ERROR_NOT_INITIALIZED);
304 if (mFlow->PickId()) {
305 aExpression.Assign(" WHERE txn.day>");
306 AppendInt(aExpression, aa_julian_day(mOpeningFilter->PickDate()));
307 aExpression.Append(" AND txn.day<=");
308 AppendInt(aExpression, aa_julian_day(mClosingFilter->PickDate()));
309 aExpression.Append(" AND (toF.flow_id=");
310 AppendInt(aExpression, mOpeningFilter->PickFlow()->PickId());
311 aExpression.Append(" OR fromF.flow_id=");
312 AppendInt(aExpression, mOpeningFilter->PickFlow()->PickId());
313 aExpression.Append(")");
314 } else {
315 aExpression.Assign(" WHERE txn.day>");
316 AppendInt(aExpression, aa_julian_day(mOpeningFilter->PickDate()));
317 aExpression.Append(" AND txn.day<=");
318 AppendInt(aExpression, aa_julian_day(mClosingFilter->PickDate()));
319 aExpression.Append(" AND txn.status=1");
321 return NS_OK;