/// <summary> /// Cancels or backorders the items in an existing order. /// </summary> /// <param name="args">The args.</param> /// <param name="cancel">if set to <c>true</c> [cancel] else backorder</param> /// <returns>{error:0,desc:""}</returns> private static Dictionary<string, object> CancelBackorderItems(List<object> args, bool cancel) { /*TODO: backorder procedure has uncertain payment stuff going on here * cancel works, backorder works, but changing * */ Dictionary<string, object> j = new Dictionary<string, object>(); using(SqlConnection cn = Site.CreateConnection(true, true)) { cn.Open(); using(SqlTransaction cancelBackorderTransaction = cn.BeginTransaction("Backorder or Cancel")) { bool rollback = true; try { foreach(object line in args) { Dictionary<string, object> fields = (Dictionary<string, object>)line; // never used -->Dictionary<string,object> flag; if(!fields.ContainsKey("serialId") || !fields.ContainsKey("qty")) { Exception e = new Exception("key serialId or qty is missing"); throw e; } int serialId = Convert.ToInt32(fields["serialId"].ToString()); int qty = Convert.ToInt32(fields["qty"].ToString()); /* update the cart table with the number of items to be backordered. */ using(SqlCommand cmd = new SqlCommand("update cart set returnToStock = @return where serialId = @serialId", cn, cancelBackorderTransaction)) { cmd.Parameters.Add("@serialId", SqlDbType.Int).Value = serialId; cmd.Parameters.Add("@return", SqlDbType.Int).Value = qty; cmd.ExecuteNonQuery(); } /* now add the flag that will trigger serial_line.TR_LINE_DEPLETE_INVENTORY*/ /* flag -11 is backorder, flag -12 is cancel */ using(SqlCommand cmd = new SqlCommand("dbo.backorderCancel @serialId,@cancel,@backorder", cn, cancelBackorderTransaction)) { cmd.Parameters.Add("@serialId", SqlDbType.Int).Value = serialId; cmd.Parameters.Add("@cancel", SqlDbType.Bit).Value = cancel; cmd.Parameters.Add("@backorder", SqlDbType.Bit).Value = !cancel; cmd.ExecuteNonQuery(); } /* if this is a cancelation don't create a new order or add to an existing order */ if(cancel) { AddFlagWithTransaction("0", "line", serialId.ToString(), "Quantity of " + qty + " canceled", cn, cancelBackorderTransaction); } else { /* first check to see if an order is already the child of this order * if so, then just add this item to the child order (backorder) * if there is no child order than create the child order now. */ Commerce.Order childOrder; List<Commerce.Order> childOrders = Commerce.Order.GetChildOrdersBySerialId(serialId, cn, cancelBackorderTransaction); if(childOrders.Count == 0) { childOrder = null; } else { childOrder = childOrders[0]; } Commerce.Order order = Commerce.Order.GetOrderBySerialId(serialId, cn, cancelBackorderTransaction); if(childOrder == null) { /* create a new order and add the item's qty to the new order */ /* get the line that will be added to the backorder */ List<Commerce.Line> sourceLines = order.Lines.FindAll(delegate(Commerce.Line ln) { return ln.SerialId == serialId && ln.KitAllocationCartId == ln.CartId; }); /* sort the items by int kitAllocationId */ sourceLines.Sort(delegate(Commerce.Line l1, Commerce.Line l2) { return l1.KitAllocationId.CompareTo(l2.KitAllocationId); }); /* when there is more than one source line, always pick the one with the larget id * this will be the parent/virtual item that needs to be added to the backorder */ Commerce.Line sourceLine = sourceLines[sourceLines.Count - 1]; /* create a new session for the new order */ Session session = new Session(Main.Site, cn, cancelBackorderTransaction); Site.LogOn(order.UserId, session, cn, cancelBackorderTransaction); session.Refresh(false, cn, cancelBackorderTransaction); AddToCartArguments addTocartArgs = new AddToCartArguments(); addTocartArgs["itemNumber"] = sourceLine.ItemNumber; addTocartArgs["qty"] = fields["qty"].ToString(); addTocartArgs["customerLineNumber"] = sourceLine.CustomLineNumber; addTocartArgs["sessionId"] = session.Id.ToString(); addTocartArgs["price"] = sourceLine.Price; addTocartArgs["allowPreorder"] = true; /* add all of the inputs as arguments */ Dictionary<string, object> addToCartArgs = Cart.AddToCart(addTocartArgs, cn, cancelBackorderTransaction); if(Convert.ToInt32(addToCartArgs["error"]) != 0) { Exception e = new Exception(addToCartArgs["description"].ToString()); throw e; } Guid newCartId = new Guid(addToCartArgs["cartId"].ToString()); /* copy all of the order header data into the new order */ using(SqlCommand cmd = new SqlCommand("dbo.duplicateCartDetail @sourceCartId,@targetCartId", cn, cancelBackorderTransaction)) { cmd.Parameters.Add("@sourceCartId", SqlDbType.UniqueIdentifier).Value = new Guid(sourceLine.CartId.ToString()); cmd.Parameters.Add("@targetCartId", SqlDbType.UniqueIdentifier).Value = new Guid(newCartId.ToString()); cmd.ExecuteNonQuery(); } OrderArguments newOrderArgs = new OrderArguments(); newOrderArgs["billToFirstName"] = order.BillToAddress.FirstName; newOrderArgs["billToLastName"] = order.BillToAddress.LastName; newOrderArgs["billToAddress1"] = order.BillToAddress.Address1; newOrderArgs["billToAddress2"] = order.BillToAddress.Address2; newOrderArgs["billToCity"] = order.BillToAddress.City; newOrderArgs["billToState"] = order.BillToAddress.State; newOrderArgs["billToZip"] = order.BillToAddress.Zip; newOrderArgs["billToCountry"] = order.BillToAddress.Country; newOrderArgs["billToHomePhone"] = order.BillToAddress.HomePhone; newOrderArgs["billToWorkPhone"] = order.BillToAddress.WorkPhone; newOrderArgs["billToCompany"] = order.BillToAddress.Company; newOrderArgs["billToComments"] = order.BillToAddress.Comments; newOrderArgs["billToSpecialInstructions"] = order.BillToAddress.SpecialInstructions; newOrderArgs["billToSendShipmentUpdates"] = order.BillToAddress.SendShipmentUpdates; newOrderArgs["FOB"] = order.FOB; newOrderArgs["termId"] = order.TermId; newOrderArgs["userId"] = session.User.UserId; newOrderArgs["manifestNumber"] = order.Manifest; newOrderArgs["purchaseOrder"] = Utilities.Iif(order.PurchaseOrder.Length > 0, order.PurchaseOrder + ">" + order.OrderNumber, ""); newOrderArgs["sessionId"] = session.Id.ToString(); newOrderArgs["shipToRateId"] = -1;/* never put a shipping method on backorders */ newOrderArgs["billToRateId"] = -1; newOrderArgs["shipToEmailAds"] = false; newOrderArgs["billToEmailAds"] = false; newOrderArgs["billToSendShipmentUpdates"] = false; newOrderArgs["shipToFirstName"] = order.ShipToAddress.FirstName; newOrderArgs["shipToLastName"] = order.ShipToAddress.LastName; newOrderArgs["shipToAddress1"] = order.ShipToAddress.Address1; newOrderArgs["shipToAddress2"] = order.ShipToAddress.Address2; newOrderArgs["shipToCity"] = order.ShipToAddress.City; newOrderArgs["shipToState"] = order.ShipToAddress.State; newOrderArgs["shipToZip"] = order.ShipToAddress.Zip; newOrderArgs["shipToCountry"] = order.ShipToAddress.Country; newOrderArgs["shipToHomePhone"] = order.ShipToAddress.HomePhone; newOrderArgs["shipToWorkPhone"] = order.ShipToAddress.WorkPhone; newOrderArgs["shipToCompany"] = order.ShipToAddress.Company; newOrderArgs["shipToComments"] = order.ShipToAddress.Comments; newOrderArgs["shipToSpecialInstructions"] = order.ShipToAddress.SpecialInstructions; newOrderArgs["shipToSendShipmentUpdates"] = order.ShipToAddress.SendShipmentUpdates; newOrderArgs["parentOrderId"] = order.OrderId; newOrderArgs["comments"] = "This order is a backorder from Order " + order.OrderNumber; newOrderArgs.Add("backorder", true); /* place the new backorder */ Dictionary<string, object> newOrder = Commerce.Order.PlaceOrderWithTransaction(newOrderArgs, cn, cancelBackorderTransaction); if(Convert.ToInt32(newOrder["error"]) != 0) { Exception e = new Exception(newOrder["description"].ToString()); throw e; } childOrder = Commerce.Order.GetOrderByOrderNumber((string)newOrder["orderNumber"], cn, cancelBackorderTransaction); j.Add("childOrder", childOrder.GetOrderJson()); } else { /* the child order (backorder) already existed, so add the item to the backorder */ Commerce.Line sourceLine = order.Lines.Find(delegate(Commerce.Line ln) { return ln.SerialId == serialId; }); /* create a new session for the new order */ Session session = new Session(Main.Site, cn, cancelBackorderTransaction); Site.LogOn(childOrder.UserId, session, cn, cancelBackorderTransaction); session.Refresh(false, cn, cancelBackorderTransaction); AddToCartArguments addTocartArgs = new AddToCartArguments(); addTocartArgs["itemNumber"] = sourceLine.ItemNumber; addTocartArgs["qty"] = fields["qty"].ToString(); addTocartArgs["customerLineNumber"] = sourceLine.CustomLineNumber; addTocartArgs["sessionId"] = session.Id.ToString(); addTocartArgs["addressId"] = sourceLine.AddressId.ToString(); addTocartArgs["price"] = sourceLine.Price; addTocartArgs["allowPreorder"] = true; /* add all of the inputs as arguments */ Dictionary<string, object> addToCartArgs = Cart.AddToCart(addTocartArgs, cn, cancelBackorderTransaction); if(Convert.ToInt32(addToCartArgs["error"]) != 0) { Exception e = new Exception(addToCartArgs["description"].ToString()); throw e; } Guid newCartId = new Guid(addToCartArgs["cartId"].ToString()); /* copy all of the order header data into the new order */ using(SqlCommand cmd = new SqlCommand("dbo.duplicateCartDetail @sourceCartId,@targetCartId", cn, cancelBackorderTransaction)) { cmd.Parameters.Add("@sourceCartId", SqlDbType.UniqueIdentifier).Value = new Guid(sourceLine.CartId.ToString()); cmd.Parameters.Add("@targetCartId", SqlDbType.UniqueIdentifier).Value = new Guid(newCartId.ToString()); cmd.ExecuteNonQuery(); } Dictionary<string, object> recalculateArgs = new Dictionary<string, object>(); recalculateArgs.Add("userId", childOrder.UserId); recalculateArgs.Add("orderSessionId", childOrder.SessionId.ToString()); recalculateArgs.Add("cartSessionId", session.Id.ToString()); recalculateArgs.Add("cardType", ""); recalculateArgs.Add("cardNumber", ""); recalculateArgs.Add("expMonth", ""); recalculateArgs.Add("expYear", ""); recalculateArgs.Add("secNumber", ""); recalculateArgs.Add("nameOnCard", ""); recalculateArgs.Add("billToAddressId", childOrder.BillToAddress.Id.ToString()); recalculateArgs.Add("shipToAddressId", childOrder.ShipToAddress.Id.ToString()); recalculateArgs.Add("preview", false); recalculateArgs.Add("purchaseOrder", childOrder.PurchaseOrder); recalculateArgs.Add("backorder", true); Dictionary<string, object> recalculatedOrder = RecalculateOrder(recalculateArgs, cn, cancelBackorderTransaction); if((int)recalculatedOrder["error"] != 0) { Exception e = new Exception(recalculatedOrder["description"].ToString()); throw e; } Commerce.Order _order = Commerce.Order.GetOrderByOrderNumber((string)recalculatedOrder["orderNumber"], cn, cancelBackorderTransaction); j.Add("childOrder", _order.GetOrderJson()); } AddFlagWithTransaction("0", "line", serialId.ToString(), "Quantity of " + qty + " added to backorder " + childOrder.OrderNumber, cn, cancelBackorderTransaction); } } rollback = false; cancelBackorderTransaction.Commit(); j.Add("error", 0); j.Add("description", ""); } catch(Exception e) { rollback = true; j.Add("error", -1); j.Add("description", e.Message); } finally { if(rollback) { cancelBackorderTransaction.Rollback(); } } } } return j; }
/// <summary> /// Process JSON messages. /// Map some messages to methods. /// Map some messages to embedded resources. /// Secondary HTTP Pipeline. /// </summary> /// <param name="httpApp">The Http app.</param> /// <returns>When true, a AJAX responder was called</returns> private static bool processHTTPRequest(HttpApplication httpApp) { /* get the current http context */ bool _JSONResponse = false; HttpContext current = HttpContext.Current; /* start a Timer */ DateTime startHTTPRequest = DateTime.Now; current.Items.Add("startHTTPRequest", startHTTPRequest); /* create a reference to the session object */ Session session = null; string executionFilePath = current.Request.AppRelativeCurrentExecutionFilePath; bool _isVirtualResourcePath = IsVirtualResourcePath(executionFilePath); /* ***1*** make sure user's don't request an invalid file resource by redirecting */ if(Main.AdminDirectory == executionFilePath) { current.Response.Redirect(Main.AdminDirectory + "/", false); current.ApplicationInstance.CompleteRequest(); goto End; } /* ***2*** if this is not a request for a /Admin or /responder directory * implement the rewriter directives */ if(!_isVirtualResourcePath) { /* try to redirect the URL */ if(redirectUrl(current)) { goto End; }; /* try to rewrite the URL */ if(RewriteUrl(current)) { goto End; }; /* site section rewrites */ if(RewriteSiteSection(current)) { goto End; }; /* check for category rewrites */ if(RewriteCategory(current)) { goto End; }; /* check for item rewrites */ if(RewriteItem(current)) { goto End; }; } /* ***3*** don't try and examine the physical path until _after_ the rewrite */ string physicalPath = current.Request.PhysicalPath; bool _isResourceFile = IsResourceFile(physicalPath); /* if this is an image or other non dynamic resource file * and not used in a virtual path than don't do any further processing */ if(_isResourceFile && !_isVirtualResourcePath) { sendNeverExpiresHeaders(); goto End; } /* if this is a public resource, give up the resource now */ foreach(string file in Main.PublicFiles) { if(executionFilePath == file || executionFilePath.StartsWith(Main.AdminDirectory + "/img")) { sendNeverExpiresHeaders(); getResxResource(current); goto End; } } /* no rewrite or redirect so now check if the file exists */ if(!File.Exists(physicalPath) && !_isVirtualResourcePath) { ErrorPage(current, 404, String.Format("Cannot find {0}", physicalPath)); goto End; } /* the file or resource exists (probably) * create a Session * this is resource consuming */ session = new Session(Site); /* place the session object in an object that is only good as long as the http pipeline lasts */ current.Items.Add("currentSession", session); /* raise the after authentication event */ AfterAuthenticationEventArgs args = new AfterAuthenticationEventArgs(session, current); Main.Site.raiseOnAfterAuthentication(args); /* execute AJAX responders - if a responder was executed then end. */ try { if(executeResponders(current, session)) { _JSONResponse = true; goto End; }; } catch(Exception ex) { String.Format("executeResponders exception =>{0}", ex.Message).Debug(0); goto End; } /* check if this is a request for the Admin directory or Admin responder virtual page */ if(_isVirtualResourcePath) { /* don't do anything for people who arn't logged on as administrators, unless we're in setup mode */ if(!session.Administrator) { /* 401 forbidden, and ask for a username / password */ /* RFC 2617 HTTP Authentication: Basic and Digest Access Authentication */ if(current.Request.Headers["Authorization"] != null) { /* user is sending logon attempt via HTTP auth */ string _raw_header = current.Request.Headers["Authorization"]; string[] _hprams = _raw_header.Split(' '); string method = _hprams[0]; string enc_auth = _hprams[1]; /* decode base 64 auth string */ string _raw_auth = Encoding.ASCII.GetString(Convert.FromBase64String(enc_auth)); string[] _auth = _raw_auth.Split(':'); string userName = _auth[0]; string password = _auth[1]; /* try to logon using the provided authentication creditials */ if(session.LogOn(userName, password) == 0) { session.Refresh(); } } /* check again */ if(!session.Administrator) { if(!UseFormsBasedAuth) { current.Response.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", current.Request.Url.DnsSafeHost)); ErrorPage(current, 401, String.Format("Only administrators can access the {0} virtual directory.", Main.AdminDirectory));/* 401 unauthorized */ current.ApplicationInstance.CompleteRequest(); goto End; } else { current.Response.Redirect(Main.PublicDirectory + "/logon.html?rdr=" + executionFilePath.UrlEncode()); current.ApplicationInstance.CompleteRequest(); goto End; } } } sendNeverExpiresHeaders(); /* if this is a request for the Admin directory tree respond with the given Admin resource */ if(!executionFilePath.Contains(Main.AdminResponder)) { getResxResource(current); goto End; } } End: /* fire off events */ EndRequestEventArgs endRequestargs = new EndRequestEventArgs(session, current); Site.raiseOnendrequest(endRequestargs); DateTime endHTTPRequest = DateTime.Now; current.Items.Add("finish_processHTTPRequest", endHTTPRequest); return _JSONResponse; }