Esempio n. 1
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);
        }
Esempio n. 2
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);
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        /// <summary>
        /// Sets the adjustment type
        /// </summary>
        /// <param name="invoiceAddItems"></param>
        /// <param name="invoiceOrderShipment"></param>
        /// <returns></returns>
        public virtual InvoiceAdjustmentType SetInvoiceAdjustmentType(InvoiceAddItems invoiceAddItems, InvoiceOrderShipment invoiceOrderShipment)
        {
            if (invoiceOrderShipment.Invoice != null)
            {
                // If there is more than one item it's adding products
                if (invoiceAddItems.IsAddProduct)
                {
                    return(InvoiceAdjustmentType.AddProducts);
                }

                // If there are any with 0 for qty it's a delete
                if (invoiceAddItems.Items.Any(x => x.Quantity <= 0))
                {
                    return(InvoiceAdjustmentType.DeleteProduct);
                }

                // Lastly see if any updates
                if (invoiceAddItems.Items.Any(x => x.NeedsUpdating))
                {
                    return(InvoiceAdjustmentType.UpdateProductDetails);
                }
            }

            // Default type which is ignored
            return(InvoiceAdjustmentType.General);
        }