/// <summary>
        /// Deletes a product option
        /// </summary>
        /// <param name="option">
        /// The option to be deleted
        /// </param>
        /// <param name="raiseEvents">
        /// Optional boolean indicating whether or not to raise events.
        /// </param>
        /// <remarks>
        /// This performs a check to ensure the option is valid to be deleted
        /// </remarks>
        public void Delete(IProductOption option, bool raiseEvents = true)
        {
            if (!EnsureSafeOptionDelete(option))
            {
                MultiLogHelper.Warn <ProductOptionService>("A ProductOption delete attempt was aborted.  The option cannot be deleted due to it being shared with one or more products.");
                return;
            }

            if (raiseEvents)
            {
                if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs <IProductOption>(option), this))
                {
                    ((ProductOption)option).WasCancelled = true;
                    return;
                }
            }

            using (new WriteLock(Locker))
            {
                var uow = UowProvider.GetUnitOfWork();
                using (var repository = RepositoryFactory.CreateProductOptionRepository(uow))
                {
                    repository.Delete(option);
                    uow.Commit();
                }
            }

            if (raiseEvents)
            {
                Deleted.RaiseEvent(new DeleteEventArgs <IProductOption>(option), this);
            }
        }
示例#2
0
        public HttpResponseMessage PutInvoiceShippingAddress(InvoiceShippingUpdateData data)
        {
            var response = Request.CreateResponse(HttpStatusCode.OK);

            try
            {
                var invoice           = _invoiceService.GetByKey(data.InvoiceKey);
                var shippingLineItems = invoice.ShippingLineItems().ToArray();
                if (shippingLineItems.Any())
                {
                    foreach (var lineItem in shippingLineItems)
                    {
                        lineItem.ExtendedData.AddAddress(data.Address.ToAddress(), Constants.ExtendedDataKeys.ShippingDestinationAddress);
                    }
                }
                else
                {
                    // Problem. There is no shipping line item when there should be! Needs more investigating as this does very, very occasionally happen
                    MultiLogHelper.Warn <InvoiceApiController>(string.Format("No shipping address line item when trying to save shipping address for {0}", invoice.PrefixedInvoiceNumber()));
                }

                _invoiceService.Save(invoice);
            }
            catch (Exception ex)
            {
                MultiLogHelper.Error <InvoiceApiController>("Failed to save shipping address", ex);
                response = Request.CreateResponse(HttpStatusCode.NotFound, string.Format("{0}", ex.Message));
            }

            return(response);
        }
示例#3
0
        /// <summary>
        /// Maps a <see cref="Page{Guid}"/> to <see cref="PagedCollection{TContent}"/>.
        /// </summary>
        /// <param name="page">
        /// The page.
        /// </param>
        /// <param name="sortBy">
        /// The sort by.
        /// </param>
        /// <returns>
        /// The <see cref="PagedCollection"/>.
        /// </returns>
        public virtual PagedCollection <TContent> MapPagedCollection(Page <Guid> page, string sortBy)
        {
            var items = page.Items.Select(GetByKey).Where(x => x != null).ToArray();

            if (items.Count() != page.ItemsPerPage)
            {
                MultiLogHelper.Warn <VirtualContentCache <TContent, TEntity> >("Could not map all items to virtual content");
            }

            return(new PagedCollection <TContent>
            {
                CurrentPage = page.CurrentPage,
                PageSize = items.Count(),
                TotalPages = page.TotalPages,
                TotalItems = page.TotalItems,
                Items = items,
                SortField = sortBy
            });
        }
        /// <summary>
        /// Itemizes the invoice.
        /// </summary>
        /// <returns>
        /// The <see cref="InvoiceItemItemization"/>.
        /// </returns>
        public InvoiceItemItemization Itemize()
        {
            var itemization = this.ItemizeInvoice();

            itemization.Reconciles = true;

            if (!this.Reconcile(itemization))
            {
                itemization.Reconciles = false;
                MultiLogHelper.Warn <InvoiceItemizationStrategyBase>("Reconciliation of invoice total failed in the itemization strategy");
            }

            itemization.ItemizationTotal = itemization.CalculateTotal();
            itemization.InvoiceTotal     = Invoice.Total;
            itemization.ProductTotal     = itemization.CalculateProductTotal();
            itemization.ShippingTotal    = itemization.CalculateShippingTotal();
            itemization.TaxTotal         = itemization.CalculateTaxTotal();
            itemization.AdjustmentTotal  = itemization.CalculateAdjustmentTotal();
            itemization.DiscountTotal    = itemization.CalculateDiscountTotal();
            itemization.CustomTotal      = itemization.CalculateCustomTotal();

            return(itemization);
        }
        /// <summary>
        /// Performs the setup for an express checkout.
        /// </summary>
        /// <param name="invoice">
        /// The <see cref="IInvoice"/>.
        /// </param>
        /// <param name="payment">
        /// The <see cref="IPayment"/>
        /// </param>
        /// <param name="returnUrl">
        /// The return URL.
        /// </param>
        /// <param name="cancelUrl">
        /// The cancel URL.
        /// </param>
        /// <returns>
        /// The <see cref="ExpressCheckoutResponse"/>.
        /// </returns>
        protected virtual PayPalExpressTransactionRecord SetExpressCheckout(IInvoice invoice, IPayment payment, string returnUrl, string cancelUrl)
        {
            var record = new PayPalExpressTransactionRecord
            {
                Success = true,
                Data    = { Authorized = false, CurrencyCode = invoice.CurrencyCode }
            };

            var factory = new PayPalPaymentDetailsTypeFactory(new PayPalFactorySettings {
                WebsiteUrl = _websiteUrl
            });
            var paymentDetailsType = factory.Build(invoice, PaymentActionCodeType.ORDER);

            // The API requires this be in a list
            var paymentDetailsList = new List <PaymentDetailsType>()
            {
                paymentDetailsType
            };

            // ExpressCheckout details
            var ecDetails = new SetExpressCheckoutRequestDetailsType()
            {
                ReturnURL       = returnUrl,
                CancelURL       = cancelUrl,
                PaymentDetails  = paymentDetailsList,
                AddressOverride = "1"
            };

            // Trigger the event to allow for overriding ecDetails
            var ecdOverride = new PayPalExpressCheckoutRequestDetailsOverride(invoice, payment, ecDetails);

            SettingCheckoutRequestDetails.RaiseEvent(new ObjectEventArgs <PayPalExpressCheckoutRequestDetailsOverride>(ecdOverride), this);

            // The ExpressCheckoutRequest
            var request = new SetExpressCheckoutRequestType
            {
                Version = Version,
                SetExpressCheckoutRequestDetails = ecdOverride.ExpressCheckoutDetails
            };

            // Crete the wrapper for Express Checkout
            var wrapper = new SetExpressCheckoutReq
            {
                SetExpressCheckoutRequest = request
            };

            try
            {
                var service  = GetPayPalService();
                var response = service.SetExpressCheckout(wrapper);

                record.SetExpressCheckout = _responseFactory.Build(response, response.Token);
                if (record.SetExpressCheckout.Success())
                {
                    record.Data.Token = response.Token;
                    record.SetExpressCheckout.RedirectUrl = GetRedirectUrl(response.Token);
                }
                else
                {
                    foreach (var et in record.SetExpressCheckout.ErrorTypes)
                    {
                        var code = et.ErrorCode;
                        var sm   = et.ShortMessage;
                        var lm   = et.LongMessage;
                        MultiLogHelper.Warn <PayPalExpressCheckoutService>(string.Format("{0} {1} {2}", code, lm, sm));
                    }

                    record.Success = false;
                }
            }
            catch (Exception ex)
            {
                record.Success            = false;
                record.SetExpressCheckout = _responseFactory.Build(ex);
            }

            return(record);
        }
