001: /*
002: * Created on Nov 4, 2004
003: */
004: package org.openedit.store;
005:
006: import java.util.ArrayList;
007: import java.util.Collection;
008: import java.util.Collections;
009: import java.util.Comparator;
010: import java.util.HashMap;
011: import java.util.Iterator;
012: import java.util.List;
013: import java.util.Map;
014: import java.util.Set;
015: import java.util.TreeSet;
016:
017: import org.apache.commons.logging.Log;
018: import org.apache.commons.logging.LogFactory;
019: import org.openedit.money.Money;
020:
021: /**
022: * This is a specific item that is held in stock
023: *
024: */
025: public class InventoryItem {
026: protected int fieldQuantityInStock;
027: protected Map fieldProperties;
028: protected Set fieldOptions;
029: protected String fieldSku;
030: protected Product fieldProduct;
031: protected PriceSupport fieldPriceSupport;
032: protected String fieldDescription;
033: protected double fieldWeight;
034: protected boolean fieldBackOrdered;
035: private static final Log log = LogFactory
036: .getLog(InventoryItem.class);
037:
038: public InventoryItem() {
039: super ();
040: }
041:
042: public InventoryItem(String inSku) {
043: setSku(inSku);
044: }
045:
046: public Money getYourPrice() {
047: return getYourPriceByQuantity(1);
048: }
049:
050: public Money getYourPriceByQuantity(int i) {
051: PriceSupport sup = getPriceSupport();
052: if (sup == null) {
053: sup = getProduct().getPriceSupport();
054: }
055: if (sup == null) {
056: return null;
057: }
058: return sup.getYourPriceByQuantity(i);
059: }
060:
061: public int getQuantityInStock() {
062: return fieldQuantityInStock;
063: }
064:
065: public void setQuantityInStock(int inQuantityInStock) {
066: fieldQuantityInStock = inQuantityInStock;
067: }
068:
069: public boolean isInStock() {
070: return fieldQuantityInStock == -1 || fieldQuantityInStock > 0;
071: }
072:
073: public void increaseQuantityInStock(int inIncrease) {
074: fieldQuantityInStock = fieldQuantityInStock + inIncrease;
075: }
076:
077: public void decreaseQuantityInStock(int inDecrease) {
078: if (fieldQuantityInStock == -1) {
079: return;
080: }
081: fieldQuantityInStock = fieldQuantityInStock - inDecrease;
082: }
083:
084: public Option getColor() {
085: Option color = getOption("color");
086: return color;
087: }
088:
089: public Option getSize() {
090: Option size = getOption("size");
091: return size;
092: }
093:
094: public void setSize(String inString) {
095: Option opt = getLocalOption("size");
096: if (opt == null) {
097: opt = new Option();
098: opt.setId("size");
099: opt.setName("Size");
100: Option parent = getOption("size");
101: if (parent != null) {
102: opt.setRequired(parent.isRequired());
103: opt.setName(parent.getName());
104: opt.setPriceSupport(parent.getPriceSupport());
105: }
106:
107: addOption(opt);
108: }
109: opt.setValue(inString);
110: }
111:
112: public void setColor(String inString) {
113: Option opt = getLocalOption("color");
114: if (opt == null) {
115: opt = new Option();
116: opt.setId("color");
117: opt.setName("Color");
118: Option parent = getOption("color");
119: if (parent != null) {
120: opt.setRequired(parent.isRequired());
121: opt.setName(parent.getName());
122: opt.setPriceSupport(parent.getPriceSupport());
123: }
124: addOption(opt);
125: }
126: opt.setValue(inString);
127: }
128:
129: public void addOption(Option inOpt) {
130: getOptions().add(inOpt);
131: }
132:
133: public String getSku() {
134: return fieldSku;
135: }
136:
137: public void setSku(String sku) {
138: fieldSku = sku;
139: }
140:
141: public boolean hasSize() {
142: Option size = getSize();
143: if (size == null || size.getValue() == null) {
144: return false;
145: }
146: return true;
147: }
148:
149: public boolean hasColor() {
150: Option option = getColor();
151: if (option == null || option.getValue() == null) {
152: return false;
153: }
154: return true;
155: }
156:
157: public String toString() {
158: return "[Item: " + getSku() + " " + getSize() + " "
159: + getColor() + "]";
160: }
161:
162: /**
163: * @param inCartItem
164: * @return
165: */
166: public boolean isExactMatch(Collection inSomeOptions) {
167: //all options must match
168: for (Iterator iter = inSomeOptions.iterator(); iter.hasNext();) {
169: Option option = (Option) iter.next();
170: Option found = getLocalOption(option.getId());
171:
172: if (found == null) {
173: //log.info("No option was found locally with id: " + option.getId());
174: continue; //it is not specified
175: }
176: //log.info("Does " + option.getId() + ":" + option.getValue()
177: // + " match " + found.getId() + ":" + option.getValue() + "?");
178:
179: if (option.equals(found)) {
180: //log.info("Yes.");
181: continue;
182: }
183: //log.info("No. Not a match");
184: return false;
185: }
186: //log.info("We found a match.");
187: return true;
188: }
189:
190: public boolean isCloseMatch(Collection inOptions) {
191: //look over all the required options and see if they all match
192: for (Iterator iter = inOptions.iterator(); iter.hasNext();) {
193: Option inCheck = (Option) iter.next();
194: if (inCheck.isRequired() || inCheck.getId().equals("color")
195: || inCheck.getId().equals("size")) {
196: Option has = getLocalOption(inCheck.getId());
197: if (has == null) {
198: return false;
199: }
200: if (has.equals(inCheck)) {
201: continue;
202: }
203: }
204: }
205: return true;
206: }
207:
208: public boolean isAnyMatch(Collection inOptions) {
209: for (Iterator iter = inOptions.iterator(); iter.hasNext();) {
210: Option inCheck = (Option) iter.next();
211: if (inCheck.getId().equals("color")
212: || inCheck.getId().equals("size")) {
213: Option has = getLocalOption(inCheck.getId());
214: if (has != null && has.equals(inCheck)) {
215: return true;
216: }
217: }
218: }
219: for (Iterator iter = inOptions.iterator(); iter.hasNext();) {
220: Option inCheck = (Option) iter.next();
221: Option has = getLocalOption(inCheck.getId());
222: if (has != null && has.equals(inCheck)) {
223: return true;
224: }
225: }
226: return false;
227: }
228:
229: protected boolean equals(Option inOption, Option inOther) {
230: if (inOption == inOther) {
231: return true;
232: }
233: if (inOption == null || inOther == null) {
234: return false;
235: }
236: if (inOption.getValue() == inOther.getValue()) {
237: return true;
238: }
239: if (inOption.getValue() == null || inOther.getValue() == null) {
240: return false;
241: }
242: return inOption.getValue().equals(inOther.getValue());
243:
244: }
245:
246: protected Option findOption(String inId, Collection inOptions) {
247: for (Iterator iterator = inOptions.iterator(); iterator
248: .hasNext();) {
249: Option found = (Option) iterator.next();
250: if (found.getId().equals(inId)) {
251: return found;
252: }
253: }
254: return null;
255:
256: }
257:
258: public Money getRetailPrice() {
259: //return getPriceSupport().getPrice();
260: if (getPriceSupport() != null) {
261: return getPriceSupport().getRetailPrice();
262: } else {
263: return Money.ZERO;
264: }
265:
266: }
267:
268: public boolean isOnSale() {
269: if (getPriceSupport() == null) {
270: return false;
271: }
272: return getPriceSupport().isOnSale();
273: }
274:
275: public void put(String inKey, String inValue) {
276: if (inKey.equals("size")) {
277: setSize(inValue);
278: } else {
279: getProperties().put(inKey, inValue);
280: }
281: }
282:
283: public String get(String inkey) {
284: String value = (String) getProperties().get(inkey);
285: if (value == null) {
286: value = getProduct().get(inkey); //Check the product and catalogs
287: }
288: return value;
289: }
290:
291: public String getProperty(String inKey) {
292: return (String) getProperties().get(inKey);
293: }
294:
295: public Map getProperties() {
296: if (fieldProperties == null) {
297: fieldProperties = new HashMap();
298: }
299:
300: return fieldProperties;
301: }
302:
303: public void addProperty(String inKey, String inValue) {
304: if (inValue == null || inValue.length() == 0) {
305: getProperties().remove(inKey);
306: } else {
307: getProperties().put(inKey, inValue);
308: }
309: }
310:
311: public void setProperties(Map inAttributes) {
312: fieldProperties = inAttributes;
313: }
314:
315: public String getName() {
316: return getProduct().getName();
317: }
318:
319: public Product getProduct() {
320: return fieldProduct;
321: }
322:
323: public void setProduct(Product product) {
324: fieldProduct = product;
325: }
326:
327: public PriceSupport getPriceSupport() {
328: return fieldPriceSupport;
329: }
330:
331: public void setPriceSupport(PriceSupport priceSupport) {
332: fieldPriceSupport = priceSupport;
333: }
334:
335: /**
336: * @return
337: */
338: public List getTiers() {
339: return getPriceSupport().getTiers();
340: }
341:
342: /**
343: * @param inQuantity
344: * @param money
345: */
346: public void addTierPrice(int inQuantity, Price inPrice) {
347: if (fieldPriceSupport == null) {
348: fieldPriceSupport = new PriceSupport();
349: }
350: getPriceSupport().addTierPrice(inQuantity, inPrice);
351: }
352:
353: /**
354: * @return
355: */
356: public boolean hasOwnPrice() {
357: return fieldPriceSupport != null
358: && fieldPriceSupport.getTiers().size() > 0;
359: }
360:
361: /**
362: * @param inI
363: * @return
364: */
365: public PriceTier getTier(int inI) {
366: if (fieldPriceSupport == null
367: || getPriceSupport().getTiers() == null
368: || getPriceSupport().getTiers().size() <= inI) {
369: return null;
370: }
371:
372: return (PriceTier) getPriceSupport().getTiers().get(inI);
373: }
374:
375: public String getDescription() {
376: return fieldDescription;
377: }
378:
379: public void setDescription(String inDescription) {
380: fieldDescription = inDescription;
381: }
382:
383: public List getPropertiesStartingWith(String inKey) {
384: List keys = new ArrayList();
385: for (Iterator iter = getProperties().keySet().iterator(); iter
386: .hasNext();) {
387: String key = (String) iter.next();
388: if (key.startsWith(inKey)) {
389: keys.add(key);
390: }
391: }
392: Collections.sort(keys);
393: List values = new ArrayList();
394: for (Iterator iter = keys.iterator(); iter.hasNext();) {
395: String key = (String) iter.next();
396: values.add(getProperty(key));
397: }
398: return values;
399: }
400:
401: public double getWeight() {
402: return fieldWeight;
403: }
404:
405: public void setWeight(double inWeight) {
406: fieldWeight = inWeight;
407: }
408:
409: public boolean isBackOrdered() {
410: return fieldBackOrdered;
411: }
412:
413: public void setBackOrdered(boolean inBackOrdered) {
414: fieldBackOrdered = inBackOrdered;
415: }
416:
417: public void clearOptions() {
418: getOptions().clear();
419: }
420:
421: public Set getOptions() {
422: if (fieldOptions == null) {
423: fieldOptions = new TreeSet(new Comparator() {
424: public int compare(Object arg0, Object arg1) {
425: Option opt0 = (Option) arg0;
426: Option opt1 = (Option) arg1;
427: return opt0.getId().compareTo(opt1.getId());
428: }
429: });
430: }
431: return fieldOptions;
432: }
433:
434: public List getAllOptions() {
435: Map optionsMap = new HashMap();
436: List productOptions = getProduct().getAllOptions();
437:
438: for (Iterator iter = productOptions.iterator(); iter.hasNext();) {
439: Option option = (Option) iter.next();
440: optionsMap.put(option.getId(), option);
441: }
442:
443: for (Iterator iter = getOptions().iterator(); iter.hasNext();) {
444: Option option = (Option) iter.next();
445: optionsMap.put(option.getId(), option);
446: }
447:
448: List allOptions = new ArrayList();
449: allOptions.addAll(new ArrayList(optionsMap.values()));
450: Collections.sort(allOptions, new Comparator() {
451: public int compare(Object inO1, Object inO2) {
452: Option one = (Option) inO1;
453: Option two = (Option) inO2;
454: return one.getName().compareTo(two.getName());
455: }
456: });
457:
458: return allOptions;
459: }
460:
461: public void setOptions(Set inOptions) {
462: fieldOptions = inOptions;
463: }
464:
465: public Option getLocalOption(String inId) {
466: for (Iterator iter = getOptions().iterator(); iter.hasNext();) {
467: Option option = (Option) iter.next();
468: if (option.getId().equals(inId)) {
469: return option;
470: }
471: }
472: return null;
473: }
474:
475: public Option getOption(String inId) {
476: Option option = getLocalOption(inId);
477: if (option == null) {
478: if (fieldProduct == null) {
479: return null;
480: }
481: return getProduct().getOption(inId);
482: }
483: return option;
484: }
485:
486: public InventoryItem copy() {
487: InventoryItem item = new InventoryItem();
488: item.fieldBackOrdered = fieldBackOrdered;
489: item.fieldDescription = fieldDescription;
490: item.fieldOptions = null;
491: Iterator i = getOptions().iterator();
492: while (i.hasNext()) {
493: item.addOption(((Option) i.next()).copy());
494: }
495:
496: item.fieldPriceSupport = getPriceSupport();
497: item.fieldProduct = fieldProduct;
498: item.fieldProperties = null;
499: i = getProperties().keySet().iterator();
500: while (i.hasNext()) {
501: String key = (String) i.next();
502: item.addProperty(key, getProperty(key));
503: }
504:
505: item.fieldQuantityInStock = fieldQuantityInStock;
506: item.fieldSku = fieldSku;
507: item.fieldWeight = fieldWeight;
508: return item;
509: }
510:
511: }
|