001: /*
002: *
003: * JMoney - A Personal Finance Manager
004: * Copyright (c) 2002 Johann Gyger <johann.gyger@switzerland.org>
005: * Copyright (c) 2004 Nigel Westbury <westbury@users.sourceforge.net>
006: *
007: *
008: * This program is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License as published by
010: * the Free Software Foundation; either version 2 of the License, or
011: * (at your option) any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package net.sf.jmoney.stocks;
025:
026: import net.sf.jmoney.model2.CapitalAccount;
027: import net.sf.jmoney.model2.Commodity;
028: import net.sf.jmoney.model2.Currency;
029: import net.sf.jmoney.model2.Entry;
030: import net.sf.jmoney.model2.IListManager;
031: import net.sf.jmoney.model2.IObjectKey;
032: import net.sf.jmoney.model2.IValues;
033: import net.sf.jmoney.model2.IncomeExpenseAccount;
034: import net.sf.jmoney.model2.ListKey;
035:
036: /**
037: * The data model for an account.
038: */
039: public class StockAccount extends CapitalAccount {
040:
041: /**
042: * Guaranteed non-null because the session default currency is
043: * set by default.
044: */
045: IObjectKey currencyKey;
046:
047: protected String brokerageFirm = null;
048:
049: protected String accountNumber = null;
050:
051: /**
052: * A table that allows the commission to be calculated based
053: * on the amount of any purchase. Null indicates no rate table
054: * is available in which case the user must enter the
055: * amount.
056: */
057: protected RatesTable buyCommissionRates;
058:
059: /**
060: * A table that allows the commission to be calculated based
061: * on the amount of any sale. Null indicates no rate table
062: * is available in which case the user must enter the
063: * amount.
064: */
065: protected RatesTable sellCommissionRates;
066:
067: /**
068: * The income account into which all dividends from stock in this
069: * account are entered.
070: */
071: IObjectKey dividendAccountKey;
072:
073: /**
074: * The income account into which any tax withholding on dividends from stock in this
075: * account are entered.
076: */
077: IObjectKey withholdingTaxAccountKey;
078:
079: /**
080: * The expense account into which all buy and sell commissions
081: * are entered.
082: */
083: IObjectKey commissionAccountKey;
084:
085: /**
086: * The name of this tax. For example, in the UK a transfer
087: * stamp is charged so you might want to call this tax
088: * "Transfer Stamp".
089: */
090: protected String tax1Name = "Tax 1";
091:
092: /**
093: * A table that allows a tax to be calculated from the
094: * amount of any purchase. Null indicates no rate table
095: * is available in which case the user must enter the
096: * amount.
097: *
098: * For example, in the UK a transfer stamp is charged
099: * on every purchase/sale.
100: */
101: protected RatesTable tax1Rates;
102:
103: /**
104: * The expense account into which all amounts of
105: * tax 1 are entered.
106: */
107: IObjectKey tax1AccountKey;
108:
109: /**
110: * The name of this tax. For example, in the UK a PTM Levy
111: * is charged so you might want to call this tax
112: * "PTM Levy".
113: */
114: protected String tax2Name = "Tax 2";
115:
116: /**
117: * A table that allows a tax to be calculated from the
118: * amount of any purchase. Null indicates no rate table
119: * is available in which case the user must enter the
120: * amount.
121: *
122: * For example, in the UK a PTM levy is charged
123: * on every purchase/sale.
124: */
125: protected RatesTable tax2Rates;
126:
127: /**
128: * The expense account into which all amounts of
129: * tax 1 are entered.
130: */
131: IObjectKey tax2AccountKey;
132:
133: /**
134: * The full constructor for a StockAccount object. This constructor is called
135: * only be the datastore when loading data from the datastore. The properties
136: * passed to this constructor must be valid because datastores should only pass back
137: * values that were previously saved from a StockAccount object. So, for example,
138: * we can be sure that a non-null name and currency are passed to this constructor.
139: *
140: * @param name the name of the account
141: */
142: public StockAccount(IObjectKey objectKey, ListKey parentKey,
143: String name, IListManager<CapitalAccount> subAccounts,
144: String abbreviation, String comment,
145: IObjectKey currencyKey, String brokerageFirm,
146: String accountNumber, String tax1Name, String tax2Name,
147: IObjectKey commissionAccountKey, IObjectKey tax1AccountKey,
148: IObjectKey tax2AccountKey, RatesTable buyCommissionRates,
149: RatesTable sellCommissionRates, RatesTable tax1Rates,
150: RatesTable tax2Rates,
151:
152: IValues extensionValues) {
153:
154: super (objectKey, parentKey, name, subAccounts, abbreviation,
155: comment, extensionValues);
156:
157: /*
158: * The currency for this account is not allowed to be null, because
159: * users of this class may assume it to be non-null and would not know
160: * how to handle this account if it were null.
161: *
162: * If null is passed, set to the default currency for the session.
163: * This is guaranteed to be never null.
164: */
165: if (currencyKey != null) {
166: this .currencyKey = currencyKey;
167: } else {
168: this .currencyKey = objectKey.getSession()
169: .getDefaultCurrency().getObjectKey();
170: }
171:
172: this .brokerageFirm = brokerageFirm;
173: this .accountNumber = accountNumber;
174: this .tax1Name = tax1Name;
175: this .tax2Name = tax2Name;
176: this .commissionAccountKey = commissionAccountKey;
177: this .tax1AccountKey = tax1AccountKey;
178: this .tax2AccountKey = tax2AccountKey;
179: this .buyCommissionRates = buyCommissionRates;
180: this .sellCommissionRates = sellCommissionRates;
181: this .tax1Rates = tax1Rates;
182: this .tax2Rates = tax2Rates;
183: }
184:
185: public StockAccount(IObjectKey objectKey, ListKey parent) {
186: super (objectKey, parent);
187:
188: // Overwrite the default name with our own default name.
189: name = "New Stock Account";
190:
191: this .currencyKey = objectKey.getSession().getDefaultCurrency()
192: .getObjectKey();
193: this .brokerageFirm = null;
194: this .accountNumber = null;
195:
196: this .buyCommissionRates = new RatesTable();
197: this .sellCommissionRates = new RatesTable();
198: this .tax1Rates = new RatesTable();
199: this .tax2Rates = new RatesTable();
200: }
201:
202: @Override
203: protected String getExtendablePropertySetId() {
204: return "net.sf.jmoney.stocks.stockAccount";
205: }
206:
207: public Currency getCurrency() {
208: return (Currency) currencyKey.getObject();
209: }
210:
211: /**
212: * Returns the commodity represented by the amount in this
213: * entry. If this entry represents an addition of stock to
214: * the account or a removal of stock from the account then
215: * the amount represents the amount of that stock. Otherwise
216: * the amount represents an amount in the currency for the account.
217: */
218: @Override
219: public Commodity getCommodity(Entry entry) {
220: StockEntry stockEntry = entry.getExtension(StockEntryInfo
221: .getPropertySet(), true);
222: if (stockEntry != null && stockEntry.isStockChange()) {
223: return stockEntry.getStock();
224: } else {
225: return getCurrency();
226: }
227: }
228:
229: /**
230: * @return the bank name of this account.
231: */
232: public String getBrokerageFirm() {
233: return brokerageFirm;
234: }
235:
236: /**
237: * @return the account number of this account.
238: */
239: public String getAccountNumber() {
240: return accountNumber;
241: }
242:
243: public String getTax1Name() {
244: return tax1Name;
245: }
246:
247: public String getTax2Name() {
248: return tax2Name;
249: }
250:
251: /**
252: * @return the account that contains the dividend income for
253: * stock in this account
254: */
255: public IncomeExpenseAccount getDividendAccount() {
256: return dividendAccountKey == null ? null
257: : (IncomeExpenseAccount) dividendAccountKey.getObject();
258: }
259:
260: public IncomeExpenseAccount getWithholdingTaxAccount() {
261: return withholdingTaxAccountKey == null ? null
262: : (IncomeExpenseAccount) withholdingTaxAccountKey
263: .getObject();
264: }
265:
266: public IncomeExpenseAccount getCommissionAccount() {
267: return commissionAccountKey == null ? null
268: : (IncomeExpenseAccount) commissionAccountKey
269: .getObject();
270: }
271:
272: public IncomeExpenseAccount getTax1Account() {
273: return tax1AccountKey == null ? null
274: : (IncomeExpenseAccount) tax1AccountKey.getObject();
275: }
276:
277: public IncomeExpenseAccount getTax2Account() {
278: return tax2AccountKey == null ? null
279: : (IncomeExpenseAccount) tax2AccountKey.getObject();
280: }
281:
282: public RatesTable getBuyCommissionRates() {
283: return buyCommissionRates;
284: }
285:
286: public RatesTable getSellCommissionRates() {
287: return sellCommissionRates;
288: }
289:
290: public RatesTable getTax1Rates() {
291: return tax1Rates;
292: }
293:
294: public RatesTable getTax2Rates() {
295: return tax2Rates;
296: }
297:
298: public void setCurrency(Currency aCurrency) {
299: if (aCurrency == null)
300: throw new IllegalArgumentException();
301: Currency oldCurrency = getCurrency();
302: currencyKey = aCurrency.getObjectKey();
303:
304: // Notify the change manager.
305: processPropertyChange(StockAccountInfo.getCurrencyAccessor(),
306: oldCurrency, aCurrency);
307: }
308:
309: /**
310: * @param aBank the name of this account.
311: */
312:
313: public void setBrokerageFirm(String brokerageFirm) {
314: String oldBrokerageFirm = this .brokerageFirm;
315: this .brokerageFirm = brokerageFirm;
316:
317: // Notify the change manager.
318: processPropertyChange(StockAccountInfo
319: .getBrokerageFirmAccessor(), oldBrokerageFirm,
320: brokerageFirm);
321: }
322:
323: public void setAccountNumber(String accountNumber) {
324: String oldAccountNumber = this .accountNumber;
325: this .accountNumber = accountNumber;
326:
327: // Notify the change manager.
328: processPropertyChange(StockAccountInfo
329: .getAccountNumberAccessor(), oldAccountNumber,
330: accountNumber);
331: }
332:
333: public void setTax1Name(String newTaxName) {
334: String oldTaxName = this .tax1Name;
335: this .tax1Name = newTaxName;
336:
337: // Notify the change manager.
338: processPropertyChange(StockAccountInfo.getTax1NameAccessor(),
339: oldTaxName, newTaxName);
340: }
341:
342: public void setTax2Name(String newTaxName) {
343: String oldTaxName = this .tax2Name;
344: this .tax2Name = newTaxName;
345:
346: // Notify the change manager.
347: processPropertyChange(StockAccountInfo.getTax2NameAccessor(),
348: oldTaxName, newTaxName);
349: }
350:
351: public void setDividendAccount(IncomeExpenseAccount newAccount) {
352: IncomeExpenseAccount oldAccount = getDividendAccount();
353: dividendAccountKey = newAccount == null ? null : newAccount
354: .getObjectKey();
355:
356: // Notify the change manager.
357: processPropertyChange(StockAccountInfo
358: .getDividendAccountAccessor(), oldAccount, newAccount);
359: }
360:
361: public void setWithholdingTaxAccount(IncomeExpenseAccount newAccount) {
362: IncomeExpenseAccount oldAccount = getWithholdingTaxAccount();
363: withholdingTaxAccountKey = newAccount == null ? null
364: : newAccount.getObjectKey();
365:
366: // Notify the change manager.
367: processPropertyChange(StockAccountInfo
368: .getWithholdingTaxAccountAccessor(), oldAccount,
369: newAccount);
370: }
371:
372: public void setCommissionAccount(IncomeExpenseAccount newAccount) {
373: IncomeExpenseAccount oldAccount = getCommissionAccount();
374: commissionAccountKey = newAccount == null ? null : newAccount
375: .getObjectKey();
376:
377: // Notify the change manager.
378: processPropertyChange(StockAccountInfo
379: .getCommissionAccountAccessor(), oldAccount, newAccount);
380: }
381:
382: public void setTax1Account(IncomeExpenseAccount newAccount) {
383: IncomeExpenseAccount oldAccount = getTax1Account();
384: tax1AccountKey = newAccount == null ? null : newAccount
385: .getObjectKey();
386:
387: // Notify the change manager.
388: processPropertyChange(
389: StockAccountInfo.getTax1AccountAccessor(), oldAccount,
390: newAccount);
391: }
392:
393: public void setTax2Account(IncomeExpenseAccount newAccount) {
394: IncomeExpenseAccount oldAccount = getTax2Account();
395: tax2AccountKey = newAccount == null ? null : newAccount
396: .getObjectKey();
397:
398: // Notify the change manager.
399: processPropertyChange(
400: StockAccountInfo.getTax2AccountAccessor(), oldAccount,
401: newAccount);
402: }
403:
404: public void setBuyCommissionRates(RatesTable newCommissionRates) {
405: RatesTable oldCommissionRates = this .buyCommissionRates;
406: this .buyCommissionRates = newCommissionRates;
407:
408: // Notify the change manager.
409: processPropertyChange(StockAccountInfo
410: .getBuyCommissionRatesAccessor(), oldCommissionRates,
411: newCommissionRates);
412: }
413:
414: public void setSellCommissionRates(RatesTable newCommissionRates) {
415: RatesTable oldCommissionRates = this .sellCommissionRates;
416: this .sellCommissionRates = newCommissionRates;
417:
418: // Notify the change manager.
419: processPropertyChange(StockAccountInfo
420: .getSellCommissionRatesAccessor(), oldCommissionRates,
421: newCommissionRates);
422: }
423:
424: public void setTax1Rates(RatesTable newTaxRates) {
425: RatesTable oldTaxRates = this .tax1Rates;
426: this .tax1Rates = newTaxRates;
427:
428: // Notify the change manager.
429: processPropertyChange(StockAccountInfo.getTax1RatesAccessor(),
430: oldTaxRates, newTaxRates);
431: }
432:
433: public void setTax2Rates(RatesTable newTaxRates) {
434: RatesTable oldTaxRates = this .tax2Rates;
435: this .tax2Rates = newTaxRates;
436:
437: // Notify the change manager.
438: processPropertyChange(StockAccountInfo.getTax2RatesAccessor(),
439: oldTaxRates, newTaxRates);
440: }
441: }
|