1 package org.paneris.jammyjoes.shopping;
2
3 import java.io.PrintWriter;
4 import java.io.StringWriter;
5 import java.util.Enumeration;
6 import java.util.Locale;
7
8 import org.melati.Melati;
9 import org.melati.servlet.Form;
10 import org.melati.login.HttpSessionAccessHandler;
11 import org.melati.poem.AccessPoemException;
12 import org.melati.poem.AccessToken;
13 import org.melati.poem.Field;
14 import org.melati.poem.PoemTask;
15 import org.melati.poem.PoemThread;
16 import org.melati.template.ServletTemplateContext;
17 import org.melati.util.InstantiationPropertyException;
18 import org.paneris.jammyjoes.model.Affiliate;
19 import org.paneris.jammyjoes.model.DeliveryCarrier;
20 import org.paneris.jammyjoes.model.DeliveryCharge;
21 import org.paneris.jammyjoes.model.DeliveryZone;
22 import org.paneris.jammyjoes.model.JammyjoesDatabase;
23 import org.paneris.jammyjoes.model.OrderType;
24 import org.paneris.jammyjoes.model.ShopCurrency;
25 import org.paneris.jammyjoes.model.ShopOrder;
26 import org.paneris.jammyjoes.model.ShopOrderItem;
27 import org.paneris.jammyjoes.model.User;
28 import org.paneris.jammyjoes.model.UserTable;
29 import org.paneris.jammyjoes.model.Wrapping;
30 import org.paneris.jammyjoes.model.WrappingTable;
31 import org.paneris.jammyjoes.util.JammyJoesContextUtil;
32 import org.paneris.jammyjoes.util.JammyJoesUtil;
33
34 /**
35 * <p> A Shopping Trolley stored information in the user's Shopping Trolley.<p>
36 * <p> It does this by storing itself in the session.</p>
37 * <p> For this reason, the constructors are private, and you will be expected to
38 * always get the Shopping Trolley using getInstance();</p>
39 *
40 * usage example:
41 *
42 * ShoppingTrolley trolley = ShoppingTrolley.getInstance(Melati melati);
43 * context.put("trolley", trolley);
44 *
45 **/
46
47 public class JammyJoesShoppingTrolley extends ShoppingTrolley {
48
49 public DeliveryZone zone;
50 public Wrapping wrapping;
51 private ShopOrder order = null;
52 public DeliveryCarrier carrier;
53 private Boolean spam;
54 private String comment;
55 private String deliveryName;
56
57 /**
58 * Get the Locale for this trolley.
59 */
60 public Locale getLocale() {
61
62 if (locale == null) {
63
64 User user = (User) melati.getUser();
65 if (!user.isGuest() && user.getCurrency() != null) {
66 locale = user.getCurrency().toLocale();
67 }
68
69 if (locale == null) {
70 locale = JammyJoesUtil.makeLocale(melati.getRequest().getHeader("accept-language"));
71 }
72 }
73 return locale;
74 }
75
76 private boolean isOrderPaidOrNew() {
77 JammyjoesDatabase db = (JammyjoesDatabase) melati.getDatabase();
78 if (order == null) {
79 return true;
80 }
81 if (order.getStatus() == db.getOrderStatusTable().getPaid()) {
82 return true;
83 }
84 return false;
85 }
86
87
88
89 public void load(Integer id) throws InstantiationPropertyException {
90 JammyjoesDatabase db = (JammyjoesDatabase) melati.getDatabase();
91 order = db.getShopOrderTable().getShopOrderObject(id);
92 setZone(order.getZone());
93 setWrapping(order.getWrapping());
94 setName(order.getName());
95 setEmail(order.getEmail());
96 setTel(order.getTel());
97 setDeliveryAddress(order.getAddress());
98 setTown(order.getTown());
99 setPostcode(order.getPostcode());
100 setMessage(order.getMessage());
101 comment = order.getCustomerComment();
102 deliveryName = order.getDeliveryName();
103 setCountry(order.getCountry());
104 setLocale(order.getCurrency().toLocale());
105 setSpam(order.getSpam());
106 Enumeration e = order.getItems();
107 while (e.hasMoreElements()) {
108 ShopOrderItem line = (ShopOrderItem) e.nextElement();
109 ShoppingTrolleyItem item = newItem(line.getProduct().getTroid(), null, null);
110 if (line.getQuantity() != null) {
111 item.setQuantity(line.getQuantity());
112 }
113 }
114 }
115
116
117
118 public void save() {
119 if (JammyJoesUtil.telesales(melati)) {
120 saveCatalogueOrder();
121 return;
122 }
123 final JammyjoesDatabase db = (JammyjoesDatabase) melati.getDatabase();
124 User user = (User) melati.getUser();
125 if (user.isGuest()) {
126 user = null;
127 }
128 user = saveOrder(db, null, db.getOrderTypeTable().getOnlineOrder());
129 melati.getSession().setAttribute(HttpSessionAccessHandler.USER, user);
130 }
131
132
133 public void saveCatalogueOrder() {
134 final JammyjoesDatabase db = (JammyjoesDatabase) melati.getDatabase();
135 User operator = (User) melati.getUser();
136 if (operator == null || operator.isGuest()) {
137 throw new AccessPoemException();
138 }
139 saveOrder(db, null, db.getOrderTypeTable().getTelephoneOrder());
140 order.setOperator(operator);
141 }
142
143 private User saveOrder(final JammyjoesDatabase db, User user, OrderType type) {
144 if (user == null) {
145 user = (User) ((UserTable) db.getUserTable()).getEmailColumn().firstWhereEq(email);
146 if (user == null) {
147
148 final User newUser;
149 newUser = (User) db.getUserTable().newPersistent();
150 newUser.setName(name);
151 newUser.setEmail(email);
152 newUser.setTel(tel);
153 newUser.setAddress(address);
154 newUser.setTown(town);
155 newUser.setZone(zone);
156 newUser.setCountry(country);
157 newUser.setPostcode(postcode);
158 newUser.setSpam(spam);
159 newUser.generateDefaults();
160 PoemThread.withAccessToken(AccessToken.root, new PoemTask() {
161 public void run() {
162 db.getUserTable().create(newUser);
163 }
164 });
165 user = newUser;
166 }
167 } else {
168
169 user.setName(name);
170 user.setEmail(email);
171 user.setTel(tel);
172 user.setAddress(address);
173 user.setTown(town);
174 user.setZone(zone);
175 user.setPostcode(postcode);
176 user.setCountry(country);
177 user.setZone(zone);
178 user.setSpam(spam);
179 }
180 if (isOrderPaidOrNew()) {
181 order = (ShopOrder) db.getShopOrderTable().newPersistent();
182 order.setType(type);
183 } else {
184 order.removeItems();
185 }
186 order.setUser(user);
187 order.setName(name);
188 order.setEmail(email);
189 order.setTel(tel);
190 order.setAddress(address);
191 order.setTown(town);
192 order.setZone(zone);
193 order.setWrapping(wrapping);
194 order.setPostcode(postcode);
195 order.setCountry(country);
196 order.setMessage(message);
197 order.setCustomerComment(comment);
198 order.setDeliveryName(deliveryName);
199 order.setStatus(db.getOrderStatusTable().getIncomplete());
200 order.setAmount(convertFromUK(getTotalValue()));
201 order.setDelivery(convertFromUK(getTotalDeliveryValue()));
202 order.setAmountUK(JammyJoesUtil.roundTo2dp(getTotalValue()));
203 order.setDeliveryUK(JammyJoesUtil.roundTo2dp(getTotalDeliveryValue()));
204 order.setCurrency(getCurrency());
205 order.setAffiliatepaid(false);
206 order.setAlert(false);
207 order.setComission(0d);
208 order.setSpam(spam);
209 String affiliateId = JammyJoesUtil.getCookieValue(melati, "jammyjoes");
210 if (affiliateId != null) {
211 Affiliate affiliate = (Affiliate)db.getAffiliateTable().getObject(new Integer(affiliateId));
212 order.setAffiliate(affiliate);
213 order.setComission(affiliate.getPercentage());
214 }
215 if (order.getTroid() == null) {
216 db.getShopOrderTable().create(order);
217 }
218 for (Enumeration en = getItems(); en.hasMoreElements();) {
219 JammyJoesShoppingTrolleyItem item = (JammyJoesShoppingTrolleyItem) en.nextElement();
220 item.save(db, order);
221 }
222 return user;
223 }
224
225
226
227
228 public boolean hasDelivery() {
229 if (zone == null)
230 return false;
231 return true;
232 }
233
234 public boolean allInStock() {
235 boolean inStock = true;
236 for (Enumeration en = getItems(); en.hasMoreElements();) {
237 JammyJoesShoppingTrolleyItem item = (JammyJoesShoppingTrolleyItem) en.nextElement();
238 if (!item.enoughStock())
239 inStock = false;
240 }
241 return inStock;
242 }
243
244 public boolean hasWrapping() {
245 if (wrapping == null)
246 return false;
247 WrappingTable wrappingTable = ((JammyjoesDatabase) melati.getDatabase()).getWrappingTable();
248 if (wrapping.equals(wrappingTable.getNoWrapping()))
249 return false;
250 return true;
251 }
252
253 public DeliveryZone getDeliveryZone() {
254 return zone;
255 }
256
257 public Wrapping getWrapping() {
258 return wrapping;
259 }
260
261 public DeliveryCarrier getDeliveryCarrier() {
262 return carrier;
263 }
264
265 public Field getZones() {
266 JammyjoesDatabase db = (JammyjoesDatabase) melati.getDatabase();
267 Integer current = null;
268 if (zone != null)
269 current = zone.getTroid();
270 return new Field(current, db.getDeliveryChargeTable().getZoneColumn());
271 }
272
273 public Field getWrappings() {
274 JammyjoesDatabase db = (JammyjoesDatabase) melati.getDatabase();
275 Integer current = null;
276 if (wrapping != null)
277 current = wrapping.getTroid();
278 return new Field(current, db.getShopOrderTable().getWrappingColumn());
279 }
280
281 public void setFromForm(Melati melati) {
282 ServletTemplateContext tc = melati.getServletTemplateContext();
283 setName(Form.getFormNulled(tc, "trolley_name"));
284 setEmail(Form.getFormNulled(tc, "trolley_email"));
285 setTel(Form.getFormNulled(tc, "trolley_tel"));
286 setDeliveryAddress(Form.getFormNulled(tc, "trolley_deliveryaddress"));
287 setTown(Form.getFormNulled(tc, "trolley_town"));
288 setCounty(Form.getFormNulled(tc, "trolley_county"));
289 setCountry(Form.getFormNulled(tc, "trolley_country"));
290 setPostcode(Form.getFormNulled(tc, "trolley_postcode"));
291 setMessage(Form.getFormNulled(tc, "trolley_message"));
292 hasDetails = true;
293
294 JammyjoesDatabase db = (JammyjoesDatabase) melati.getDatabase();
295 Integer zoneId = Form.getIntegerField(tc, "field_zone");
296 DeliveryZone newCode = (DeliveryZone) db.getDeliveryZoneTable().getObject(zoneId);
297 setZone(newCode);
298 Integer wrappingId = Form.getIntegerField(tc, "field_wrapping");
299 WrappingTable wrappingTable = db.getWrappingTable();
300 Wrapping newWrapping = (Wrapping) wrappingTable.getObject(wrappingId);
301 setWrapping(newWrapping);
302 setSpam(Form.getBooleanField(tc, "trolley_spam"));
303 comment = Form.getFormNulled(tc, "trolley_comment");
304 deliveryName = Form.getFormNulled(tc, "trolley_deliveryName");
305 }
306
307
308
309
310 public double getDeliveryValue() {
311 carrier = null;
312 if (zone == null)
313 return 0;
314 double cost = 0;
315
316 if (zone.getChargeByValue() != null && zone.getChargeByValue().booleanValue()) {
317 cost += getDeliveryValueByValue();
318 } else {
319 cost += getDeliveryValueByWeight();
320 }
321 return cost;
322 }
323 public double getWrappingValue() {
324 if (hasWrapping())
325 return WrappingTable.WRAPPING_COST;
326 return 0;
327 }
328
329 public double getDeliveryValueByValue() {
330 carrier = null;
331 if (zone == null)
332 return 0;
333 DeliveryCharge thisCharge = zone.getChargeValue(getValue());
334 if (thisCharge == null)
335 return 0;
336 carrier = thisCharge.getCarrier();
337 return thisCharge.getCost().doubleValue();
338 }
339
340 public double getDeliveryValueByWeight() {
341 carrier = null;
342 if (zone == null)
343 return 0;
344 DeliveryCharge maxCharge = zone.getMaxCharge();
345 if (maxCharge == null)
346 return 0;
347 double weight = getTotalWeight();
348 double cost = 0;
349 while (weight > maxCharge.getWeight().doubleValue()) {
350 cost += maxCharge.getCost().doubleValue();
351 weight -= maxCharge.getWeight().doubleValue();
352 }
353 DeliveryCharge thisCharge = zone.getCharge(weight);
354 if (thisCharge == null)
355 return cost;
356 cost += thisCharge.getCost().doubleValue();
357 carrier = thisCharge.getCarrier();
358 return cost;
359 }
360
361 public double getTotalWeight() {
362 double weight = 0;
363 for (Enumeration en = getItems(); en.hasMoreElements();) {
364 JammyJoesShoppingTrolleyItem item = (JammyJoesShoppingTrolleyItem) en.nextElement();
365 weight += item.getWeight();
366 }
367 return weight;
368 }
369
370
371
372
373 public boolean hasDiscount() {
374 return false;
375 }
376
377
378
379 public double getDiscountRate() {
380 return 0;
381 }
382
383
384
385
386 public boolean hasVAT() {
387 return true;
388 }
389
390
391
392
393
394 public void setDefaultDetails(Melati melati) {
395 if (!JammyJoesUtil.telesales(melati)) {
396 User user = (User) melati.getUser();
397 if (user != null && !user.isGuest()) {
398 if (address == null)
399 address = user.getAddress();
400 if (town == null)
401 town = user.getTown();
402 if (zone == null)
403 zone = user.getZone();
404 if (name == null)
405 name = user.getName();
406 if (tel == null)
407 tel = user.getTel();
408 if (country == null)
409 country = user.getCountry();
410 if (postcode == null)
411 postcode = user.getPostcode();
412 if (email == null)
413 email = user.getEmail();
414 if (spam == null)
415 setSpam(user.getSpam());
416 }
417 }
418 }
419
420 public void confirmPayment(Melati melati) {
421 JammyjoesDatabase db = (JammyjoesDatabase) melati.getDatabase();
422 ServletTemplateContext context = melati.getServletTemplateContext();
423 String amountString = context.getForm("amount");
424 amountString = amountString.trim();
425 String uniqueString = melati.getRequest().getQueryString();
426 Integer orderInteger = Form.getIntegerField(context, "orderref");
427 boolean error = false;
428 try {
429 Integer amount = new Integer(amountString);
430 load(orderInteger);
431 context.put("trolley", this);
432 context.put("jjutil", new JammyJoesContextUtil());
433 if (!uniqueString.equals("few90kjnr32908908kjfdsa98432kjlfds9009432lk90lk43209")) {
434 error = true;
435 context.put("error", "2");
436 }
437 if (!amount.equals(new Integer(getTotalValuePence()))) {
438 error = true;
439 context.put("expect", getTotalValuePence());
440 context.put("paid", amountString);
441 context.put("error", "1");
442 }
443 if (!error) {
444 order.setStatus(db.getOrderStatusTable().getPaid());
445 for (Enumeration en = order.getItems(); en.hasMoreElements();) {
446 ShopOrderItem item = (ShopOrderItem) en.nextElement();
447 item.setTransaction();
448 }
449 remove(melati);
450 }
451 } catch (Exception e) {
452 error = true;
453 StringWriter sw = new StringWriter();
454 PrintWriter pw = new PrintWriter(sw);
455 e.printStackTrace(pw);
456 context.put("error", sw);
457 }
458 }
459
460 /**
461 * remove any trolley from the session
462 */
463 public void remove(Melati melati) {
464 super.remove(melati);
465 melati.getSession().removeAttribute(HttpSessionAccessHandler.USER);
466 }
467
468 public ShopOrder getOrder() {
469 return order;
470 }
471
472
473
474 public double getTotalValue() {
475 return getValue()
476 + getTotalDeliveryValue()
477 + getDiscountValue()
478 + getWrappingValue()
479 + getVATValue();
480 }
481
482
483
484 public double getTotalVat() {
485 return roundTo2dp(getTotalValue() / 1.175 * 0.175);
486 }
487
488 public String getWrappingDisplay() {
489 return displayCurrency(getWrappingValue());
490 }
491
492
493
494 public String convertFromUKandFormat(double value) {
495 return getCurrency().convertFromUKandFormat(value);
496 }
497
498
499 public double convertFromUK(double value) {
500 return getCurrency().convertFromUK(value);
501 }
502
503
504
505 public double convertToUK(double value) {
506 return getCurrency().convertToUK(value);
507 }
508
509 public ShopCurrency getCurrency(Locale locale) {
510 return ((JammyjoesDatabase) melati.getDatabase()).getShopCurrencyTable().getCurrency(locale);
511 }
512
513 public ShopCurrency getCurrency() {
514 return getCurrency(getLocale());
515 }
516
517 public String displayCurrency(double value) {
518 return convertFromUKandFormat(value);
519 }
520
521 public void setWrapping(Wrapping newWrapping) {
522 wrapping = newWrapping;
523 }
524
525 public void setZone(DeliveryZone zone) {
526 this.zone = zone;
527 }
528
529 public void setSpam(Boolean s) {
530 spam = s;
531 }
532
533 public String getComment() {
534 return comment;
535 }
536
537 public String getDeliveryName() {
538 return deliveryName;
539 }
540
541 public Boolean getSpam() {
542 if (spam == null)
543 return Boolean.TRUE;
544 return spam;
545 }
546
547 private JammyJoesContextUtil jjutil;
548 public JammyJoesContextUtil getJJUtil() {
549 if (jjutil == null)
550 jjutil = new JammyJoesContextUtil();
551 return jjutil;
552 }
553
554 }