KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > nightlabs > ipanema > accounting > PriceConfig


1 /*
2  * Created on 28.10.2004
3  */

4 package com.nightlabs.ipanema.accounting;
5
6 import java.io.Serializable JavaDoc;
7 import java.util.Collection JavaDoc;
8 import java.util.HashMap JavaDoc;
9 import java.util.Map JavaDoc;
10
11 import javax.jdo.JDOHelper;
12 import javax.jdo.PersistenceManager;
13 import javax.jdo.StoreCallback;
14
15 import com.nightlabs.ipanema.trade.OfferItem;
16
17 /**
18  * A <tt>PriceConfig</tt> is a complete set of prices which can be assigned to a product by setting
19  * it's <tt>ProductInfo.priceConfig</tt>. This class may be inherited thus, the PriceConfig can be
20  * specialized for special products.
21  * <br/><br/>
22  * Because the prices are not hardlinked to a product but indirectly assigned via a PriceConfig, it is
23  * no problem for multiple products to share the same <tt>PriceConfig</tt>. The property <tt>PriceConfig</tt>
24  * of <tt>ProductInfo</tt> is inherited.
25  *
26  * @author Marco Schulze - marco at nightlabs dot de
27  *
28  * @jdo.persistence-capable
29  * identity-type = "application"
30  * objectid-class = "com.nightlabs.ipanema.accounting.id.PriceConfigID"
31  * detachable = "true"
32  *
33  * @jdo.inheritance strategy = "new-table"
34  */

