public ApplyOrderResult Apply(ILogService log, IUnitOfWork db, IOrderHistoryService orderHistoryService, IQuantityManager quantityManager, DateTime when, long?by) { var dbOrder = db.Orders.GetById(EntityId); var addressChanged = false; var shipmentProviderChanged = false; var shouldRecalcRates = dbOrder.IsInsured != IsInsured || dbOrder.IsSignConfirmation != IsSignConfirmation; var manuallyAddress = ComposeAddressDto(); //NOTE: empty when fields was readonly if (!AddressHelper.IsEmptyManually(manuallyAddress)) { var originalAddress = dbOrder.GetAddressDto(); addressChanged = AddressHelper.CompareWithManuallyAllFields(originalAddress, manuallyAddress); shouldRecalcRates = shouldRecalcRates || AddressHelper.CompareWithManuallyBigChanges(originalAddress, manuallyAddress); if (addressChanged) { orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyPersonNameKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyPersonName : dbOrder.PersonName, ManuallyPersonName, by); dbOrder.ManuallyPersonName = ManuallyPersonName; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingAddress1Key, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingAddress1 : dbOrder.ShippingAddress1, ManuallyShippingAddress1, by); dbOrder.ManuallyShippingAddress1 = ManuallyShippingAddress1; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingAddress2Key, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingAddress2 : dbOrder.ShippingAddress2, ManuallyShippingAddress2, by); dbOrder.ManuallyShippingAddress2 = ManuallyShippingAddress2; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingCityKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingCity : dbOrder.ShippingCity, ManuallyShippingCity, by); dbOrder.ManuallyShippingCity = ManuallyShippingCity; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingCountryKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingCountry : dbOrder.ShippingCountry, ManuallyShippingCountry, by); dbOrder.ManuallyShippingCountry = ManuallyShippingCountry; dbOrder.ManuallyShippingState = !ShippingUtils.IsInternational(dbOrder.ManuallyShippingCountry) // == "US" ? ManuallyShippingUSState : ManuallyShippingState; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingZipKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingZip : dbOrder.ShippingZip, ManuallyShippingZip, by); dbOrder.ManuallyShippingZip = StringHelper.TrimWhitespace(ManuallyShippingZip); orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingZipAddonKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingZipAddon : dbOrder.ShippingZipAddon, ManuallyShippingZipAddon, by); dbOrder.ManuallyShippingZipAddon = StringHelper.TrimWhitespace(ManuallyShippingZipAddon); orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ManuallyShippingPhoneKey, dbOrder.IsManuallyUpdated ? dbOrder.ManuallyShippingPhone : dbOrder.ShippingPhone, ManuallyShippingPhone, by); dbOrder.ManuallyShippingPhone = ManuallyShippingPhone; dbOrder.IsManuallyUpdated = true; } else { dbOrder.ManuallyPersonName = String.Empty; dbOrder.ManuallyShippingAddress1 = String.Empty; dbOrder.ManuallyShippingAddress2 = String.Empty; dbOrder.ManuallyShippingCity = String.Empty; dbOrder.ManuallyShippingCountry = String.Empty; dbOrder.ManuallyShippingState = String.Empty; dbOrder.ManuallyShippingZip = String.Empty; dbOrder.ManuallyShippingZipAddon = String.Empty; dbOrder.ManuallyShippingPhone = String.Empty; dbOrder.IsManuallyUpdated = false; } } dbOrder.InsuredValue = InsuredValue; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.IsInsuredKey, dbOrder.IsInsured, IsInsured, by); dbOrder.IsInsured = IsInsured; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.IsSignConfirmationKey, dbOrder.IsSignConfirmation, IsSignConfirmation, by); dbOrder.IsSignConfirmation = IsSignConfirmation; if (ManuallyShipmentProviderType.HasValue) { if (dbOrder.ShipmentProviderType != ManuallyShipmentProviderType.Value) { shipmentProviderChanged = true; shouldRecalcRates = true; } orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ShipmentProviderTypeKey, dbOrder.ShipmentProviderType, ManuallyShipmentProviderType, by); dbOrder.ShipmentProviderType = ManuallyShipmentProviderType.Value; } //dbOrder.OnHold = OnHold; dbOrder.UpdateDate = when; dbOrder.UpdatedBy = by; if (Items.All(i => i.NewListingId > 0)) //NOTE: only when enabled items edit { var changeNotes = ""; var itemSizeWasChanged = false; var joinItems = JoinItems(Items); var dbOrderItems = db.OrderItems.GetAll().Where(i => i.OrderId == dbOrder.Id).ToList(); var orderItemSources = db.OrderItemSources.GetAllAsDto().Where(i => i.OrderId == dbOrder.Id).ToList(); foreach (var item in joinItems) { var dbOrderItem = dbOrderItems.FirstOrDefault(im => im.ItemOrderIdentifier == item.ItemOrderId); //NOTE: Get source info for set proprotionally ItemPrice etc. var sourceItemOrderId = item.SourceItemOrderId; var sourceItemMapping = orderItemSources.FirstOrDefault(i => i.ItemOrderIdentifier == sourceItemOrderId); if (dbOrderItem != null) { log.Info("Updated orderItemId=" + item.ItemOrderId + ", qty=" + item.Quantity); } else { log.Info("Added orderItemId=" + item.ItemOrderId + ", qty=" + item.Quantity); dbOrderItem = db.OrderItemSources.CreateItemFromSourceDto(sourceItemMapping); dbOrderItem.CreateDate = when; db.OrderItems.Add(dbOrderItem); } dbOrderItem.ItemOrderIdentifier = item.ItemOrderId; dbOrderItem.QuantityOrdered = item.Quantity; dbOrderItem.ListingId = item.NewListingId; dbOrderItem.SourceListingId = sourceItemMapping.ListingId; dbOrderItem.SourceItemOrderIdentifier = sourceItemMapping.ItemOrderIdentifier; var newListing = db.Listings.GetViewListingsAsDto(withUnmaskedStyles: false) .FirstOrDefault(l => l.Id == item.NewListingId); var keepListingUpdateOnlyStyle = newListing.StyleItemId != dbOrderItem.StyleItemId; if (dbOrderItem.Id == 0 || item.NewListingId != item.ListingId || keepListingUpdateOnlyStyle) { var oldListing = db.Listings.GetViewListingsAsDto(withUnmaskedStyles: false) .FirstOrDefault(l => l.Id == sourceItemMapping.ListingId); if (newListing != null && oldListing != null) { itemSizeWasChanged = newListing.StyleItemId != oldListing.StyleItemId; if (itemSizeWasChanged) { var isStyleChanged = newListing.StyleString != oldListing.StyleString; changeNotes += (isStyleChanged ? "Order item" : "Size") + " was changed from: " + (isStyleChanged ? oldListing.StyleString + " - " : " ") + SizeHelper.ToVariation(oldListing.StyleSize, oldListing.StyleColor) + " to: " + (isStyleChanged ? newListing.StyleString + " - " : "") + SizeHelper.ToVariation(newListing.StyleSize, newListing.StyleColor); dbOrderItem.ReplaceType = (int)ItemReplaceTypes.Change; dbOrderItem.ReplaceDate = when; orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ReplaceItemKey, dbOrderItem.StyleItemId, dbOrderItem.Id.ToString(), newListing.StyleItemId, null, by); var quantityOperation = new QuantityOperationDTO() { Type = (int)QuantityOperationType.Lost, QuantityChanges = new List <QuantityChangeDTO>() { new QuantityChangeDTO() { StyleId = oldListing.StyleId.Value, StyleItemId = oldListing.StyleItemId.Value, Quantity = dbOrderItem.QuantityOrdered, //NOTE: W/o sign means that the qty will be substracted } }, Comment = "Order edit, change style/size", }; quantityManager.AddQuantityOperation(db, quantityOperation, when, by); } //NOTE: Actualize current style info dbOrderItem.StyleId = newListing.StyleId; dbOrderItem.StyleItemId = newListing.StyleItemId; dbOrderItem.StyleString = newListing.StyleString; dbOrderItem.SourceStyleString = oldListing.StyleString; dbOrderItem.SourceStyleItemId = oldListing.StyleItemId; dbOrderItem.SourceStyleSize = oldListing.StyleSize; dbOrderItem.SourceStyleColor = oldListing.StyleColor; } } if (dbOrderItem.ItemOrderIdentifier != dbOrderItem.SourceItemOrderIdentifier) { var portionCoef = dbOrderItem.QuantityOrdered / (decimal)sourceItemMapping.QuantityOrdered; dbOrderItem.ItemPrice = sourceItemMapping.ItemPrice * portionCoef; dbOrderItem.ItemPriceInUSD = sourceItemMapping.ItemPriceInUSD * portionCoef; dbOrderItem.ShippingPrice = sourceItemMapping.ShippingPrice * portionCoef; dbOrderItem.ShippingPriceInUSD = sourceItemMapping.ShippingPriceInUSD * portionCoef; dbOrderItem.ShippingDiscount = sourceItemMapping.ShippingDiscount * portionCoef; dbOrderItem.ShippingDiscountInUSD = sourceItemMapping.ShippingDiscountInUSD * portionCoef; } else //NOTE: m.b. no needed, for now no cases, but can be found in future { dbOrderItem.ItemPrice = sourceItemMapping.ItemPrice; dbOrderItem.ItemPriceInUSD = sourceItemMapping.ItemPriceInUSD; dbOrderItem.ShippingPrice = sourceItemMapping.ShippingPrice; dbOrderItem.ShippingPriceInUSD = sourceItemMapping.ShippingPriceInUSD; dbOrderItem.ShippingDiscount = sourceItemMapping.ShippingDiscount; dbOrderItem.ShippingDiscountInUSD = sourceItemMapping.ShippingDiscountInUSD; } } db.Commit(); var toRemoveOrderItems = dbOrderItems.Where(oi => joinItems.All(i => i.ItemOrderId != oi.ItemOrderIdentifier) && oi.QuantityOrdered > 0).ToList(); //Keeping cancelled items with qty = 0 foreach (var toRemove in toRemoveOrderItems) { log.Info("Remove orderItem, ordrItemId=" + toRemove.ItemOrderIdentifier + ", qty=" + toRemove.QuantityOrdered); db.OrderItems.Remove(toRemove); itemSizeWasChanged = true; } db.Commit(); if (itemSizeWasChanged) { shouldRecalcRates = true; Comments.Add(new CommentViewModel() { Comment = changeNotes, Type = (int)CommentType.ReturnExchange }); } } if (!string.IsNullOrEmpty(ManuallyShippingGroupId)) { var groupId = int.Parse(ManuallyShippingGroupId); var shippings = db.OrderShippingInfos.GetByOrderId(EntityId).ToList(); var previousIsActiveMethodIds = String.Join(";", shippings.Where(sh => sh.IsActive).Select(sh => sh.ShippingMethodId).ToList()); var hasDropdown = shippings.Where(sh => sh.IsVisible).GroupBy(sh => sh.ShippingMethodId).Count() > 1; if (shippings.Any(sh => sh.ShippingGroupId == groupId)) { foreach (var shipping in shippings) { shipping.IsActive = shipping.ShippingGroupId == groupId; if (hasDropdown) //Keep is visible { shipping.IsVisible = shipping.IsVisible || shipping.ShippingGroupId == groupId; } else { shipping.IsVisible = shipping.ShippingGroupId == groupId; } } var newIsActiveMethodIds = String.Join(";", shippings.Where(sh => sh.IsActive).Select(sh => sh.ShippingMethodId).ToList()); orderHistoryService.AddRecord(dbOrder.Id, OrderHistoryHelper.ShippingMethodKey, previousIsActiveMethodIds, newIsActiveMethodIds, by); } else { //Can't change active shipping to not exists } } db.Commit(); //Update Package Sizes var activeShippings = db.OrderShippingInfos.GetByOrderId(EntityId) .Where(sh => sh.IsActive) .OrderBy(sh => sh.Id) .ToList(); for (var i = 0; i < activeShippings.Count; i++) { if (Packages != null && i < Packages.Count) { if (activeShippings[i].PackageLength != Packages[i].PackageLength) { log.Info("Changed length: " + activeShippings[i].PackageLength + "=>" + Packages[i].PackageLength); activeShippings[i].PackageLength = Packages[i].PackageLength; shouldRecalcRates = true; } if (activeShippings[i].PackageWidth != Packages[i].PackageWidth) { log.Info("Changed width: " + activeShippings[i].PackageWidth + "=>" + Packages[i].PackageWidth); activeShippings[i].PackageWidth = Packages[i].PackageWidth; shouldRecalcRates = true; } if (activeShippings[i].PackageHeight != Packages[i].PackageHeight) { log.Info("Changed height: " + activeShippings[i].PackageHeight + "=>" + Packages[i].PackageHeight); activeShippings[i].PackageHeight = Packages[i].PackageHeight; shouldRecalcRates = true; } } } db.Commit(); foreach (var comment in Comments) { if (comment.Id == 0) { log.Info("New comment: " + comment.Comment); } } db.OrderComments.AddComments( Comments.Select(c => new CommentDTO() { Id = c.Id, Message = c.Comment, Type = c.Type, }).ToList(), EntityId, when, by); return(new ApplyOrderResult() { RateRecalcRequested = shouldRecalcRates, AddressValidationRequested = addressChanged || dbOrder.AddressValidationStatus == (int)Core.Models.AddressValidationStatus.ExceptionCommunication || dbOrder.AddressValidationStatus == (int)Core.Models.AddressValidationStatus.Exception, ShipmentProviderChanged = shipmentProviderChanged }); }