private PlaceOrderResult PlaceOrder(Order newOrder, Customer customer) { var processPaymentRequest = new ProcessPaymentRequest(); processPaymentRequest.StoreId = newOrder.StoreId; processPaymentRequest.CustomerId = customer.Id; processPaymentRequest.PaymentMethodSystemName = newOrder.PaymentMethodSystemName; PlaceOrderResult placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest); return(placeOrderResult); }
public async Task <PlaceOrderResult> PlaceOrder(Pair pair, decimal amountToBuyInQuoteCurrency) { var result = new PlaceOrderResult(); using (var binance = new BinanceClient()) { var response = await binance.Spot.Order.PlaceOrderAsync(ToBinanceSymbol(pair.QuoteCurrency, pair.BaseCurrency), OrderSide.Buy, OrderType.Market, quoteOrderQuantity : amountToBuyInQuoteCurrency); if (response.Success) { result.Message = $"Market Buy Order placed: {response.Data.Quantity} {pair.BaseCurrency} / {response.Data.QuoteQuantityFilled} {pair.QuoteCurrency}"; result.Success = true; } else { result.Message = $"Error while placing Order: {response.Error?.Message}"; } } return(result); }
public async Task <PlaceOrderResult> PlaceOrder(Pair pair, decimal amountToBuyInQuoteCurrency) { var result = new PlaceOrderResult(); using (var huobi = new HuobiClient()) { var accounts = await huobi.GetAccountsAsync(); var response = await huobi.PlaceOrderAsync(accounts.Data.Single().Id, ToHuobiSymbol(pair.QuoteCurrency, pair.BaseCurrency), HuobiOrderType.MarketBuy, amountToBuyInQuoteCurrency); if (response.Success) { result.Message = $"Market Buy Order placed. ID: {response.Data}"; result.Success = true; } else { result.Message = $"Error while placing Order: {response.Error?.Message}"; } } return(result); }
public ActionResult ConfirmOrder(FormCollection form) { //validation var storeId = _storeContext.CurrentStore.Id; var customer = _workContext.CurrentCustomer; var cart = customer.GetCartItems(ShoppingCartType.ShoppingCart, storeId); if (cart.Count == 0) { return(RedirectToRoute("ShoppingCart")); } if ((customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed)) { return(new HttpUnauthorizedResult()); } var model = new CheckoutConfirmModel(); PlaceOrderResult placeOrderResult = null; PostProcessPaymentRequest postProcessPaymentRequest = null; try { var processPaymentRequest = _httpContext.Session["OrderPaymentInfo"] as ProcessPaymentRequest; if (processPaymentRequest == null) { //Check whether payment workflow is required if (IsPaymentWorkflowRequired(cart)) { return(RedirectToAction("PaymentMethod")); } processPaymentRequest = new ProcessPaymentRequest(); } //prevent 2 orders being placed within an X seconds time frame if (!IsMinimumOrderPlacementIntervalValid(customer)) { throw new Exception(T("Checkout.MinOrderPlacementInterval")); } //place order processPaymentRequest.StoreId = storeId; processPaymentRequest.CustomerId = customer.Id; processPaymentRequest.PaymentMethodSystemName = customer.GetAttribute <string>(SystemCustomerAttributeNames.SelectedPaymentMethod, _genericAttributeService, storeId); var placeOrderExtraData = new Dictionary <string, string>(); placeOrderExtraData["CustomerComment"] = form["customercommenthidden"]; placeOrderExtraData["SubscribeToNewsLetter"] = form["SubscribeToNewsLetterHidden"]; placeOrderExtraData["AcceptThirdPartyEmailHandOver"] = form["AcceptThirdPartyEmailHandOverHidden"]; placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest, placeOrderExtraData); if (!placeOrderResult.Success) { model.Warnings.AddRange(placeOrderResult.Errors.Select(x => HtmlUtils.ConvertPlainTextToHtml(x))); } } catch (Exception exception) { Logger.Warn(exception, exception.Message); if (!model.Warnings.Any(x => x == exception.Message)) { model.Warnings.Add(exception.Message); } } if (placeOrderResult == null || !placeOrderResult.Success || model.Warnings.Any()) { return(View(model)); } try { postProcessPaymentRequest = new PostProcessPaymentRequest { Order = placeOrderResult.PlacedOrder }; _paymentService.PostProcessPayment(postProcessPaymentRequest); } catch (Exception exception) { NotifyError(exception); } finally { _httpContext.Session["OrderPaymentInfo"] = null; _httpContext.RemoveCheckoutState(); } if (postProcessPaymentRequest != null && postProcessPaymentRequest.RedirectUrl.HasValue()) { return(Redirect(postProcessPaymentRequest.RedirectUrl)); } return(RedirectToAction("Completed")); }
/// <summary> /// Places an order /// </summary> /// <param name="processPaymentRequest">Process payment request</param> /// <returns>Place order result</returns> public override PlaceOrderResult PlaceOrder(ProcessPaymentRequest processPaymentRequest) { //think about moving functionality of processing recurring orders (after the initial order was placed) to ProcessNextRecurringPayment() method if (processPaymentRequest == null) throw new ArgumentNullException("processPaymentRequest"); var result = new PlaceOrderResult(); try { if (processPaymentRequest.OrderGuid == Guid.Empty) processPaymentRequest.OrderGuid = Guid.NewGuid(); //prepare order details var details = PreparePlaceOrderDetails(processPaymentRequest); #region Payment workflow //process payment ProcessPaymentResult processPaymentResult = null; //skip payment workflow if order total equals zero var skipPaymentWorkflow = details.OrderTotal == decimal.Zero; if (!skipPaymentWorkflow) { var paymentMethod = _paymentService.LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName); if (paymentMethod == null) throw new NopException("Payment method couldn't be loaded"); //ensure that payment method is active if (!paymentMethod.IsPaymentMethodActive(_paymentSettings)) throw new NopException("Payment method is not active"); if (!processPaymentRequest.IsRecurringPayment) { if (details.IsRecurringShoppingCart) { //recurring cart var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName); switch (recurringPaymentType) { case RecurringPaymentType.NotSupported: throw new NopException("Recurring payments are not supported by selected payment method"); case RecurringPaymentType.Manual: case RecurringPaymentType.Automatic: processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest); break; default: throw new NopException("Not supported recurring payment type"); } } else { //standard cart processPaymentResult = _paymentService.ProcessPayment(processPaymentRequest); } } else { if (details.IsRecurringShoppingCart) { //Old credit card info processPaymentRequest.CreditCardType = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardType) : ""; processPaymentRequest.CreditCardName = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardName) : ""; processPaymentRequest.CreditCardNumber = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardNumber) : ""; processPaymentRequest.CreditCardCvv2 = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardCvv2) : ""; try { processPaymentRequest.CreditCardExpireMonth = details.InitialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(details.InitialOrder.CardExpirationMonth)) : 0; processPaymentRequest.CreditCardExpireYear = details.InitialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(details.InitialOrder.CardExpirationYear)) : 0; } catch { } var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName); switch (recurringPaymentType) { case RecurringPaymentType.NotSupported: throw new NopException("Recurring payments are not supported by selected payment method"); case RecurringPaymentType.Manual: processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest); break; case RecurringPaymentType.Automatic: //payment is processed on payment gateway site processPaymentResult = new ProcessPaymentResult(); break; default: throw new NopException("Not supported recurring payment type"); } } else { throw new NopException("No recurring products"); } } } else { //payment is not required if (processPaymentResult == null) processPaymentResult = new ProcessPaymentResult(); processPaymentResult.NewPaymentStatus = PaymentStatus.Paid; } if (processPaymentResult == null) throw new NopException("processPaymentResult is not available"); #endregion if (processPaymentResult.Success) { #region Save order details var order = new Order { StoreId = processPaymentRequest.StoreId, OrderGuid = processPaymentRequest.OrderGuid, CustomerId = details.Customer.Id, CustomerLanguageId = details.CustomerLanguage.Id, CustomerTaxDisplayType = details.CustomerTaxDisplayType, CustomerIp = _webHelper.GetCurrentIpAddress(), OrderSubtotalInclTax = details.OrderSubTotalInclTax, OrderSubtotalExclTax = details.OrderSubTotalExclTax, OrderSubTotalDiscountInclTax = details.OrderSubTotalDiscountInclTax, OrderSubTotalDiscountExclTax = details.OrderSubTotalDiscountExclTax, OrderShippingInclTax = details.OrderShippingTotalInclTax, OrderShippingExclTax = details.OrderShippingTotalExclTax, PaymentMethodAdditionalFeeInclTax = details.PaymentAdditionalFeeInclTax, PaymentMethodAdditionalFeeExclTax = details.PaymentAdditionalFeeExclTax, TaxRates = details.TaxRates, OrderTax = details.OrderTaxTotal, OrderTotal = details.OrderTotal, RefundedAmount = decimal.Zero, OrderDiscount = details.OrderDiscountAmount, CheckoutAttributeDescription = details.CheckoutAttributeDescription, CheckoutAttributesXml = details.CheckoutAttributesXml, CustomerCurrencyCode = details.CustomerCurrencyCode, CurrencyRate = details.CustomerCurrencyRate, AffiliateId = details.AffiliateId, OrderStatus = OrderStatus.Pending, AllowStoringCreditCardNumber = processPaymentResult.AllowStoringCreditCardNumber, CardType = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardType) : string.Empty, CardName = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardName) : string.Empty, CardNumber = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardNumber) : string.Empty, MaskedCreditCardNumber = _encryptionService.EncryptText(_paymentService.GetMaskedCreditCardNumber(processPaymentRequest.CreditCardNumber)), CardCvv2 = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardCvv2) : string.Empty, CardExpirationMonth = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireMonth.ToString()) : string.Empty, CardExpirationYear = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireYear.ToString()) : string.Empty, PaymentMethodSystemName = processPaymentRequest.PaymentMethodSystemName, AuthorizationTransactionId = processPaymentResult.AuthorizationTransactionId, AuthorizationTransactionCode = processPaymentResult.AuthorizationTransactionCode, AuthorizationTransactionResult = processPaymentResult.AuthorizationTransactionResult, CaptureTransactionId = processPaymentResult.CaptureTransactionId, CaptureTransactionResult = processPaymentResult.CaptureTransactionResult, SubscriptionTransactionId = processPaymentResult.SubscriptionTransactionId, PaymentStatus = processPaymentResult.NewPaymentStatus, PaidDateUtc = null, BillingAddress = details.BillingAddress, ShippingAddress = details.ShippingAddress, ShippingStatus = details.ShippingStatus, ShippingMethod = details.ShippingMethodName, PickUpInStore = details.PickUpInStore, ShippingRateComputationMethodSystemName = details.ShippingRateComputationMethodSystemName, CustomValuesXml = processPaymentRequest.SerializeCustomValues(), VatNumber = details.VatNumber, CreatedOnUtc = DateTime.UtcNow }; _orderService.InsertOrder(order); #region Promo _promoService.SendConfirmedBasket(order); BasketResponse basketResponse = _promoUtilities.GetBasketResponse(); if (basketResponse == null) { throw new NopException(string.Format("Failed to create PromoOrder for order: {0}", order.Id)); } else { PromoOrder promoOrder = new PromoOrder() { RequestXml = _workContext.CurrentCustomer.GetAttribute<string>(PromoCustomerAttributeNames.PromoBasketRequest, _genericAttributeService, _storeContext.CurrentStore.Id), ResponseXml = basketResponse.ToXml(), OrderId = order.Id, DeliveryOriginalPrice = basketResponse.DeliveryOriginalPrice }; _promoOrderService.InsertPromoOrder(promoOrder); basketResponse.Items.ForEach(bi => { PromoOrderItem promoOrderItem = new PromoOrderItem() { LineAmount = bi.LineAmount, OrderId = order.Id, PromoOrderId = promoOrder.Id, IsDelivery = bi.IsDelivery, ProductCode = bi.ProductCode, VariantCode = bi.VariantCode, LinePromotionDiscount = bi.LinePromotionDiscount, Barcode = bi.Barcode, Generated = bi.Generated, ManualDiscount = bi.ManualDiscount, OriginalAmount = bi.OriginalAmount, OriginalPrice = bi.OriginalPrice, OriginalQuantity = bi.OriginalQuantity, Price = bi.Price, ProductDescription = bi.ProductDescription, Quantity = bi.Quantity, SplitFromLineId = bi.SplitFromLineId, TotalDiscount = bi.TotalDiscount, TotalIssuedPoints = bi.TotalIssuedPoints }; promoOrder.PromoOrderItems.Add(promoOrderItem); _promoOrderService.UpdatePromoOrder(promoOrder); bi.AppliedPromotions.ForEach(ap => { string promotionTypeDisplay = string.Empty; string promotionType = string.Empty; string promotionName = string.Empty; string promotionDisplayText = string.Empty; var appliedPromo = (from sap in basketResponse.Summary.AppliedPromotions where sap.PromotionId == ap.PromotionId select sap).FirstOrDefault(); if (appliedPromo != null) { promotionName = appliedPromo.PromotionName; promotionType = appliedPromo.PromotionType; promotionTypeDisplay = appliedPromo.PromotionTypeDisplay; promotionDisplayText = appliedPromo.DisplayText; } PromoOrderItemPromotion promoOrderItemPromotion = new PromoOrderItemPromotion() { BasketLevel = ap.BasketLevelPromotion, DeliveryLevel = ap.DeliveryLevelPromotion, DiscountAmount = ap.DiscountAmount, ForLineId = ap.AssociatedLine, Instance = ap.InstanceId, PointsIssued = ap.PointsIssued, PromotionId = ap.PromotionId, DisplayText = promotionDisplayText, PromotionTypeDisplay = promotionTypeDisplay, PromotionName = promotionName, PromotionType = promotionType, ExternalIdentifier = ap.ExternalIdentifier, ReportingGroupCode = ap.ReportingGroupCode }; promoOrderItem.PromoOrderItemPromotions.Add(promoOrderItemPromotion); _promoOrderService.UpdatePromoOrder(promoOrder); }); }); basketResponse.Coupons.ForEach(c => { PromoOrderCoupon promoOrderCoupon = new PromoOrderCoupon() { CouponCode = c.CouponCode, Issued = c.Issued, OrderId = order.Id, PromoOrderId = promoOrder.Id, CouponName = c.CouponName, IssuedConfirmed = c.IssuedConfirmed, DisplayText = c.DisplayText }; promoOrder.PromoOrderCoupons.Add(promoOrderCoupon); _promoOrderService.UpdatePromoOrder(promoOrder); }); } #region clean up Customer customer = _workContext.CurrentCustomer; // basket guid _genericAttributeService.SaveAttribute<string>(customer, PromoCustomerAttributeNames.PromoBasketUniqueReference, null, _storeContext.CurrentStore.Id); // basket response _genericAttributeService.SaveAttribute<string>(customer, PromoCustomerAttributeNames.PromoBasketResponse, null, _storeContext.CurrentStore.Id); // basket request _genericAttributeService.SaveAttribute<string>(customer, PromoCustomerAttributeNames.PromoBasketRequest, null, _storeContext.CurrentStore.Id); // coupon code _genericAttributeService.SaveAttribute<string>(customer, SystemCustomerAttributeNames.DiscountCouponCode, null); #endregion #endregion result.PlacedOrder = order; if (!processPaymentRequest.IsRecurringPayment) { //move shopping cart items to order items foreach (var sc in details.Cart) { var basketResponseItems = basketResponse.FindBasketResponseItems(sc); if (basketResponseItems == null) { // TODO: handle this error } else { //prices decimal taxRate; decimal discountAmount = basketResponseItems.Sum(i => i.LinePromotionDiscount); decimal scUnitPrice = _priceCalculationService.GetUnitPrice(sc); decimal scSubTotal = basketResponseItems.Sum(i => i.LineAmount); decimal scUnitPriceInclTax = _taxService.GetProductPrice(sc.Product, scUnitPrice, true, details.Customer, out taxRate); decimal scUnitPriceExclTax = _taxService.GetProductPrice(sc.Product, scUnitPrice, false, details.Customer, out taxRate); decimal scSubTotalInclTax = _taxService.GetProductPrice(sc.Product, scSubTotal, true, details.Customer, out taxRate); decimal scSubTotalExclTax = _taxService.GetProductPrice(sc.Product, scSubTotal, false, details.Customer, out taxRate); decimal discountAmountInclTax = _taxService.GetProductPrice(sc.Product, discountAmount, true, details.Customer, out taxRate); decimal discountAmountExclTax = _taxService.GetProductPrice(sc.Product, discountAmount, false, details.Customer, out taxRate); //attributes string attributeDescription = _productAttributeFormatter.FormatAttributes(sc.Product, sc.AttributesXml, details.Customer); var itemWeight = _shippingService.GetShoppingCartItemWeight(sc); //save order item var orderItem = new OrderItem { OrderItemGuid = Guid.NewGuid(), Order = order, ProductId = sc.ProductId, UnitPriceInclTax = scUnitPriceInclTax, UnitPriceExclTax = scUnitPriceExclTax, PriceInclTax = scSubTotalInclTax, PriceExclTax = scSubTotalExclTax, OriginalProductCost = _priceCalculationService.GetProductCost(sc.Product, sc.AttributesXml), AttributeDescription = attributeDescription, AttributesXml = sc.AttributesXml, Quantity = sc.Quantity, DiscountAmountInclTax = discountAmountInclTax, DiscountAmountExclTax = discountAmountExclTax, DownloadCount = 0, IsDownloadActivated = false, LicenseDownloadId = 0, ItemWeight = itemWeight, RentalStartDateUtc = sc.RentalStartDateUtc, RentalEndDateUtc = sc.RentalEndDateUtc }; order.OrderItems.Add(orderItem); _orderService.UpdateOrder(order); //gift cards if (sc.Product.IsGiftCard) { string giftCardRecipientName, giftCardRecipientEmail, giftCardSenderName, giftCardSenderEmail, giftCardMessage; _productAttributeParser.GetGiftCardAttribute(sc.AttributesXml, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); for (int i = 0; i < sc.Quantity; i++) { var gc = new GiftCard { GiftCardType = sc.Product.GiftCardType, PurchasedWithOrderItem = orderItem, Amount = scUnitPriceExclTax, IsGiftCardActivated = false, GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(), RecipientName = giftCardRecipientName, RecipientEmail = giftCardRecipientEmail, SenderName = giftCardSenderName, SenderEmail = giftCardSenderEmail, Message = giftCardMessage, IsRecipientNotified = false, CreatedOnUtc = DateTime.UtcNow }; _giftCardService.InsertGiftCard(gc); } } //inventory _productService.AdjustInventory(sc.Product, -sc.Quantity, sc.AttributesXml); } } //clear shopping cart details.Cart.ToList().ForEach(sci => _shoppingCartService.DeleteShoppingCartItem(sci, false)); } else { //recurring payment var initialOrderItems = details.InitialOrder.OrderItems; foreach (var orderItem in initialOrderItems) { //save item var newOrderItem = new OrderItem { OrderItemGuid = Guid.NewGuid(), Order = order, ProductId = orderItem.ProductId, UnitPriceInclTax = orderItem.UnitPriceInclTax, UnitPriceExclTax = orderItem.UnitPriceExclTax, PriceInclTax = orderItem.PriceInclTax, PriceExclTax = orderItem.PriceExclTax, OriginalProductCost = orderItem.OriginalProductCost, AttributeDescription = orderItem.AttributeDescription, AttributesXml = orderItem.AttributesXml, Quantity = orderItem.Quantity, DiscountAmountInclTax = orderItem.DiscountAmountInclTax, DiscountAmountExclTax = orderItem.DiscountAmountExclTax, DownloadCount = 0, IsDownloadActivated = false, LicenseDownloadId = 0, ItemWeight = orderItem.ItemWeight, RentalStartDateUtc = orderItem.RentalStartDateUtc, RentalEndDateUtc = orderItem.RentalEndDateUtc }; order.OrderItems.Add(newOrderItem); _orderService.UpdateOrder(order); //gift cards if (orderItem.Product.IsGiftCard) { string giftCardRecipientName, giftCardRecipientEmail, giftCardSenderName, giftCardSenderEmail, giftCardMessage; _productAttributeParser.GetGiftCardAttribute(orderItem.AttributesXml, out giftCardRecipientName, out giftCardRecipientEmail, out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage); for (int i = 0; i < orderItem.Quantity; i++) { var gc = new GiftCard { GiftCardType = orderItem.Product.GiftCardType, PurchasedWithOrderItem = newOrderItem, Amount = orderItem.UnitPriceExclTax, IsGiftCardActivated = false, GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(), RecipientName = giftCardRecipientName, RecipientEmail = giftCardRecipientEmail, SenderName = giftCardSenderName, SenderEmail = giftCardSenderEmail, Message = giftCardMessage, IsRecipientNotified = false, CreatedOnUtc = DateTime.UtcNow }; _giftCardService.InsertGiftCard(gc); } } //inventory _productService.AdjustInventory(orderItem.Product, -orderItem.Quantity, orderItem.AttributesXml); } } //discount usage history // TODO: replace with Promo discount usage history? //gift card usage history if (!processPaymentRequest.IsRecurringPayment) if (details.AppliedGiftCards != null) foreach (var agc in details.AppliedGiftCards) { decimal amountUsed = agc.AmountCanBeUsed; var gcuh = new GiftCardUsageHistory { GiftCard = agc.GiftCard, UsedWithOrder = order, UsedValue = amountUsed, CreatedOnUtc = DateTime.UtcNow }; agc.GiftCard.GiftCardUsageHistory.Add(gcuh); _giftCardService.UpdateGiftCard(agc.GiftCard); } //reward points history if (details.RedeemedRewardPointsAmount > decimal.Zero) { details.Customer.AddRewardPointsHistoryEntry(-details.RedeemedRewardPoints, string.Format(_localizationService.GetResource("RewardPoints.Message.RedeemedForOrder", order.CustomerLanguageId), order.Id), order, details.RedeemedRewardPointsAmount); _customerService.UpdateCustomer(details.Customer); } //recurring orders if (!processPaymentRequest.IsRecurringPayment && details.IsRecurringShoppingCart) { //create recurring payment (the first payment) var rp = new RecurringPayment { CycleLength = processPaymentRequest.RecurringCycleLength, CyclePeriod = processPaymentRequest.RecurringCyclePeriod, TotalCycles = processPaymentRequest.RecurringTotalCycles, StartDateUtc = DateTime.UtcNow, IsActive = true, CreatedOnUtc = DateTime.UtcNow, InitialOrder = order, }; _orderService.InsertRecurringPayment(rp); var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName); switch (recurringPaymentType) { case RecurringPaymentType.NotSupported: { //not supported } break; case RecurringPaymentType.Manual: { //first payment var rph = new RecurringPaymentHistory { RecurringPayment = rp, CreatedOnUtc = DateTime.UtcNow, OrderId = order.Id, }; rp.RecurringPaymentHistory.Add(rph); _orderService.UpdateRecurringPayment(rp); } break; case RecurringPaymentType.Automatic: { //will be created later (process is automated) } break; default: break; } } #endregion #region Notifications & notes //notes, messages if (_workContext.OriginalCustomerIfImpersonated != null) { //this order is placed by a store administrator impersonating a customer order.OrderNotes.Add(new OrderNote { Note = string.Format("Order placed by a store owner ('{0}'. ID = {1}) impersonating the customer.", _workContext.OriginalCustomerIfImpersonated.Email, _workContext.OriginalCustomerIfImpersonated.Id), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); } else { order.OrderNotes.Add(new OrderNote { Note = "Order placed", DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); } //send email notifications int orderPlacedStoreOwnerNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedStoreOwnerNotification(order, _localizationSettings.DefaultAdminLanguageId); if (orderPlacedStoreOwnerNotificationQueuedEmailId > 0) { order.OrderNotes.Add(new OrderNote { Note = string.Format("\"Order placed\" email (to store owner) has been queued. Queued email identifier: {0}.", orderPlacedStoreOwnerNotificationQueuedEmailId), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); } var orderPlacedAttachmentFilePath = _orderSettings.AttachPdfInvoiceToOrderPlacedEmail ? _pdfService.PrintOrderToPdf(order, order.CustomerLanguageId) : null; var orderPlacedAttachmentFileName = _orderSettings.AttachPdfInvoiceToOrderPlacedEmail ? "order.pdf" : null; int orderPlacedCustomerNotificationQueuedEmailId = _workflowMessageService .SendOrderPlacedCustomerNotification(order, order.CustomerLanguageId, orderPlacedAttachmentFilePath, orderPlacedAttachmentFileName); if (orderPlacedCustomerNotificationQueuedEmailId > 0) { order.OrderNotes.Add(new OrderNote { Note = string.Format("\"Order placed\" email (to customer) has been queued. Queued email identifier: {0}.", orderPlacedCustomerNotificationQueuedEmailId), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); } var vendors = GetVendorsInOrder(order); foreach (var vendor in vendors) { int orderPlacedVendorNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedVendorNotification(order, vendor, order.CustomerLanguageId); if (orderPlacedVendorNotificationQueuedEmailId > 0) { order.OrderNotes.Add(new OrderNote { Note = string.Format("\"Order placed\" email (to vendor) has been queued. Queued email identifier: {0}.", orderPlacedVendorNotificationQueuedEmailId), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); } } //check order status CheckOrderStatus(order); //reset checkout data if (!processPaymentRequest.IsRecurringPayment) _customerService.ResetCheckoutData(details.Customer, processPaymentRequest.StoreId, clearCouponCodes: true, clearCheckoutAttributes: true); if (!processPaymentRequest.IsRecurringPayment) { _customerActivityService.InsertActivity( "PublicStore.PlaceOrder", _localizationService.GetResource("ActivityLog.PublicStore.PlaceOrder"), order.Id); } //raise event _eventPublisher.Publish(new OrderPlacedEvent(order)); if (order.PaymentStatus == PaymentStatus.Paid) { ProcessOrderPaid(order); } #endregion } else { foreach (var paymentError in processPaymentResult.Errors) result.AddError(string.Format(_localizationService.GetResource("Checkout.PaymentError"), paymentError)); } } catch (Exception exc) { _logger.Error(exc.Message, exc); result.AddError(exc.Message); } #region Process errors string error = ""; for (int i = 0; i < result.Errors.Count; i++) { error += string.Format("Error {0}: {1}", i + 1, result.Errors[i]); if (i != result.Errors.Count - 1) error += ". "; } if (!String.IsNullOrEmpty(error)) { //log it string logError = string.Format("Error while placing order. {0}", error); _logger.Error(logError); } #endregion return result; }
partial void PlaceOrder(ProcessPaymentRequest processPaymentRequest, ref PlaceOrderResult result);
public IHttpActionResult CreateOrder([ModelBinder(typeof(JsonModelBinder <OrderDto>))] Delta <OrderDto> orderDelta) { // Here we display the errors if the validation has failed at some point. if (!ModelState.IsValid) { return(Error()); } // We doesn't have to check for value because this is done by the order validator. Customer customer = _customerService.GetCustomerById(orderDelta.Dto.CustomerId.Value); if (customer == null) { return(Error(HttpStatusCode.NotFound, "customer", "not found")); } bool shippingRequired = false; if (orderDelta.Dto.OrderItemDtos != null) { bool shouldReturnError = ValidateEachOrderItem(orderDelta.Dto.OrderItemDtos); if (shouldReturnError) { return(Error(HttpStatusCode.BadRequest)); } shouldReturnError = AddOrderItemsToCart(orderDelta.Dto.OrderItemDtos, customer, orderDelta.Dto.StoreId ?? _storeContext.CurrentStore.Id); if (shouldReturnError) { return(Error(HttpStatusCode.BadRequest)); } shippingRequired = IsShippingAddressRequired(orderDelta.Dto.OrderItemDtos); } if (shippingRequired) { bool isValid = true; isValid &= SetShippingOption(orderDelta.Dto.ShippingRateComputationMethodSystemName, orderDelta.Dto.ShippingMethod, orderDelta.Dto.StoreId ?? _storeContext.CurrentStore.Id, customer, BuildShoppingCartItemsFromOrderItemDtos(orderDelta.Dto.OrderItemDtos.ToList(), customer.Id, orderDelta.Dto.StoreId ?? _storeContext.CurrentStore.Id)); isValid &= ValidateAddress(orderDelta.Dto.ShippingAddress, "shipping_address"); if (!isValid) { return(Error(HttpStatusCode.BadRequest)); } } if (!OrderSettings.DisableBillingAddressCheckoutStep) { bool isValid = ValidateAddress(orderDelta.Dto.BillingAddress, "billing_address"); if (!isValid) { return(Error(HttpStatusCode.BadRequest)); } } Order newOrder = _factory.Initialize(); orderDelta.Merge(newOrder); customer.BillingAddress = newOrder.BillingAddress; customer.ShippingAddress = newOrder.ShippingAddress; // If the customer has something in the cart it will be added too. Should we clear the cart first? newOrder.Customer = customer; // The default value will be the currentStore.id, but if it isn't passed in the json we need to set it by hand. if (!orderDelta.Dto.StoreId.HasValue) { newOrder.StoreId = _storeContext.CurrentStore.Id; } PlaceOrderResult placeOrderResult = PlaceOrder(newOrder, customer); if (!placeOrderResult.Success) { foreach (var error in placeOrderResult.Errors) { ModelState.AddModelError("order placement", error); } return(Error(HttpStatusCode.BadRequest)); } _customerActivityService.InsertActivity("AddNewOrder", _localizationService.GetResource("ActivityLog.AddNewOrder"), newOrder.Id); var ordersRootObject = new OrdersRootObject(); OrderDto placedOrderDto = _dtoHelper.PrepareOrderDTO(placeOrderResult.PlacedOrder); ordersRootObject.Orders.Add(placedOrderDto); var json = _jsonFieldsSerializer.Serialize(ordersRootObject, string.Empty); return(new RawJsonActionResult(json)); }
public ActionResult CreateOrder(orderModelApi orderDelta) { // Here we display the errors if the validation has failed at some point. bool shippingRequired = false; Customer customer = _customerService.GetCustomerById(orderDelta.CustomerId.Value); if (orderDelta.OrderItemDtos != null) { bool shouldReturnError = ValidateEachOrderItem(orderDelta.OrderItemDtos); if (shouldReturnError) { } shouldReturnError = AddOrderItemsToCart(orderDelta.OrderItemDtos, customer, orderDelta.StoreId ?? _storeContext.CurrentStore.Id); shippingRequired = IsShippingAddressRequired(orderDelta.OrderItemDtos); } if (shippingRequired) { bool isValid = true; isValid &= SetShippingOption(orderDelta.ShippingRateComputationMethodSystemName, orderDelta.ShippingMethod, orderDelta.StoreId ?? _storeContext.CurrentStore.Id, customer, BuildShoppingCartItemsFromOrderItemDtos(orderDelta.OrderItemDtos.ToList(), customer.Id, orderDelta.StoreId ?? _storeContext.CurrentStore.Id)); //isValid &= ValidateAddress(orderDelta.ShippingAddress, "shipping_address"); //if (!isValid) //{ // return Error(HttpStatusCode.BadRequest); //} } //if (!OrderSettings.DisableBillingAddressCheckoutStep) //{ // bool isValid = ValidateAddress(orderDelta.Dto.BillingAddress, "billing_address"); // if (!isValid) // { // return Error(HttpStatusCode.BadRequest); // } //} Core.Domain.Orders.Order newOrder = new Core.Domain.Orders.Order(); newOrder.BillingAddress.Address1 = orderDelta.BillingAddress.Address1; newOrder.BillingAddress.Address2 = orderDelta.BillingAddress.Address2; newOrder.BillingAddress.City = orderDelta.BillingAddress.City; newOrder.BillingAddress.Company = orderDelta.BillingAddress.Company; newOrder.BillingAddress.Country.Name = orderDelta.BillingAddress.CountryName; newOrder.BillingAddress.CountryId = orderDelta.BillingAddress.CountryId; newOrder.BillingAddress.Email = orderDelta.BillingAddress.Email; newOrder.BillingAddress.FaxNumber = orderDelta.BillingAddress.FaxNumber; newOrder.BillingAddress.FirstName = orderDelta.BillingAddress.FirstName; newOrder.BillingAddress.LastName = orderDelta.BillingAddress.LastName; newOrder.BillingAddress.PhoneNumber = orderDelta.BillingAddress.PhoneNumber; newOrder.BillingAddress.StateProvince.Name = orderDelta.BillingAddress.StateProvinceName; newOrder.BillingAddress.StateProvinceId = orderDelta.BillingAddress.StateProvinceId; newOrder.BillingAddress.ZipPostalCode = orderDelta.BillingAddress.ZipPostalCode; newOrder.BillingAddress.CreatedOnUtc = orderDelta.BillingAddress.CreatedOnUtc; newOrder.ShippingAddress.Address1 = orderDelta.ShippingAddress.Address1; newOrder.ShippingAddress.Address2 = orderDelta.ShippingAddress.Address2; newOrder.ShippingAddress.City = orderDelta.ShippingAddress.City; newOrder.ShippingAddress.Company = orderDelta.ShippingAddress.Company; newOrder.ShippingAddress.Country.Name = orderDelta.ShippingAddress.CountryName; newOrder.ShippingAddress.CountryId = orderDelta.ShippingAddress.CountryId; newOrder.ShippingAddress.Email = orderDelta.ShippingAddress.Email; newOrder.ShippingAddress.FaxNumber = orderDelta.ShippingAddress.FaxNumber; newOrder.ShippingAddress.FirstName = orderDelta.ShippingAddress.FirstName; newOrder.ShippingAddress.LastName = orderDelta.ShippingAddress.LastName; newOrder.ShippingAddress.PhoneNumber = orderDelta.ShippingAddress.PhoneNumber; newOrder.ShippingAddress.StateProvince.Name = orderDelta.ShippingAddress.StateProvinceName; newOrder.ShippingAddress.StateProvinceId = orderDelta.ShippingAddress.StateProvinceId; newOrder.ShippingAddress.ZipPostalCode = orderDelta.ShippingAddress.ZipPostalCode; newOrder.ShippingAddress.CreatedOnUtc = orderDelta.ShippingAddress.CreatedOnUtc; // If the customer has something in the cart it will be added too. Should we clear the cart first? newOrder.Customer = customer; newOrder.OrderItems = orderDelta.OrderItemDtos; // The default value will be the currentStore.id, but if it isn't passed in the json we need to set it by hand. if (!orderDelta.StoreId.HasValue) { newOrder.StoreId = _storeContext.CurrentStore.Id; } PlaceOrderResult placeOrderResult = PlaceOrder(newOrder, customer); if (!placeOrderResult.Success) { foreach (var error in placeOrderResult.Errors) { // ModelState.AddModelError("order placement", error); } // return Error(HttpStatusCode.BadRequest); } // _customerActivityService.InsertActivity("AddNewOrder",_localizationService.GetResource("ActivityLog.AddNewOrder"), newOrder.Id); var ordersRootObject = new OrdersRootObject(); OrderDto placedOrderDto = placeOrderResult.PlacedOrder.(); ordersRootObject.Orders.Add(placedOrderDto); var json = _jsonFieldsSerializer.Serialize(ordersRootObject, string.Empty); return(new RawJsonActionResult(json)); }
public ActionResult SubmitButton() { ActionResult result; try { if (_workContext.CurrentCustomer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed) { result = RedirectToRoute("Login"); } else { IEnumerable <ShoppingCartItem> shoppingCartItems = _workContext.CurrentCustomer.ShoppingCartItems; List <ShoppingCartItem> list = shoppingCartItems.Where(item => item.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList(); if (list.Count == 0) { result = RedirectToRoute("ShoppingCart"); } else { string currencyCode = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId).CurrencyCode; var curencies = _p24PaymentSettings.Currencies.Split(new[] { ",", " " }, StringSplitOptions.RemoveEmptyEntries); if (!curencies.Contains(currencyCode)) { throw new ApplicationException("Privat24. currency is not supported. (only UAH, USD, EUR)"); } if (string.IsNullOrEmpty(_p24PaymentSettings.MerchantId)) { throw new ApplicationException("Privat24. merchant_id is not set"); } if (string.IsNullOrEmpty(_p24PaymentSettings.MerchantSignature)) { throw new ApplicationException("Privat24. merchant_sig is not set"); } var privat24PaymentProcessor = _paymentService.LoadPaymentMethodBySystemName("Nop.Payments.Privat24") as Privat24PaymentProcessor; if (privat24PaymentProcessor == null || !privat24PaymentProcessor.IsPaymentMethodActive(_paymentSettings) || !privat24PaymentProcessor.PluginDescriptor.Installed) { throw new NopException("Privat24 module cannot be loaded"); } var processPaymentRequest = new ProcessPaymentRequest { PaymentMethodSystemName = "Nop.Payments.Privat24", CustomerId = _workContext.CurrentCustomer.Id }; ProcessPaymentRequest processPaymentRequest2 = processPaymentRequest; PlaceOrderResult placeOrderResult = _orderProcessingService.PlaceOrder(processPaymentRequest2); if (!placeOrderResult.Success) { privat24PaymentProcessor.LogMessage(string.Format("CreateOrder() error: {0}", placeOrderResult)); result = RedirectToRoute("ShoppingCart"); } else { Order placedOrder = placeOrderResult.PlacedOrder; if (placedOrder == null) { privat24PaymentProcessor.LogMessage("order==null"); result = RedirectToRoute("ShoppingCart"); } else { privat24PaymentProcessor.LogMessage("create new order: Order Number " + placedOrder.Id); string text = privat24PaymentProcessor.CreateFormPrivat24(placedOrder.Id, placedOrder.OrderTotal); result = new RedirectResult(text); } } } } } catch (Exception arg) { result = Content("Error: " + arg); } return(result); }
partial void PlaceOrder(ProcessPaymentRequest processPaymentRequest, ref PlaceOrderResult result) { // actual code goes here }
public void ClosePositionReceived(string message) { Task task = new Task(() => { Log(LogEntryImportance.Info, "Closing Position...", true); //Cancel opening order bool cancelOpeningOrderRes = CancelOpeningOrder(); //cancel closing order bool cancelClosingOrder = CancelClosingOrder(); //execute emergency exit order if (BrokerPosition != null && BrokerPosition.EmergencyExitOrder != null) { Order emergencyExitOrder = BrokerPosition.EmergencyExitOrder; PlaceOrderResult emergencyExitOrderResult = _client.PlaceOrder(emergencyExitOrder, true); emergencyExitOrder = emergencyExitOrderResult.Order; //update PositionView and PanelView UpdateEmergencyOrder(emergencyExitOrder); #region Handle emergency order result switch (emergencyExitOrderResult.ResultType) { case PlaceOrderResultType.error: _client.HandleErrors(emergencyExitOrderResult.Errors); break; case PlaceOrderResultType.success: Log(LogEntryImportance.Info, "Emergency exit order filled", true); break; case PlaceOrderResultType.partial: Log(LogEntryImportance.Info, string.Format("Emergency exit order partially filled: {0}/{1}", emergencyExitOrder.VolumeExecuted, emergencyExitOrder.Volume), true); break; case PlaceOrderResultType.txid_null: Log(LogEntryImportance.Error, "An error occured while attempting to place the emergency exit order: txid is null (unknown reason. Maybe the ValidateOnly argument was set to true)", true); break; case PlaceOrderResultType.canceled_not_partial: Log(LogEntryImportance.Info, string.Format("The emergency exiting order was canceled: {0}", emergencyExitOrder.Reason), true); break; case PlaceOrderResultType.exception: Log(LogEntryImportance.Error, string.Format("An error occured while attempting to place the emergency exit order: {0}", emergencyExitOrderResult.Exception.Message), true); break; default: Log(LogEntryImportance.Error, string.Format("Unknown PlaceOrderResultType {0}", emergencyExitOrderResult.ResultType), true); break; } #endregion } else { Log(LogEntryImportance.Info, "No emergency order to execute.", true); } Log(LogEntryImportance.Info, "Position closed.", true); BrokerPosition = null; }); task.Start(); }
private void OpenPosition(OpenPositionData openPositionData) { try { BrokerPosition = new Position(this); BrokerPosition.Direction = openPositionData.Direction; //Create opening order Order openingOrder = _orderFactory.CreateOpeningOrder(openPositionData.Direction, KrakenOrderType.stop_loss, openPositionData.EnteringPrice, openPositionData.Volume, openPositionData.CandleStickId, openPositionData.ConfirmationId, validateOnly: openPositionData.ValidateOnly); UpdateOpeningOrder(openingOrder); //Place opening order and wait until closed or canceled Log(LogEntryImportance.Info, "Placing opening order...", true); PlaceOrderResult openingOrderResult = _client.PlaceOrder(openingOrder, true); openingOrder = openingOrderResult.Order; UpdateOpeningOrder(openingOrder); bool ok = false; #region Handle opening-order result switch (openingOrderResult.ResultType) { case PlaceOrderResultType.error: _client.HandleErrors(openingOrderResult.Errors); break; case PlaceOrderResultType.success: Log(LogEntryImportance.Info, "Opening order filled", true); UpdateEmergencyOrder(_orderFactory.CreateEmergencyExitOrder(openingOrder)); ok = true; break; case PlaceOrderResultType.partial: Log(LogEntryImportance.Info, string.Format("Opening order partially filled: {0}/{1}", openingOrder.VolumeExecuted, openingOrder.Volume), true); ok = true; break; case PlaceOrderResultType.txid_null: Log(LogEntryImportance.Error, "An error occured while attempting to place an opening order: txid is null (unknown reason. Maybe the ValidateOnly argument was set to true)", true); break; case PlaceOrderResultType.canceled_not_partial: Log(LogEntryImportance.Info, string.Format("The opening order was canceled: {0}", openingOrder.Reason), true); break; case PlaceOrderResultType.exception: Log(LogEntryImportance.Error, string.Format("An error occured while attempting to place an opening order: {0}", openingOrderResult.Exception.Message), true); break; default: Log(LogEntryImportance.Error, string.Format("Unknown PlaceOrderResultType {0}", openingOrderResult.ResultType), true); break; } #endregion if (!ok) { return; } //if nothing went wrong, place exiting order Order closingOrder = _orderFactory.CreateStopLossOrder(openingOrder, openPositionData.ExitingPrice, openPositionData.ValidateOnly); UpdateClosingOrder(closingOrder); //Place closing order and wait until closed or canceled Log(LogEntryImportance.Info, "Placing closing order...", true); PlaceOrderResult closingOrderResult = _client.PlaceOrder(closingOrder, true); closingOrder = closingOrderResult.Order; UpdateClosingOrder(closingOrder); #region Handle closing-order result switch (closingOrderResult.ResultType) { case PlaceOrderResultType.error: _client.HandleErrors(closingOrderResult.Errors); break; case PlaceOrderResultType.success: Log(LogEntryImportance.Info, "Closing order filled", true); UpdateEmergencyOrder(null); break; case PlaceOrderResultType.partial: Log(LogEntryImportance.Info, string.Format("Closing order partially filled: {0}/{1}", closingOrder.VolumeExecuted, closingOrder.Volume), true); break; case PlaceOrderResultType.txid_null: Log(LogEntryImportance.Error, "An error occured while attempting to place a closing order: txid is null (unknown reason. Maybe the ValidateOnly argument was set to true)", true); break; case PlaceOrderResultType.canceled_not_partial: Log(LogEntryImportance.Info, string.Format("The closing order was canceled: {0}", closingOrder.Reason), true); break; case PlaceOrderResultType.exception: Log(LogEntryImportance.Error, string.Format("An error occured while attempting to place a closing order: {0}", closingOrderResult.Exception.Message), true); break; default: Log(LogEntryImportance.Error, string.Format("Unknown PlaceOrderResultType {0}", closingOrderResult.ResultType), true); break; } #endregion } catch (Exception ex) { Log(LogEntryImportance.Error, string.Format("An exception occured in OpenPosition at line {0}. {1} {2}", ex.LineNumber(), ex.Message, ((ex.InnerException != null) ? ex.InnerException.Message : "")), true); } }
private void ShiftPositionLimits(ShiftPositionLimitsData shiftPositionLimitsData) { Log(LogEntryImportance.Info, "In ShiftPositionLimits", true); try { //Cancel current stoploss order bool cancelClosingOrderRes = CancelClosingOrder(); if (cancelClosingOrderRes) { //create new stop loss order Order newStopLossOrder = _orderFactory.CreateStopLossOrder(BrokerPosition.OpeningOrder, shiftPositionLimitsData.NewLimitPrice, shiftPositionLimitsData.ValidateOnly); UpdateClosingOrder(newStopLossOrder); //place order and wait Log(LogEntryImportance.Info, "Placing new closing order...", true); PlaceOrderResult placeOrderResult = _client.PlaceOrder(newStopLossOrder, true); newStopLossOrder = placeOrderResult.Order; UpdateClosingOrder(newStopLossOrder); #region Handle place-order result switch (placeOrderResult.ResultType) { case PlaceOrderResultType.error: _client.HandleErrors(placeOrderResult.Errors); break; case PlaceOrderResultType.success: Log(LogEntryImportance.Info, "Closing order filled", true); UpdateEmergencyOrder(null); break; case PlaceOrderResultType.partial: Log(LogEntryImportance.Info, string.Format("Closing order partially filled: {0}/{1}", newStopLossOrder.VolumeExecuted, newStopLossOrder.Volume), true); break; case PlaceOrderResultType.txid_null: Log(LogEntryImportance.Error, "An error occured while attempting to place a closing order: txid is null (unknown reason. Maybe the ValidateOnly argument was set to true)", true); break; case PlaceOrderResultType.canceled_not_partial: Log(LogEntryImportance.Info, string.Format("The closing order was canceled: {0}", newStopLossOrder.Reason), true); break; case PlaceOrderResultType.exception: Log(LogEntryImportance.Error, string.Format("An error occured while attempting to place a closing order: {0}", placeOrderResult.Exception.Message), true); break; default: Log(LogEntryImportance.Error, string.Format("Unknown PlaceOrderResultType {0}", placeOrderResult.ResultType), true); break; } #endregion } else { Log(LogEntryImportance.Error, "Unable to cancel current closing order. Cannot shift limits", true); } } catch (Exception ex) { Log(LogEntryImportance.Error, string.Format("An exception occured in ShiftPositionLimits at line {0}. {1} {2}", ex.LineNumber(), ex.Message, ((ex.InnerException != null) ? ex.InnerException.Message : "")), true); } }