Example #1
0
        /// <summary>
        /// Either adds new orderlineitems to an existing order on the invoice or creates a new one
        /// </summary>
        /// <param name="orderLineItem"></param>
        /// <param name="invoice"></param>
        /// <param name="invoiceAdjustmentResult"></param>
        internal InvoiceAdjustmentResult AddOrderLineItemsToInvoice(OrderLineItem orderLineItem, IInvoice invoice,
                                                                    InvoiceAdjustmentResult invoiceAdjustmentResult)
        {
            try
            {
                // We get this fresh, in case there have been orders added in the above method and then we want to add to existing
                // not create lots of individual orders
                var allOrders = GetOrdersByInvoiceKey(invoice.Key).ToArray();

                // Order Key - Use this for adding products to existing orders
                var orderToAddTo = FirstEditableOrderOnInvoice(allOrders);

                // Need to add the order
                if (orderLineItem != null)
                {
                    // The list of orders we will update
                    var ordersToUpdate = new List <IOrder>();

                    // If null we create a new order
                    if (orderToAddTo != null)
                    {
                        // Add the orderlineitems
                        orderToAddTo.Items.Add(orderLineItem);
                        ordersToUpdate.Add(orderToAddTo);
                    }
                    else
                    {
                        // We don't have an open order. So need to create a new one
                        var order = CreateOrder(Core.Constants.OrderStatus.NotFulfilled, invoice.Key);
                        order.OrderNumberPrefix = invoice.InvoiceNumberPrefix;

                        order.Items.Add(orderLineItem);

                        // Add the new order to the invoice
                        ordersToUpdate.Add(order);
                    }

                    // Finally Save the orders
                    Save(ordersToUpdate);
                }

                invoiceAdjustmentResult.Success = true;
            }
            catch (Exception ex)
            {
                MultiLogHelper.Error <OrderService>("Failed to adjust invoice", ex);
                invoiceAdjustmentResult.Success = false;
                invoiceAdjustmentResult.Message = ex.Message;
            }

            return(invoiceAdjustmentResult);
        }
Example #2
0
        /// <summary>
        /// Either adds new orderlineitems to an existing order on the invoice or creates a new one
        /// </summary>
        /// <param name="orderLineItems"></param>
        /// <param name="invoice"></param>
        /// <param name="invoiceAdjustmentResult"></param>
        /// <returns></returns>
        internal InvoiceAdjustmentResult AddOrderLineItemsToInvoice(List <OrderLineItem> orderLineItems, IInvoice invoice,
                                                                    InvoiceAdjustmentResult invoiceAdjustmentResult)
        {
            foreach (var orderLineItem in orderLineItems)
            {
                invoiceAdjustmentResult = AddOrderLineItemsToInvoice(orderLineItem, invoice, invoiceAdjustmentResult);
                if (!invoiceAdjustmentResult.Success)
                {
                    return(invoiceAdjustmentResult);
                }
            }

            invoiceAdjustmentResult.Success = true;
            return(invoiceAdjustmentResult);
        }
