View Javadoc
1   /*
2    * MoneyWise: Finance Application
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.moneywise.quicken.file;
18  
19  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
20  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
21  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
22  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseCash;
23  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDeposit;
24  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseLoan;
25  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePortfolio;
26  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransAsset;
27  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryClass;
28  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseDepositCategoryClass;
29  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseLoanCategoryClass;
30  import io.github.tonywasher.joceanus.moneywise.quicken.definitions.MoneyWiseQAccountLineType;
31  import io.github.tonywasher.joceanus.moneywise.quicken.file.MoneyWiseQIFLine.MoneyWiseQIFMoneyLine;
32  import io.github.tonywasher.joceanus.moneywise.quicken.file.MoneyWiseQIFLine.MoneyWiseQIFStringLine;
33  
34  import java.util.HashMap;
35  import java.util.List;
36  import java.util.Map;
37  import java.util.Map.Entry;
38  
39  /**
40   * Class representing a QIF Account record.
41   */
42  public class MoneyWiseQIFAccount
43          extends MoneyWiseQIFRecord<MoneyWiseQAccountLineType>
44          implements Comparable<MoneyWiseQIFAccount> {
45      /**
46       * Item type.
47       */
48      protected static final String QIF_HDR = "!Account";
49  
50      /**
51       * Bank Account Type.
52       */
53      protected static final String QIFACT_BANK = "Bank";
54  
55      /**
56       * Cash Account Type.
57       */
58      protected static final String QIFACT_CASH = "Cash";
59  
60      /**
61       * Investment Account Type.
62       */
63      protected static final String QIFACT_INVST = "Invst";
64  
65      /**
66       * Credit Card Account Type.
67       */
68      protected static final String QIFACT_CCARD = "CCard";
69  
70      /**
71       * Asset Account Type.
72       */
73      protected static final String QIFACT_ASSET = "Oth A";
74  
75      /**
76       * Loan Account Type.
77       */
78      protected static final String QIFACT_LOAN = "Oth L";
79  
80      /**
81       * Category Map.
82       */
83      protected static final Map<Enum<?>, String> QIF_ACTCATMAP = createClassMap();
84  
85      /**
86       * The Account Name.
87       */
88      private final String theName;
89  
90      /**
91       * The Account Description.
92       */
93      private final String theDesc;
94  
95      /**
96       * The Account CategoryClass.
97       */
98      private final Enum<?> theClass;
99  
100     /**
101      * Constructor.
102      *
103      * @param pFile    the QIF File
104      * @param pAccount the Account
105      */
106     public MoneyWiseQIFAccount(final MoneyWiseQIFFile pFile,
107                                final MoneyWiseTransAsset pAccount) {
108         /* Call super-constructor */
109         super(pFile, MoneyWiseQAccountLineType.class);
110 
111         /* Store data */
112         theName = pAccount.getName();
113 
114         /* Handle deposit */
115         if (pAccount instanceof MoneyWiseDeposit myDeposit) {
116             theClass = myDeposit.getCategoryClass();
117             theDesc = myDeposit.getDesc();
118 
119             /* Handle cash */
120         } else if (pAccount instanceof MoneyWiseCash myCash) {
121             theClass = myCash.getCategoryClass();
122             theDesc = myCash.getDesc();
123 
124             /* Handle loan */
125         } else if (pAccount instanceof MoneyWiseLoan myLoan) {
126             theClass = myLoan.getCategoryClass();
127             theDesc = myLoan.getDesc();
128 
129             /* Handle portfolio */
130         } else if (pAccount instanceof MoneyWisePortfolio myPortfolio) {
131             theClass = MoneyWiseBasicDataType.PORTFOLIO;
132             theDesc = myPortfolio.getDesc();
133         } else {
134             throw new IllegalArgumentException();
135         }
136 
137         /* Build lines */
138         addLine(new MoneyWiseQIFAccountNameLine(theName));
139         if (theDesc != null) {
140             addLine(new MoneyWiseQIFAccountDescLine(theDesc));
141         }
142         addLine(new MoneyWiseQIFAccountTypeLine(theClass));
143     }
144 
145     /**
146      * Constructor for holding account.
147      *
148      * @param pFile the QIF File
149      * @param pName the Portfolio Name
150      */
151     protected MoneyWiseQIFAccount(final MoneyWiseQIFFile pFile,
152                                   final String pName) {
153         /* Call super-constructor */
154         super(pFile, MoneyWiseQAccountLineType.class);
155 
156         /* Store data */
157         theName = pName;
158         theClass = MoneyWiseDepositCategoryClass.SAVINGS;
159         theDesc = null;
160 
161         /* Build lines */
162         addLine(new MoneyWiseQIFAccountNameLine(theName));
163         addLine(new MoneyWiseQIFAccountTypeLine(theClass));
164     }
165 
166     /**
167      * Constructor.
168      *
169      * @param pFile      the QIF File
170      * @param pFormatter the formatter
171      * @param pLines     the data lines
172      */
173     protected MoneyWiseQIFAccount(final MoneyWiseQIFFile pFile,
174                                   final OceanusDataFormatter pFormatter,
175                                   final List<String> pLines) {
176         /* Call super-constructor */
177         super(pFile, MoneyWiseQAccountLineType.class);
178 
179         /* Determine details */
180         String myName = null;
181         String myDesc = null;
182         Enum<?> myClass = null;
183 
184         /* Loop through the lines */
185         for (String myLine : pLines) {
186             /* Determine the category */
187             final MoneyWiseQAccountLineType myType = MoneyWiseQAccountLineType.parseLine(myLine);
188             if (myType != null) {
189                 /* Access data */
190                 final String myData = myLine.substring(myType.getSymbol().length());
191 
192                 /* Switch on line type */
193                 switch (myType) {
194                     case NAME:
195                         addLine(new MoneyWiseQIFAccountNameLine(myData));
196                         myName = myData;
197                         break;
198                     case DESCRIPTION:
199                         addLine(new MoneyWiseQIFAccountDescLine(myData));
200                         myDesc = myData;
201                         break;
202                     case TYPE:
203                         final MoneyWiseQIFAccountTypeLine myQLine = new MoneyWiseQIFAccountTypeLine(myData);
204                         addLine(myQLine);
205                         myClass = myQLine.getAccountClass();
206                         break;
207                     case CREDITLIMIT:
208                         final OceanusMoney myMoney = pFormatter.getDecimalParser().parseMoneyValue(myData);
209                         addLine(new MoneyWiseQIFAccountLimitLine(myMoney));
210                         break;
211                     default:
212                         break;
213                 }
214             }
215         }
216 
217         /* Build details */
218         theName = myName;
219         theDesc = myDesc;
220         theClass = myClass;
221     }
222 
223     @Override
224     public String toString() {
225         return getName();
226     }
227 
228     /**
229      * Obtain the Name.
230      *
231      * @return the Name
232      */
233     public String getName() {
234         return theName;
235     }
236 
237     /**
238      * Obtain the description.
239      *
240      * @return the Name
241      */
242     public String getDesc() {
243         return theDesc;
244     }
245 
246     /**
247      * Obtain the account type.
248      *
249      * @return the Type
250      */
251     public String getType() {
252         return QIF_ACTCATMAP.get(theClass);
253     }
254 
255     /**
256      * Create the CategoryClass to type map.
257      *
258      * @return the map
259      */
260     private static Map<Enum<?>, String> createClassMap() {
261         /* Create the map */
262         final Map<Enum<?>, String> myMap = new HashMap<>();
263 
264         /* Add the entries */
265         myMap.put(MoneyWiseDepositCategoryClass.CHECKING, QIFACT_BANK);
266         myMap.put(MoneyWiseDepositCategoryClass.SAVINGS, QIFACT_BANK);
267         myMap.put(MoneyWiseDepositCategoryClass.PEER2PEER, QIFACT_BANK);
268         myMap.put(MoneyWiseDepositCategoryClass.BOND, QIFACT_BANK);
269         myMap.put(MoneyWiseCashCategoryClass.CASH, QIFACT_CASH);
270         myMap.put(MoneyWiseCashCategoryClass.AUTOEXPENSE, QIFACT_CASH);
271         myMap.put(MoneyWiseLoanCategoryClass.CREDITCARD, QIFACT_CCARD);
272         myMap.put(MoneyWiseBasicDataType.PORTFOLIO, QIFACT_INVST);
273         myMap.put(MoneyWiseLoanCategoryClass.PRIVATELOAN, QIFACT_ASSET);
274         myMap.put(MoneyWiseLoanCategoryClass.LOAN, QIFACT_LOAN);
275 
276         /* Return the map */
277         return myMap;
278     }
279 
280     @Override
281     public int compareTo(final MoneyWiseQIFAccount pThat) {
282         return theName.compareTo(pThat.getName());
283     }
284 
285     /**
286      * The Account Name line.
287      */
288     public static class MoneyWiseQIFAccountNameLine
289             extends MoneyWiseQIFStringLine<MoneyWiseQAccountLineType> {
290         /**
291          * Constructor.
292          *
293          * @param pName the Name
294          */
295         protected MoneyWiseQIFAccountNameLine(final String pName) {
296             /* Call super-constructor */
297             super(pName);
298         }
299 
300         @Override
301         public MoneyWiseQAccountLineType getLineType() {
302             return MoneyWiseQAccountLineType.NAME;
303         }
304 
305         /**
306          * Obtain name.
307          *
308          * @return the name
309          */
310         public String getName() {
311             return getValue();
312         }
313     }
314 
315     /**
316      * The Security Symbol line.
317      */
318     public static class MoneyWiseQIFAccountDescLine
319             extends MoneyWiseQIFStringLine<MoneyWiseQAccountLineType> {
320         /**
321          * Constructor.
322          *
323          * @param pDesc the Description
324          */
325         protected MoneyWiseQIFAccountDescLine(final String pDesc) {
326             /* Call super-constructor */
327             super(pDesc);
328         }
329 
330         @Override
331         public MoneyWiseQAccountLineType getLineType() {
332             return MoneyWiseQAccountLineType.DESCRIPTION;
333         }
334 
335         /**
336          * Obtain description.
337          *
338          * @return the description
339          */
340         public String getDesc() {
341             return getValue();
342         }
343     }
344 
345     /**
346      * The Account Type line.
347      */
348     public static class MoneyWiseQIFAccountTypeLine
349             extends MoneyWiseQIFStringLine<MoneyWiseQAccountLineType> {
350         /**
351          * The Account Category Class.
352          */
353         private final Enum<?> theClass;
354 
355         /**
356          * Constructor.
357          *
358          * @param pClass the Account Class
359          */
360         protected MoneyWiseQIFAccountTypeLine(final Enum<?> pClass) {
361             /* Call super-constructor */
362             super(QIF_ACTCATMAP.get(pClass));
363 
364             /* Record the class */
365             theClass = pClass;
366         }
367 
368         /**
369          * Constructor.
370          *
371          * @param pType the Account Type
372          */
373         protected MoneyWiseQIFAccountTypeLine(final String pType) {
374             /* Call super-constructor */
375             super(pType);
376 
377             /* Loop through the map entries */
378             Enum<?> myClass = null;
379             for (Entry<Enum<?>, String> myEntry : QIF_ACTCATMAP.entrySet()) {
380                 /* If we have a match */
381                 if (pType.equals(myEntry.getValue())) {
382                     myClass = myEntry.getKey();
383                     break;
384                 }
385             }
386 
387             /* Store the class */
388             theClass = myClass;
389         }
390 
391         @Override
392         public MoneyWiseQAccountLineType getLineType() {
393             return MoneyWiseQAccountLineType.TYPE;
394         }
395 
396         @Override
397         public String toString() {
398             return theClass.toString();
399         }
400 
401         /**
402          * Obtain account class.
403          *
404          * @return the account class
405          */
406         public Enum<?> getAccountClass() {
407             return theClass;
408         }
409     }
410 
411     /**
412      * The Account Credit Limit line.
413      */
414     public static class MoneyWiseQIFAccountLimitLine
415             extends MoneyWiseQIFMoneyLine<MoneyWiseQAccountLineType> {
416         /**
417          * Constructor.
418          *
419          * @param pLimit the Credit Limit
420          */
421         protected MoneyWiseQIFAccountLimitLine(final OceanusMoney pLimit) {
422             /* Call super-constructor */
423             super(pLimit);
424         }
425 
426         @Override
427         public MoneyWiseQAccountLineType getLineType() {
428             return MoneyWiseQAccountLineType.CREDITLIMIT;
429         }
430 
431         /**
432          * Obtain credit limit.
433          *
434          * @return the credit limit
435          */
436         public OceanusMoney getCreditLimit() {
437             return getMoney();
438         }
439     }
440 }