/// <summary> /// Deletes a shipment /// </summary> /// <param name="shipment">Shipment</param> public virtual void DeleteShipment(Shipment shipment) { if (shipment == null) throw new ArgumentNullException("shipment"); _shipmentRepository.Delete(shipment); //event notification _eventPublisher.EntityDeleted(shipment); }
/// <summary> /// Deletes a shipment /// </summary> /// <param name="shipment">Shipment</param> public virtual void DeleteShipment(Shipment shipment) { if (shipment == null) throw new ArgumentNullException("shipment"); int orderId = shipment.OrderId; _shipmentRepository.Delete(shipment); //event notifications _eventPublisher.EntityDeleted(shipment); if (orderId != 0) { var order = _orderRepository.GetById(orderId); _eventPublisher.PublishOrderUpdated(order); } }
public void Can_save_and_load_shipment() { var shipment = new Shipment { Order = GetTestOrder(), TrackingNumber = "TrackingNumber 1", TotalWeight = 9.87M, ShippedDateUtc = new DateTime(2010, 01, 01), DeliveryDateUtc = new DateTime(2010, 01, 02), CreatedOnUtc = new DateTime(2010, 01, 03), }; var fromDb = SaveAndLoadEntity(shipment); fromDb.ShouldNotBeNull(); fromDb.TrackingNumber.ShouldEqual("TrackingNumber 1"); fromDb.TotalWeight.ShouldEqual(9.87M); fromDb.ShippedDateUtc.ShouldEqual(new DateTime(2010, 01, 01)); fromDb.DeliveryDateUtc.ShouldEqual(new DateTime(2010, 01, 02)); fromDb.CreatedOnUtc.ShouldEqual(new DateTime(2010, 01, 03)); }
public void Can_save_and_load_shipment_with_items() { var shipment = new Shipment { Order = GetTestOrder(), TrackingNumber = "TrackingNumber 1", ShippedDateUtc = new DateTime(2010, 01, 01), DeliveryDateUtc = new DateTime(2010, 01, 02), CreatedOnUtc = new DateTime(2010, 01, 03), }; shipment.ShipmentItems.Add(new ShipmentItem() { OrderItemId = 1, Quantity = 2, }); var fromDb = SaveAndLoadEntity(shipment); fromDb.ShouldNotBeNull(); fromDb.ShipmentItems.ShouldNotBeNull(); (fromDb.ShipmentItems.Count == 1).ShouldBeTrue(); fromDb.ShipmentItems.First().Quantity.ShouldEqual(2); }
public virtual void AddShipmentTokens(IList<Token> tokens, Shipment shipment, int languageId) { tokens.Add(new Token("Shipment.ShipmentNumber", shipment.Id.ToString())); tokens.Add(new Token("Shipment.TrackingNumber", shipment.TrackingNumber)); tokens.Add(new Token("Shipment.Product(s)", ProductListToHtmlTable(shipment, languageId), true)); tokens.Add(new Token("Shipment.URLForCustomer", string.Format("{0}order/shipmentdetails/{1}", _webHelper.GetStoreLocation(false), shipment.Id), true)); //event notification _eventPublisher.EntityTokensAdded(shipment, tokens); }
/// <summary> /// Convert a collection to a HTML table /// </summary> /// <param name="shipment">Shipment</param> /// <param name="languageId">Language identifier</param> /// <returns>HTML table of products</returns> protected virtual string ProductListToHtmlTable(Shipment shipment, int languageId) { var result = ""; var sb = new StringBuilder(); sb.AppendLine("<table border=\"0\" style=\"width:100%;\">"); #region Products sb.AppendLine(string.Format("<tr style=\"background-color:{0};text-align:center;\">", _templatesSettings.Color1)); sb.AppendLine(string.Format("<th>{0}</th>", _localizationService.GetResource("Messages.Order.Product(s).Name", languageId))); sb.AppendLine(string.Format("<th>{0}</th>", _localizationService.GetResource("Messages.Order.Product(s).Quantity", languageId))); sb.AppendLine("</tr>"); var table = shipment.ShipmentItems.ToList(); for (int i = 0; i <= table.Count - 1; i++) { var si = table[i]; var orderItem = _orderService.GetOrderItemById(si.OrderItemId); if (orderItem == null) continue; var product = orderItem.Product; if (product == null) continue; sb.AppendLine(string.Format("<tr style=\"background-color: {0};text-align: center;\">", _templatesSettings.Color2)); //product name string productName = product.GetLocalized(x => x.Name, languageId); sb.AppendLine("<td style=\"padding: 0.6em 0.4em;text-align: left;\">" + HttpUtility.HtmlEncode(productName)); //attributes if (!String.IsNullOrEmpty(orderItem.AttributeDescription)) { sb.AppendLine("<br />"); sb.AppendLine(orderItem.AttributeDescription); } //sku if (_catalogSettings.ShowProductSku) { product.MergeWithCombination(orderItem.AttributesXml, _productAttributeParser); if (!String.IsNullOrEmpty(product.Sku)) { sb.AppendLine("<br />"); sb.AppendLine(string.Format(_localizationService.GetResource("Messages.Order.Product(s).SKU", languageId), HttpUtility.HtmlEncode(product.Sku))); } } sb.AppendLine("</td>"); sb.AppendLine(string.Format("<td style=\"padding: 0.6em 0.4em;text-align: center;\">{0}</td>", si.Quantity)); sb.AppendLine("</tr>"); } #endregion sb.AppendLine("</table>"); result = sb.ToString(); return result; }
/// <summary> /// Marks a shipment as delivered /// </summary> /// <param name="shipment">Shipment</param> /// <param name="notifyCustomer">True to notify customer</param> public virtual void Deliver(Shipment shipment, bool notifyCustomer) { if (shipment == null) throw new ArgumentNullException("shipment"); var order = shipment.Order; if (order == null) throw new Exception("Order cannot be loaded"); if (shipment.DeliveryDateUtc.HasValue) throw new Exception("This shipment is already delivered"); shipment.DeliveryDateUtc = DateTime.UtcNow; _shipmentService.UpdateShipment(shipment); if (!order.HasItemsToAddToShipment() && !order.HasItemsToShip() && !order.HasItemsToDeliver()) order.ShippingStatusId = (int)ShippingStatus.Delivered; _orderService.UpdateOrder(order); //add a note order.OrderNotes.Add(new OrderNote() { Note = string.Format(T("ShipmentDelivered"), shipment.Id), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); if (notifyCustomer) { //send email notification int queuedEmailId = _workflowMessageService.SendShipmentDeliveredCustomerNotification(shipment, order.CustomerLanguageId); if (queuedEmailId > 0) { order.OrderNotes.Add(new OrderNote() { Note = string.Format(T("CustomerDeliveredEmailQueued"), queuedEmailId), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); } } //check order status CheckOrderStatus(order); }
/// <summary> /// Send a shipment /// </summary> /// <param name="shipment">Shipment</param> /// <param name="notifyCustomer">True to notify customer</param> public virtual void Ship(Shipment shipment, bool notifyCustomer) { if (shipment == null) throw new ArgumentNullException("shipment"); var order = _orderService.GetOrderById(shipment.OrderId); if (order == null) throw new Exception("Order cannot be loaded"); if (shipment.ShippedDateUtc.HasValue) throw new Exception("This shipment is already shipped"); shipment.ShippedDateUtc = DateTime.UtcNow; _shipmentService.UpdateShipment(shipment); //check whether we have more items to ship if (order.HasItemsToAddToShipment() || order.HasItemsToShip()) order.ShippingStatusId = (int)ShippingStatus.PartiallyShipped; else order.ShippingStatusId = (int)ShippingStatus.Shipped; _orderService.UpdateOrder(order); //add a note order.OrderNotes.Add(new OrderNote() { Note = string.Format(T("ShipmentSent"), shipment.Id), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); if (notifyCustomer) { //notify customer int queuedEmailId = _workflowMessageService.SendShipmentSentCustomerNotification(shipment, order.CustomerLanguageId); if (queuedEmailId > 0) { order.OrderNotes.Add(new OrderNote() { Note = string.Format(T("CustomerShippedEmailQueued"), queuedEmailId), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); } } //check order status CheckOrderStatus(order); }
/// <summary> /// Sends a shipment delivered notification to a customer /// </summary> /// <param name="shipment">Shipment</param> /// <param name="languageId">Message language identifier</param> /// <returns>Queued email identifier</returns> public virtual int SendShipmentDeliveredCustomerNotification(Shipment shipment, int languageId) { if (shipment == null) throw new ArgumentNullException("shipment"); var order = shipment.Order; if (order == null) throw new Exception("Order cannot be loaded"); var store = _storeService.GetStoreById(order.StoreId) ?? _storeContext.CurrentStore; languageId = EnsureLanguageIsActive(languageId, store.Id); var messageTemplate = GetLocalizedActiveMessageTemplate("ShipmentDelivered.CustomerNotification", languageId, store.Id); if (messageTemplate == null) return 0; //tokens var tokens = new List<Token>(); _messageTokenProvider.AddStoreTokens(tokens, store); _messageTokenProvider.AddShipmentTokens(tokens, shipment, languageId); _messageTokenProvider.AddOrderTokens(tokens, shipment.Order, languageId); _messageTokenProvider.AddCustomerTokens(tokens, shipment.Order.Customer); //event notification _eventPublisher.MessageTokensAdded(messageTemplate, tokens); var emailAccount = GetEmailAccountOfMessageTemplate(messageTemplate, languageId); var toEmail = order.BillingAddress.Email; var toName = string.Format("{0} {1}", order.BillingAddress.FirstName, order.BillingAddress.LastName); return SendNotification(messageTemplate, emailAccount, languageId, tokens, toEmail, toName); }
protected ShipmentDetailsModel PrepareShipmentDetailsModel(Shipment shipment) { if (shipment == null) throw new ArgumentNullException("shipment"); var order = shipment.Order; if (order == null) throw new Exception("order cannot be loaded"); var store = _storeService.GetStoreById(order.StoreId) ?? _services.StoreContext.CurrentStore; var catalogSettings = _services.Settings.LoadSetting<CatalogSettings>(store.Id); var shippingSettings = _services.Settings.LoadSetting<ShippingSettings>(store.Id); var model = new ShipmentDetailsModel(); model.Id = shipment.Id; if (shipment.ShippedDateUtc.HasValue) model.ShippedDate = _dateTimeHelper.ConvertToUserTime(shipment.ShippedDateUtc.Value, DateTimeKind.Utc); if (shipment.DeliveryDateUtc.HasValue) model.DeliveryDate = _dateTimeHelper.ConvertToUserTime(shipment.DeliveryDateUtc.Value, DateTimeKind.Utc); //tracking number and shipment information model.TrackingNumber = shipment.TrackingNumber; var srcm = _shippingService.LoadShippingRateComputationMethodBySystemName(order.ShippingRateComputationMethodSystemName); if (srcm != null && srcm.IsShippingRateComputationMethodActive(shippingSettings)) { var shipmentTracker = srcm.Value.ShipmentTracker; if (shipmentTracker != null) { model.TrackingNumberUrl = shipmentTracker.GetUrl(shipment.TrackingNumber); if (shippingSettings.DisplayShipmentEventsToCustomers) { var shipmentEvents = shipmentTracker.GetShipmentEvents(shipment.TrackingNumber); if (shipmentEvents != null) foreach (var shipmentEvent in shipmentEvents) { var shipmentStatusEventModel = new ShipmentDetailsModel.ShipmentStatusEventModel(); var shipmentEventCountry = _countryService.GetCountryByTwoLetterIsoCode(shipmentEvent.CountryCode); shipmentStatusEventModel.Country = shipmentEventCountry != null ? shipmentEventCountry.GetLocalized(x => x.Name) : shipmentEvent.CountryCode; shipmentStatusEventModel.Date = shipmentEvent.Date; shipmentStatusEventModel.EventName = shipmentEvent.EventName; shipmentStatusEventModel.Location = shipmentEvent.Location; model.ShipmentStatusEvents.Add(shipmentStatusEventModel); } } } } //products in this shipment model.ShowSku = catalogSettings.ShowProductSku; foreach (var shipmentItem in shipment.ShipmentItems) { var orderItem = _orderService.GetOrderItemById(shipmentItem.OrderItemId); if (orderItem == null) continue; orderItem.Product.MergeWithCombination(orderItem.AttributesXml); var shipmentItemModel = new ShipmentDetailsModel.ShipmentItemModel() { Id = shipmentItem.Id, Sku = orderItem.Product.Sku, ProductId = orderItem.Product.Id, ProductName = orderItem.Product.GetLocalized(x => x.Name), ProductSeName = orderItem.Product.GetSeName(), AttributeInfo = orderItem.AttributeDescription, QuantityOrdered = orderItem.Quantity, QuantityShipped = shipmentItem.Quantity, }; model.Items.Add(shipmentItemModel); } //order details model model.Order = PrepareOrderDetailsModel(order); return model; }
public ActionResult AddShipment(int orderId, FormCollection form, bool continueEditing) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders)) return AccessDeniedView(); var order = _orderService.GetOrderById(orderId); if (order == null) //No order found with the specified id return RedirectToAction("List"); Shipment shipment = null; decimal? totalWeight = null; foreach (var orderItem in order.OrderItems) { //is shippable if (!orderItem.Product.IsShipEnabled) continue; //ensure that this product can be shipped (have at least one item to ship) var maxQtyToAdd = orderItem.GetTotalNumberOfItemsCanBeAddedToShipment(); if (maxQtyToAdd <= 0) continue; int qtyToAdd = 0; //parse quantity foreach (string formKey in form.AllKeys) if (formKey.Equals(string.Format("qtyToAdd{0}", orderItem.Id), StringComparison.InvariantCultureIgnoreCase)) { int.TryParse(form[formKey], out qtyToAdd); break; } //validate quantity if (qtyToAdd <= 0) continue; if (qtyToAdd > maxQtyToAdd) qtyToAdd = maxQtyToAdd; //ok. we have at least one item. let's create a shipment (if it does not exist) var orderItemTotalWeight = orderItem.ItemWeight.HasValue ? orderItem.ItemWeight * qtyToAdd : null; if (orderItemTotalWeight.HasValue) { if (!totalWeight.HasValue) totalWeight = 0; totalWeight += orderItemTotalWeight.Value; } if (shipment == null) { shipment = new Shipment() { OrderId = order.Id, TrackingNumber = form["TrackingNumber"], TotalWeight = null, ShippedDateUtc = null, DeliveryDateUtc = null, CreatedOnUtc = DateTime.UtcNow, }; } //create a shipment item var shipmentItem = new ShipmentItem() { OrderItemId = orderItem.Id, Quantity = qtyToAdd, }; shipment.ShipmentItems.Add(shipmentItem); } //if we have at least one item in the shipment, then save it if (shipment != null && shipment.ShipmentItems.Count > 0) { shipment.TotalWeight = totalWeight; _shipmentService.InsertShipment(shipment); NotifySuccess(_localizationService.GetResource("Admin.Orders.Shipments.Added")); return continueEditing ? RedirectToAction("ShipmentDetails", new {id = shipment.Id}) : RedirectToAction("Edit", new { id = orderId }); } else { NotifyError(_localizationService.GetResource("Admin.Orders.Shipments.NoProductsSelected")); return RedirectToAction("AddShipment", new { orderId = orderId }); } }
protected ShipmentModel PrepareShipmentModel(Shipment shipment, bool prepareProducts, bool prepareAddresses) { //measures var baseWeight = _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId); var baseWeightIn = baseWeight != null ? baseWeight.Name : ""; var baseDimension = _measureService.GetMeasureDimensionById(_measureSettings.BaseDimensionId); var baseDimensionIn = baseDimension != null ? baseDimension.Name : ""; var orderStoreId = shipment.Order.StoreId; var model = new ShipmentModel { Id = shipment.Id, OrderId = shipment.OrderId, StoreId = orderStoreId, ShippingMethod = shipment.Order.ShippingMethod, TrackingNumber = shipment.TrackingNumber, TotalWeight = shipment.TotalWeight.HasValue ? string.Format("{0:F2} [{1}]", shipment.TotalWeight, baseWeightIn) : "", ShippedDate = shipment.ShippedDateUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(shipment.ShippedDateUtc.Value, DateTimeKind.Utc).ToString() : _localizationService.GetResource("Admin.Orders.Shipments.ShippedDate.NotYet"), CanShip = !shipment.ShippedDateUtc.HasValue, DeliveryDate = shipment.DeliveryDateUtc.HasValue ? _dateTimeHelper.ConvertToUserTime(shipment.DeliveryDateUtc.Value, DateTimeKind.Utc).ToString() : _localizationService.GetResource("Admin.Orders.Shipments.DeliveryDate.NotYet"), CanDeliver = shipment.ShippedDateUtc.HasValue && !shipment.DeliveryDateUtc.HasValue, DisplayPdfPackagingSlip = _pdfSettings.Enabled, }; if (prepareAddresses) { model.ShippingAddress = shipment.Order.ShippingAddress; var store = _services.StoreService.GetStoreById(orderStoreId) ?? _services.StoreContext.CurrentStore; var companyInfoSettings = _services.Settings.LoadSetting<CompanyInformationSettings>(store.Id); model.MerchantCompanyInfo = companyInfoSettings; } if (prepareProducts) { foreach (var shipmentItem in shipment.ShipmentItems) { var orderItem = _orderService.GetOrderItemById(shipmentItem.OrderItemId); if (orderItem == null) continue; //quantities var qtyInThisShipment = shipmentItem.Quantity; var maxQtyToAdd = orderItem.GetTotalNumberOfItemsCanBeAddedToShipment(); var qtyOrdered = orderItem.Quantity; var qtyInAllShipments = orderItem.GetTotalNumberOfItemsInAllShipment(); orderItem.Product.MergeWithCombination(orderItem.AttributesXml); var shipmentItemModel = new ShipmentModel.ShipmentItemModel() { Id = shipmentItem.Id, OrderItemId = orderItem.Id, ProductId = orderItem.ProductId, ProductName = orderItem.Product.Name, ProductTypeName = orderItem.Product.GetProductTypeLabel(_localizationService), ProductTypeLabelHint = orderItem.Product.ProductTypeLabelHint, Sku = orderItem.Product.Sku, AttributeInfo = orderItem.AttributeDescription, ItemWeight = orderItem.ItemWeight.HasValue ? string.Format("{0:F2} [{1}]", orderItem.ItemWeight, baseWeightIn) : "", ItemDimensions = string.Format("{0:F2} x {1:F2} x {2:F2} [{3}]", orderItem.Product.Length, orderItem.Product.Width, orderItem.Product.Height, baseDimensionIn), QuantityOrdered = qtyOrdered, QuantityInThisShipment = qtyInThisShipment, QuantityInAllShipments = qtyInAllShipments, QuantityToAdd = maxQtyToAdd, }; model.Items.Add(shipmentItemModel); } } return model; }
/// <summary> /// Updates the shipment /// </summary> /// <param name="shipment">Shipment</param> public virtual void UpdateShipment(Shipment shipment) { if (shipment == null) throw new ArgumentNullException("shipment"); _shipmentRepository.Update(shipment); //event notification _eventPublisher.EntityUpdated(shipment); _eventPublisher.PublishOrderUpdated(shipment.Order); }
/// <summary> /// Marks a shipment as delivered /// </summary> /// <param name="shipment">Shipment</param> /// <param name="notifyCustomer">True to notify customer</param> public virtual void Deliver(Shipment shipment, bool notifyCustomer) { if (shipment == null) throw new ArgumentNullException("shipment"); var order = shipment.Order; if (order == null) throw new SmartException(T("Order.NotFound", shipment.OrderId)); if (shipment.DeliveryDateUtc.HasValue) throw new SmartException(T("Shipment.AlreadyDelivered")); shipment.DeliveryDateUtc = DateTime.UtcNow; _shipmentService.UpdateShipment(shipment); if (!order.HasItemsToAddToShipment() && !order.HasItemsToShip() && !order.HasItemsToDeliver()) { order.ShippingStatusId = (int)ShippingStatus.Delivered; } _orderService.UpdateOrder(order); _orderService.AddOrderNote(order, T("Admin.OrderNotice.ShipmentDelivered", shipment.Id)); if (notifyCustomer) { //send email notification int queuedEmailId = _workflowMessageService.SendShipmentDeliveredCustomerNotification(shipment, order.CustomerLanguageId); if (queuedEmailId > 0) { _orderService.AddOrderNote(order, T("Admin.OrderNotice.CustomerDeliveredEmailQueued", queuedEmailId)); } } //check order status CheckOrderStatus(order); }
/// <summary> /// Send a shipment /// </summary> /// <param name="shipment">Shipment</param> /// <param name="notifyCustomer">True to notify customer</param> public virtual void Ship(Shipment shipment, bool notifyCustomer) { if (shipment == null) throw new ArgumentNullException("shipment"); var order = _orderService.GetOrderById(shipment.OrderId); if (order == null) throw new SmartException(T("Order.NotFound", shipment.OrderId)); if (shipment.ShippedDateUtc.HasValue) throw new SmartException(T("Shipment.AlreadyShipped")); shipment.ShippedDateUtc = DateTime.UtcNow; _shipmentService.UpdateShipment(shipment); //check whether we have more items to ship if (order.HasItemsToAddToShipment() || order.HasItemsToShip()) order.ShippingStatusId = (int)ShippingStatus.PartiallyShipped; else order.ShippingStatusId = (int)ShippingStatus.Shipped; _orderService.UpdateOrder(order); _orderService.AddOrderNote(order, T("Admin.OrderNotice.ShipmentSent", shipment.Id)); if (notifyCustomer) { //notify customer int queuedEmailId = _workflowMessageService.SendShipmentSentCustomerNotification(shipment, order.CustomerLanguageId); if (queuedEmailId > 0) { _orderService.AddOrderNote(order, T("Admin.OrderNotice.CustomerShippedEmailQueued", queuedEmailId)); } } //check order status CheckOrderStatus(order); }
public virtual Shipment AddShipment(Order order, string trackingNumber, Dictionary<int, int> quantities) { Guard.ArgumentNotNull(() => order); Shipment shipment = null; decimal? totalWeight = null; foreach (var orderItem in order.OrderItems) { if (!orderItem.Product.IsShipEnabled) continue; //ensure that this product can be shipped (have at least one item to ship) var maxQtyToAdd = orderItem.GetTotalNumberOfItemsCanBeAddedToShipment(); if (maxQtyToAdd <= 0) continue; var qtyToAdd = 0; if (quantities != null && quantities.ContainsKey(orderItem.Id)) qtyToAdd = quantities[orderItem.Id]; else if (quantities == null) qtyToAdd = maxQtyToAdd; if (qtyToAdd <= 0) continue; if (qtyToAdd > maxQtyToAdd) qtyToAdd = maxQtyToAdd; var orderItemTotalWeight = orderItem.ItemWeight.HasValue ? orderItem.ItemWeight * qtyToAdd : null; if (orderItemTotalWeight.HasValue) { if (!totalWeight.HasValue) totalWeight = 0; totalWeight += orderItemTotalWeight.Value; } if (shipment == null) { shipment = new Shipment { OrderId = order.Id, Order = order, // otherwise order updated event would not be fired during InsertShipment TrackingNumber = trackingNumber, TotalWeight = null, ShippedDateUtc = null, DeliveryDateUtc = null, CreatedOnUtc = DateTime.UtcNow, }; } var shipmentItem = new ShipmentItem { OrderItemId = orderItem.Id, Quantity = qtyToAdd }; shipment.ShipmentItems.Add(shipmentItem); } if (shipment != null && shipment.ShipmentItems.Count > 0) { shipment.TotalWeight = totalWeight; _shipmentService.InsertShipment(shipment); return shipment; } return null; }