Example #3
0
        /// <summary>
        /// Internal method to add products and orders to existing invoice
        /// </summary>
        /// <param name="invoiceOrderShipment"></param>
        /// <param name="invoiceAddItems"></param>
        /// <param name="invoiceAdjustmentResult"></param>
        public virtual InvoiceAdjustmentResult AddNewLineItemsToInvoice(InvoiceOrderShipment invoiceOrderShipment, IEnumerable <InvoiceAddItem> invoiceAddItems, InvoiceAdjustmentResult invoiceAdjustmentResult)
        {
            if (invoiceAdjustmentResult.InvoiceLineItemType == InvoiceLineItemType.Product)
            {
                // Get the current items in a dictionary so we can quickly check the SKU
                var currentLineItemsDict = invoiceOrderShipment.Invoice.Items.ToDictionary(x => x.Sku, x => x);

                // Store the orderlineitems
                var orderLineItems = new List <OrderLineItem>();

                // Loop and add the new products as InvoiceLineItemDisplay to the InvoiceDisplay
                foreach (var invoiceAddItem in invoiceAddItems)
                {
                    // If both null, just skip below
                    if (invoiceAddItem.ProductVariant == null && invoiceAddItem.Product == null)
                    {
                        continue;
                    }

                    // Get the sku to check
                    var sku = invoiceAddItem.Product == null
                        ? invoiceAddItem.ProductVariant.Sku
                        : invoiceAddItem.Product.Sku;

                    // Product Pricing Enabled
                    var productPricingEnabled = MerchelloContext.Gateways.Taxation.ProductPricingEnabled;

                    // Create the lineitem
                    var invoiceLineItem = invoiceAddItem.Product == null
                        ? invoiceAddItem.ProductVariant.ToInvoiceLineItem(invoiceAddItem.Quantity, productPricingEnabled)
                        : invoiceAddItem.Product.ToInvoiceLineItem(invoiceAddItem.Quantity, productPricingEnabled);

                    // See if the current line items have this product/variant
                    if (!currentLineItemsDict.ContainsKey(sku))
                    {
                        invoiceOrderShipment.Invoice.Items.Add(invoiceLineItem);
                    }
                    else
                    {
                        // Already exists, just update qty
                        // Update Quantities
                        foreach (var currentLineItem in invoiceOrderShipment.Invoice.Items)
                        {
                            if (currentLineItem.Sku == sku)
                            {
                                // Update qty by one, as when adding they can only add one product at a time
                                currentLineItem.Quantity++;

                                // Break out of loop
                                break;
                            }
                        }
                    }

                    if (invoiceOrderShipment.HasOrders && invoiceLineItem.IsShippable())
                    {
                        // Add to Order
                        orderLineItems.Add(invoiceLineItem.AsLineItemOf <OrderLineItem>());
                    }
                }

                // Need to add the order
                if (invoiceOrderShipment.HasOrders)
                {
                    // Add to order or create a new one
                    invoiceAdjustmentResult = ((OrderService)_orderService).AddOrderLineItemsToInvoice(orderLineItems, invoiceOrderShipment.Invoice, invoiceAdjustmentResult);
                    if (!invoiceAdjustmentResult.Success)
                    {
                        // Just return if there is an error, don't save anything
                        return(invoiceAdjustmentResult);
                    }
                }

                // Now update invoice and save
                ((InvoiceService)_invoiceService).ReSyncInvoiceTotal(invoiceOrderShipment.Invoice, true);

                invoiceAdjustmentResult.Success = true;
            }
            else
            {
                invoiceAdjustmentResult.Success = false;
                invoiceAdjustmentResult.Message = "Only products can be added";
            }

            return(invoiceAdjustmentResult);
        }
