1 package org.paneris.bibliomania.shopping;
2
3 import java.io.PrintWriter;
4 import java.io.StringWriter;
5 import java.util.Enumeration;
6 import java.util.Hashtable;
7 import java.util.Locale;
8
9 import org.melati.Melati;
10 import org.melati.servlet.Form;
11 import org.melati.poem.AccessToken;
12 import org.melati.poem.Field;
13 import org.melati.poem.PoemTask;
14 import org.melati.poem.PoemThread;
15 import org.melati.template.ServletTemplateContext;
16 import org.melati.template.TemplateEngine;
17 import org.melati.util.Email;
18 import org.melati.util.InstantiationPropertyException;
19 import org.melati.util.MelatiWriter;
20 import org.paneris.bibliomania.BibliomaniaDatabase;
21 import org.paneris.bibliomania.Country;
22 import org.paneris.bibliomania.Currency;
23 import org.paneris.bibliomania.DeliveryCharge;
24 import org.paneris.bibliomania.NotLoggedInException;
25 import org.paneris.bibliomania.ShopOrder;
26 import org.paneris.bibliomania.ShopOrderItem;
27 import org.paneris.bibliomania.User;
28 import org.paneris.bibliomania.UserTable;
29 import org.paneris.bibliomania.util.BibliomaniaUtil;
30 import org.paneris.melati.shopping.MelatiShoppingConfig;
31 import org.paneris.melati.shopping.ShoppingTrolley;
32 import org.paneris.melati.shopping.ShoppingTrolleyItem;
33 import org.webmacro.servlet.WebContext;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class BibliomaniaShoppingTrolley extends ShoppingTrolley {
49
50 private static String MY_TROLLEY = "org.paneris.bibliomania.shopping.BibliomaniaShoppingTrolley";
51 private ShopOrder order = null;
52 public Country countryCode;
53
54
55
56
57 public Locale getLocale(){
58
59 if (locale == null) {
60 BibliomaniaDatabase db = (BibliomaniaDatabase)melati.getDatabase();
61 User user = (User)melati.getUser();
62 if (user.isRegisteredUser(db) && user.getCurrency() != null) {
63 locale = user.getCurrency().toLocale();
64 }
65
66 if (locale == null) {
67 locale = BibliomaniaUtil.makeLocale(
68 melati.getRequest().getHeader("accept-language"));
69 }
70 }
71 return locale;
72 }
73
74
75
76
77 public void initialise(Melati melatiP, MelatiShoppingConfig configP) {
78 super.initialise(melatiP, configP);
79 }
80
81
82
83
84
85 public void load(Integer id) throws InstantiationPropertyException {
86 BibliomaniaDatabase db = (BibliomaniaDatabase)melati.getDatabase();
87 order = db.getShopOrderTable().getShopOrderObject(id);
88 setCountryCode(order.getCountry());
89 setCountry(countryCode.getDisplayname());
90 setName(order.getName());
91 setEmail(order.getEmail());
92 setTel(order.getTel());
93 setDeliveryAddress(order.getAddress());
94 setTown(order.getTown());
95 setCounty(order.getCounty());
96 setPostcode(order.getPostcode());
97 setLocale(order.getCurrency().toLocale());
98 Enumeration e = order.getItems();
99 while (e.hasMoreElements()) {
100 ShopOrderItem line = (ShopOrderItem)e.nextElement();
101 ShoppingTrolleyItem item = newItem(line.getProduct().getTroid(), null, null);
102 if (line.getQuantity() != null) {
103 item.setQuantity(line.getQuantity().doubleValue());
104 }
105 }
106 }
107
108
109
110
111 public void save() {
112 final BibliomaniaDatabase db = (BibliomaniaDatabase)melati.getDatabase();
113 User user = (User)melati.getUser();
114 if (user == null || !user.isRegisteredUser(db)) {
115 user = (User)((UserTable)db.getUserTable()).getEmailColumn()
116 .firstWhereEq(email);
117 if (user == null) {
118
119 final User newUser;
120 newUser = (User)db.getUserTable().newPersistent();
121 newUser.setName(name);
122 newUser.setEmail(email);
123 newUser.setTel(tel);
124 newUser.setAddress(address);
125 newUser.setTown(town);
126 newUser.setCounty(county);
127 newUser.setRegion(postcode);
128 newUser.setCountry(countryCode);
129 newUser.generateDefaults();
130 PoemThread.withAccessToken(
131 AccessToken.root,
132 new PoemTask() {
133 public void run() {
134 db.getUserTable().create(newUser);
135 }
136 }
137 );
138 user = newUser;
139 }
140 } else {
141
142 user.setName(name);
143 user.setEmail(email);
144 user.setTel(tel);
145 user.setAddress(address);
146 user.setTown(town);
147 user.setCounty(county);
148 user.setRegion(postcode);
149 user.setCountry(countryCode);
150 }
151 if (order == null) {
152 order = (ShopOrder)db.getShopOrderTable().newPersistent();
153 } else {
154 order.removeItems();
155 }
156 order.setUser(user);
157 order.setName(name);
158 order.setEmail(email);
159 order.setTel(tel);
160 order.setAddress(address);
161 order.setTown(town);
162 order.setCounty(county);
163 order.setPostcode(postcode);
164 order.setCountry(countryCode);
165 order.setStatus(db.getOrderStatusTable().getNotAuthorised());
166 order.setAmount(convertFromUK(getTotalValue()));
167 order.setDelivery(convertFromUK(getTotalDeliveryValue()));
168 order.setAmountUK(getTotalValue());
169 order.setDeliveryUK(getTotalDeliveryValue());
170 order.setCurrency(getCurrency());
171 if (order.getTroid() == null) {
172 db.getShopOrderTable().create(order);
173 }
174 for (Enumeration en = getItems(); en.hasMoreElements();) {
175 BibliomaniaShoppingTrolleyItem item = (BibliomaniaShoppingTrolleyItem) en.nextElement();
176 item.save(db, order);
177 }
178 }
179
180
181
182
183
184 public boolean hasDelivery(){
185 if (countryCode == null) return false;
186 return true;
187 }
188
189
190
191
192
193 public boolean canSupply(){
194 boolean canSupply = true;
195 for (Enumeration en = getItems(); en.hasMoreElements();) {
196 BibliomaniaShoppingTrolleyItem item = (BibliomaniaShoppingTrolleyItem) en.nextElement();
197 if (item.getDeliveryCharge() == null) canSupply = false;
198 }
199 return canSupply;
200 }
201
202
203
204
205 public double getDeliveryValue() {
206 double cost = 0;
207
208 Enumeration f = getSuppliersCharges();
209 while (f.hasMoreElements()) {
210 cost += ((SupplierCharge)f.nextElement()).charge.getOrdercharge().doubleValue();
211 }
212 return cost;
213 }
214
215
216
217
218 public Enumeration getSuppliersCharges() {
219
220 Hashtable charges = new Hashtable();
221 Enumeration e = getItems();
222 while (e.hasMoreElements()) {
223 BibliomaniaShoppingTrolleyItem item = (BibliomaniaShoppingTrolleyItem)e.nextElement();
224 DeliveryCharge charge = item.getDeliveryCharge();
225 if (charge != null) {
226 Integer troid = charge.getTroid();
227 SupplierCharge sc = new SupplierCharge(charge,item);
228 if (charges.containsKey(troid))
229 sc.amount += ((SupplierCharge)charges.get(troid)).getAmount();
230 charges.put(troid,sc);
231 }
232 }
233 return charges.elements();
234 }
235
236
237
238
239
240 public boolean hasDiscount() {
241 return false;
242 }
243
244
245
246
247 public double getDiscountRate() {
248 return 0;
249 }
250
251
252
253
254
255 public boolean hasVAT() {
256 return true;
257 }
258
259 public Field getCountries() {
260 BibliomaniaDatabase db = (BibliomaniaDatabase)melati.getDatabase();
261 Integer current = null;
262 if (countryCode != null) current = countryCode.getTroid();
263 return new Field(current, db.getShopOrderTable().getCountryColumn());
264 }
265
266 public Country getCountryCode() {
267 return countryCode;
268 }
269
270 public void setFromForm(Melati melati) {
271 super.setFromForm(melati);
272 BibliomaniaDatabase db = (BibliomaniaDatabase)melati.getDatabase();
273 Integer countryCodeId =
274 Form.getIntegerField(melati.getServletTemplateContext(),"field_country");
275 Country newCode = (Country)db.getCountryTable()
276 .getIdColumn().firstWhereEq(countryCodeId);
277 setCountryCode(newCode);
278 }
279
280 public void setCountryCode(Country newCode) {
281 if (newCode != countryCode) {
282
283 Enumeration e = getItems();
284 while (e.hasMoreElements()) {
285 BibliomaniaShoppingTrolleyItem line = (BibliomaniaShoppingTrolleyItem)e.nextElement();
286 line.setGotCharge(false);
287 }
288 }
289 countryCode = newCode;
290 }
291
292 public void setDefaultDetails(Melati melati) {
293 BibliomaniaDatabase db = (BibliomaniaDatabase)melati.getDatabase();
294 User user = (User)melati.getUser();
295 if (user != null && user.isRegisteredUser(db)) {
296 if (address == null) address = user.getAddress();
297 if (town == null) town = user.getTown();
298 if (county == null) county = user.getCounty();
299 if (name == null) name = user.getName();
300 if (tel == null) tel = user.getTel();
301 if (countryCode == null) setCountryCode(user.getCountry());
302 if (postcode == null) postcode = user.getRegion();
303 if (email == null) email = user.getEmail();
304 }
305 }
306
307 public void assertLogin(Melati melatiP) {
308 BibliomaniaDatabase db = (BibliomaniaDatabase)melatiP.getDatabase();
309 if (!PoemThread.accessToken().givesCapability(
310 db.getRegisteredUserCapability()))
311 throw new NotLoggedInException();
312 }
313
314 public void confirmPayment(Melati melatiP) {
315 BibliomaniaDatabase db = (BibliomaniaDatabase)melatiP.getDatabase();
316 ServletTemplateContext context = melatiP.getServletTemplateContext();
317 String amountString = context.getFormField("amount");
318 String uniqueString = melatiP.getRequest().getQueryString();
319 Integer orderInteger = Form.getIntegerField(context,"orderref");
320 ServletTemplateContext templateContext = melatiP.getServletTemplateContext();
321 boolean error = false;
322 try {
323 double amount = new Double(amountString).doubleValue();
324 load(orderInteger);
325 amount /= 100;
326 templateContext.put("trolley",this);
327 if (!uniqueString.equals("foo")) {
328 error = true;
329 context.put("error", "2");
330 }
331 if (getTotalValue() != amount) {
332 error = true;
333 context.put("expect", new Double(convertFromUK(getTotalValue())));
334 context.put("paid", new Double(convertFromUK(amount)));
335 context.put("error", "1");
336 }
337 if (!error) {
338 TemplateEngine templateEngine = melati.getTemplateEngine();
339 templateContext.put("melati",melati);
340
341
342 MelatiWriter sw = templateEngine.getStringWriter();
343 String templateName = "email/Bibliomania.wm";
344 templateEngine.expandTemplate(sw, templateName, templateContext);
345 String emailText = sw.toString();
346 sw = templateEngine.getStringWriter();
347 Email.send(db.getSettingTable().get(Email.SMTPSERVER), getEmail(), db.getOrderEmailTo(), "",
348 "Bibliomania Order (number: " + orderInteger + ")", emailText);
349
350
351 sw = templateEngine.getStringWriter();
352 templateName = "email/Customer.wm";
353 templateEngine.expandTemplate(sw, templateName, templateContext);
354 emailText = sw.toString();
355 Email.send(db.getSettingTable().get(Email.SMTPSERVER), db.getOrderEmailFrom(), getEmail(), "",
356 "Your order at Bibliomania.com (number: " + orderInteger + ")", emailText);
357
358
359 Enumeration f = getSuppliersCharges();
360 while (f.hasMoreElements()) {
361 SupplierCharge charge = (SupplierCharge)f.nextElement();
362 templateContext.put("charge",charge);
363 sw = templateEngine.getStringWriter();
364 templateName = "email/Supplier.wm";
365 templateEngine.expandTemplate(sw, templateName, templateContext);
366 emailText = sw.toString();
367 Email.send(db.getSettingTable().get(Email.SMTPSERVER), db.getOrderEmailFrom(), charge.getCharge().getSupplier().getEmail(), "",
368 "Book orders via Bibliomania.com (number: " + orderInteger + ")", emailText);
369 }
370
371 order.setStatus(db.getOrderStatusTable().getAuthorised());
372 Enumeration e = order.getItems();
373 while (e.hasMoreElements()) {
374 ShopOrderItem purchase = (ShopOrderItem)e.nextElement();
375 purchase.setStatus(db.getOrderStatusTable().getAuthorised());
376 }
377 remove(melati);
378 }
379 } catch (Exception e) {
380 error = true;
381 StringWriter sw = new StringWriter();
382 PrintWriter pw = new PrintWriter(sw);
383 e.printStackTrace(pw);
384 context.put("error", sw);
385 }
386 }
387
388
389
390
391 public static String name() {
392 return MY_TROLLEY;
393 }
394
395 public ShopOrder getOrder() {
396 return order;
397 }
398
399 public static double round(double num) {
400 int a = Math.round(new Float(num * 100).floatValue());
401 double b = new Double(a).doubleValue();
402 return (b/100);
403 }
404
405
406
407
408 public String convertFromUKandFormat(double value) {
409 return getCurrency().convertFromUKandFormat(value);
410 }
411
412
413
414
415 public double convertFromUK(double value) {
416 return getCurrency().convertFromUK(value);
417 }
418
419
420
421
422 public double convertToUK(double value) {
423 return getCurrency().convertToUK(value);
424 }
425
426 public Currency getCurrency(Locale localeP) {
427 return ((BibliomaniaDatabase) melati.getDatabase())
428 .getCurrencyTable().getCurrency(localeP);
429 }
430
431 public Currency getCurrency() {
432 return getCurrency(getLocale());
433 }
434
435 public String displayCurrency(double value) {
436 return convertFromUKandFormat(value);
437 }
438
439 public void configureRequest(Melati melatiP) {
440 this.melati = melatiP;
441 BibliomaniaDatabase db = (BibliomaniaDatabase)melatiP.getDatabase();
442 db.setupContext(melatiP, (WebContext)melatiP.getTemplateContext().getContext(),
443 db.getShopSectionGroup());
444 }
445
446
447 public class SupplierCharge {
448 public DeliveryCharge charge;
449 public double amount;
450
451 public SupplierCharge (DeliveryCharge c, BibliomaniaShoppingTrolleyItem item) {
452 charge = c;
453 amount = item.getValue();
454 }
455
456 public DeliveryCharge getCharge() {
457 return charge;
458 }
459
460 public double getAmount() {
461 return amount;
462 }
463 }
464
465 }
466