Exemplo n.º 1
0
        public bool ProcessPayment(IPayment payment, ref string message)
        {
            try
            {
                Logger.Debug("Klarna checkout gateway. Processing Payment ....");

                if (_orderForm == null)
                {
                    _orderForm = OrderGroup.Forms.FirstOrDefault(form => form.Payments.Contains(payment));
                }

                var authorizePaymentStep = new AuthorizePaymentStep(payment, OrderGroup.MarketId, KlarnaOrderServiceFactory);
                var capturePaymentStep   = new CapturePaymentStep(payment, OrderGroup.MarketId, KlarnaOrderServiceFactory);
                var creditPaymentStep    = new CreditPaymentStep(payment, OrderGroup.MarketId, KlarnaOrderServiceFactory);
                var cancelPaymentStep    = new CancelPaymentStep(payment, OrderGroup.MarketId, KlarnaOrderServiceFactory);

                authorizePaymentStep.SetSuccessor(capturePaymentStep);
                capturePaymentStep.SetSuccessor(creditPaymentStep);
                creditPaymentStep.SetSuccessor(cancelPaymentStep);

                return(authorizePaymentStep.Process(payment, _orderForm, OrderGroup, OrderGroup.GetFirstShipment(), ref message));
            }
            catch (Exception ex)
            {
                Logger.Error("Process checkout failed with error: " + ex.Message, ex);
                message = ex.Message;
                throw;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Pre processes item record adding additional LineItems if needed.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="record">The record.</param>
        private void PreProcessItemRecord(OrderGroup order, PromotionItemRecord record)
        {
            // We do special logic for the gift promotion reward
            if (record.PromotionReward is GiftPromotionReward)
            {
                // Check if item already in the cart, if not add
                if (((GiftPromotionReward)record.PromotionReward).AddStrategy == GiftPromotionReward.Strategy.AddWhenNeeded)
                {
                    // We assume that all affected entries are the gifts that need to be added to the cart
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        LineItem item = FindLineItemByCatalogEntryId(order, entry.CatalogEntryCode);

                        // Didn't find, add it
                        if (item == null)
                        {
                            // we should some kind of delegate or common implementation here so we can use the same function in both discount and front end
                            Entry    catEntry = CatalogContext.Current.GetCatalogEntry(entry.CatalogEntryCode);
                            LineItem lineItem = CreateLineItem(catEntry, entry.Quantity);

                            // Need to determine which order form the entry belongs to (which should be the same as the target entry)

                            // hack: add to the first
                            order.OrderForms[0].LineItems.Add(lineItem);
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        public static List <Discount> GetAllDiscounts(OrderGroup cart)
        {
            var discounts = new List <Discount>();

            foreach (OrderForm form in cart.OrderForms)
            {
                foreach (var discount in form.Discounts.Cast <Discount>().Where(x => !String.IsNullOrEmpty(x.DiscountCode)))
                {
                    AddToDiscountList(discount, discounts);
                }

                foreach (Mediachase.Commerce.Orders.LineItem item in form.LineItems)
                {
                    foreach (var discount in item.Discounts.Cast <Discount>().Where(x => !String.IsNullOrEmpty(x.DiscountCode)))
                    {
                        AddToDiscountList(discount, discounts);
                    }
                }

                foreach (Shipment shipment in form.Shipments)
                {
                    foreach (var discount in shipment.Discounts.Cast <Discount>().Where(x => !String.IsNullOrEmpty(x.DiscountCode)))
                    {
                        AddToDiscountList(discount, discounts);
                    }
                }
            }
            return(discounts);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Adds the discount to line item.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="itemRecord">The item record.</param>
        /// <param name="entryCode">The entry code.</param>
        /// <param name="itemDiscount">The item discount.</param>
        /// <param name="orderLevelDiscount">The order level discount.</param>
        private void AddDiscountToLineItem(OrderGroup order, PromotionItemRecord itemRecord, PromotionEntry promotionEntry,
                                           decimal itemDiscount, decimal orderLevelDiscount)
        {
            LineItem item = FindLineItemByPromotionEntry(order, promotionEntry);

            if (item != null)
            {
                // Add line item properties
                item.LineItemDiscountAmount   += itemDiscount;
                item.OrderLevelDiscountAmount += orderLevelDiscount;
                item.ExtendedPrice             = item.ListPrice * item.Quantity - item.LineItemDiscountAmount - item.OrderLevelDiscountAmount;

                if (itemRecord.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Entry).Key, StringComparison.OrdinalIgnoreCase))
                {
                    LineItemDiscount discount = FindLineItemDiscountById(order, itemRecord.PromotionItem.DataRow.PromotionId, item.LineItemId);

                    if (discount == null)
                    {
                        discount = new LineItemDiscount();
                    }

                    discount.DiscountAmount = itemRecord.PromotionItem.DataRow.OfferAmount;
                    discount.DiscountCode   = itemRecord.PromotionItem.DataRow.CouponCode;
                    discount.DiscountName   = itemRecord.PromotionItem.DataRow.Name;
                    discount.DiscountValue  = itemRecord.PromotionItem.DataRow.OfferAmount;
                    discount.DisplayMessage = GetDisplayName(itemRecord.PromotionItem.DataRow, Thread.CurrentThread.CurrentCulture.Name);
                    discount.LineItemId     = item.LineItemId;
                    discount.DiscountId     = itemRecord.PromotionItem.DataRow.PromotionId;
                    item.Discounts.Add(discount);
                }
            }
        }
 public BuyXFromCategoryGetProductForFreeResult(FulfillmentStatus status, string description, VariationContent variation, OrderGroup group)
 {
     this.Status = status;
     this.Description = description;
     this._variation = variation;
     this._orderGroup = group;
 }
Exemplo n.º 6
0
        protected void Page_Load(object sender, EventArgs e)
        {
            if (LoadOrderGroup())
            {
                //ConfigureDisplay();

                if (!IsPostBack)
                {
                    ConfigureDisplay();

                    // Detect presence of auto-add order and add the javascript to pop the add order window up (if presence detected).
                    if ((!string.IsNullOrEmpty(Request.QueryString[_addorder_QS]) && Request.QueryString[_addorder_QS].ToLower() == "true"))
                    {
                        LaunchAddOrderWindow();
                    }
                }
                else
                {
                    Facade.IOrder facOrder = new Facade.Order();
                    this.IsBeingInvoiced = facOrder.IsOrderBeingInvoiced(OrderGroup.OrderIDs());
                }
            }
            else
            {
                // Invalid order group specified.
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Processes the delete command.
        /// </summary>
        /// <param name="items">The items.</param>
        /// <param name="type">The type.</param>
        void ProcessDeleteCommand(string[] items, string type)
        {
            for (int i = 0; i < items.Length; i++)
            {
                string[] keys = EcfListView.GetPrimaryKeyIdStringItems(items[i]);
                if (keys != null)
                {
                    int  id       = Int32.Parse(keys[0]);
                    Guid customer = new Guid(keys[1]);

                    OrderGroup order = null;
                    if (type == "ShoppingCart")
                    {
                        order = (OrderGroup)OrderContext.Current.GetCart(customer, id);
                    }
                    else if (type == "PaymentPlan")
                    {
                        order = (OrderGroup)OrderContext.Current.GetPaymentPlan(customer, id);
                    }
                    else
                    {
                        order = (OrderGroup)OrderContext.Current.GetPurchaseOrder(customer, id);
                    }

                    if (order != null)
                    {
                        order.Delete();
                        order.AcceptChanges();
                    }
                }
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Processes the table events.
        /// </summary>
        /// <param name="po">The po.</param>
        private void ProcessTableEvents(OrderGroup order)
        {
            foreach (GridItem item in _removedItems)
            {
                //int id = 0;
                //if (item["ShipmentId"] != null && Int32.TryParse(item["ShipmentId"].ToString(), out id))
                //{
                //    // find the existing one
                //    foreach (Shipment shipment in order.OrderForms[0].Shipments)
                //    {
                //        if (shipment.ShipmentId == id)
                //        {
                //            StringCollection shipmentLineItems = shipment.LineItemIndexes;
                //            shipment.Delete();

                //            // update all lineitems that were associated with this shipment
                //            foreach (LineItem li in order.OrderForms[0].LineItems)
                //            {
                //                if (shipmentLineItems.Contains(li.LineItemId.ToString()))
                //                {
                //                    li.ShippingAddressId = String.Empty;
                //                    li.ShippingMethodId = Guid.Empty;
                //                    li.ShippingMethodName = String.Empty;
                //                }
                //            }
                //        }
                //    }
                //}
            }

            _removedItems.Clear();
        }
Exemplo n.º 9
0
        private void UpdateManualDiscounts(OrderGroup orderGroup)
        {
            var lineItems = orderGroup.OrderForms.SelectMany(x => x.LineItems);

            foreach (LineItem lineItem in lineItems)
            {
                var lineItemManualDiscountAmount = 0m;
                foreach (var discount in lineItem.Discounts)
                {
                    if (discount.DiscountName.StartsWith("@"))
                    {
                        var previousDiscountAmount = discount.DiscountValue;

                        if (discount.DiscountName.EndsWith(":PercentageBased", StringComparison.OrdinalIgnoreCase))
                        {
                            discount.DiscountValue = discount.DiscountAmount * 0.01m * lineItem.PlacedPrice * lineItem.Quantity;
                        }
                        else
                        {
                            discount.DiscountValue = discount.DiscountAmount * lineItem.Quantity;
                        }

                        lineItemManualDiscountAmount += discount.DiscountValue - previousDiscountAmount;
                    }
                }

                var extendedPrice = lineItem.GetExtendedPrice(orderGroup.BillingCurrency).Amount;
                lineItemManualDiscountAmount = Math.Min(extendedPrice, lineItemManualDiscountAmount);
                lineItem.TrySetDiscountValue(x => x.EntryAmount, lineItem.TryGetDiscountValue(x => x.EntryAmount) + lineItemManualDiscountAmount);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Calculates the totals.
        /// </summary>
        private void CalculateTotals()
        {
            decimal subTotal = 0m;
            //decimal discountTotal = 0m;
            decimal shippingTotal = 0m;
            decimal handlingTotal = 0m;
            decimal taxTotal      = 0m;
            decimal total         = 0m;

            // Get the property, since it is expensive process, make sure to get it once
            OrderGroup order = OrderGroup;

            // Calculate totals for OrderForms
            foreach (OrderForm form in order.OrderForms)
            {
                // Calculate totals for order form
                CalculateTotalsOrderForms(form);

                subTotal += form.SubTotal;
                //discountTotal += form.DiscountAmount;
                shippingTotal += form.ShippingTotal;
                handlingTotal += form.HandlingTotal;
                taxTotal      += form.TaxTotal;
                total         += form.Total;
            }

            // calculate OrderGroup totals
            order.SubTotal      = subTotal;
            order.ShippingTotal = shippingTotal;
            order.TaxTotal      = taxTotal;
            order.Total         = total;
            order.HandlingTotal = handlingTotal;
        }
Exemplo n.º 11
0
        private IEnumerable <IEnumerable <ProcessingOrder> > ProcessOrderGroup(CreateOrder createModel)
        {
            var orders = this.SelectOrders(createModel);

            var dataGroups = createModel.Dishes
                             .OrderBy(id => id)
                             .GroupBy(key => key, item => item);

            var result = new List <IEnumerable <ProcessingOrder> >(dataGroups.Count());

            foreach (var idGroup in dataGroups)
            {
                var groupKey           = idGroup.Key;
                var correspondingOrder = orders.FirstOrDefault(o => o.Id.Equals(groupKey));

                var item = new OrderGroup(correspondingOrder, idGroup);

                if (!(item is null))
                {
                    var processed = item.Process();
                    result.Add(processed);
                }
            }

            return(result);
        }
Exemplo n.º 12
0
        void btnProducePILs_Click(object sender, EventArgs e)
        {
            if (OrderGroup != null && OrderGroup.Orders.Count > 0)
            {
                NameValueCollection reportParams = new NameValueCollection();
                DataSet             dsPIL        = null;

                Orchestrator.Facade.ICollectDropLoadOrder facLoadOrder = new Orchestrator.Facade.CollectDrop();

                #region Pop-up Report

                dsPIL = facLoadOrder.GetPILData(OrderGroup.OrderIDs());

                //-------------------------------------------------------------------------------------
                //									Load Report Section
                //-------------------------------------------------------------------------------------
                Session[Orchestrator.Globals.Constants.ReportTypeSessionVariable]       = eReportType.PIL;
                Session[Orchestrator.Globals.Constants.ReportParamsSessionVariable]     = reportParams;
                Session[Orchestrator.Globals.Constants.ReportDataSessionTableVariable]  = dsPIL;
                Session[Orchestrator.Globals.Constants.ReportDataSessionSortVariable]   = String.Empty;
                Session[Orchestrator.Globals.Constants.ReportDataMemberSessionVariable] = "Table";

                // Show the user control
                Page.ClientScript.RegisterStartupScript(this.GetType(), "onload",
                                                        "<script language=\"javascript\">window.open('" +
                                                        Page.ResolveClientUrl("../reports/reportviewer.aspx?wiz=true") +
                                                        "');</script>");

                #endregion
            }

            RebindPage();
        }
 /// <summary>
 ///     Finds the name of the address by.
 /// </summary>
 /// <param name="group"></param>
 /// <param name="name">The name.</param>
 /// <returns></returns>
 public static OrderAddress FindAddressByName(OrderGroup group, string name)
 {
     return(string.IsNullOrEmpty(name)
                                ? null
                                : @group.OrderAddresses.FirstOrDefault(
                address => address.Name.Equals(name, StringComparison.OrdinalIgnoreCase)));
 }
 public BuyXFromCategoryGetProductForFreeResult(FulfillmentStatus status, string description, VariationContent variation, OrderGroup group)
 {
     this.Status      = status;
     this.Description = description;
     this._variation  = variation;
     this._orderGroup = group;
 }
 public static OrderAddress FindAddressById(OrderGroup group, string addressId)
 {
     return(String.IsNullOrEmpty(addressId)
                                ? null
                                : @group.OrderAddresses.FirstOrDefault(
                address => address.OrderAddressId.Equals(addressId, StringComparison.OrdinalIgnoreCase)));
 }
Exemplo n.º 16
0
        public static List<Discount> GetAllDiscounts(OrderGroup cart)
        {
            var discounts = new List<Discount>();
            foreach (OrderForm form in cart.OrderForms)
            {
                foreach (var discount in form.Discounts.Cast<Discount>().Where(x => !String.IsNullOrEmpty(x.DiscountCode)))
                {
                    AddToDiscountList(discount, discounts);
                }

                foreach (Mediachase.Commerce.Orders.LineItem item in form.LineItems)
                {
                    foreach (var discount in item.Discounts.Cast<Discount>().Where(x => !String.IsNullOrEmpty(x.DiscountCode)))
                    {
                        AddToDiscountList(discount, discounts);
                    }
                }

                foreach (Shipment shipment in form.Shipments)
                {
                    foreach (var discount in shipment.Discounts.Cast<Discount>().Where(x => !String.IsNullOrEmpty(x.DiscountCode)))
                    {
                        AddToDiscountList(discount, discounts);
                    }
                }
            }
            return discounts;
        }
Exemplo n.º 17
0
        public async Task <ApiResult <PagedResult <GoodsDeliveryNotesDto> > > GetGoodsDeliveryNotePagingAsync(int pageIndex, int pageSize)
        {
            var goodsDeliveryNotes = await(from gdn in _context.GoodsDeliveryNotes
                                           join order in _context.Orders on gdn.OrderId equals order.Id
                                           into OrderGroup
                                           from o in OrderGroup.DefaultIfEmpty()
                                           join employee in _context.Employees on gdn.EmployeeId equals employee.Id
                                           into EmployeeGroup
                                           from e in EmployeeGroup.DefaultIfEmpty()
                                           join sa in _context.StockActions on gdn.StockActionId equals sa.Id
                                           join w in _context.Warehouses on gdn.WarehouseId equals w.Id
                                           join b in _context.Branches on w.BranchId equals b.Id
                                           orderby gdn.Id descending
                                           select new GoodsDeliveryNotesDto()
            {
                Id            = gdn.Id,
                BranchName    = b.Name,
                EmployeeName  = e.Name,
                ExportDate    = gdn.ExportDate,
                OrderId       = o.Id,
                WarehouseName = w.Name,
                StockActionId = sa.Name
            }).GetPagedAsync(pageIndex, pageSize);

            return(new ApiResult <PagedResult <GoodsDeliveryNotesDto> >(HttpStatusCode.OK, goodsDeliveryNotes));
        }
Exemplo n.º 18
0
        /// <summary>
        /// Removing now not aplyied Gift discounts from Order
        /// </summary>
        private void RemoveGiftPromotionFromOrder(OrderGroup order, PromotionContext promoContext)
        {
            var notApliedOldGiftDiscounts = new List <OrderFormDiscount>();

            foreach (OrderFormDiscount discount in order.OrderForms[0].Discounts)
            {
                var promoRecord = promoContext.PromotionResult.PromotionRecords.FirstOrDefault(x => GetGiftPromotionName(x) == discount.DiscountName);
                if (promoRecord == null)
                {
                    notApliedOldGiftDiscounts.Add(discount);
                }
            }

            foreach (OrderFormDiscount toRemoveDiscount in notApliedOldGiftDiscounts)
            {
                toRemoveDiscount.Delete();
                //remove Gift items from order
                var lineitems = order.OrderForms[0].LineItems.ToArray();
                foreach (LineItem lineItem in lineitems)
                {
                    foreach (LineItemDiscount lineItemDiscount in lineItem.Discounts)
                    {
                        if (lineItemDiscount.DiscountName == toRemoveDiscount.DiscountName)
                        {
                            lineItem.Delete();
                        }
                    }
                }
            }
        }
Exemplo n.º 19
0
        public PipelineExecutionResult RunPipeline(OrderGroup og, bool transacted, bool loggingEnabled, String pipelineName, String pipelinePath)
        {
            PipelineBase            pipeline;
            PipelineExecutionResult res;
            PipelineInfo            pipeInfo = CreatePipelineInfo(pipelineName);

            // we attribute the pipeline's run with a log name and it needs to be the absolute path
            // also, it will overwrite the log if that file exists, so we add the orderform's name to provide some
            // sort of scheme that won't overwrite every log
            string pipelineLog = string.Format("{0}\\log\\{1}_{2}.log",
                                               pipelinePath.Substring(0, pipelinePath.LastIndexOf("\\")),
                                               og.OrderForms[0].ParentOrderGroup.Name,
                                               pipelineName);

            pipeline =
                new CommerceServer.Core.Runtime.Pipelines.OrderPipeline(name: pipelineName,
                                                                        pipelineConfigPath: pipelinePath,
                                                                        loggingEnabled: loggingEnabled,
                                                                        logPath: pipelineLog,
                                                                        transactional: transacted);
            res = og.RunPipeline(pipeInfo, pipeline);

            CheckPipelineResultAndPrintWarnings(og, res);

            //Calling dispose on PipelineInfo to release any unmanaged resources
            pipeInfo.Dispose();

            return(res);
        }
Exemplo n.º 20
0
        public void OrderSystem_SerializeTest()
        {
            XmlTextWriter writer     = null; // TODO: Initialize to an appropriate value
            OrderGroup    orderGroup = null; // TODO: Initialize to an appropriate value

            OrderContext.Serialize(writer, orderGroup);
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }
Exemplo n.º 21
0
        public static bool IsModifyable(this Shipment item, OrderGroup order)
        {
            var shipmentStatus = item.GetCurrentStatus(order);
            var orderStatus    = order.GetCurrentStatus();
            var retVal         = orderStatus == (orderStatus & ((int)OrderStatus.AwaitingExchange | (int)OrderStatus.InProgress | (int)OrderStatus.PartiallyShipped | (int)OrderStatus.Pending)) &&
                                 (shipmentStatus == ShipmentStatus.AwaitingInventory.ToString() || shipmentStatus == ShipmentStatus.InventoryAssigned.ToString());

            return(retVal);
        }
Exemplo n.º 22
0
        public static int GetIntegerValue(this OrderGroup orderGroup, string fieldName, int defaultValue)
        {
            if (orderGroup[fieldName] == null)
            {
                return(defaultValue);
            }

            return(int.TryParse(orderGroup[fieldName].ToString(), out var retVal) ? retVal : defaultValue);
        }
Exemplo n.º 23
0
        /// <summary>
        /// Pre processes item record adding additional LineItems if needed.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="record">The record.</param>
        private void PreProcessItemRecord(OrderGroup order, PromotionItemRecord record)
        {
            // We do special logic for the gift promotion reward
            if (record.PromotionReward is GiftPromotionReward)
            {
                // Check if item already in the cart, if not add
                if (((GiftPromotionReward)record.PromotionReward).AddStrategy == GiftPromotionReward.Strategy.AddWhenNeeded)
                {
                    // We assume that all affected entries are the gifts that need to be added to the cart
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        LineItem giftLineItem = FindGiftLineItemInOrder(order, entry.CatalogEntryCode, record);

                        if (!IsOrderHaveSpecifiedGiftPromotion(order, record))
                        {
                            // Didn't find, add it
                            if (giftLineItem == null)
                            {
                                // we should some kind of delegate or common implementation here so we can use the same function in both discount and front end
                                CatalogEntryResponseGroup responseGroup = new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.Variations);
                                Entry catEntry = CatalogContext.Current.GetCatalogEntry(entry.CatalogEntryCode, responseGroup);
                                giftLineItem = AddNewGiftLineItemToOrder(order, catEntry, entry.Quantity);
                                AddGiftItemToAShipment(giftLineItem, giftLineItem.Parent.LineItems.Count - 1);
                                CatalogEntryDto entryDto = CatalogContext.Current.GetCatalogEntryDto(giftLineItem.Code, responseGroup);
                                CatalogEntryDto.CatalogEntryRow entryRow = entryDto.CatalogEntry[0];
                                Money?price = GetItemPrice(entryRow, giftLineItem, CustomerContext.Current.CurrentContact);
                                giftLineItem.ListPrice   = price.HasValue ? price.Value.Amount : 0m;
                                giftLineItem.PlacedPrice = giftLineItem.ListPrice;
                                // populate inventory information for giftLineItem
                                var aggregateInventory = ServiceLocator.Current.GetInstance <IInventoryService>().QueryByEntry(new [] { entryRow.Code });
                                foreach (var inventoryRecord in aggregateInventory)
                                {
                                    PopulateInventoryInfo(inventoryRecord, giftLineItem);
                                }
                            }
                            else
                            {
                                giftLineItem.Quantity = Math.Max(entry.Quantity, giftLineItem.Quantity);

                                var index = giftLineItem.Parent.LineItems.IndexOf(giftLineItem);

                                if (!giftLineItem.Parent.Shipments.SelectMany(x => x.LineItemIndexes).Contains(index.ToString()))
                                {
                                    AddGiftItemToAShipment(giftLineItem, index);
                                }
                            }
                        }
                        else
                        {
                            entry.Quantity = giftLineItem != null?Math.Min(entry.Quantity, giftLineItem.Quantity) : entry.Quantity;
                        }
                        entry.Owner        = giftLineItem;
                        entry.CostPerEntry = giftLineItem != null ? giftLineItem.ListPrice : 0m;
                    }
                }
            }
        }
Exemplo n.º 24
0
        /// <summary>
        /// 获取指定交路下指定出勤点的机组信息
        /// </summary>
        /// <param name="TrainmanJiaolu">人员交路ID</param>
        /// <param name="PlaceIDs">出勤点列表</param>
        ///<param name="TrainmanGUID">乘务员GUID列表</param>
        /// <returns></returns>
        public List <TF.RunSafty.Model.InterfaceModel.OrderGroup> GetOrderGroups(string TrainmanJiaolu, List <string> PlaceIDs, string TrainmanGUID)
        {
            string sqlText = @"select *,
                (select max(dtInRoomTime) from TAB_Plan_InRoom where strTrainmanNumber = strTrainmanNumber1) as InRoomTime1,
                (select max(dtInRoomTime) from TAB_Plan_InRoom where strTrainmanNumber = strTrainmanNumber2) as InRoomTime2, 
                (select max(dtInRoomTime) from TAB_Plan_InRoom where strTrainmanNumber = strTrainmanNumber3) as InRoomTime3, 
                (select max(dtInRoomTime) from TAB_Plan_InRoom where strTrainmanNumber = strTrainmanNumber4) as InRoomTime4 
              from VIEW_Nameplate_TrainmanJiaolu_Order  where 1=1 ";

            if (TrainmanGUID != "")
            {
                sqlText += @"  and (strTrainmanGUID1 = @TrainmanID or strTrainmanGUID2 = @TrainmanID or
                    strTrainmanGUID3 =  @TrainmanID or strTrainmanGUID4 = @TrainmanID) ";
            }
            if (TrainmanJiaolu != "")
            {
                sqlText += " and strTrainmanJiaoluGUID = @Trainmanjiaolu";
            }
            string placewhere = "";

            if (PlaceIDs.Count > 0)
            {
                for (int i = 0; i < PlaceIDs.Count; i++)
                {
                    if (placewhere == "")
                    {
                        placewhere = PlaceIDs[i];
                    }
                    else
                    {
                        placewhere += "," + PlaceIDs[i];
                    }
                }
                sqlText += " and strPlaceID in (@Place)";
            }
            sqlText += " order by groupState,(case when year(dtLastArriveTime)=1899  then 1 else 0 end ),dtLastArriveTime,strTrainmanName1,strTrainmanName2";
            System.Data.SqlClient.SqlParameter[] sqlParams =
            {
                new System.Data.SqlClient.SqlParameter("TrainmanID",     TrainmanGUID),
                new System.Data.SqlClient.SqlParameter("Trainmanjiaolu", TrainmanJiaolu),
                new System.Data.SqlClient.SqlParameter("Place",          placewhere)
            };
            DataTable dtGroups = SqlHelper.ExecuteDataset(SqlHelper.ConnString, CommandType.Text, sqlText, sqlParams).Tables[0];
            List <TF.RunSafty.Model.InterfaceModel.OrderGroup> result = new List <Model.InterfaceModel.OrderGroup>();

            for (int k = 0; k < dtGroups.Rows.Count; k++)
            {
                OrderGroup group = new OrderGroup();
                result.Add(group);
                group.orderID          = dtGroups.Rows[k]["strOrderGUID"].ToString();
                group.order            = int.Parse(dtGroups.Rows[k]["nOrder"].ToString());
                group.trainmanjiaoluID = dtGroups.Rows[k]["strTrainmanJiaoluGUID"].ToString();
                group.lastArriveTime   = Convert.ToDateTime(dtGroups.Rows[k]["dtLastArriveTime"]).ToString("yyyy-MM-dd HH:mm:ss");
                DataRowToGroup(dtGroups.Rows[k], group.group);
            }
            return(result);
        }
Exemplo n.º 25
0
        public override void DataBind()
        {
            OrderGroup paymentPlanById;

            if (base.Request.QueryString["_v"].Equals("PaymentPlan-ObjectView"))
            {
                paymentPlanById = OrderHelper.GetPaymentPlanById(PrincipalInfo.CurrentPrincipal.GetContactId(), this.OrderGroupId);
            }
            else
            {
                paymentPlanById = OrderHelper.GetPurchaseOrderById(this.OrderGroupId);
            }
            OrderGroup             orderGroup             = paymentPlanById;
            Shipment               dataItem               = null;
            ObjectRepeaterDataItem objectRepeaterDataItem = this.DataItem as ObjectRepeaterDataItem;

            if (objectRepeaterDataItem != null && objectRepeaterDataItem.DataItem != null)
            {
                dataItem         = (Shipment)objectRepeaterDataItem.DataItem;
                this._shipmentId = dataItem.Id;
                this.btnShipmentStatus.ContainerId = dataItem.Id.ToString();
                this.btnShipmentStatus.DataBind();
                this.ReturnExchangeButtonsHolder.ContainerId = dataItem.Id.ToString();
                this.ReturnExchangeButtonsHolder.DataBind();
                this.CompletePickupButton.ContainerId = dataItem.Id.ToString();
                this.CompletePickupButton.DataBind();
            }
            if (dataItem != null)
            {
                OrderShipmentStatus orderShipmentStatus = OrderStatusManager.GetOrderShipmentStatus(dataItem);
                this.lblShipStatus.Text = (string)base.GetGlobalResourceObject("OrderStrings", string.Concat(typeof(OrderShipmentStatus).Name, "_", orderShipmentStatus.ToString()));
                Currency currency = new Currency(orderGroup.BillingCurrency);
                decimal  num      = ((IEnumerable <ILineItem>)dataItem.LineItems.ToArray <ILineItem>()).Sum <ILineItem>((ILineItem x) => x.TryGetDiscountValue((ILineItemDiscountAmount y) => y.OrderAmount));
                Label    str      = this.lblItemsSubTotal;
                Money    money    = new Money(dataItem.SubTotal + num, currency);
                //str.Text = money.ToString();
                Label label = this.lblOrderLevelDiscount;
                money = new Money(num, currency);
                //label.Text = money.ToString();
                Label str1 = this.lblOrderSubTotal;
                money = new Money(dataItem.SubTotal, currency);
                //str1.Text = money.ToString();
                Label label1 = this.lblShippingCost;
                money       = new Money(dataItem.ShippingSubTotal, currency);
                label1.Text = money.ToString();
                Label str2 = this.lblShippingDiscount;
                money     = new Money(dataItem.ShippingDiscountAmount, currency);
                str2.Text = money.ToString();
                Label label2 = this.lblShippingTax;
                money       = new Money(dataItem.ShippingTax, currency);
                label2.Text = money.ToString();
                Label str3 = this.lblShipTotal;
                money     = new Money(((dataItem.SubTotal + dataItem.ShippingSubTotal) + dataItem.ShippingTax) - dataItem.ShippingDiscountAmount, currency);
                str3.Text = money.ToString();
            }
        }
Exemplo n.º 26
0
        /// <summary>
        /// Saves the changes.
        /// </summary>
        /// <param name="context">The context.</param>
        public void SaveChanges(IDictionary context)
        {
            OrderGroup order = (OrderGroup)context[_OrderContextObjectString];

            order.Status          = OrderStatusList.SelectedValue;
            order.BillingCurrency = OrderCurrencyList.SelectedValue;
            order.AddressId       = AddressesList.SelectedValue;
            if (!String.IsNullOrEmpty(order.AddressId) && order.OrderForms.Count > 0)
            {
                order.OrderForms[0].BillingAddressId = order.AddressId;
            }

            /*
             * if(typeof(order) == typeof(OrderGroup))
             *  order.TrackingNumber = TrackingNo.Text;
             *
             * order.ExpirationDate = OrderExpires.Value;
             * */

            if (CustomerName.SelectedItem != null)
            {
                order.CustomerId = new Guid(CustomerName.SelectedValue);

                // assign order.CustomerName
                OrderAddress address = null;
                if (!String.IsNullOrEmpty(order.AddressId))
                {
                    if (order.OrderAddresses != null && order.OrderAddresses.Count > 0)
                    {
                        foreach (OrderAddress addr in order.OrderAddresses)
                        {
                            if (String.Compare(addr.Name, order.AddressId, true) == 0)
                            {
                                address = addr;
                                break;
                            }
                        }
                    }
                }
                if (address != null)
                {
                    order.CustomerName = address.FirstName + " " + address.LastName;
                }
                else
                {
                    order.CustomerName = CustomerName.SelectedItem.Text;
                }
            }

            // Save meta data
            MetaDataTab.ObjectId = order.OrderGroupId;
            IDictionary dic = new ListDictionary();

            dic.Add("MetaObjectContext-" + MetaDataTab.Languages[0], order);
            MetaDataTab.SaveChanges(dic);
        }
        private void UpdateGiftLineItems()
        {
            if (!OrderGroup.GetAllLineItems().Any(item => item.IsGift))
            {
                return;
            }

            UpdateGiftLineItemWarehouse();
            UpdateGiftLineItemIndexQuantity();
        }
Exemplo n.º 28
0
 /// <summary>
 /// Gets the line items.
 /// </summary>
 /// <param name="order">The order.</param>
 /// <returns></returns>
 public IEnumerable <LineItem> GetLineItems(OrderGroup order)
 {
     foreach (OrderForm orderForm in order.OrderForms)
     {
         foreach (LineItem lineItem in orderForm.LineItems)
         {
             yield return(lineItem);
         }
     }
 }
        public OrderAddress GetShippingAddress(OrderGroup orderGroup)
        {
            OrderForm orderForm = orderGroup.OrderForms.ToArray().First();

            if (orderForm == null || orderForm.Shipments == null || orderForm.Shipments.Count == 0 || string.IsNullOrEmpty(orderForm.Shipments[0].ShippingAddressId))
            {
                return(null);
            }
            return(orderGroup.OrderAddresses.ToArray().FirstOrDefault(x => x.Name.Equals(orderForm.Shipments[0].ShippingAddressId, StringComparison.OrdinalIgnoreCase)));
        }
Exemplo n.º 30
0
 /// <summary>
 /// Gets the payments.
 /// </summary>
 /// <param name="order">The order.</param>
 /// <returns></returns>
 public IEnumerable <Payment> GetPayments(OrderGroup order)
 {
     foreach (OrderForm orderForm in order.OrderForms)
     {
         foreach (Payment payment in orderForm.Payments)
         {
             yield return(payment);
         }
     }
 }
Exemplo n.º 31
0
        public static string GetCurrentStatus(this Shipment item, OrderGroup order)
        {
            // shipment inherits onHold status from the order
            if (order.GetCurrentStatus() == (int)OrderStatus.OnHold)
            {
                return(ShipmentStatus.OnHold.ToString());
            }

            return(string.IsNullOrEmpty(item.Status) ? ShipmentStatus.InventoryAssigned.ToString() : item.Status);
        }
Exemplo n.º 32
0
        private TestOrderBuilder(OrderGroup order)
        {
            _order = order;

            var orderForm = new OrderForm {
                Name = "default", OrderGroupId = _order.OrderGroupId, OrderGroup = _order
            };

            _order.OrderForms.Add(orderForm);
        }
        /// <summary>
        /// Checks the warehouse assigned to an order line item to determine if it is a valid pickup location
        /// </summary>
        /// <param name="orderGroup">The order group parent for the line item.</param>
        /// <param name="lineItem">The item being processed.</param>
        /// <param name="checkInventory">Set to false to override the check against current stock.</param>
        /// <returns>true if the assigned warehouse is an active pickup location; otherwise false.</returns>
        /// <remarks>
        /// With no shipping method selected, this can only be a "could be valid" check rather than an 
        /// explicit "is valid", and thus this can report positives that will eventually be processed for
        /// delivery instead of pickups.
        /// </remarks>
        private bool IsValidPickupFromLineItem(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory)
        {
            if (string.IsNullOrEmpty(lineItem.WarehouseCode))
            {
                return false;
            }

            var lineApplicationId = lineItem.Parent.Parent.ApplicationId;
            var lineItemWarehouse = WarehouseRepository.Service.List()
                .Where(w => w.ApplicationId == lineApplicationId
                    && w.Code == lineItem.WarehouseCode
                    && w.IsActive
                    && (w.IsPickupLocation || w.IsDeliveryLocation) // TODO: Validate that should be both rather than just pickup
                    )
                .FirstOrDefault();

            if (lineItemWarehouse == null)
            {
                return false;
            }

            // In case lineItem shipping method is InStorePickup , check if lineItemWarehouse is pickup location
            // If not, return false.
            if (lineItem.ShippingMethodName == ShippingManager.PickupShippingMethodName && !lineItemWarehouse.IsPickupLocation)
            {
                return false;
            }
            if (checkInventory == CheckInventoryMode.Ignore)
            {
                return true;
            }

            var catalogKey = new Mediachase.Commerce.Catalog.CatalogKey(lineApplicationId, lineItem.CatalogEntryId);
            var pickupInventory = InventoryService.Service.List(catalogKey).FirstOrDefault(i=>i.WarehouseCode.Equals(lineItem.WarehouseCode, StringComparison.OrdinalIgnoreCase));
            return IsEnoughQuantity(pickupInventory, lineItem);
        }
 /// <summary>
 /// Validates that an order line item has a valid in-store pickup set as its shipment method
 /// </summary>
 /// <param name="orderGroup">The order group parent for the line item.</param>
 /// <param name="lineItem">The item being processed.</param>
 /// <param name="checkInventory">Set to false to override the check against current stock.</param>
 /// <returns>true if the shipment is set and is a valid pickup; otherwise false.</returns>
 /// <remarks>
 /// In the standard workflow process the inventory is checked in a later step by the CheckInventoryActivity, so it may be 
 /// useful to override the inventory processing here.  It also allows us to distinguish between insufficient inventory and 
 /// an error in the warehouse configuration.
 /// </remarks>
 private bool IsValidPickupFromShipment(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory)
 {
     return (GetValidPickupFromShipment(orderGroup, lineItem, checkInventory) != null);
 }
        private LineItem AddNewGiftLineItemToOrder(OrderGroup order, Entry entry, decimal quantity)
        {
            LineItem lineItem = order.OrderForms[0].LineItems.AddNew();

            // If entry has a parent, add parents name
            if (entry.ParentEntry != null)
            {
                lineItem.DisplayName = String.Format("{0}: {1}", entry.ParentEntry.Name, entry.Name);
                lineItem.ParentCatalogEntryId = entry.ParentEntry.ID;
            }
            else
            {
                lineItem.DisplayName = entry.Name;
                lineItem.ParentCatalogEntryId = String.Empty;
            }

            lineItem.Code = entry.ID;
            //Price price = StoreHelper.GetSalePrice(entry, quantity);
            //entry.ItemAttributes always null
            //lineItem.ListPrice = entry.ItemAttributes.ListPrice.Amount;
            lineItem.MaxQuantity = entry.ItemAttributes.MaxQuantity;
            lineItem.MinQuantity = entry.ItemAttributes.MinQuantity;
            lineItem.Quantity = quantity;

            // try to add warehouseCode from shipment record or other line items
            string warehouseCode = string.Empty;
            if (order.OrderForms[0].Shipments.Count > 0)
            {
                warehouseCode = order.OrderForms[0].Shipments[0].WarehouseCode;
            }
            // Add warehouse from existing items in case not specified for gift item
            if (String.IsNullOrEmpty(lineItem.WarehouseCode))
            {
                warehouseCode = order.OrderForms[0].LineItems[0].WarehouseCode;
            }
            if (!String.IsNullOrEmpty(warehouseCode))
            {
                lineItem.WarehouseCode = warehouseCode;
            }
            lineItem.InventoryStatus = (int)GetInventoryStatus(entry, warehouseCode);

            return lineItem;
        }
        /// <summary>
        /// Validates the current warehouse selection for a line item or assigns and returns the appropriate warehouse if needed
        /// </summary>
        /// <param name="orderGroup">The order group that contains the line item.</param>
        /// <param name="lineItem">The item being purchased.</param>
        /// <returns>The Code of the warehouse that should provide the line item, or the empty string if no warehouse can supply the item</returns>
        /// <remarks>
        /// This is the main processing step for the fulfillment process.  Customer implementations that wish to override the fulfillment process
        /// with custom logic (e.g. to enable true multi-warehouse fulfillment) should start by looking here.
        /// IsValidPickupByShipment() and CanBeValidPickupByLineItem() are necessary to support the in-store pickup feature and generally will not
        /// require changes, but please verify that for your implementation.  IsValidPickupByShipment() checks line items that already have a shipment
        /// set, and CanBeValidPickupByLineItem() validates that an order with no shipment can be fulfilled as a pickup.  CanBeValidPickupByLineItem() 
        /// can generate false positives so it may need a closer look.
        /// IsValidFulfillment() is a straightforward check to validate that a (non-pickup) order with a warehouse already assigned can actually 
        /// provide the goods.  The only tricky point is that it does check that the line item is not configured for pickup, and that may not be 
        /// appropriate in some custom setups.
        /// TryDetermineFulfillmentWarehouse() is the holder for the actual warehouse assignment when it has not been assigned already (by the UI or
        /// in an earlier pass) and will hold the key logic for any custom fulfillment implementation.
        /// </remarks>
        private string GetFulfillmentWarehouseForLineItem(OrderGroup orderGroup, LineItem lineItem)
        {
            var returnCode = String.Empty;

            var catalogKey = new Mediachase.Commerce.Catalog.CatalogKey(lineItem.Parent.Parent.ApplicationId, lineItem.CatalogEntryId);
            IWarehouse warehouse = null;

            if (!String.IsNullOrEmpty(lineItem.WarehouseCode))
            {
                // If a warehouse is already assigned, still need to validate whether it can fulfill the order (e.g. activity, fulfillment/pickup) or not
                // Allowing the logic in CheckInventoryActivity deal with the inventory issues, as otherwise the double evaluation can lead to larger order amounts being rejected
                warehouse = WarehouseRepository.Service.Get(lineItem.WarehouseCode);
                if (IsValidPickupFromShipment(orderGroup, lineItem, CheckInventoryMode.Ignore) ||
                    IsValidPickupFromLineItem(orderGroup, lineItem, CheckInventoryMode.Ignore) ||
                    IsValidFulfillment(warehouse, lineItem, CheckInventoryMode.Ignore))
                {
                    return warehouse.Code;
                }
                // Redundant to the inventory amount that will be shown too, but provides useful detail
                Warnings.Add("LineItemUnfulfilled-" + lineItem.Id.ToString(), String.Format("Item \"{0}\" cannot be added to the cart because the assigned warehouse cannot fulfill or provide pickup services for the request.", lineItem.DisplayName));
                return string.Empty;
            }

            warehouse = GetValidPickupFromShipment(orderGroup, lineItem, CheckInventoryMode.Check);
            if (warehouse != null)
            {
                return warehouse.Code;
            }
            warehouse = GetFulfillmentWarehouse(lineItem, checkInventory: CheckInventoryMode.Check);
            if (warehouse != null)
            {
                return warehouse.Code;
            }
            warehouse = GetFulfillmentWarehouse(lineItem, CheckInventoryMode.Ignore);
            if (warehouse != null)
            {
                return warehouse.Code; //TODO: Validate - effectively gets overridden in CheckInventoryActivity, but lets us set an error for the bad config
            }

            // No fallback assignment, this should be an error case not a best guess
            Warnings.Add("LineItemUnfulfilled-" + lineItem.Id.ToString(), String.Format("Item \"{0}\" cannot be added to the cart because of a configuration error.", lineItem.DisplayName));

            return string.Empty;
        }
        /// <summary>
        /// Finds the shipment discount by id.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="promotionId">The promotion id.</param>
        /// <param name="shipmentId">The shipment id.</param>
        /// <returns></returns>
        private ShipmentDiscount FindShipmentDiscountById(OrderGroup order, int promotionId, int shipmentId)
        {
            foreach (OrderForm form in order.OrderForms)
            {
                foreach (Shipment shipment in form.Shipments)
                {
                    if (shipment.ShipmentId == shipmentId)
                    {
                        foreach (ShipmentDiscount discount in shipment.Discounts)
                        {
                            if (discount.DiscountId == promotionId)
                                return discount;
                        }
                    }
                }
            }

            return null;
        }
        /// <summary>
        /// Finds the order form discount by id.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="promotionId">The promotion id.</param>
        /// <param name="orderFormId">The order form id.</param>
        /// <returns></returns>
        private OrderFormDiscount FindOrderFormDiscountById(OrderGroup order, int promotionId, int orderFormId)
        {
            foreach (OrderForm form in order.OrderForms)
            {
                if (form.OrderFormId == orderFormId)
                {
                    foreach (OrderFormDiscount discount in form.Discounts)
                    {
                        if (discount.DiscountId == promotionId)
                            return discount;
                    }
                }
            }

            return null;
        }
        private static LineItem FindLineItemByPromotionEntry(OrderGroup order, PromotionEntry prmotionEntry)
        {
            LineItem retVal = null;

            foreach (OrderForm form in order.OrderForms)
            {
                foreach (LineItem item in form.LineItems)
                {
                    if (item == prmotionEntry.Owner)
                    {
                        retVal = item;
                        break;
                    }
                }

                if (retVal != null)
                    break;
            }

            return retVal;
        }
 private bool IsOrderHaveSpecifiedGiftPromotion(OrderGroup order, PromotionItemRecord promoRecord)
 {
     bool retVal = false;
     foreach (OrderFormDiscount discount in order.OrderForms[0].Discounts)
     {
         if (GetGiftPromotionName(promoRecord) == discount.DiscountName)
         {
             retVal = true;
             break;
         }
     }
     return retVal;
 }
 private LineItem FindGiftLineItemInOrder(OrderGroup order, string catalogEntryId, PromotionItemRecord promoRecord)
 {
     var lineItems = order.OrderForms[0].LineItems.ToArray().Where(x => x.Code == catalogEntryId);
     foreach (var lineitem in lineItems)
     {
         foreach (LineItemDiscount discount in lineitem.Discounts)
         {
             if (discount.DiscountName == GetGiftPromotionName(promoRecord))
             {
                 return lineitem;
             }
         }
     }
     return null;
 }
        private void AddDiscountToLineItem(OrderGroup order, PromotionItemRecord itemRecord, PromotionEntry promotionEntry,
                                          decimal itemDiscount, decimal orderLevelDiscount)
        {
            orderLevelDiscount = Math.Floor(orderLevelDiscount * 100) * 0.01m;
            LineItem item = FindLineItemByPromotionEntry(order, promotionEntry);
            if (item != null)
            {
                //reset gift line item discount
                if (IsGiftLineItem(item))
                {
                    item.PlacedPrice = promotionEntry.CostPerEntry;
                    item.LineItemDiscountAmount = itemDiscount;
                    item.OrderLevelDiscountAmount = 0;
                    item.ExtendedPrice = item.PlacedPrice;
                }
                else
                {
                    // Add line item properties
                    item.LineItemDiscountAmount += itemDiscount;
                    item.OrderLevelDiscountAmount += orderLevelDiscount;
                    item.ExtendedPrice = item.PlacedPrice * item.Quantity - item.LineItemDiscountAmount - item.OrderLevelDiscountAmount;
                }

                if (itemRecord.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Entry).Key, StringComparison.OrdinalIgnoreCase)
                    || itemRecord.PromotionReward is GiftPromotionReward
                    || (itemRecord.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Order).Key,
                        StringComparison.OrdinalIgnoreCase) && itemRecord.PromotionReward.RewardType == PromotionRewardType.EachAffectedEntry))
                {
                    LineItemDiscount discount = FindLineItemDiscountById(order, itemRecord.PromotionItem.DataRow.PromotionId, item.LineItemId);

                    if (discount == null)
                    {
                        discount = new LineItemDiscount();
                        item.Discounts.Add(discount);
                    }

                    var discountName = itemRecord.PromotionItem.DataRow.Name;
                    if (itemRecord.PromotionReward is GiftPromotionReward)
                    {
                        discount.DiscountName = GetGiftPromotionName(itemRecord);
                    }
                    else
                    {
                        discount.DiscountName = String.Format("{0}{1}", itemRecord.PromotionItem.DataRow.Name,
                            itemRecord.PromotionItem.DataRow.OfferType == 1 ? ":PercentageBased" : ":ValueBased");
                    }

                    discount.DiscountAmount = itemRecord.PromotionReward.AmountOff;
                    discount.DiscountCode = itemRecord.PromotionItem.DataRow.CouponCode;

                    discount.DiscountValue = itemDiscount;
                    // use the promotion name if the localized display message is null or empty
                    discount.DisplayMessage = GetDisplayName(itemRecord.PromotionItem.DataRow, Thread.CurrentThread.CurrentCulture.Name);
                    if (string.IsNullOrEmpty(discount.DisplayMessage))
                        discount.DisplayMessage = itemRecord.PromotionItem.DataRow.Name;
                    discount.LineItemId = item.LineItemId;
                    discount.DiscountId = itemRecord.PromotionItem.DataRow.PromotionId;
                }
            }
        }
        /// <summary>
        /// Applies the item discount.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="record">The record.</param>
        /// <param name="totalAmount">The total amount.</param>
        /// <returns></returns>
        private decimal ApplyItemDiscount(OrderGroup order, PromotionItemRecord record, decimal totalAmount)
        {

            decimal discountAmount = 0;
            if (record.PromotionReward.RewardType == PromotionRewardType.AllAffectedEntries)
            {
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    discountAmount = record.AffectedEntriesSet.TotalCost * record.PromotionReward.AmountOff / 100;
                    decimal averageDiscountAmount = discountAmount / record.AffectedEntriesSet.TotalQuantity;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        // Sasha: changed back, CostPerEntry does not change dynamically, while total cost does
                        // AddDiscountToLineItem(order, record, entry, entry.CostPerEntry * entry.Quantity * record.PromotionReward.AmountOff / 100m, 0);
                        // AddDiscountToLineItem(order, record, entry.CatalogEntryCode, averageDiscountAmount * entry.Quantity, 0);
                        AddDiscountToLineItem(order, record, entry, averageDiscountAmount * entry.Quantity, 0);
                    }
                }
                else // need to split discount between all items
                {
                    discountAmount = record.PromotionReward.AmountOff;
                    decimal averageDiscountAmount = record.PromotionReward.AmountOff / record.AffectedEntriesSet.TotalQuantity;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, averageDiscountAmount * entry.Quantity, 0);
                    }
                }
            }
            else if (record.PromotionReward.RewardType == PromotionRewardType.EachAffectedEntry)
            {
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    discountAmount = record.AffectedEntriesSet.TotalCost * record.PromotionReward.AmountOff / 100;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, entry.CostPerEntry * entry.Quantity * record.PromotionReward.AmountOff / 100, 0);
                    }
                }
                else
                {
                    discountAmount = record.AffectedEntriesSet.TotalQuantity * record.PromotionReward.AmountOff;
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        AddDiscountToLineItem(order, record, entry, record.PromotionReward.AmountOff * entry.Quantity, 0);
                    }
                }
            }
            else if (record.PromotionReward.RewardType == PromotionRewardType.WholeOrder)
            {
                decimal percentageOffTotal = 0;
                if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                {
                    decimal extendedCost = 0;
                    foreach (OrderForm orderForm in order.OrderForms)
                    {
                        extendedCost += orderForm.LineItems.ToArray().Sum(x => x.ExtendedPrice);
                    }
                    // calculate percentage adjusted by the running amount, so it will be a little less if running amount is less than total
                    percentageOffTotal = (record.PromotionReward.AmountOff / 100) * (totalAmount / extendedCost);
                    //percentageOffTotal = PromotionReward.AmountOff / 100;
                    discountAmount = totalAmount * record.PromotionReward.AmountOff / 100;
                }
                else
                {
                    // Calculate percentage off discount price
                    if (totalAmount > 0)
                    {
                        percentageOffTotal = record.PromotionReward.AmountOff / totalAmount;
                        // but since CostPerEntry is not an adjusted price, we need to take into account additional discounts already applied
                        percentageOffTotal = percentageOffTotal * (totalAmount / record.AffectedEntriesSet.TotalCost);
                    }
                    else
                    {
                        percentageOffTotal = 100m;
                    }

                    discountAmount = record.PromotionReward.AmountOff;
                }

                // Now distribute discount amount evenly over all entries taking into account running total
                // Special case for shipments, we consider WholeOrder to be a shipment
                if (!record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key, StringComparison.OrdinalIgnoreCase))
                {
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        LineItem item = FindLineItemByPromotionEntry(order, entry);
                        AddDiscountToLineItem(order, record, entry, 0, item.ExtendedPrice * percentageOffTotal);
                    }
                }
            }

            // Save discounts
            if (record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Order).Key, StringComparison.OrdinalIgnoreCase)
                || record.PromotionReward is GiftPromotionReward)
            {
                if (record.PromotionReward.RewardType == PromotionRewardType.WholeOrder)
                {
                    OrderFormDiscount discount = FindOrderFormDiscountById(order, record.PromotionItem.DataRow.PromotionId, Int32.Parse(record.AffectedEntriesSet.OrderFormId));
                    bool hasOrderFormDiscount = true;
                    if (discount == null)
                    {
                        discount = new OrderFormDiscount();
                        hasOrderFormDiscount = false;
                    }

                    var discountName = record.PromotionItem.DataRow.Name;
                    if (record.PromotionReward is GiftPromotionReward)
                    {
                        discountName = GetGiftPromotionName(record);
                    }
                    discount.DiscountName = discountName;

                    discount.DiscountAmount = record.PromotionReward.AmountOff;
                    discount.DiscountCode = record.PromotionItem.DataRow.CouponCode;
                    discount.DiscountValue = hasOrderFormDiscount ? discountAmount + discount.DiscountValue : discountAmount;
                    discount.DisplayMessage = GetDisplayName(record.PromotionItem.DataRow, Thread.CurrentThread.CurrentCulture.Name);
                    discount.OrderFormId = Int32.Parse(record.AffectedEntriesSet.OrderFormId);
                    discount.DiscountId = record.PromotionItem.DataRow.PromotionId;

                    foreach (OrderForm form in order.OrderForms)
                    {
                        if (form.OrderFormId == discount.OrderFormId && !hasOrderFormDiscount)
                            form.Discounts.Add(discount);
                    }
                }
            }
            else if (record.PromotionItem.DataRow.PromotionGroup.Equals(PromotionGroup.GetPromotionGroup(PromotionGroup.PromotionGroupKey.Shipping).Key, StringComparison.OrdinalIgnoreCase))
            {
                ShipmentDiscount discount = FindShipmentDiscountById(order, record.PromotionItem.DataRow.PromotionId, Int32.Parse(record.AffectedEntriesSet.ShipmentId));

                if (discount == null)
                    discount = new ShipmentDiscount();

                discount.DiscountAmount = record.PromotionReward.AmountOff;
                discount.DiscountCode = record.PromotionItem.DataRow.CouponCode;
                discount.DiscountName = record.PromotionItem.DataRow.Name;
                discount.DisplayMessage = GetDisplayName(record.PromotionItem.DataRow, Thread.CurrentThread.CurrentCulture.Name);
                discount.ShipmentId = Int32.Parse(record.AffectedEntriesSet.ShipmentId);
                discount.DiscountId = record.PromotionItem.DataRow.PromotionId;

                foreach (OrderForm form in order.OrderForms)
                {
                    foreach (Shipment shipment in form.Shipments)
                    {
                        if (shipment.ShipmentId == discount.ShipmentId)
                        {
                            shipment.Discounts.Add(discount);

                            if (record.PromotionReward.AmountType == PromotionRewardAmountType.Percentage)
                            {
                                discountAmount = shipment.ShippingSubTotal * record.PromotionReward.AmountOff / 100;
                            }
                            else
                            {
                                discountAmount = Math.Min(record.PromotionReward.AmountOff, shipment.ShippingSubTotal);
                            }

                            shipment.ShippingDiscountAmount = Math.Min(shipment.ShippingDiscountAmount + discountAmount, shipment.ShippingSubTotal);
                            // ShippingDiscountAmount will not be subtracted from the ShipmentTotal per discussions on 2/22/2012.
                            break;
                        }
                    }
                }
                discount.DiscountValue = discountAmount;
            }
            return discountAmount;
        }
        /// <summary>
        /// Checks the warehouse assigned to an order line item to determine if it is a valid pickup location
        /// </summary>
        /// <param name="orderGroup">The order group parent for the line item.</param>
        /// <param name="lineItem">The item being processed.</param>
        /// <param name="checkInventory">Set to false to override the check against current stock.</param>
        /// <returns>true if the assigned warehouse is an active pickup location; otherwise false.</returns>
        /// <remarks>
        /// With no shipping method selected, this can only be a "could be valid" check rather than an 
        /// explicit "is valid", and thus this can report positives that will eventually be processed for
        /// delivery instead of pickups.
        /// </remarks>
        private bool IsValidPickupFromLineItem(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory)
        {
            if (string.IsNullOrEmpty(lineItem.WarehouseCode))
            {
                return false;
            }

            var lineApplicationId = lineItem.Parent.Parent.ApplicationId;
            var lineItemWarehouse = WarehouseRepository.List()
                .Where(w => w.ApplicationId == lineApplicationId
                    && w.Code == lineItem.WarehouseCode
                    && w.IsActive
                    && (w.IsPickupLocation || w.IsDeliveryLocation) // TODO: Validate that should be both rather than just pickup
                    )
                .FirstOrDefault();

            if (lineItemWarehouse == null)
            {
                return false;
            }

            // In case lineItem shipping method is InStorePickup , check if lineItemWarehouse is pickup location
            // If not, return false.
            if (lineItem.ShippingMethodName == ShippingManager.PickupShippingMethodName && !lineItemWarehouse.IsPickupLocation)
            {
                return false;
            }
            if (checkInventory == CheckInventoryMode.Ignore)
            {
                return true;
            }

            return IsEnoughQuantity(lineItem, lineItemWarehouse.Code);
        }
        /// <summary>
        /// Matches the shipment information attached to an order line item to against the pickup warehouses to find the source warehouse, or 
        /// validates the assigned warehouse if one is set already
        /// </summary>
        /// <param name="orderGroup">The order group parent for the line item.</param>
        /// <param name="lineItem">The item being processed.</param>
        /// <param name="checkInventory">Set to false to override the check against current stock.</param>
        /// <returns>the matching warehouse if all of the following are true: the shipment is set, is a valid active pickup location, and matches the line 
        /// item warehouse (if set); otherwise null.</returns>
        private IWarehouse GetValidPickupFromShipment(OrderGroup orderGroup, LineItem lineItem, CheckInventoryMode checkInventory)
        {
            var shippingMethod = ShippingManager.GetShippingMethod(lineItem.ShippingMethodId).ShippingMethod.FirstOrDefault();
            if (shippingMethod == null || !ShippingManager.IsHandoffShippingMethod(shippingMethod.Name))
            {
                return null;
            }

            var pickupAddress = orderGroup.OrderAddresses.ToArray().FirstOrDefault(x => x.Name == lineItem.ShippingAddressId);
            if (pickupAddress == null)
            {
                return null;
            }

            var pickupWarehouse = ShippingManager.GetHandoffLocationFromAddressName(pickupAddress.Name);
            if (pickupWarehouse == null || (!string.IsNullOrEmpty(lineItem.WarehouseCode) && (pickupWarehouse.Code != lineItem.WarehouseCode)))
            {
                return null;
            }

            var lineApplicationId = lineItem.Parent.Parent.ApplicationId;
            if ((pickupWarehouse.ApplicationId != lineApplicationId) || !pickupWarehouse.IsActive || (!pickupWarehouse.IsPickupLocation && !pickupWarehouse.IsDeliveryLocation))
            {
                return null;
            }

            if (checkInventory == CheckInventoryMode.Check)
            {
                var catalogKey = new Mediachase.Commerce.Catalog.CatalogKey(lineApplicationId, lineItem.CatalogEntryId);
                var pickupInventory = InventoryService.Service.Get(catalogKey, pickupWarehouse);

                if (pickupInventory == null)
                {
                    return null;
                }
                if (!IsEnoughQuantity(pickupInventory, lineItem))
                {
                    pickupWarehouse = null;
                }
            }

            return pickupWarehouse;
        }
        /// <summary>
        /// Removing now not aplyied Gift discounts from Order 
        /// </summary>
        private void RemoveGiftPromotionFromOrder(OrderGroup order, PromotionContext promoContext)
        {
            var notApliedOldGiftDiscounts = new List<OrderFormDiscount>();

            foreach (OrderFormDiscount discount in order.OrderForms[0].Discounts)
            {
                var promoRecord = promoContext.PromotionResult.PromotionRecords.FirstOrDefault(x => GetGiftPromotionName(x) == discount.DiscountName);
                if (promoRecord == null)
                {
                    notApliedOldGiftDiscounts.Add(discount);
                }
            }

            foreach (OrderFormDiscount toRemoveDiscount in notApliedOldGiftDiscounts)
            {
                toRemoveDiscount.Delete();
                //remove Gift items from order
                var lineitems = order.OrderForms[0].LineItems.ToArray();
                foreach (LineItem lineItem in lineitems)
                {
                    foreach (LineItemDiscount lineItemDiscount in lineItem.Discounts)
                    {
                        if (lineItemDiscount.DiscountName == toRemoveDiscount.DiscountName)
                        {
                            lineItem.Delete();
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Finds the line item discount by id.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="promotionId">The promotion id.</param>
        /// <param name="lineItemId">The line item id.</param>
        /// <returns></returns>
        private LineItemDiscount FindLineItemDiscountById(OrderGroup order, int promotionId, int lineItemId)
        {
            foreach (OrderForm form in order.OrderForms)
            {
                foreach (LineItem lineItem in form.LineItems)
                {
                    foreach (LineItemDiscount discount in lineItem.Discounts)
                    {
                        if (discount.DiscountId == promotionId && discount.LineItemId == lineItemId && discount.ObjectState != MetaDataPlus.MetaObjectState.Deleted)
                            return discount;
                    }
                }
            }

            return null;
        }
        /// <summary>
        /// Pre processes item record adding additional LineItems if needed.
        /// </summary>
        /// <param name="order">The order.</param>
        /// <param name="record">The record.</param>
        private void PreProcessItemRecord(OrderGroup order, PromotionItemRecord record)
        {
            // We do special logic for the gift promotion reward
            if (record.PromotionReward is GiftPromotionReward)
            {
                // Check if item already in the cart, if not add
                if (((GiftPromotionReward)record.PromotionReward).AddStrategy == GiftPromotionReward.Strategy.AddWhenNeeded)
                {
                    // We assume that all affected entries are the gifts that need to be added to the cart
                    foreach (PromotionEntry entry in record.AffectedEntriesSet.Entries)
                    {
                        LineItem giftLineItem = FindGiftLineItemInOrder(order, entry.CatalogEntryCode, record);

                        if (!IsOrderHaveSpecifiedGiftPromotion(order, record))
                        {
                            // Didn't find, add it
                            if (giftLineItem == null)
                            {
                                // we should some kind of delegate or common implementation here so we can use the same function in both discount and front end
                                CatalogEntryResponseGroup responseGroup = new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.Variations);
                                Entry catEntry = CatalogContext.Current.GetCatalogEntry(entry.CatalogEntryCode, responseGroup);
                                giftLineItem = AddNewGiftLineItemToOrder(order, catEntry, entry.Quantity);
                                AddGiftItemToAShipment(giftLineItem);
                                CatalogEntryDto entryDto = CatalogContext.Current.GetCatalogEntryDto(giftLineItem.Code, responseGroup);
                                CatalogEntryDto.CatalogEntryRow entryRow = entryDto.CatalogEntry[0];
                                Money? price = GetItemPrice(entryRow, giftLineItem, CustomerContext.Current.CurrentContact);
                                giftLineItem.ListPrice = price.HasValue ? price.Value.Amount : 0m;
                                giftLineItem.PlacedPrice = giftLineItem.ListPrice;
                                // populate inventory information for giftLineItem
                                IWarehouseInventory aggregateInventory = ServiceLocator.Current.GetInstance<IWarehouseInventoryService>().GetTotal(new CatalogKey(entryRow));
                                PopulateInventoryInfo(aggregateInventory, giftLineItem);
                            }
                            else
                            {
                                giftLineItem.Quantity = Math.Max(entry.Quantity, giftLineItem.Quantity);
                            }
                        }
                        else
                        {
                            entry.Quantity = giftLineItem != null ? Math.Min(entry.Quantity, giftLineItem.Quantity) : entry.Quantity;
                        }
                        entry.Owner = giftLineItem;
                        entry.CostPerEntry = giftLineItem != null ? giftLineItem.ListPrice : 0m;
                    }
                }
            }
        }