Example #4
0
        /// <summary>
        /// Delete products from an existing invoice
        /// </summary>
        /// <param name="invoiceOrderShipment"></param>
        /// <param name="invoiceAddItems"></param>
        /// <param name="invoiceAdjustmentResult"></param>
        public virtual InvoiceAdjustmentResult DeleteLineItemsFromInvoice(InvoiceOrderShipment invoiceOrderShipment, IEnumerable <InvoiceAddItem> invoiceAddItems, InvoiceAdjustmentResult invoiceAdjustmentResult)
        {
            // Get the items to be deleted in a dictionary by SKU too
            var skusToBeDeleted = invoiceAddItems.Where(x => x.Quantity <= 0).Select(x => x.OriginalSku);

            // Now get the correct items
            var toBeDeleted = invoiceOrderShipment.LineItems.Where(x => skusToBeDeleted.Contains(x.Sku)).ToArray();

            // Can we delete
            var canDelete = true;

            // Check if we have an order
            if (invoiceAdjustmentResult.InvoiceLineItemType == InvoiceLineItemType.Product)
            {
                // Order needs saving
                var saveOrder = false;

                foreach (var lineItem in toBeDeleted)
                {
                    if (lineItem.HasShipment)
                    {
                        // Cannot delete as this lineitem is in a shipment
                        canDelete = false;
                    }
                    else
                    {
                        if (invoiceOrderShipment.HasOrders)
                        {
                            var order = invoiceOrderShipment.Orders.FirstOrDefault(x => x.Key == lineItem.OrderId);
                            if (order != null)
                            {
                                // Remove this orderline item
                                invoiceOrderShipment.Orders.FirstOrDefault(x => x.Key == lineItem.OrderId).Items.RemoveItem(lineItem.Sku);

                                // Save the order
                                saveOrder = true;
                            }
                        }

                        // Remove invoice line item too
                        invoiceOrderShipment.Invoice.Items.RemoveItem(lineItem.Sku);
                    }

                    // Found a product we can't delete so break
                    if (canDelete == false)
                    {
                        break;
                    }

                    // Finally Save the order?
                    if (saveOrder)
                    {
                        foreach (var order in invoiceOrderShipment.Orders.Where(x => x.Key == lineItem.OrderId))
                        {
                            _orderService.Save(order);
                        }
                        saveOrder = false;
                    }
                }
            }

            // If we can delete then do it.
            if (canDelete)
            {
                // Now update invoice and save as well as doing the tax
                ((InvoiceService)_invoiceService).ReSyncInvoiceTotal(invoiceOrderShipment.Invoice, true);

                // Set to true
                invoiceAdjustmentResult.Success = true;
            }
            else
            {
                const string message = "Unable to delete product because there is already an order that has a shipment with one of the products to be deleted. Either delete the shipment or use adjustments to reduce invoice.";
                MultiLogHelper.Warn <InvoiceApiController>(message);
                invoiceAdjustmentResult.Success = false;
                invoiceAdjustmentResult.Message = message;
            }

            return(invoiceAdjustmentResult);
        }
Example #5
0
        /// <summary>
        /// Updates a line item details
        /// </summary>
        /// <param name="invoiceOrderShipment"></param>
        /// <param name="invoiceAddItems"></param>
        /// <param name="invoiceAdjustmentResult"></param>
        /// <returns></returns>
        public virtual InvoiceAdjustmentResult UpdateCustomProductsOnInvoice(InvoiceOrderShipment invoiceOrderShipment,
                                                                             IEnumerable <InvoiceAddItem> invoiceAddItems, InvoiceAdjustmentResult invoiceAdjustmentResult)
        {
            var addItems = invoiceAddItems.ToArray();

            // Get SKU's that need updating
            var skusToEdit = addItems.Where(x => x.NeedsUpdating).Select(x => x.OriginalSku);

            // Get the invoiceordershipmentlineitems
            var lineItems = invoiceOrderShipment.LineItems.Where(x => skusToEdit.Contains(x.Sku));

            // Loops the items to be updated
            foreach (var iosLineItem in lineItems)
            {
                if (iosLineItem.HasShipment)
                {
                    invoiceAdjustmentResult.Message = string.Format("Unable to update, as {0} is in a shipment.", iosLineItem.Name);
                    invoiceAdjustmentResult.Success = false;
                    return(invoiceAdjustmentResult);
                }
            }

            foreach (var invoiceAddItem in addItems)
            {
                // If we get here we're good to update
                // Do the order
                foreach (var order in invoiceOrderShipment.Orders)
                {
                    foreach (var orderItem in order.Items)
                    {
                        if (orderItem.Sku == invoiceAddItem.OriginalSku)
                        {
                            orderItem.Sku      = invoiceAddItem.OriginalSku;
                            orderItem.Name     = invoiceAddItem.OriginalName;
                            orderItem.Quantity = invoiceAddItem.Quantity;
                            orderItem.Price    = invoiceAddItem.OriginalPrice;

                            break;
                        }
                    }
                }

                // Do the invoice
                foreach (var invoiceItem in invoiceOrderShipment.Invoice.Items)
                {
                    if (invoiceItem.Sku == invoiceAddItem.OriginalSku)
                    {
                        invoiceItem.Sku      = invoiceAddItem.OriginalSku;
                        invoiceItem.Name     = invoiceAddItem.OriginalName;
                        invoiceItem.Quantity = invoiceAddItem.Quantity;
                        invoiceItem.Price    = invoiceAddItem.OriginalPrice;

                        break;
                    }
                }
            }


            // If we get here we can update
            foreach (var order in invoiceOrderShipment.Orders)
            {
                _orderService.Save(order);
            }

            // Now update invoice and save as well as doing the tax
            ((InvoiceService)_invoiceService).ReSyncInvoiceTotal(invoiceOrderShipment.Invoice, true);

            // Set to true
            invoiceAdjustmentResult.Success = true;

            return(invoiceAdjustmentResult);
        }
