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