示例#6
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);
        }
示例#7
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);
        }
示例#8
0
        public QueryResultDisplay SearchInvoices(QueryDisplay query)
        {
            var term             = query.Parameters.FirstOrDefault(x => x.FieldName == "term");
            var invoiceDateStart = query.Parameters.FirstOrDefault(x => x.FieldName == "invoiceDateStart");
            var invoiceDateEnd   = query.Parameters.FirstOrDefault(x => x.FieldName == "invoiceDateEnd");

            var isTermSearch = term != null && !string.IsNullOrEmpty(term.Value);

            var isDateSearch = invoiceDateStart != null && !string.IsNullOrEmpty(invoiceDateStart.Value);

            var startDate = DateTime.MinValue;
            var endDate   = DateTime.MaxValue;

            if (isDateSearch)
            {
                var settings   = _storeSettingService.GetAll().ToList();
                var dateFormat = settings.FirstOrDefault(s => s.Name == "dateFormat");

                if (dateFormat == null)
                {
                    if (!DateTime.TryParse(invoiceDateStart.Value, out startDate))
                    {
                        MultiLogHelper.Warn <InvoiceApiController>(string.Format("Was unable to parse startDate: {0}", invoiceDateStart.Value));
                        startDate = DateTime.MinValue;
                    }
                }
                else if (!DateTime.TryParseExact(invoiceDateStart.Value, dateFormat.Value, CultureInfo.InvariantCulture, DateTimeStyles.None, out startDate))
                {
                    MultiLogHelper.Warn <InvoiceApiController>(string.Format("Was unable to parse startDate: {0}", invoiceDateStart.Value));
                    startDate = DateTime.MinValue;
                }

                endDate = invoiceDateEnd == null || dateFormat == null
                ? DateTime.MaxValue
                : DateTime.TryParseExact(invoiceDateEnd.Value, dateFormat.Value, CultureInfo.InvariantCulture, DateTimeStyles.None, out endDate)
                    ? endDate
                    : DateTime.MaxValue;
            }


            if (isTermSearch && isDateSearch)
            {
                return(_merchello.Query.Invoice.Search(
                           term.Value,
                           startDate,
                           endDate,
                           query.CurrentPage + 1,
                           query.ItemsPerPage,
                           query.SortBy,
                           query.SortDirection));
            }

            if (isTermSearch)
            {
                return(this._merchello.Query.Invoice.Search(
                           term.Value,
                           query.CurrentPage + 1,
                           query.ItemsPerPage,
                           query.SortBy,
                           query.SortDirection));
            }

            if (isDateSearch)
            {
                return(this._merchello.Query.Invoice.Search(
                           startDate,
                           endDate,
                           query.CurrentPage + 1,
                           query.ItemsPerPage,
                           query.SortBy,
                           query.SortDirection));
            }

            return(this._merchello.Query.Invoice.Search(
                       query.CurrentPage + 1,
                       query.ItemsPerPage,
                       query.SortBy,
                       query.SortDirection));
        }