private void ConfirmPackList(TradevineGateway gateway, IList<Messages.SalesOrder> salesOrders, Dictionary<string, int> headerIndexes, List<string> row)
        {
            string packListID = string.Empty;

            try
            {
                packListID = row[headerIndexes["PackListID"]];
                packListID = packListID.Replace("ID:", string.Empty);
                var id = !string.IsNullOrEmpty(packListID) ? long.Parse(packListID) : (long?)null;
                var courier = row[headerIndexes["Courier"]];
                var trackingReference1 = row[headerIndexes["TrackingReference1"]];
                var trackingReference2 = row[headerIndexes["TrackingReference2"]];

                var salesOrder = salesOrders.FirstOrDefault(x => x.PackLists.Any(y => y.PackListID == id));
                if (null == salesOrder)
                    return;

                var packList = salesOrder.PackLists.Single(x => x.PackListID == id);
                packList.Courier = !string.IsNullOrEmpty(courier) ? int.Parse(courier) : (int?)null;
                packList.TrackingReference = trackingReference1;
                packList.TrackingReference2 = trackingReference2;

                packList.ConfirmOptions = new Messages.ConfirmOptions() { IsInvoiceEmailed = true, IsPackingSlipEmailed = true };

                var output = gateway.Sales.ConfirmPackList(packList);

                Console.WriteLine("Packlist {0} now has status {1}", output.PackListNumber, output.Status);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error confirming packlist {0} : {1} : {2}", packListID, ex.Message, ex.StackTrace);
            }
        }
        private PackList UpdateDeliveryNotesWithProductDescriptions(TradevineGateway gateway, PackList input)
        {
            var originalDeliveryNotes = input.DeliveryNotes;

            foreach (var packListItem in input.PackListItems)
            {
                string productDescription = gateway.Products.GetProductById(packListItem.ProductID.Value).Description;
                string productCode = gateway.Products.GetProductById(packListItem.ProductID.Value).Code;
                if (productCode != "SHIP")
                {
                    productDescription = productDescription.Substring(0, Math.Min(1000, productDescription.Length));

                    if (string.IsNullOrEmpty(input.DeliveryNotes) || !input.DeliveryNotes.Contains(productDescription))
                    {
                        input.DeliveryNotes = (input.DeliveryNotes ?? string.Empty) + productDescription;
                    }
                }
            }

            if (input.DeliveryNotes == originalDeliveryNotes)
                return input;

            Console.WriteLine("Updating delivery notes for {0}", input.PackListNumber);
            var output = gateway.Sales.UpdatePackList(input);

            return output;
        }
        private PackList UpdatePacklistToAwaitingPack(TradevineGateway gateway, PackList input)
        {
            input.Status = Constants.CVs.PackListStatus.Values.AwaitingPack;
            var output = gateway.Sales.UpdatePackList(input);

            Console.WriteLine("Packlist {0} now has status {1}", output.PackListNumber, output.Status);

            return output;
        }
        private void GoCheckProducts(TradevineGateway gateway)
        {
            var products = gateway.Products.GetAllProducts();

            var boughtProductsNeedingStockReduction = products.List.Where(x => x.SoftAllocated > 0 &&
            x.PerWarehouseInventory != null && x.PerWarehouseInventory.Any(y => y.WarehouseCode == "WH2" && y.QuantityInStockSnapshot > 0)).ToList();

            boughtProductsNeedingStockReduction.ForEach(x => ReduceFakeStock(x, gateway));
        }
        private PackList GetFirstAwaitingShipmentPackList(TradevineGateway gateway)
        {
            PackList output = null;
            var salesOrder = gateway.Sales.GetSalesOrders(1, Constants.CVs.SalesOrderStatus.Values.AwaitingShipment, null, null).List.FirstOrDefault();
            if (null != salesOrder)
            {
                output = salesOrder.PackLists.FirstOrDefault(x => x.Status != Constants.CVs.PackListStatus.Values.Completed);
            }

            return output;
        }
        private void ReduceFakeStock(Product product, TradevineGateway gateway)
        {
            var adjustment = new ProductInventory
            {
                ProductID = product.ProductID,
                InventoryType = Constants.CVs.InventoryEntryType.Values.Stocktake,
                QuantityInStockSnapshot = 0M,
                WarehouseCode = "WH2"
            };

            gateway.Products.AdjustProductInventory(adjustment);

            Console.WriteLine("Reducing fake stock for product " + product.Code);
        }
        private void CreateSalesOrder(TradevineGateway gateway, Dictionary<string, int> headerIndexes, List<string> row)
        {
            string orderID = string.Empty;

            try
            {
                var salesOrder = ParseSalesOrderFromRow(headerIndexes, row);

                var output = gateway.Sales.SaveSalesOrder(null, salesOrder);

                Console.WriteLine("Sales Order {0} with reference {1} saved to Tradevine {1}", output.OrderNumber, output.CustomerOrderReference);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error creating sales order {0} : {1} : {2}", orderID, ex.Message, ex.StackTrace);
            }
        }
        private List<PackList> GetAllPendingPackLists(TradevineGateway gateway)
        {
            var output = new List<PackList>();
            var pageNumber = 1;
            var salesOrders = gateway.Sales.GetSalesOrders(pageNumber, Constants.CVs.SalesOrderStatus.Values.AwaitingShipment, null, null);
            if (!salesOrders.List.Any())
                return output;

            while (output.Count < salesOrders.TotalCount)
            {
                output.AddRange(salesOrders.List.SelectMany(x => x.PackLists).Where(y => y.Status == Constants.CVs.PackListStatus.Values.Pending));
                if (salesOrders.TotalCount > output.Count)
                {
                    salesOrders = gateway.Sales.GetSalesOrders(++pageNumber, Constants.CVs.SalesOrderStatus.Values.AwaitingShipment, null, null);
                }
            }

            return output;
        }