View Javadoc

1   package org.paneris.jammyjoes.model;
2   
3   import java.sql.Date;
4   import java.util.Enumeration;
5   
6   import org.melati.poem.AccessPoemException;
7   import org.melati.poem.Persistent;
8   import org.melati.poem.ValidationPoemException;
9   import org.melati.util.StringUtils;
10  import org.paneris.jammyjoes.model.generated.ProductBase;
11  import org.paneris.jammyjoes.util.JammyJoesUtil;
12  
13  public class Product extends ProductBase {
14  
15    private Double quantitySold;
16    private Double quantityPurchased;
17    private Double quantityShopSale;
18    private Double quantityInternetSale;
19    private Double quantityTelephoneSale;
20    private Double quantityStockCheckIncrease;
21    private Double quantityStockCheckDecrease;
22    private Double quantityCorrectLevel;
23    private Double quantityAjustmentRequired;
24  
25    public void setVatexempt(Boolean cooked) throws AccessPoemException, ValidationPoemException {
26      super.setVatexempt(cooked);
27      setRetailpriceincvat(getRetailpriceincvat());
28    }
29  
30    public Product() {
31    }
32  
33    public boolean hasStatus(ProductStatus status) {
34      if (getStatus().equals(status)) {
35        return true;
36      }
37      return false;
38    }
39  
40    public boolean getHasStock() {
41      if (getStocklevel().intValue() > 0) {
42        return true;
43      }
44      return false;
45    }
46  
47    public boolean getDoWeSellIt() {
48      if (getHasStock()) {
49        return true;
50      }
51      ProductStatusTable statuses =  getJammyjoesDatabaseTables().getProductStatusTable();
52      if (hasStatus(statuses.getNew()) || hasStatus(statuses.getNormallyStocked())) {
53        return true;
54      }
55      return false;
56    }
57  
58    public boolean getDiscontinued() {
59      if (getStatus().equals(getJammyjoesDatabaseTables().getProductStatusTable().getDiscontinued())){
60        return true;
61      }
62      return false;
63    }
64    
65    public Double getPreSaleprice() {
66      return getSaleprice();
67    }
68  
69    // there doesn't seem to be a better place to put this
70    public Double getCostpriceIncVat() {
71      if (isVatexempt()) {
72        return new Double(getCostprice().doubleValue());
73      } else {
74        return new Double(getCostprice().doubleValue() * 1.175);
75      }
76    }
77  
78    public void setRetailpriceincvat(Double cooked)
79      throws AccessPoemException, ValidationPoemException {
80      if (cooked != null) {
81        if (isVatexempt()) {
82          setRetailprice(cooked.doubleValue());
83        } else {
84          setRetailprice(cooked.doubleValue() / 1.175);
85        }
86      }
87      super.setRetailpriceincvat(cooked);
88    }
89  
90    private boolean isVatexempt() {
91      return getVatexempt().booleanValue();
92    }
93  
94    public void setRetailprice(Double cooked) throws AccessPoemException, ValidationPoemException {
95      calculateMargin(cooked, getCostprice());
96      super.setRetailprice(cooked);
97    }
98  
99    public void setCostprice(Double cooked) throws AccessPoemException, ValidationPoemException {
100     calculateMargin(getRetailprice(), cooked);
101     super.setCostprice(cooked);
102   }
103 
104   public void calculateMargin(Double retailprice, Double costprice) {
105     if (retailprice != null && costprice != null) {
106       double margin = retailprice.doubleValue() - costprice.doubleValue();
107       setMargin(margin);
108       setMarginpercent(margin / retailprice.doubleValue() * 100);
109       setMarkuppercent(margin / costprice.doubleValue() * 100);
110     }
111   }
112 
113   public void clearQuantities() {
114     quantitySold = null;
115     quantityPurchased = null;
116     quantityShopSale = null;
117     quantityInternetSale = null;
118     quantityTelephoneSale = null;
119     quantityStockCheckIncrease = null;
120     quantityStockCheckDecrease = null;
121     quantityCorrectLevel = null;
122     quantityAjustmentRequired = null;
123   }
124 
125   private void calculateQuantities() {
126     StockTransactionTypeTable st = getJammyjoesDatabaseTables().getStockTransactionTypeTable();
127     quantityPurchased = calculateQuantity(st.getPurchase());
128     quantityShopSale = calculateQuantity(st.getShopSale());
129     quantityInternetSale = calculateQuantity(st.getInternetSale());
130     quantityTelephoneSale = calculateQuantity(st.getTelephoneSale());
131     quantityStockCheckIncrease = calculateQuantity(st.getStockCheckIncreasee());
132     quantityStockCheckDecrease = calculateQuantity(st.getStockCheckDecrease());
133     quantitySold = new Double(quantityShopSale.doubleValue() + quantityInternetSale.doubleValue() + quantityTelephoneSale.doubleValue());
134     quantityCorrectLevel =
135       new Double(
136         quantityPurchased.doubleValue()
137           - quantitySold.doubleValue()
138           + quantityStockCheckIncrease.doubleValue()
139           - quantityStockCheckDecrease.doubleValue());
140     quantityAjustmentRequired = quantityCorrectLevel;
141     if (getStocklevel() != null)
142       quantityAjustmentRequired =
143         new Double(quantityCorrectLevel.doubleValue() - getStocklevel().doubleValue());
144   }
145 
146   private Double calculateQuantity(StockTransactionType type) {
147     return calculateQuantityToDate(type, null);
148   }
149 
150   private Double calculateQuantityToDate(StockTransactionType type, Date date) {
151     return calculateQuantity(type, date, true);
152   }
153 
154   private Double calculateQuantityFromDate(StockTransactionType type, Date date) {
155     return calculateQuantity(type, date, false);
156   }
157 
158   private Double calculateQuantity(StockTransactionType type, Date date, boolean to) {
159     double total = 0;
160     String selection =
161       q("product") + " = " + getTroid() + " AND " + q("type") + " = " + type.getTroid();
162     // FIXME date format for query
163     if (date != null) {
164       selection += " AND " + q("date");
165       if (to) {
166         selection += " < ";
167       } else {
168         selection += " >= ";
169       }
170       selection += JammyJoesUtil.formatDateForSQL(getDatabase(), date);
171     }
172     Enumeration e =
173       getJammyjoesDatabaseTables()
174         .getStockTransactionTable()
175         .cachedSelection(selection, null)
176         .objects();
177     while (e.hasMoreElements()) {
178       StockTransaction t = (StockTransaction) e.nextElement();
179       total += t.getQuantity().doubleValue();
180     }
181     return new Double(total);
182   }
183 
184   private String q(String name) {
185       StringBuffer b = new StringBuffer();
186       StringUtils.appendQuoted(b, name, '"');
187       return b.toString();
188   }
189 
190   public double getQuantityPurchased() {
191     if (quantityPurchased == null)
192       calculateQuantities();
193     return quantityPurchased.doubleValue();
194   }
195 
196   public double getQuantityShopSale() {
197     if (quantityShopSale == null)
198       calculateQuantities();
199     return quantityShopSale.doubleValue();
200   }
201 
202   public double getQuantityInternetSale() {
203     if (quantityInternetSale == null)
204       calculateQuantities();
205     return quantityInternetSale.doubleValue();
206   }
207 
208   public double getQuantityTelephoneSale() {
209     if (quantityTelephoneSale == null)
210       calculateQuantities();
211     return quantityTelephoneSale.doubleValue();
212   }
213 
214   public double getQuantityStockCheckIncrease() {
215     if (quantityStockCheckIncrease == null)
216       calculateQuantities();
217     return quantityStockCheckIncrease.doubleValue();
218   }
219 
220   public double getQuantityStockCheckDecrease() {
221     if (quantityStockCheckDecrease == null)
222       calculateQuantities();
223     return quantityStockCheckDecrease.doubleValue();
224   }
225 
226   public double getQuantitySold() {
227     if (quantitySold == null)
228       calculateQuantities();
229     return quantitySold.doubleValue();
230   }
231 
232   public double getQuantityCorrectLevel() {
233     if (quantityCorrectLevel == null)
234       calculateQuantities();
235     return quantityCorrectLevel.doubleValue();
236   }
237 
238   public int getQuantityAjustmentRequired() {
239     if (quantityAjustmentRequired == null)
240       calculateQuantities();
241     return quantityAjustmentRequired.intValue();
242   }
243 
244   public double getRequiredOrderValue() {
245     return getCostprice().doubleValue() * getReorderquantity().intValue();
246   }
247 
248   /**
249    * when duplicating, the new Persistent needs a zero stock level
250    */
251   public Persistent duplicated() throws AccessPoemException {
252     Product prod = (Product) super.duplicated();
253     prod.setStocklevel(0);
254     return prod;
255   }
256 
257   public Double getStockLevel(Date date) {
258     StockTransactionTypeTable st = getJammyjoesDatabaseTables().getStockTransactionTypeTable();
259     Double quantityPurchased = calculateQuantityToDate(st.getPurchase(), date);
260     Double quantityStockCheckIncrease = calculateQuantityToDate(st.getStockCheckIncreasee(), date);
261     Double quantityStockCheckDecrease = calculateQuantityToDate(st.getStockCheckDecrease(), date);
262     Double quantitySold = getQuantitySoldToDate(date);
263     return new Double(
264       quantityPurchased.doubleValue()
265         - quantitySold.doubleValue()
266         + quantityStockCheckIncrease.doubleValue()
267         - quantityStockCheckDecrease.doubleValue());
268   }
269 
270   public Double getQuantitySoldToDate(Date date) {
271     StockTransactionTypeTable st = getJammyjoesDatabaseTables().getStockTransactionTypeTable();
272     Double quantityShopSale = calculateQuantityToDate(st.getShopSale(), date);
273     Double quantityInternetSale = calculateQuantityToDate(st.getInternetSale(), date);
274     Double quantityTelephoneSale = calculateQuantityToDate(st.getTelephoneSale(), date);
275     Double quantitySold =
276       new Double(quantityShopSale.doubleValue() + quantityInternetSale.doubleValue() + quantityTelephoneSale.doubleValue());
277     return quantitySold;
278   }
279 
280   public Double getQuantitySoldFromDate(Date date) {
281     StockTransactionTypeTable st = getJammyjoesDatabaseTables().getStockTransactionTypeTable();
282     Double quantityShopSale = calculateQuantityFromDate(st.getShopSale(), date);
283     Double quantityTelephoneSale = calculateQuantityToDate(st.getTelephoneSale(), date);
284     Double quantityInternetSale = calculateQuantityFromDate(st.getInternetSale(), date);
285     Double quantitySold =
286       new Double(quantityShopSale.doubleValue() + quantityInternetSale.doubleValue() + quantityTelephoneSale.doubleValue());
287     return quantitySold;
288   }
289 
290   public StockValues getStockLevels(Date date) {
291     double stockLevel = 0;
292     if (getStocklevel() != null)
293       stockLevel = getStocklevel().doubleValue();
294     if (date != null)
295       stockLevel = getStockLevel(date).doubleValue();
296     return new StockValues(this, stockLevel);
297   }
298 
299   public class StockValues {
300     private Product product;
301     private double stockLevel = 0;
302 
303     public StockValues(Product p, double sl) {
304       product = p;
305       stockLevel = sl;
306     }
307 
308     public double getValue(Double price) {
309       if (price == null)
310         return 0;
311       return stockLevel * price.doubleValue();
312     }
313 
314     public double getLevel() {
315       return stockLevel;
316     }
317 
318     public double getCostPriceExVat() {
319       return getValue(product.getCostprice());
320     }
321 
322     public double getCostPriceIncVat() {
323       return product.getCostpriceIncVat().doubleValue();
324     }
325 
326     public double getRetailPriceExVat() {
327       return getValue(product.getRetailprice());
328     }
329 
330     public double getRetailPriceIncVat() {
331       return getValue(product.getRetailpriceincvat());
332     }
333   }
334 
335   public Boolean getNew() {
336     if (getStatus().equals(getJammyjoesDatabaseTables().getProductStatusTable().getNew()))
337       return Boolean.TRUE;
338     return Boolean.FALSE;
339   }
340 
341   public StockTransaction newStockTransaction(Date date, StockTransactionType type, Integer quantity) {
342     StockTransaction st = (StockTransaction)getJammyjoesDatabaseTables().getStockTransactionTable().newPersistent();
343     st.setProduct(this);
344     st.setDate(date);
345     st.setType(type);
346     st.setQuantity(quantity);
347     st.setCostprice(getCostprice());
348     st.setRetailpriceincvat(getRetailpriceincvat());
349     st.setVatexempt(getVatexempt());
350     return st;
351   }
352 }