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.moneywise.data.basic.MoneyWiseBasicDataType;
20  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseCash;
21  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDeposit;
22  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseLoan;
23  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePortfolio;
24  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransAsset;
25  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryClass;
26  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseDepositCategoryClass;
27  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseLoanCategoryClass;
28  import io.github.tonywasher.joceanus.moneywise.quicken.definitions.MoneyWiseQAccountLineType;
29  import io.github.tonywasher.joceanus.moneywise.quicken.file.MoneyWiseQIFLine.MoneyWiseQIFMoneyLine;
30  import io.github.tonywasher.joceanus.moneywise.quicken.file.MoneyWiseQIFLine.MoneyWiseQIFStringLine;
31  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
32  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
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         /* Switch on account */
115         switch (pAccount) {
116             case MoneyWiseDeposit myDeposit -> {
117                 theClass = myDeposit.getCategoryClass();
118                 theDesc = myDeposit.getDesc();
119             }
120             case MoneyWiseCash myCash -> {
121                 theClass = myCash.getCategoryClass();
122                 theDesc = myCash.getDesc();
123             }
124             case MoneyWiseLoan myLoan -> {
125                 theClass = myLoan.getCategoryClass();
126                 theDesc = myLoan.getDesc();
127             }
128             case MoneyWisePortfolio myPortfolio -> {
129                 theClass = MoneyWiseBasicDataType.PORTFOLIO;
130                 theDesc = myPortfolio.getDesc();
131             }
132             default -> throw new IllegalArgumentException();
133         }
134 
135         /* Build lines */
136         addLine(new MoneyWiseQIFAccountNameLine(theName));
137         if (theDesc != null) {
138             addLine(new MoneyWiseQIFAccountDescLine(theDesc));
139         }
140         addLine(new MoneyWiseQIFAccountTypeLine(theClass));
141     }
142 
143     /**
144      * Constructor for holding account.
145      *
146      * @param pFile the QIF File
147      * @param pName the Portfolio Name
148      */
149     protected MoneyWiseQIFAccount(final MoneyWiseQIFFile pFile,
150                                   final String pName) {
151         /* Call super-constructor */
152         super(pFile, MoneyWiseQAccountLineType.class);
153 
154         /* Store data */
155         theName = pName;
156         theClass = MoneyWiseDepositCategoryClass.SAVINGS;
157         theDesc = null;
158 
159         /* Build lines */
160         addLine(new MoneyWiseQIFAccountNameLine(theName));
161         addLine(new MoneyWiseQIFAccountTypeLine(theClass));
162     }
163 
164     /**
165      * Constructor.
166      *
167      * @param pFile      the QIF File
168      * @param pFormatter the formatter
169      * @param pLines     the data lines
170      */
171     protected MoneyWiseQIFAccount(final MoneyWiseQIFFile pFile,
172                                   final OceanusDataFormatter pFormatter,
173                                   final List<String> pLines) {
174         /* Call super-constructor */
175         super(pFile, MoneyWiseQAccountLineType.class);
176 
177         /* Determine details */
178         String myName = null;
179         String myDesc = null;
180         Enum<?> myClass = null;
181 
182         /* Loop through the lines */
183         for (String myLine : pLines) {
184             /* Determine the category */
185             final MoneyWiseQAccountLineType myType = MoneyWiseQAccountLineType.parseLine(myLine);
186             if (myType != null) {
187                 /* Access data */
188                 final String myData = myLine.substring(myType.getSymbol().length());
189 
190                 /* Switch on line type */
191                 switch (myType) {
192                     case NAME:
193                         addLine(new MoneyWiseQIFAccountNameLine(myData));
194                         myName = myData;
195                         break;
196                     case DESCRIPTION:
197                         addLine(new MoneyWiseQIFAccountDescLine(myData));
198                         myDesc = myData;
199                         break;
200                     case TYPE:
201                         final MoneyWiseQIFAccountTypeLine myQLine = new MoneyWiseQIFAccountTypeLine(myData);
202                         addLine(myQLine);
203                         myClass = myQLine.getAccountClass();
204                         break;
205                     case CREDITLIMIT:
206                         final OceanusMoney myMoney = pFormatter.getDecimalParser().parseMoneyValue(myData);
207                         addLine(new MoneyWiseQIFAccountLimitLine(myMoney));
208                         break;
209                     default:
210                         break;
211                 }
212             }
213         }
214 
215         /* Build details */
216         theName = myName;
217         theDesc = myDesc;
218         theClass = myClass;
219     }
220 
221     @Override
222     public String toString() {
223         return getName();
224     }
225 
226     /**
227      * Obtain the Name.
228      *
229      * @return the Name
230      */
231     public String getName() {
232         return theName;
233     }
234 
235     /**
236      * Obtain the description.
237      *
238      * @return the Name
239      */
240     public String getDesc() {
241         return theDesc;
242     }
243 
244     /**
245      * Obtain the account type.
246      *
247      * @return the Type
248      */
249     public String getType() {
250         return QIF_ACTCATMAP.get(theClass);
251     }
252 
253     /**
254      * Create the CategoryClass to type map.
255      *
256      * @return the map
257      */
258     private static Map<Enum<?>, String> createClassMap() {
259         /* Create the map */
260         final Map<Enum<?>, String> myMap = new HashMap<>();
261 
262         /* Add the entries */
263         myMap.put(MoneyWiseDepositCategoryClass.CHECKING, QIFACT_BANK);
264         myMap.put(MoneyWiseDepositCategoryClass.SAVINGS, QIFACT_BANK);
265         myMap.put(MoneyWiseDepositCategoryClass.PEER2PEER, QIFACT_BANK);
266         myMap.put(MoneyWiseDepositCategoryClass.BOND, QIFACT_BANK);
267         myMap.put(MoneyWiseCashCategoryClass.CASH, QIFACT_CASH);
268         myMap.put(MoneyWiseCashCategoryClass.AUTOEXPENSE, QIFACT_CASH);
269         myMap.put(MoneyWiseLoanCategoryClass.CREDITCARD, QIFACT_CCARD);
270         myMap.put(MoneyWiseBasicDataType.PORTFOLIO, QIFACT_INVST);
271         myMap.put(MoneyWiseLoanCategoryClass.PRIVATELOAN, QIFACT_ASSET);
272         myMap.put(MoneyWiseLoanCategoryClass.LOAN, QIFACT_LOAN);
273 
274         /* Return the map */
275         return myMap;
276     }
277 
278     @Override
279     public int compareTo(final MoneyWiseQIFAccount pThat) {
280         return theName.compareTo(pThat.getName());
281     }
282 
283     /**
284      * The Account Name line.
285      */
286     public static class MoneyWiseQIFAccountNameLine
287             extends MoneyWiseQIFStringLine<MoneyWiseQAccountLineType> {
288         /**
289          * Constructor.
290          *
291          * @param pName the Name
292          */
293         protected MoneyWiseQIFAccountNameLine(final String pName) {
294             /* Call super-constructor */
295             super(pName);
296         }
297 
298         @Override
299         public MoneyWiseQAccountLineType getLineType() {
300             return MoneyWiseQAccountLineType.NAME;
301         }
302 
303         /**
304          * Obtain name.
305          *
306          * @return the name
307          */
308         public String getName() {
309             return getValue();
310         }
311     }
312 
313     /**
314      * The Security Symbol line.
315      */
316     public static class MoneyWiseQIFAccountDescLine
317             extends MoneyWiseQIFStringLine<MoneyWiseQAccountLineType> {
318         /**
319          * Constructor.
320          *
321          * @param pDesc the Description
322          */
323         protected MoneyWiseQIFAccountDescLine(final String pDesc) {
324             /* Call super-constructor */
325             super(pDesc);
326         }
327 
328         @Override
329         public MoneyWiseQAccountLineType getLineType() {
330             return MoneyWiseQAccountLineType.DESCRIPTION;
331         }
332 
333         /**
334          * Obtain description.
335          *
336          * @return the description
337          */
338         public String getDesc() {
339             return getValue();
340         }
341     }
342 
343     /**
344      * The Account Type line.
345      */
346     public static class MoneyWiseQIFAccountTypeLine
347             extends MoneyWiseQIFStringLine<MoneyWiseQAccountLineType> {
348         /**
349          * The Account Category Class.
350          */
351         private final Enum<?> theClass;
352 
353         /**
354          * Constructor.
355          *
356          * @param pClass the Account Class
357          */
358         protected MoneyWiseQIFAccountTypeLine(final Enum<?> pClass) {
359             /* Call super-constructor */
360             super(QIF_ACTCATMAP.get(pClass));
361 
362             /* Record the class */
363             theClass = pClass;
364         }
365 
366         /**
367          * Constructor.
368          *
369          * @param pType the Account Type
370          */
371         protected MoneyWiseQIFAccountTypeLine(final String pType) {
372             /* Call super-constructor */
373             super(pType);
374 
375             /* Loop through the map entries */
376             Enum<?> myClass = null;
377             for (Entry<Enum<?>, String> myEntry : QIF_ACTCATMAP.entrySet()) {
378                 /* If we have a match */
379                 if (pType.equals(myEntry.getValue())) {
380                     myClass = myEntry.getKey();
381                     break;
382                 }
383             }
384 
385             /* Store the class */
386             theClass = myClass;
387         }
388 
389         @Override
390         public MoneyWiseQAccountLineType getLineType() {
391             return MoneyWiseQAccountLineType.TYPE;
392         }
393 
394         @Override
395         public String toString() {
396             return theClass.toString();
397         }
398 
399         /**
400          * Obtain account class.
401          *
402          * @return the account class
403          */
404         public Enum<?> getAccountClass() {
405             return theClass;
406         }
407     }
408 
409     /**
410      * The Account Credit Limit line.
411      */
412     public static class MoneyWiseQIFAccountLimitLine
413             extends MoneyWiseQIFMoneyLine<MoneyWiseQAccountLineType> {
414         /**
415          * Constructor.
416          *
417          * @param pLimit the Credit Limit
418          */
419         protected MoneyWiseQIFAccountLimitLine(final OceanusMoney pLimit) {
420             /* Call super-constructor */
421             super(pLimit);
422         }
423 
424         @Override
425         public MoneyWiseQAccountLineType getLineType() {
426             return MoneyWiseQAccountLineType.CREDITLIMIT;
427         }
428 
429         /**
430          * Obtain credit limit.
431          *
432          * @return the credit limit
433          */
434         public OceanusMoney getCreditLimit() {
435             return getMoney();
436         }
437     }
438 }