private void CalculateTaxes(OrderGroup order)
		{
			var catalogHelper = new CatalogClient(CatalogRepository, null, null, CacheRepository, null);

			foreach (var form in order.OrderForms)
			{
				decimal totalTaxes = 0;

			    foreach (var shipment in form.Shipments)
				{
					decimal itemTax = 0;
					decimal shippingTax = 0;
					foreach (var shipItem in shipment.ShipmentItems)
					{
						if (shipItem.LineItem == null)
						{
							continue;
						}

						decimal lineItemTaxTotal = 0m;

						// Try getting an address
						var address = GetAddressByName(form, shipment.ShippingAddressId);
						if (address != null) // no taxes if there is no address
						{
							// Try getting an item
							var item = catalogHelper.GetItem(shipItem.LineItem.CatalogItemId);
							if (item != null) // no entry, no tax category, no tax
							{
								var taxCategory = item.TaxCategory;
								// calls the method that returns all the tax values
								var taxes = GetTaxes(taxCategory, Thread.CurrentThread.CurrentCulture.Name, address.CountryCode, address.StateProvince, address.PostalCode, address.RegionName, string.Empty, string.Empty, address.City);

								if (taxes != null && taxes.Any())
								{
									foreach (var tax in taxes)
									{
										if (tax != null)
										{
                                            var taxAmount = Math.Round(shipItem.LineItem.ExtendedPrice * (tax.Percentage / 100), 2);
											if (tax.Tax.TaxType == (int) TaxTypes.SalesTax)
											{
												itemTax += taxAmount;
												lineItemTaxTotal += taxAmount;
												totalTaxes += taxAmount;
											}
											else if (tax.Tax.TaxType == (int) TaxTypes.ShippingTax)
											{
                                                shippingTax += Math.Round(shipment.ShippingCost * (tax.Percentage / 100), 2);
												totalTaxes += shippingTax;
											}
										}
									}
								}
							}
						}
						shipItem.LineItem.TaxTotal = lineItemTaxTotal;
					}

					//TODO Round taxes to money
					shipment.ItemTaxTotal = itemTax;
					shipment.ShippingTaxTotal = shippingTax;
				}
				form.TaxTotal = totalTaxes;
			}
			order.TaxTotal = order.OrderForms.Sum(x=>x.TaxTotal);
		}
		private void ValidateItems()
		{
			//We don't need to validate quantity in the wish list
			var orderForms = CurrentOrderGroup.OrderForms.ToArray();
			var lineItems = orderForms.SelectMany(x => x.LineItems.ToArray());
			var validLineItems = lineItems.Where(x => !String.IsNullOrEmpty(x.CatalogItemId) && !x.CatalogItemId.StartsWith("@"));

			foreach (var lineItem in validLineItems)
			{
				var changeQtyReason = new List<string>();
				bool isUsingBackordersAndPreorders;
				var newQty = GetNewLineItemQty(lineItem, changeQtyReason, out isUsingBackordersAndPreorders);
				if (newQty == 0)
				{
					// Remove item if it reached this stage
					RegisterWarning(WorkflowMessageCodes.ITEM_NOT_AVAILABLE, lineItem, String.Format("Item \"{0}\" has been removed from the cart because it is no longer available", lineItem.DisplayName));
					DeleteLineItemFromShipments(lineItem);
					lineItem.OrderForm.LineItems.Remove(lineItem);
				}
				else
				{
					var delta = lineItem.Quantity - newQty;
					if (delta != 0)
					{
						lineItem.Quantity -= delta;
						ChangeShipmentsLineItemQty(lineItem, delta);
						RegisterWarning(WorkflowMessageCodes.ITEM_QTY_CHANGED, lineItem, String.Format("Item \"{0}\" quantity has been changed", lineItem.DisplayName));
					}

					// update Shipment Status if LineItem InStockQuantity was insufficient and Backorders/Preorders were used.
					if (isUsingBackordersAndPreorders)
					{
						var catalogHelper = new CatalogClient(CatalogRepository, null, null, CacheRepository, null);
						var catalogItem = catalogHelper.GetItem(lineItem.CatalogItemId);
						if (catalogItem != null && catalogItem.TrackInventory)
						{
							var allShipmentContainingLineItem = orderForms
								.SelectMany(x => x.Shipments)
								.Where(x => x.ShipmentItems.Select(si => si.LineItem).Contains(lineItem))
								.ToList();
							allShipmentContainingLineItem.ForEach(x => x.Status = ShipmentStatus.AwaitingInventory.ToString());
						}
					}
				}
			}
		}
        private void AdjustStockItemQuantity(LineItem lineItem)
        {
            if (String.IsNullOrEmpty(lineItem.CatalogItemId) ||
                lineItem.CatalogItemId.StartsWith("@"))
            {
                return;
            }

            var catalogHelper = new CatalogClient(CatalogRepository, null, CustomerSessionService, CacheRepository, InventoryRepository);
            var item = catalogHelper.GetItem(lineItem.CatalogItemId);

			if (item != null && item.TrackInventory)
			{
                var repo = InventoryRepository;
                var inventory = catalogHelper.GetItemInventory(lineItem.CatalogItemId, lineItem.FulfillmentCenterId, false);
			    if (inventory != null)
			    {
				    if (AdjustStockInventoryQuantity(lineItem, inventory))
				    {
					    repo.UnitOfWork.Commit();
				    }
				    else
				    {
					    throw new InvalidWorkflowException(string.Format("Failed to adjust inventory for lineItem {0}", lineItem.LineItemId));
				    }
			    }
			}
        }