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.date.OceanusDate;
20  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
21  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
22  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseSecurityPrice;
23  import io.github.tonywasher.joceanus.moneywise.quicken.definitions.MoneyWiseQIFType;
24  
25  import java.util.ArrayList;
26  import java.util.Iterator;
27  import java.util.List;
28  
29  /**
30   * Class representing a QIF Price record.
31   */
32  public class MoneyWiseQIFPrice
33          implements Comparable<MoneyWiseQIFPrice> {
34      /**
35       * Item type.
36       */
37      protected static final String QIF_ITEM = "Prices";
38  
39      /**
40       * Quicken Quote.
41       */
42      private static final String QIF_QUOTE = "\"";
43  
44      /**
45       * Quicken Comma.
46       */
47      private static final String QIF_COMMA = ",";
48  
49      /**
50       * The file type.
51       */
52      private final MoneyWiseQIFType theFileType;
53  
54      /**
55       * The security.
56       */
57      private final MoneyWiseQIFSecurity theSecurity;
58  
59      /**
60       * The date.
61       */
62      private final OceanusDate theDate;
63  
64      /**
65       * The price.
66       */
67      private final OceanusPrice thePrice;
68  
69      /**
70       * The element list.
71       */
72      private final List<MoneyWiseQIFPrice> thePrices;
73  
74      /**
75       * Constructor.
76       *
77       * @param pFile     the QIF File
78       * @param pSecurity the security
79       * @param pPrice    the price
80       */
81      protected MoneyWiseQIFPrice(final MoneyWiseQIFFile pFile,
82                                  final MoneyWiseQIFSecurity pSecurity,
83                                  final MoneyWiseSecurityPrice pPrice) {
84          /* Store data */
85          theFileType = pFile.getFileType();
86          theSecurity = pSecurity;
87          theDate = pPrice.getDate();
88          thePrice = pPrice.getPrice();
89          thePrices = null;
90      }
91  
92      /**
93       * Constructor.
94       *
95       * @param pFile      the QIF File
96       * @param pFormatter the Data Formatter
97       * @param pLine      the line
98       */
99      private MoneyWiseQIFPrice(final MoneyWiseQIFFile pFile,
100                               final OceanusDataFormatter pFormatter,
101                               final String pLine) {
102         /* Split out the parts */
103         final String[] myParts = pLine.split(QIF_COMMA);
104 
105         /* Strip leading and trailing quotes */
106         for (int i = 0; i < myParts.length; i++) {
107             final String myStr = myParts[i];
108             if (myStr.startsWith(QIF_QUOTE)
109                     && myStr.endsWith(QIF_QUOTE)) {
110                 myParts[i] = myStr.substring(1, myStr.length() - 1);
111             }
112         }
113 
114         /* Store the data */
115         theFileType = pFile.getFileType();
116         theSecurity = pFile.getSecurityBySymbol(myParts[0]);
117         theDate = pFormatter.getDateFormatter().parseDateBase(myParts[2], MoneyWiseQIFWriter.QIF_BASEYEAR);
118         thePrice = pFormatter.getDecimalParser().parsePriceValue(myParts[1]);
119         thePrices = null;
120     }
121 
122     /**
123      * Constructor.
124      *
125      * @param pFile      the QIF File
126      * @param pFormatter the Data Formatter
127      * @param pLines     the lines
128      */
129     protected MoneyWiseQIFPrice(final MoneyWiseQIFFile pFile,
130                                 final OceanusDataFormatter pFormatter,
131                                 final List<String> pLines) {
132         /* Build the price list */
133         thePrices = new ArrayList<>();
134 
135         /* Loop through the lines */
136         MoneyWiseQIFSecurity mySecurity = null;
137         for (String myLine : pLines) {
138             /* Create the price and add to the list */
139             final MoneyWiseQIFPrice myPrice = new MoneyWiseQIFPrice(pFile, pFormatter, myLine);
140             mySecurity = myPrice.getSecurity();
141             thePrices.add(myPrice);
142         }
143 
144         /* Store the data */
145         theFileType = pFile.getFileType();
146         theSecurity = mySecurity;
147         theDate = null;
148         thePrice = null;
149     }
150 
151     /**
152      * Obtain the security.
153      *
154      * @return the security
155      */
156     public MoneyWiseQIFSecurity getSecurity() {
157         return theSecurity;
158     }
159 
160     /**
161      * Obtain the date.
162      *
163      * @return the date
164      */
165     public OceanusDate getDate() {
166         return theDate;
167     }
168 
169     /**
170      * Obtain the price.
171      *
172      * @return the security
173      */
174     public OceanusPrice getPrice() {
175         return thePrice;
176     }
177 
178     /**
179      * Obtain iterator for list.
180      *
181      * @return the iterator
182      */
183     public Iterator<MoneyWiseQIFPrice> priceIterator() {
184         return thePrices.iterator();
185     }
186 
187     /**
188      * Format record.
189      *
190      * @param pFormatter the formatter
191      * @param pBuilder   the string builder
192      */
193     protected void formatRecord(final OceanusDataFormatter pFormatter,
194                                 final StringBuilder pBuilder) {
195         /* Format the security */
196         pBuilder.append(QIF_QUOTE);
197         pBuilder.append(theSecurity.getSymbol());
198         pBuilder.append(QIF_QUOTE);
199         pBuilder.append(QIF_COMMA);
200 
201         /* Format the price */
202         if (theFileType.escapePrices()) {
203             pBuilder.append(QIF_QUOTE);
204         }
205         pBuilder.append(thePrice.toString());
206         if (theFileType.escapePrices()) {
207             pBuilder.append(QIF_QUOTE);
208         }
209         pBuilder.append(QIF_COMMA);
210 
211         /* Format the date */
212         pBuilder.append(QIF_QUOTE);
213         pBuilder.append(pFormatter.formatObject(theDate));
214         pBuilder.append(QIF_QUOTE);
215         pBuilder.append(MoneyWiseQIFRecord.QIF_EOL);
216 
217         /* Add the end of record indicator */
218         pBuilder.append(MoneyWiseQIFRecord.QIF_EOI);
219         pBuilder.append(MoneyWiseQIFRecord.QIF_EOL);
220     }
221 
222     @Override
223     public boolean equals(final Object pThat) {
224         /* Handle trivial cases */
225         if (this == pThat) {
226             return true;
227         }
228         if (pThat == null) {
229             return false;
230         }
231 
232         /* Check class */
233         if (!getClass().equals(pThat.getClass())) {
234             return false;
235         }
236 
237         /* Cast correctly */
238         final MoneyWiseQIFPrice myLine = (MoneyWiseQIFPrice) pThat;
239 
240         /* Check security */
241         if (!getSecurity().equals(myLine.getSecurity())) {
242             return false;
243         }
244 
245         /* Check price */
246         if (!getPrice().equals(myLine.getPrice())) {
247             return false;
248         }
249 
250         /* Check date */
251         return theDate.equals(myLine.getDate());
252     }
253 
254     @Override
255     public int hashCode() {
256         int myResult = MoneyWiseQIFFile.HASH_BASE * theSecurity.hashCode();
257         myResult += thePrice.hashCode();
258         myResult *= MoneyWiseQIFFile.HASH_BASE;
259         return myResult + theDate.hashCode();
260     }
261 
262     @Override
263     public int compareTo(final MoneyWiseQIFPrice pThat) {
264         return theDate.compareTo(pThat.getDate());
265     }
266 }