1 4 package com.openedit.store; 5 6 import java.io.File ; 7 import java.io.FileReader ; 8 import java.io.FilenameFilter ; 9 import java.text.DateFormat ; 10 import java.text.ParseException ; 11 import java.text.SimpleDateFormat ; 12 import java.util.ArrayList ; 13 import java.util.Collections ; 14 import java.util.Date ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 20 import org.apache.commons.collections.map.ListOrderedMap; 21 import org.apache.commons.logging.Log; 22 import org.apache.commons.logging.LogFactory; 23 import org.dom4j.Element; 24 import org.openedit.money.Money; 25 26 import com.openedit.OpenEditException; 27 import com.openedit.WebPageRequest; 28 import com.openedit.modules.email.PostMail; 29 import com.openedit.store.customer.Address; 30 import com.openedit.store.customer.Customer; 31 import com.openedit.store.orders.SubmittedOrder; 32 import com.openedit.users.StringEncrypter; 33 import com.openedit.users.filesystem.MapPropertyContainer; 34 import com.openedit.util.XmlUtil; 35 36 40 public class XmlOrderArchive extends AbstractXmlOrderArchive 41 { 42 private static final Log log = LogFactory.getLog(XmlOrderArchive.class); 43 protected static final DateFormat DATE_FORMAT = new SimpleDateFormat ( "M/d/yy h:mm:ss a" ); 44 protected static final String ORDERS_FILENAME = "orders.xml"; 45 protected PostMail postMail; 46 47 public PostMail getPostMail() { 48 return postMail; 49 } 50 51 52 53 public void setPostMail(PostMail postMail) { 54 this.postMail = postMail; 55 } 56 57 58 59 public Map getOrderStates() 60 { 61 Map list = ListOrderedMap.decorate( new HashMap () ); 62 OrderState state = new OrderState(); 63 state.setId(Order.ACCEPTED); 64 state.setDescription("Accepted"); 65 list.put(state.getId(),state); 66 67 state = new OrderState(); 68 state.setId(Order.AUTHORIZED); 69 state.setDescription("Authorized"); 70 list.put(state.getId(),state); 71 72 73 state = new OrderState(); 74 state.setId(Order.COMPLETED); 75 state.setDescription("Accepted"); 76 list.put(state.getId(),state); 77 78 state = new OrderState(); 79 state.setId(Order.CAPTURED); 80 state.setDescription("Captured"); 81 list.put(state.getId(),state); 82 83 state = new OrderState(); 84 state.setId(Order.REJECTED); 85 state.setDescription("Rejected"); 86 list.put(state.getId(),state); 87 88 return list; 89 } 90 91 92 93 public void archiveOrderData(Store inStore) throws StoreException 94 { 95 } 97 98 public void exportNewOrder(WebPageRequest inContext, Store inStore, Order inOrder) 99 throws StoreException 100 { 101 try 102 { 103 Customer customer = inOrder.getCustomer(); 104 log.info("Exporting order to XML"); 105 File customerOrdersFile = getOrderFile(inStore, inOrder); 106 log.debug("Using " + customerOrdersFile.getPath()); 107 Element orderElem = getRootElement( customerOrdersFile, "order" ); 108 109 110 orderElem.addAttribute( "order_number", inOrder.getId() ); 112 orderElem.addAttribute( "date", DATE_FORMAT.format( inOrder.getDate() ) ); 113 ShippingMethod shippingMethod = inOrder.getShippingMethod(); 114 if ( shippingMethod != null ) 115 { 116 orderElem.addAttribute( "shipping_method", shippingMethod.getId() ); 117 } 118 orderElem.addAttribute( "subtotal", inOrder.getSubTotal().toShortString() ); 119 orderElem.addAttribute( "tax", inOrder.getTax().toShortString() ); 120 orderElem.addAttribute( "shipping_cost", inOrder.getTotalShipping().toShortString() ); 121 orderElem.addAttribute( "total", inOrder.getTotalPrice().toShortString() ); 122 123 125 Element customerElem = orderElem.addElement( "customer" ); 126 customerElem.addAttribute( "customerid", customer.getUserName() ); 127 customerElem.addAttribute( "title", customer.getTitle() ); 128 customerElem.addAttribute( "first_name", customer.getFirstName() ); 129 customerElem.addAttribute( "last_name", customer.getLastName() ); 130 customerElem.addAttribute( "company", customer.getCompany() ); 131 customerElem.addAttribute( "phone1", customer.getPhone1() ); 132 customerElem.addAttribute( "email", customer.getEmail() ); 133 customerElem.addAttribute( "fax", customer.getFax()); 134 135 String user1 = customer.getUserField1(); 136 if ( user1 != null) 137 { 138 customerElem.addAttribute( "userfield1", user1 ); 139 } 140 String user2 = customer.getUserField2(); 141 if ( user2 != null) 142 { 143 customerElem.addAttribute( "userfield2", user2); 144 } 145 if ( customer.getBillingAddress() != null && customer.getBillingAddress().getAddress1() != null ) 146 { 147 appendAddress( customerElem, customer.getBillingAddress(), "billing" ); 148 } 149 if ( customer.getShippingAddress() != null && customer.getShippingAddress().getAddress1() != null ) 150 { 151 appendAddress( customerElem, customer.getShippingAddress(), "shipping" ); 152 } 153 154 for (Iterator it = inOrder.getItems().iterator(); it.hasNext();) 156 { 157 CartItem item = (CartItem)it.next(); 158 appendItem( orderElem, inStore, item ); 159 } 160 161 CreditPaymentMethod paymentMethod = (CreditPaymentMethod)inOrder.getPaymentMethod(); 163 Element paymentElem = orderElem.addElement( "payment_method" ); 164 paymentElem.addAttribute( "payment_type", "credit" ); 165 if ( paymentMethod instanceof PurchaseOrderMethod ) 166 { 167 paymentElem.addAttribute( "po_number", 168 ((PurchaseOrderMethod)paymentMethod).getPoNumber() ); 169 } 170 paymentElem.addAttribute( "card_type", paymentMethod.getCreditCardType().getId() ); 171 paymentElem.addAttribute( "card_number", encrypt(paymentMethod.getCardNumber() ) ); 172 paymentElem.addAttribute( "expiration_date", paymentMethod.getExpirationDateString() ); 173 boolean bill = paymentMethod.getBillMeLater(); 174 paymentElem.addAttribute( "bill_me_later", String.valueOf( bill ) ); 175 paymentElem.addAttribute( "note", paymentMethod.getNote() ); 176 177 writeXmlFile( orderElem, customerOrdersFile ); 178 179 inOrder.getOrderState().setOk(true); 180 181 String status = "accepted"; 182 orderElem.addAttribute("order_status", status); 183 inOrder.getOrderState().setId(status); 184 inOrder.getOrderState().setDescription("Order accepted"); 185 186 notifyStoreOwners(inStore,inOrder); 187 } 188 catch (Exception e) 189 { 190 log.error( "Could not archive this order request:\n" 191 + inOrder.getCustomer(), e ); 192 inOrder.getOrderState().setDescription("Order could not be sent: " + e.getMessage()); 193 inOrder.getOrderState().setOk(false); 194 throw new StoreException( e ); 195 } 196 } 197 198 public void changeOrderStatus(OrderState inStatus, Store inStore, Order inOrder) 199 throws StoreException 200 { 201 203 String orderFileString = getOrdersDirectory(inStore) + "/data/"; 205 orderFileString += inOrder.getCustomer().getUser().getUserName() + "/" + inOrder.getOrderNumber() + ".xml"; 206 File orderFile = new File (orderFileString); 207 208 Element orderElem = getRootElement( orderFile, "order" ); 209 orderElem.addAttribute("order_status", inStatus.getId()); 210 writeXmlFile( orderElem, orderFile ); 211 } 212 213 214 218 protected void notifyStoreOwners(Store inStore, Order inOrder) throws Exception 219 { 220 String [] recipients = (String [])inStore.getNotifyAddresses().toArray( new String [inStore.getNotifyAddresses().size()]); 221 log.info("Sending notification to " + recipients.length + " people"); 222 if ( recipients.length > 0) 223 { 224 225 String content = "A new order has been received\n "; 226 if (inStore.getHostName() != null) 227 { 228 content += "http://" + inStore.getHostName() + "/admin/orders/vieworders.html \n"; 229 content += "Secure Link: https://" + inStore.getHostName() + "/admin/orders/vieworders.html"; 230 } 231 postMail.postMail(recipients,"Order Notification",content, null,inStore.getFromAddress() 232 ); 233 } 234 235 } 236 237 protected void appendItem( Element inOrderElem, Store inStore, CartItem inItem ) 238 { 239 Element itemElem = inOrderElem.addElement( "item" ); 240 itemElem.addAttribute( "sku", inItem.getSku() ); 241 itemElem.addAttribute( "product_id", inItem.getProduct().getId() ); 242 itemElem.addAttribute( "quantity", String.valueOf(inItem.getQuantity()) ); 243 itemElem.addAttribute( "price", inItem.getYourPrice().toShortString() ); 244 245 for (Iterator it = inItem.getOptions().iterator(); it.hasNext();) 246 { 247 Option option = (Option)it.next(); 248 Element optionElem = itemElem.addElement( "option" ); 249 optionElem.addAttribute( "id", option.getId() ); 250 optionElem.addAttribute( "value", option.getValue() ); 251 optionElem.addAttribute( "name", option.getName() ); 252 } 253 254 if( inItem.getProperties() != null) 255 { 256 for (Iterator it = inItem.getProperties().entrySet().iterator(); it.hasNext(); ) 257 { 258 Map.Entry entry = (Map.Entry )it.next(); 259 if (entry.getKey() == null || entry.getValue() == null) 260 { 261 continue; 262 } 263 String key = (String )entry.getKey(); 264 final String START_OF_KEY = "item.extrainfo"; 265 if ( key.startsWith( START_OF_KEY ) ) 266 { 267 Element extraInfoElem = itemElem.addElement( "extra_info" ); 268 extraInfoElem.addAttribute( "key", key ); 269 extraInfoElem.addAttribute( "value", entry.getValue().toString() ); 270 } 271 } 272 } 273 } 274 275 protected void appendAddress( Element inCustomerElem, 276 Address inAddress, String inType ) 277 { 278 Element addressElem = inCustomerElem.addElement( "address" ); 279 addressElem.addAttribute( "type", inType ); 280 addressElem.addAttribute( "address1", inAddress.getAddress1() ); 281 addressElem.addAttribute( "address2", inAddress.getAddress2() ); 282 addressElem.addAttribute( "city", inAddress.getCity() ); 283 addressElem.addAttribute( "state", inAddress.getState() ); 284 addressElem.addAttribute( "zip_code", inAddress.getZipCode() ); 285 addressElem.addAttribute( "country", inAddress.getCountry() ); 286 } 287 288 protected File getOrderFile( Store inStore, Order inOrder ) 289 { 290 return new File ( getOrdersDirectory( inStore ) + "/data/" + inOrder.getCustomer().getUserName(), inOrder.getId() + ".xml" ); 291 } 292 293 public List listOrders( Store inStore, WebPageRequest inContext ) throws StoreException 294 { 295 File ordersFile = getOrdersDirectory(inStore); 296 List allorders = new ArrayList (); 297 try 298 { 299 findOrders( inStore, new File ( ordersFile , "data"),allorders); 300 } 301 catch ( Exception ex) 302 { 303 throw new StoreException(ex); 304 } 305 Collections.sort( allorders); 306 return allorders; 307 } 308 309 protected void findOrders(Store inStore, File inFile, List inAllorders) throws Exception 310 { 311 File [] listing = inFile.listFiles(new FilenameFilter () 312 { 313 public boolean accept(File inDir, String inName) 314 { 315 return inDir.isDirectory() || inName.endsWith(".xml"); 316 } 317 }); 318 if( listing != null) 319 { 320 for (int i = 0; i < listing.length; i++) 321 { 322 File one = listing[i]; 323 if ( one.isDirectory() ) 324 { 325 findOrders(inStore, one, inAllorders); 326 } 327 else 328 { 329 Element orderElement = new XmlUtil().getXml(new FileReader (one),"UTF-8"); 330 SubmittedOrder order = new SubmittedOrder(); 331 loadSubmittedOrder( inStore, orderElement, order ); 332 inAllorders.add( order ); 333 } 334 } 335 } 336 } 337 338 protected void loadSubmittedOrder( Store inStore, Element inOrderElement, SubmittedOrder inOrder ) throws StoreException 339 { 340 inOrder.setId( inOrderElement.attributeValue("order_number") ); 341 inOrder.setShippingMethod( makeShippingMethod( inStore, inOrderElement.attributeValue("shipping_method") ) ); 342 inOrder.setSubTotal(new Money(inOrderElement.attributeValue("subtotal"))); 343 inOrder.setTax(new Money(inOrderElement.attributeValue("tax"))); 344 inOrder.setShippingCost(new Money(inOrderElement.attributeValue("shipping_cost"))); 345 String total = inOrderElement.attributeValue("total"); 346 if( total != null) 347 { 348 inOrder.setTotalPrice(new Money(total)); 349 } 350 else 351 { 352 Money totalp = inOrder.getSubTotal().add(inOrder.getTax()); 353 totalp = totalp.add( inOrder.getShippingCost()); 354 inOrder.setTotalPrice(totalp); 355 } 356 357 String state = inOrderElement.attributeValue("order_status"); 362 OrderState ostate = inStore.getOrderState(state); 363 inOrder.setOrderState(ostate); 364 365 try 366 { 367 String formated = inOrderElement.attributeValue("date"); 368 Date date = DATE_FORMAT.parse( formated ); 369 inOrder.setDate(date); 370 inOrder.setDateOrdered(formated); 371 } 372 catch ( ParseException ex) 373 { 374 throw new StoreException(ex); 375 } 376 377 Customer customer = new Customer(); 378 inOrder.setCustomer(customer); 379 Element customerElem = inOrderElement.element("customer"); 380 customer.setUserName(customerElem.attributeValue("customerid")); 381 customer.setTitle(customerElem.attributeValue("title")); 382 customer.setFirstName(customerElem.attributeValue("first_name")); 383 customer.setLastName(customerElem.attributeValue("last_name")); 384 customer.setCompany(customerElem.attributeValue("company")); 385 customer.setPhone1(customerElem.attributeValue("phone1")); 386 customer.setUserField1(customerElem.attributeValue("userfield1")); 387 customer.setUserField2(customerElem.attributeValue("userfield2")); 388 customer.setEmail(customerElem.attributeValue("email")); 389 customer.setFax(customerElem.attributeValue("fax")); 390 for (Iterator it = customerElem.elementIterator("address"); it.hasNext();) 391 { 392 Element addressElem = (Element)it.next(); 393 String addressType = addressElem.attributeValue("type"); 394 if ("billing".equals(addressType)) 395 { 396 customer.setBillingAddress(makeAddress(addressElem)); 397 } 398 else if ("shipping".equals(addressType)) 399 { 400 customer.setShippingAddress(makeAddress(addressElem)); 401 } 402 } 403 List items = new ArrayList (); 404 for (Iterator it = inOrderElement.elementIterator("item"); it.hasNext();) 405 { 406 Element itemElement = (Element)it.next(); 407 items.add(makeItem(inStore, itemElement)); 408 } 409 inOrder.setItems(items); 410 411 Element paymentMethodElem = inOrderElement.element("payment_method"); 412 inOrder.setPaymentMethod( makePaymentMethod( inStore, paymentMethodElem ) ); 413 } 414 415 protected CartItem makeItem( Store inStore, Element inItemElem ) throws StoreException 416 { 417 CartItem item = new CartItem(); 418 item.setQuantity( Integer.parseInt(inItemElem.attributeValue("quantity")) ); 419 420 item.setYourPrice(new Money(inItemElem.attributeValue("price"))); 421 422 for (Iterator it = inItemElem.elementIterator("option"); it.hasNext();) 423 { 424 Element optionElem = (Element)it.next(); 425 String optionId = optionElem.attributeValue("id"); 426 Option option = new Option(); 427 option.setId(optionId); 428 option.setValue(optionElem.attributeValue("value")); 429 option.setName(optionElem.attributeValue("name")); 430 item.addOption(option); 431 } 432 for (Iterator it = inItemElem.elementIterator("extra_info"); it.hasNext();) 434 { 435 Element extraInfoElem = (Element)it.next(); 436 String key = extraInfoElem.attributeValue("key"); 437 String value = extraInfoElem.attributeValue("value"); 438 item.putProperty( key, value ); 439 } 440 for (Iterator it = inItemElem.elementIterator("property"); it.hasNext();) 441 { 442 Element extraInfoElem = (Element)it.next(); 443 String key = extraInfoElem.attributeValue("key"); 444 String value = extraInfoElem.attributeValue("value"); 445 item.putProperty( key, value ); 446 } 447 String productId = inItemElem.attributeValue("product_id"); 448 Product product = inStore.getProduct(productId); 449 String isku = inItemElem.attributeValue("sku"); 450 InventoryItem inventory = product.getInventoryItemBySku(isku); 451 item.setProduct(product); 453 item.setInventoryItem(inventory); 454 455 return item; 456 } 457 458 protected PaymentMethod makePaymentMethod( Store inStore, Element inPaymentMethodElem ) throws StoreException 459 { 460 String poNumber = inPaymentMethodElem.attributeValue("po_number"); 461 CreditPaymentMethod paymentMethod; 462 if ( poNumber != null && poNumber.length() > 0 ) 463 { 464 paymentMethod = new PurchaseOrderMethod(); 465 ((PurchaseOrderMethod)paymentMethod).setPoNumber(poNumber); 466 } 467 else 468 { 469 paymentMethod = new CreditPaymentMethod(); 470 } 471 String ccId = inPaymentMethodElem.attributeValue("card_type"); 472 if (ccId == null) 473 { 474 ccId = ""; 475 } 476 for (Iterator it = inStore.getCreditCardTypes().iterator(); it.hasNext();) 477 { 478 CreditCardType ccType = (CreditCardType)it.next(); 479 if (ccType.getId().equals(ccId)) 480 { 481 paymentMethod.setCreditCardType(ccType); 482 break; 483 } 484 } 485 if (paymentMethod.getCreditCardType() == null) 486 { 487 CreditCardType ccType = new CreditCardType(); 488 ccType.setId(ccId); 489 ccType.setName(ccId); 490 paymentMethod.setCreditCardType(ccType); 491 } 492 paymentMethod.setCardNumber(decrypt( inPaymentMethodElem.attributeValue("card_number") ) ); 493 String expDate = inPaymentMethodElem.attributeValue("expiration_date"); 494 if (expDate != null) 495 { 496 int slashPos = expDate.indexOf('/'); 497 if (slashPos >= 0) 498 { 499 String monthStr = expDate.substring(0, slashPos).trim(); 500 paymentMethod.setExpirationMonth(Integer.parseInt(monthStr)); 501 String yearStr = expDate.substring(slashPos + 1).trim(); 502 paymentMethod.setExpirationYear(Integer.parseInt(yearStr)); 503 } 504 } 505 String note = inPaymentMethodElem.attributeValue("note"); 506 if (note == null) 507 { 508 note = ""; 509 } 510 paymentMethod.setNote(note); 511 String billmelater = inPaymentMethodElem.attributeValue("bill_me_later"); 512 paymentMethod.setBillMeLater("true".equals(billmelater)); 513 return paymentMethod; 514 } 515 516 protected ShippingMethod makeShippingMethod( Store inStore, String inMethodId ) 517 { 518 if (inMethodId == null) 519 { 520 inMethodId = ""; 521 } 522 for (Iterator it = inStore.getAllShippingMethods().iterator(); it.hasNext();) 523 { 524 ShippingMethod method = (ShippingMethod)it.next(); 525 if (method.getId().equals(inMethodId)) 526 { 527 return method; 528 } 529 } 530 return null; 532 } 533 534 protected Address makeAddress( Element inAddressElem ) 535 { 536 Address address = new Address(new MapPropertyContainer()); 537 address.setAddress1(inAddressElem.attributeValue("address1")); 538 address.setAddress2(inAddressElem.attributeValue("address2")); 539 address.setCity(inAddressElem.attributeValue("city")); 540 address.setState(inAddressElem.attributeValue("state")); 541 address.setZipCode(inAddressElem.attributeValue("zip_code")); 542 address.setCountry(inAddressElem.attributeValue("country")); 543 return address; 544 } 545 546 protected String decrypt(String inCreditCard) throws StoreException 547 { 548 if(inCreditCard ==null || inCreditCard.trim().length() == 0 || !inCreditCard.startsWith("DES:")) 549 { 550 return inCreditCard; 551 } 552 long encryptionKey = 7939805759879765L; encryptionKey++; 554 try 555 { 556 StringEncrypter encrypter = new StringEncrypter( StringEncrypter.DES_ENCRYPTION_SCHEME, encryptionKey + "42" + encryptionKey ); 557 String code = inCreditCard.substring(4,inCreditCard.length()); String decryptedString = encrypter.decrypt( code ); 559 return decryptedString; 560 } catch ( Exception ex) 561 { 562 throw new StoreException(ex); 563 } 564 } 565 566 public String encrypt(String inCreditCard) throws StoreException 567 { 568 try 569 { 570 if( inCreditCard == null || inCreditCard.trim().length() == 0) 571 { 572 return inCreditCard; 573 } 574 long encryptionKey = 7939805759879765L; encryptionKey++; 575 StringEncrypter encrypter = new StringEncrypter( StringEncrypter.DES_ENCRYPTION_SCHEME, encryptionKey + "42" + encryptionKey ); 576 String val = encrypter.encrypt( inCreditCard ); 577 return "DES:" + val; 578 } catch ( OpenEditException ex) 579 { 580 throw new StoreException(ex); 581 } 582 } 583 584 585 } | Popular Tags |