Example #6
0
        public virtual HttpResponseMessage PutInvoiceNewProducts(InvoiceAddItems invoiceAddItems)
        {
            var response = Request.CreateResponse(HttpStatusCode.OK);

            try
            {
                if (invoiceAddItems.Items != null)
                {
                    // Get the invoice and associated data
                    var invoiceOrderShipment = _invoiceService.GetInvoiceOrderShipment(invoiceAddItems.InvoiceKey);

                    if (invoiceOrderShipment.Invoice != null)
                    {
                        //var currentUser = Umbraco.UmbracoContext.Security.CurrentUser;
                        var invoiceAdjustmentResult = new InvoiceAdjustmentResult(invoiceAddItems.LineItemType);

                        // The adjustment type
                        var invoiceAdjustmentType = SetInvoiceAdjustmentType(invoiceAddItems, invoiceOrderShipment);

                        //// Use the merchello helper to get the prdoucts, so the data modifiers are triggered.
                        var merchelloHelper = new MerchelloHelper();

                        // Get the product service
                        var productService = merchelloHelper.Query.Product;

                        // See if we can get the products
                        foreach (var invoiceAddItem in invoiceAddItems.Items)
                        {
                            if (invoiceAddItems.IsAddProduct && invoiceAddItem.Key != Guid.Empty)
                            {
                                invoiceAddItem.ProductVariant = productService.GetProductVariantByKey(invoiceAddItem.Key);
                                invoiceAddItem.Product        = productService.GetByKey(invoiceAddItem.Key);

                                // Complete the Sku too
                                invoiceAddItem.Sku = invoiceAddItem.Product != null ? invoiceAddItem.Product.Sku : invoiceAddItem.ProductVariant.Sku;
                            }
                            else if (!string.IsNullOrWhiteSpace(invoiceAddItem.Sku))
                            {
                                invoiceAddItem.ProductVariant = productService.GetProductVariantBySku(invoiceAddItem.Sku);
                                invoiceAddItem.Product        = productService.GetBySku(invoiceAddItem.Sku);
                            }
                        }

                        // Work out the type of adjustment
                        switch (invoiceAdjustmentType)
                        {
                        case InvoiceAdjustmentType.AddProducts:
                            invoiceAdjustmentResult = AddNewLineItemsToInvoice(invoiceOrderShipment, invoiceAddItems.Items, invoiceAdjustmentResult);
                            break;

                        case InvoiceAdjustmentType.DeleteProduct:
                            invoiceAdjustmentResult = DeleteLineItemsFromInvoice(invoiceOrderShipment, invoiceAddItems.Items, invoiceAdjustmentResult);
                            break;

                        case InvoiceAdjustmentType.UpdateProductDetails:
                            invoiceAdjustmentResult = UpdateCustomProductsOnInvoice(invoiceOrderShipment, invoiceAddItems.Items, invoiceAdjustmentResult);
                            break;
                        }

                        if (!invoiceAdjustmentResult.Success)
                        {
                            response = Request.CreateResponse(HttpStatusCode.Conflict, invoiceAdjustmentResult.Message);
                            MultiLogHelper.Warn <InvoiceApiController>(invoiceAdjustmentResult.Message);
                        }
                    }
                    else
                    {
                        response = Request.CreateResponse(HttpStatusCode.NotFound, "Invoice not found");
                    }
                }
                else
                {
                    response = Request.CreateResponse(HttpStatusCode.NotFound, "No items to update");
                }
            }
            catch (Exception ex)
            {
                MultiLogHelper.Error <InvoiceApiController>("Failed to adjust invoice", ex);
                response = Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }

            return(response);
        }