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