35 public abstract class PriceConfig implements Serializable JavaDoc, StoreCallback
36 {
37     /**
38      * @jdo.field primary-key="true"
39      * @jdo.column length="100"
40      */

41     private String JavaDoc organisationID = null;
42
43     /**
44      * @jdo.field primary-key="true"
45      */

46     private long priceConfigID = -1;
47     
48     /**
49      * @jdo.field persistence-modifier="persistent"
50      */

51     private String JavaDoc primaryKey;
52
53 // protected PriceConfig extendedPriceConfig = null;
54

55     protected PriceConfig() { }
56     public PriceConfig(String JavaDoc organisationID, long priceConfigID)
57     {
58         if (organisationID == null)
59             throw new NullPointerException JavaDoc("organisationID must not be null!");
60         if (priceConfigID < 0)
61             throw new IllegalArgumentException JavaDoc("priceConfigID < 0!");
62
63         this.organisationID = organisationID;
64         this.priceConfigID = priceConfigID;
65         this.primaryKey = getPrimaryKey(organisationID, priceConfigID);
66     }
67
68     /**
69      * @return Returns the organisationID.
70      */

71     public String JavaDoc getOrganisationID()
72     {
73         return organisationID;
74     }
75     /**
76      * @return Returns the priceConfigID.
77      */

78     public long getPriceConfigID()
79     {
80         return priceConfigID;
81     }
82     public static String JavaDoc getPrimaryKey(String JavaDoc organisationID, long priceConfigID)
83     {
84         if (organisationID == null)
85             throw new NullPointerException JavaDoc("organisationID must not be null!");
86         if (priceConfigID < 0)
87             throw new IllegalArgumentException JavaDoc("priceConfigID < 0!");
88
89         return organisationID + '/' + Long.toHexString(priceConfigID);
90     }
91
92     public String JavaDoc getPrimaryKey()
93     {
94         return primaryKey;
95     }
96
97     /**
98      * Not every PriceConfig needs to know all Currencies. The usual behaviour of a
99      * PriceConfig is that you first add all the possible parameters for which it
100      * should then be able to deliver prices.
101      *
102      * <br/>br/>
103      *
104      * key: String currencyID<br/>
105      * value: Currency currency
106      *
107      * @jdo.field
108      * persistence-modifier="persistent"
109      * collection-type="map"
110      * key-type="java.lang.String"
111      * value-type="Currency"
112      *
113      * @jdo.join
114      */

115     private Map JavaDoc currencies = new HashMap JavaDoc();
116
117     public Collection JavaDoc getCurrencies()
118     {
119         return currencies.values();
120     }
121
122     /**
123      * @param currency The Currency to add.
124      *
125      * @see #beginAdjustParameters()
126      * @see #endAdjustParameters()
127      */

128     public void addCurrency(Currency currency)
129     {
130         currencies.put(currency.getCurrencyID(), currency);
131     }
132
133     /**
134      * @return Returns the desired Currency if registered or <tt>null</tt> if the
135      * given currencyID is not known.
136      */

137     public Currency getCurrency(String JavaDoc currencyID, boolean throwExceptionIfNotRegistered)
138     {
139         Currency res = (Currency) currencies.get(currencyID);
140         if (res == null && throwExceptionIfNotRegistered)
141             throw new IndexOutOfBoundsException JavaDoc("There is no Currency registered in this PriceConfig with the currencyID "+currencyID);
142         return res;
143     }
144     public boolean containsCurrency(String JavaDoc currencyID)
145     {
146         return currencies.containsKey(currencyID);
147     }
148     public boolean containsCurrency(Currency currency)
149     {
150         return currencies.containsKey(currency.getCurrencyID());
151     }
152     public Currency removeCurrency(String JavaDoc currencyID)
153     {
154         return (Currency) currencies.remove(currencyID);
155     }
156     
157     /**
158      * key: String priceFragmentTypePK<br/>
159      * value: PriceFragmentType priceFragmentType
160      *
161      * @jdo.field
162      * persistence-modifier="persistent"
163      * collection-type="map"
164      * key-type="java.lang.String"
165      * value-type="PriceFragmentType"
166      *
167      * @jdo.join
168      */

169     private Map JavaDoc priceFragmentTypes = new HashMap JavaDoc();
170     
171     public Collection JavaDoc getPriceFragmentTypes()
172     {
173         return priceFragmentTypes.values();
174     }
175     public void addPriceFragmentType(PriceFragmentType priceFragmentType)
176     {
177         priceFragmentTypes.put(priceFragmentType.getPrimaryKey(), priceFragmentType);
178     }
179     public PriceFragmentType getPriceFragmentType(String JavaDoc organisationID, String JavaDoc priceFragmentTypeID, boolean throwExceptionIfNotExistent)
180     {
181         return getPriceFragmentType(
182                 PriceFragmentType.getPrimaryKey(organisationID, priceFragmentTypeID),
183                 throwExceptionIfNotExistent);
184     }
185     public PriceFragmentType getPriceFragmentType(String JavaDoc priceFragmentTypePK, boolean throwExceptionIfNotExistent)
186     {
187         PriceFragmentType res = (PriceFragmentType) priceFragmentTypes.get(priceFragmentTypePK);
188         if (throwExceptionIfNotExistent && res == null)
189             throw new IllegalArgumentException JavaDoc("No PriceFragmentType registered with \""+priceFragmentTypePK+"\"!");
190         return res;
191     }
192     public boolean containsPriceFragmentType(PriceFragmentType priceFragmentType)
193     {
194         return priceFragmentTypes.containsKey(priceFragmentType.getPrimaryKey());
195     }
196     public boolean containsPriceFragmentType(String JavaDoc priceFragmentTypePK)
197     {
198         return priceFragmentTypes.containsKey(priceFragmentTypePK);
199     }
200     public boolean containsPriceFragmentType(String JavaDoc organisationID, String JavaDoc priceFragmentTypeID)
201     {
202         return priceFragmentTypes.containsKey(
203                 PriceFragmentType.getPrimaryKey(organisationID, priceFragmentTypeID));
204     }
205     /**
206      * This method calls removePriceFragmentType(String priceFragmentTypePK), hence
207      * you don't need to overwrite this method to react on a remove.
208      *
209      * @see #removePriceFragmentType(String)
210      * @see PriceFragmentType#getPrimaryKey(String, String)
211      */

212     public PriceFragmentType removePriceFragmentType(String JavaDoc organisationID, String JavaDoc priceFragmentTypeID)
213     {
214         return removePriceFragmentType(
215                 PriceFragmentType.getPrimaryKey(organisationID, priceFragmentTypeID));
216     }
217     /**
218      * @param priceFragmentTypePK The composite primary key of the PriceFragmentType to remove.
219      * @return Returns the PriceFragmentType that has been removed or <tt>null</tt> if none was registered with the given key.
220      *
221      * @see #removePriceFragmentType(String, String)
222      */

223     public PriceFragmentType removePriceFragmentType(String JavaDoc priceFragmentTypePK)
224     {
225         return (PriceFragmentType) priceFragmentTypes.remove(priceFragmentTypePK);
226     }
227
228 // /**
229
// * This method must return a price of a product for a certain customer in a certain
230
// * currency.
231
// *
232
// * @param productInfo The ProductInfo representing a Product for which to get a price. Never null.
233
// * @param customer The customer to whom the Product should be sold.
234
// * @param currency The currency for which to give a price.
235
// * @return Returns an instance of OfferItemPrice representing the price in a certain currency for the given
236
// * situation. This method may return null if there is no price available for the given parameters.
237
// * In this case, a product cannot be added to an Offer.
238
// */
239
// public abstract OfferItemPrice getPrice(ProductInfo productInfo, LegalEntity customer, Currency currency);
240

241     /**
242      * This method returns a price of a product in a certain context. The context
243      * is defined by offerItem, which knows the product, the customer and all the
244      * other items in the offer and even the whole order.
245      * <p>
246      * In a simple PriceConfig, the result is usually dependent only from the customer
247      * and the product, but the PriceConfig may integrate other factors like total
248      * offer amount into price calculation, as well.
249      * <p>
250      * But be careful! This means, you can easily program instable offers which have
251      * an indefinite price! To avoid this problem, the offer is recalculated
252      * twice whenever it is validated. If the second result does not match the first,
253      * the offer is not valid and marked as not stable. Only if it is marked stable,
254      * it can be confirmed.
255      *
256      * @param offerItem
257      */

258     public abstract Price getPrice(OfferItem offerItem);
259
260     public abstract boolean isDependentOnOffer();
261
262     /**
263      * There are implementations of <tt>PriceConfig</tt> that are useable only within
264      * product packages, because their values are indefinit (formulas depending on the
265      * siblings within the package). Therefore a <tt>Product</tt> is not saleable directly
266      * if such a <tt>PriceConfig</tt> is assigned.
267      *
268      * @return An implementation of <tt>PriceConfig</tt> must return <tt>true</tt>, if
269      * it's prices are dependent on the <tt>Product</tt>'s siblings within a package
270      * (or the package itself) and therefore, the <tt>Product</tt> cannot be sold outside
271      * of a package.
272      */

273     public abstract boolean isDependentOnProductPackage();
274
275     /**
276      * @jdo.field persistence-modifier="persistent"
277      */

278     private long nextPriceID = 0;
279
280     /**
281      * Creates a <tt>priceID</tt> by incrementing the member nextPriceID.
282      * The new ID is unique within the context of this <tt>PriceConfig</tt>
283      * (<tt>organisationID</tt> & <tt>priceConfigID</tt>).
284      *
285      * @return Returns a price id, which is unique within the context of this <tt>PriceConfig</tt>.
286      */

287     public synchronized long createPriceID()
288     {
289         long res = nextPriceID;
290         nextPriceID = res + 1;
291         return res;
292     }
293
294     /**
295      * @see javax.jdo.StoreCallback#jdoPreStore()
296      */

297     public void jdoPreStore()
298     {
299         if (JDOHelper.isNew(this)) {
300             PersistenceManager pm = JDOHelper.getPersistenceManager(this);
301
302             PriceFragmentType totalPFT = PriceFragmentType.getTotalPriceFragmentType(pm);
303             addPriceFragmentType(totalPFT);
304         }
305     }
306
307 // /**
308
// * @jdo.field persistence-modifier="none"
309
// */
310
// private transient int adjustParametersCounter = 0;
311
//
312
// /**
313
// *
314
// */
315
// public void beginAdjustParameters()
316
// {
317
//
318
// }
319
// public void endAdjustParameters()
320
// {
321
//
322
// }
323
}
324
Popular Tags