1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.paneris.jammyjoes.shopping;
47
48 import java.text.NumberFormat;
49 import java.util.Enumeration;
50 import java.util.Hashtable;
51 import java.util.Locale;
52 import java.util.Vector;
53
54 import javax.servlet.http.HttpSession;
55
56 import org.melati.Melati;
57 import org.melati.poem.AccessPoemException;
58 import org.melati.poem.AccessToken;
59 import org.melati.poem.Capability;
60 import org.melati.poem.PoemThread;
61 import org.melati.util.InstantiationPropertyException;
62 import org.paneris.jammyjoes.model.JammyjoesDatabase;
63 import org.paneris.jammyjoes.util.JammyJoesUtil;
64
65 /**
66 * <p> A Shopping Trolley stored information in the user's Shopping Trolley.<p>
67 * <p> It does this by storing itself in the session.</p>
68 * <p> For this reason, the constructors are private, and you will be expected to
69 * always get the Shopping Trolley using getInstance();</p>
70 *
71 * usage example:
72 *
73 * ShoppingTrolley trolley = ShoppingTrolley.getInstance(Melati melati);
74 * context.put("trolley", trolley);
75 *
76 **/
77
78 public abstract class ShoppingTrolley {
79
80 private static String TROLLEY = "org.paneris.melati.shopping.DefaultShoppingTrolley";
81 protected Locale locale;
82 protected String address;
83 protected String name;
84 protected String tel;
85 protected String town;
86 protected String county;
87 protected String country;
88 protected String postcode;
89 protected String message;
90 protected String email;
91 protected boolean hasDetails = false;
92 Vector orderedItems = new Vector();
93 Hashtable items = new Hashtable();
94 public MelatiShoppingConfig config;
95 public Melati melati;
96
97 /**
98 * private Constructor to build an empty ShoppingTrolley
99 **/
100 protected void initialise(Melati melati, MelatiShoppingConfig config) {
101 this.config = config;
102 this.melati = melati;
103 }
104
105 /**
106 * public Constructor to build a trolley from some id
107 **/
108 public void initialise(Melati melati, MelatiShoppingConfig config, Integer id)
109 throws InstantiationPropertyException {
110 initialise(melati,config);
111 load(id);
112 HttpSession session = melati.getSession();
113 session.setAttribute(name(),this);
114 }
115
116 /**
117 * remove any trolley from the session
118 */
119 public void remove(Melati melati) {
120 HttpSession session = melati.getSession();
121 session.removeAttribute(name());
122 }
123
124
125 /**
126 * Returns the single instance, creating one if it can't be found.
127 */
128 public static synchronized ShoppingTrolley getInstance(Melati melati, MelatiShoppingConfig config)
129 throws InstantiationPropertyException {
130 HttpSession session = melati.getSession();
131 ShoppingTrolley instance = (ShoppingTrolley) session.getAttribute(name());
132 if (instance == null || instance.isPaid()) {
133 instance = newTrolley(config);
134 instance.initialise(melati,config);
135 session.setAttribute(name(),instance);
136 }
137 instance.configureRequest(melati);
138 return instance;
139 }
140
141 private boolean isPaid() {
142 return false;
143 }
144
145 public static synchronized ShoppingTrolley newTrolley(MelatiShoppingConfig config)
146 throws InstantiationPropertyException {
147 return config.getShoppingTrolley();
148 }
149
150
151
152 public abstract Locale getLocale();
153
154
155
156
157 public void setLocale(Locale locale){
158 this.locale = locale;
159 }
160
161
162
163 public abstract void confirmPayment(Melati melati);
164
165
166
167 public abstract void load(Integer id) throws InstantiationPropertyException;
168
169
170
171 public abstract void save();
172
173
174
175
176 public void configureRequest(Melati melati) {
177 this.melati = melati;
178 }
179
180
181
182
183
184 public void assertLogin(Melati melati) {
185 JammyjoesDatabase db = (JammyjoesDatabase) melati.getDatabase();
186 Capability operator = db.getOperatorCapability();
187 AccessToken token = PoemThread.accessToken();
188 if (!token.givesCapability(operator))
189 throw new AccessPoemException(token, operator);
190 }
191
192
193
194
195
196 public abstract void setDefaultDetails(Melati melati);
197
198
199
200
201 public static String name() {
202 return TROLLEY;
203 }
204
205
206
207 public Enumeration getItems() {
208 return orderedItems.elements();
209 }
210
211
212
213 public boolean isEmpty() {
214 return items.isEmpty();
215 }
216
217
218
219 public boolean hasDetails() {
220 return hasDetails;
221 }
222
223
224
225 public ShoppingTrolleyItem getItem(Integer id) {
226 return (ShoppingTrolleyItem)items.get(id);
227 }
228
229
230
231 public void removeItem(ShoppingTrolleyItem item) {
232 items.remove(item.getId());
233 orderedItems.removeElement(item);
234 }
235
236
237
238 public void addItem(ShoppingTrolleyItem item) {
239
240 if (!items.containsKey(item.getId())) {
241 orderedItems.add(item);
242 }
243 items.put(item.getId(),item);
244 }
245
246 public ShoppingTrolleyItem newItem(Integer id, String description, Double price)
247 throws InstantiationPropertyException {
248 ShoppingTrolleyItem item = ShoppingTrolleyItem.newTrolleyItem(config);
249 item.initialise(this, melati, id, description, price);
250 addItem(item);
251 return item;
252 }
253
254
255
256 public double getValue() {
257 double value = 0;
258 for (Enumeration en = items.elements(); en.hasMoreElements();) {
259 ShoppingTrolleyItem product = (ShoppingTrolleyItem) en.nextElement();
260 value += product.getValue();
261 }
262 return value;
263 }
264
265
266
267
268 public String getValueDisplay() {
269 return displayCurrency(getValue());
270 }
271
272
273
274 public double getTotalValue() {
275 return getValue() + getTotalDeliveryValue() + getDiscountValue() + getVATValue();
276 }
277
278
279
280
281 public String getTotalValueDisplay() {
282 return displayCurrency(getTotalValue());
283 }
284
285
286
287
288
289 public String getTotalValuePence() {
290 return getValuePence(getTotalValue());
291 }
292
293 public static String getValuePence(double totalValue) {
294 return (new Double(roundTo2dp(totalValue * 100))).intValue() + "";
295 }
296
297
298
299
300 public abstract boolean hasDelivery();
301
302
303
304
305 public abstract double getDeliveryValue();
306
307
308
309
310 public double getTotalDeliveryValue() {
311 double value = 0;
312 if (hasDelivery()) {
313 value = getDeliveryValue();
314 for (Enumeration en = items.elements(); en.hasMoreElements();) {
315 ShoppingTrolleyItem item = (ShoppingTrolleyItem) en.nextElement();
316 value += item.getDeliveryValue();
317 }
318 }
319 return value;
320 }
321
322
323
324 public String getDeliveryDisplay() {
325 return displayCurrency(getTotalDeliveryValue());
326 }
327
328
329
330
331 public abstract boolean hasDiscount();
332
333
334
335 public abstract double getDiscountRate();
336
337
338
339
340 public double getDiscountValue() {
341 double value = 0;
342 if (hasDiscount()) {
343 value = 0 - roundTo2dp(getValue()*getDiscountRate());
344 }
345 return value;
346 }
347
348
349
350 public String getDiscountRateDisplay() {
351 if (hasDiscount()) {
352 try {
353 return (new Double(getDiscountRate())).intValue() + "%";
354 } catch (NumberFormatException e) {
355 return getDiscountRate() + "%";
356 }
357 } else {
358 return "";
359 }
360 }
361
362
363
364 public String getDiscountValueDisplay() throws Exception {
365 return displayCurrency(getDiscountValue());
366 }
367
368
369
370
371 public abstract boolean hasVAT();
372
373
374
375
376
377
378
379 public double getVATValue() {
380 if (!hasVAT()) {
381 return roundTo2dp(getValue() * -0.14894);
382 } else {
383 return 0;
384 }
385 }
386
387
388
389 public String getVATDisplay() {
390 return displayCurrency(getVATValue());
391 }
392
393
394
395 public void setDeliveryAddress(String a) {
396 address = a;
397 }
398
399
400 public String getDeliveryAddress() {
401 return address;
402 }
403
404
405
406 public void setName(String a) {
407 name = a;
408 }
409
410
411 public String getName() {
412 return name;
413 }
414
415
416
417 public void setEmail(String a) {
418 email = a;
419 }
420
421
422 public String getEmail() {
423 return email;
424 }
425
426
427
428 public void setPostcode(String a) {
429 postcode = a;
430 }
431
432
433 public String getPostcode() {
434 return postcode;
435 }
436
437
438
439 public void setTel(String a) {
440 tel = a;
441 }
442
443
444 public String getTel() {
445 return tel;
446 }
447
448
449
450 public void setTown(String a) {
451 town = a;
452 }
453
454
455 public String getTown() {
456 return town;
457 }
458
459
460
461 public void setCounty(String a) {
462 county = a;
463 }
464
465
466 public String getCounty() {
467 return county;
468 }
469
470
471
472 public void setCountry(String a) {
473 country = a;
474 }
475
476
477 public String getCountry() {
478 return country;
479 }
480
481
482
483 public void setMessage(String a) {
484 message = a;
485 }
486
487
488 public String getMessage() {
489 return message;
490 }
491
492
493
494 public String displayCurrency(double value) {
495 return new String(NumberFormat.getCurrencyInstance(getLocale()).format(value));
496 }
497
498
499
500 public String displayCurrency(Double value) {
501 return displayCurrency(value.doubleValue());
502 }
503
504 public String baseURL() {
505 String result = "";
506 if (JammyJoesUtil.telesales(melati)) {
507 result = "/telesales/";
508 } else {
509 result = "/jammyjoes/";
510 }
511 result += "Trolley/" + melati.getPoemContext().getLogicalDatabase() + "/";
512 return result;
513 }
514
515 public String viewURL() {
516 return baseURL() + "View/";
517 }
518
519 public String detailsURL() {
520 return baseURL() + "Details/";
521 }
522
523 public String confirmURL() {
524 return baseURL() + "Confirm/";
525 }
526
527 public String abandonURL() {
528 return baseURL() + "Abandon/";
529 }
530
531 public String updateURL() {
532 return baseURL() + "Update/";
533 }
534
535 public String paidURL() {
536 return baseURL() + "Paid/";
537 }
538
539 public String catalogueURL() {
540 return baseURL() + "CatalogueEntry/";
541 }
542
543 public static double roundTo2dp(double num) {
544 int a = Math.round(new Float(num * 100).floatValue());
545 double b = new Double(a).doubleValue();
546 return (b/100);
547 }
548
549 }
550