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