Skip to content

Commit

Permalink
Allow a store owner to configure a pickup location
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanovM committed Jul 14, 2016
1 parent 4fea3d9 commit b644bad
Show file tree
Hide file tree
Showing 53 changed files with 1,835 additions and 253 deletions.
2 changes: 2 additions & 0 deletions src/Libraries/Nop.Core/CommonHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ public static TypeConverter GetNopCustomTypeConverter(Type type)
return new ShippingOptionTypeConverter();
if (type == typeof(List<ShippingOption>) || type == typeof(IList<ShippingOption>))
return new ShippingOptionListTypeConverter();
if (type == typeof(PickupPoint))
return new PickupPointTypeConverter();
if (type == typeof(Dictionary<int, int>))
return new GenericDictionaryTypeConverter<int, int>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ public static partial class SystemCustomerAttributeNames
public static string LanguageAutomaticallyDetected { get { return "LanguageAutomaticallyDetected"; } }
public static string SelectedPaymentMethod { get { return "SelectedPaymentMethod"; } }
public static string SelectedShippingOption { get { return "SelectedShippingOption"; } }
//value indicating whether customer chose "pick up in store" option
public static string SelectedPickUpInStore { get { return "SelectedPickUpInStore"; } }
public static string SelectedPickupPoint { get { return "SelectedPickupPoint"; } }
public static string CheckoutAttributes { get { return "CheckoutAttributes"; } }
public static string OfferedShippingOptions { get { return "OfferedShippingOptions"; } }
public static string LastContinueShoppingPage { get { return "LastContinueShoppingPage"; } }
Expand Down
12 changes: 11 additions & 1 deletion src/Libraries/Nop.Core/Domain/Orders/Order.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ public partial class Order : BaseEntity
/// </summary>
public int? ShippingAddressId { get; set; }

/// <summary>
/// Gets or sets the pickup address identifier
/// </summary>
public int? PickupAddressId { get; set; }

/// <summary>
/// Gets or sets a value indicating whether a customer chose "pick up in store" shipping option
/// </summary>
Expand Down Expand Up @@ -348,7 +353,12 @@ public partial class Order : BaseEntity
/// Gets or sets the shipping address
/// </summary>
public virtual Address ShippingAddress { get; set; }


/// <summary>
/// Gets or sets the pickup address
/// </summary>
public virtual Address PickupAddress { get; set; }

/// <summary>
/// Gets or sets the reward points history record (spent by a customer when placing this order)
/// </summary>
Expand Down
129 changes: 129 additions & 0 deletions src/Libraries/Nop.Core/Domain/Shipping/PickupPoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml.Serialization;

namespace Nop.Core.Domain.Shipping
{
public partial class PickupPoint
{
/// <summary>
/// Gets or sets an identifier
/// </summary>
public string Id { get; set; }

/// <summary>
/// Gets or sets a name
/// </summary>
public string Name { get; set; }

/// <summary>
/// Gets or sets a description
/// </summary>
public string Description { get; set; }

/// <summary>
/// Gets or sets a system name of the pickup point provider
/// </summary>
public string ProviderSystemName { get; set; }

/// <summary>
/// Gets or sets an address
/// </summary>
public string Address { get; set; }

/// <summary>
/// Gets or sets a city
/// </summary>
public string City { get; set; }

/// <summary>
/// Gets or sets a two-letter ISO country code
/// </summary>
public string CountryCode { get; set; }

/// <summary>
/// Gets or sets a zip postal code
/// </summary>
public string ZipPostalCode { get; set; }

/// <summary>
/// Gets or sets a latitude
/// </summary>
public decimal? Latitude { get; set; }

/// <summary>
/// Gets or sets a longitude
/// </summary>
public decimal? Longitude { get; set; }

/// <summary>
/// Gets or sets a fee for the pickup
/// </summary>
public decimal PickupFee { get; set; }

/// <summary>
/// Gets or sets an oppening hours
/// </summary>
public string OpeningHours { get; set; }
}

public class PickupPointTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
return true;

return base.CanConvertFrom(context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string)
{
PickupPoint pickupPoint = null;
var valueStr = value as string;
if (!string.IsNullOrEmpty(valueStr))
{
try
{
using (var tr = new StringReader(valueStr))
{
pickupPoint = (PickupPoint)(new XmlSerializer(typeof(PickupPoint)).Deserialize(tr));
}
}
catch { }
}

return pickupPoint;
}

return base.ConvertFrom(context, culture, value);
}

public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
var pickupPoint = value as PickupPoint;
if (pickupPoint != null)
{
var sb = new StringBuilder();
using (var tw = new StringWriter(sb))
{
new XmlSerializer(typeof(PickupPoint)).Serialize(tw, value);

return sb.ToString();
}
}

return string.Empty;
}

return base.ConvertTo(context, culture, value, destinationType);
}
}
}
15 changes: 13 additions & 2 deletions src/Libraries/Nop.Core/Domain/Shipping/ShippingSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@ public class ShippingSettings : ISettings
public ShippingSettings()
{
ActiveShippingRateComputationMethodSystemNames = new List<string>();
ActivePickupPointProviderSystemNames = new List<string>();
}

/// <summary>
/// Gets or sets system names of active shipping rate computation methods
/// </summary>
public List<string> ActiveShippingRateComputationMethodSystemNames { get; set; }

/// <summary>
/// Gets or sets system names of active pickup point providers
/// </summary>
public List<string> ActivePickupPointProviderSystemNames { get; set; }

/// <summary>
/// Gets or sets a value indicating "Ship to the same address" option is enabled
/// </summary>
Expand All @@ -26,10 +32,15 @@ public ShippingSettings()
public bool AllowPickUpInStore { get; set; }

/// <summary>
/// Gets or sets "pick up in store" fee (used with "AllowPickUpInStore" setting enabled)
/// Gets or sets a value indicating whether display a pickup points in the map
/// </summary>
public decimal PickUpInStoreFee { get; set; }
public bool DisplayPickupPointsOnMap { get; set; }

/// <summary>
/// Gets or sets Google map API key
/// </summary>
public string GoogleMapsApiKey { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the system should use warehouse location when requesting shipping rates
/// This is useful when you ship from multiple warehouses
Expand Down
1 change: 1 addition & 0 deletions src/Libraries/Nop.Core/Nop.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
<Compile Include="Domain\Orders\ReturnRequestAction.cs" />
<Compile Include="Domain\Seo\WwwRequirement.cs" />
<Compile Include="Domain\Shipping\Events.cs" />
<Compile Include="Domain\Shipping\PickupPoint.cs" />
<Compile Include="Domain\Shipping\Warehouse.cs" />
<Compile Include="Domain\Shipping\DeliveryDate.cs" />
<Compile Include="Domain\Topics\TopicTemplate.cs" />
Expand Down
4 changes: 4 additions & 0 deletions src/Libraries/Nop.Data/Mapping/Orders/OrderMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ public OrderMap()
.WithMany()
.HasForeignKey(o => o.ShippingAddressId)
.WillCascadeOnDelete(false);
this.HasOptional(o => o.PickupAddress)
.WithMany()
.HasForeignKey(o => o.PickupAddressId)
.WillCascadeOnDelete(false);
}
}
}
32 changes: 30 additions & 2 deletions src/Libraries/Nop.Services/Common/PdfService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,20 @@ public virtual void PrintOrdersToPdf(Stream stream, IList<Order> orders, int lan
}
shippingAddress.AddCell(new Paragraph(" "));
}
else
if (order.PickupAddress != null)
{
shippingAddress.AddCell(new Paragraph(_localizationService.GetResource("PDFInvoice.Pickup", lang.Id), titleFont));
if (!string.IsNullOrEmpty(order.PickupAddress.Address1))
shippingAddress.AddCell(new Paragraph(string.Format(" {0}", string.Format(_localizationService.GetResource("PDFInvoice.Address", lang.Id), order.PickupAddress.Address1)), font));
if (!string.IsNullOrEmpty(order.PickupAddress.City))
shippingAddress.AddCell(new Paragraph(string.Format(" {0}", order.PickupAddress.City), font));
if (order.PickupAddress.Country != null)
shippingAddress.AddCell(new Paragraph(string.Format(" {0}", order.PickupAddress.Country.GetLocalized(x => x.Name, lang.Id)), font));
if (!string.IsNullOrEmpty(order.PickupAddress.ZipPostalCode))
shippingAddress.AddCell(new Paragraph(string.Format(" {0}", order.PickupAddress.ZipPostalCode), font));
shippingAddress.AddCell(new Paragraph(" "));
}
shippingAddress.AddCell(new Paragraph(" " + String.Format(_localizationService.GetResource("PDFInvoice.ShippingMethod", lang.Id), order.ShippingMethod), font));
shippingAddress.AddCell(new Paragraph());

Expand Down Expand Up @@ -1015,7 +1029,7 @@ public virtual void PrintPackagingSlipsToPdf(Stream stream, IList<Shipment> ship
{
if (order.ShippingAddress == null)
throw new NopException(string.Format("Shipping is required, but address is not available. Order ID = {0}", order.Id));

if (_addressSettings.CompanyEnabled && !String.IsNullOrEmpty(order.ShippingAddress.Company))
addressTable.AddCell(new Paragraph(String.Format(_localizationService.GetResource("PDFPackagingSlip.Company", lang.Id),
order.ShippingAddress.Company), font));
Expand Down Expand Up @@ -1050,7 +1064,21 @@ public virtual void PrintPackagingSlipsToPdf(Stream stream, IList<Shipment> ship
addressTable.AddCell(new Paragraph(HtmlHelper.ConvertHtmlToPlainText(customShippingAddressAttributes, true, true), font));
}
}

else
if (order.PickupAddress != null)
{
addressTable.AddCell(new Paragraph(_localizationService.GetResource("PDFInvoice.Pickup", lang.Id), titleFont));
if (!string.IsNullOrEmpty(order.PickupAddress.Address1))
addressTable.AddCell(new Paragraph(string.Format(" {0}", string.Format(_localizationService.GetResource("PDFInvoice.Address", lang.Id), order.PickupAddress.Address1)), font));
if (!string.IsNullOrEmpty(order.PickupAddress.City))
addressTable.AddCell(new Paragraph(string.Format(" {0}", order.PickupAddress.City), font));
if (order.PickupAddress.Country != null)
addressTable.AddCell(new Paragraph(string.Format(" {0}", order.PickupAddress.Country.GetLocalized(x => x.Name, lang.Id)), font));
if (!string.IsNullOrEmpty(order.PickupAddress.ZipPostalCode))
addressTable.AddCell(new Paragraph(string.Format(" {0}", order.PickupAddress.ZipPostalCode), font));
addressTable.AddCell(new Paragraph(" "));
}

addressTable.AddCell(new Paragraph(" "));

addressTable.AddCell(new Paragraph(String.Format(_localizationService.GetResource("PDFPackagingSlip.ShippingMethod", lang.Id), order.ShippingMethod), font));
Expand Down
2 changes: 1 addition & 1 deletion src/Libraries/Nop.Services/Customers/CustomerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ public virtual void UpdateCustomer(Customer customer)
{
_genericAttributeService.SaveAttribute<ShippingOption>(customer, SystemCustomerAttributeNames.SelectedShippingOption, null, storeId);
_genericAttributeService.SaveAttribute<ShippingOption>(customer, SystemCustomerAttributeNames.OfferedShippingOptions, null, storeId);
_genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.SelectedPickUpInStore, false, storeId);
_genericAttributeService.SaveAttribute<ShippingOption>(customer, SystemCustomerAttributeNames.SelectedPickupPoint, null, storeId);
}

//clear selected payment method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6044,7 +6044,7 @@ protected virtual void InstallSettings()
ActiveShippingRateComputationMethodSystemNames = new List<string> { "Shipping.FixedRate" },
ShipToSameAddress = false,
AllowPickUpInStore = true,
PickUpInStoreFee = decimal.Zero,
DisplayPickupPointsOnMap = false,
UseWarehouseLocation = false,
NotifyCustomerAboutShippingFromMultipleLocations = false,
FreeShippingOverXEnabled = false,
Expand Down
2 changes: 2 additions & 0 deletions src/Libraries/Nop.Services/Nop.Services.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@
<Compile Include="Orders\RewardPointService.cs" />
<Compile Include="Orders\ReturnRequestService.cs" />
<Compile Include="Shipping\EventPublisherExtensions.cs" />
<Compile Include="Shipping\Pickup\GetPickupPointsResponse.cs" />
<Compile Include="Shipping\Pickup\IPickupPointProvider.cs" />
<Compile Include="Topics\ITopicTemplateService.cs" />
<Compile Include="Topics\TopicTemplateService.cs" />
<Compile Include="Vendors\VendorExtensions.cs" />
Expand Down
27 changes: 23 additions & 4 deletions src/Libraries/Nop.Services/Orders/OrderProcessingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public partial class OrderProcessingService : IOrderProcessingService
private readonly IPdfService _pdfService;
private readonly IRewardPointService _rewardPointService;
private readonly IGenericAttributeService _genericAttributeService;
private readonly ICountryService _countryService;

private readonly ShippingSettings _shippingSettings;
private readonly PaymentSettings _paymentSettings;
Expand Down Expand Up @@ -119,6 +120,7 @@ public partial class OrderProcessingService : IOrderProcessingService
/// <param name="pdfService">PDF service</param>
/// <param name="rewardPointService">Reward point service</param>
/// <param name="genericAttributeService">Generic attribute service</param>
/// <param name="countryService">Country service</param>
/// <param name="paymentSettings">Payment settings</param>
/// <param name="shippingSettings">Shipping settings</param>
/// <param name="rewardPointsSettings">Reward points settings</param>
Expand Down Expand Up @@ -157,6 +159,7 @@ public partial class OrderProcessingService : IOrderProcessingService
IPdfService pdfService,
IRewardPointService rewardPointService,
IGenericAttributeService genericAttributeService,
ICountryService countryService,
ShippingSettings shippingSettings,
PaymentSettings paymentSettings,
RewardPointsSettings rewardPointsSettings,
Expand Down Expand Up @@ -196,6 +199,7 @@ public partial class OrderProcessingService : IOrderProcessingService
this._pdfService = pdfService;
this._rewardPointService = rewardPointService;
this._genericAttributeService = genericAttributeService;
this._countryService = countryService;

this._paymentSettings = paymentSettings;
this._shippingSettings = shippingSettings;
Expand Down Expand Up @@ -232,6 +236,7 @@ public PlaceOrderContainter()
public string ShippingMethodName { get; set; }
public string ShippingRateComputationMethodSystemName { get; set; }
public bool PickUpInStore { get; set; }
public Address PickupAddress { get; set; }

public bool IsRecurringShoppingCart { get; set; }
//initial order (used with recurring payments)
Expand Down Expand Up @@ -384,10 +389,20 @@ protected virtual PlaceOrderContainter PreparePlaceOrderDetails(ProcessPaymentRe
//shipping info
if (details.Cart.RequiresShipping())
{
details.PickUpInStore = _shippingSettings.AllowPickUpInStore &&
details.Customer.GetAttribute<bool>(SystemCustomerAttributeNames.SelectedPickUpInStore, processPaymentRequest.StoreId);

if (!details.PickUpInStore)
var pickupPoint = details.Customer.GetAttribute<PickupPoint>(SystemCustomerAttributeNames.SelectedPickupPoint, processPaymentRequest.StoreId);
if (_shippingSettings.AllowPickUpInStore && pickupPoint != null)
{
details.PickUpInStore = true;
details.PickupAddress = new Address
{
Address1 = pickupPoint.Address,
City = pickupPoint.City,
Country = _countryService.GetCountryByTwoLetterIsoCode(pickupPoint.CountryCode),
ZipPostalCode = pickupPoint.ZipPostalCode,
CreatedOnUtc = DateTime.UtcNow,
};
}
else
{
if (details.Customer.ShippingAddress == null)
throw new NopException("Shipping address is not provided");
Expand Down Expand Up @@ -563,6 +578,9 @@ protected virtual PlaceOrderContainter PrepareRecurringOrderDetails(ProcessPayme
if (details.ShippingAddress.Country != null && !details.ShippingAddress.Country.AllowsShipping)
throw new NopException(string.Format("Country '{0}' is not allowed for shipping", details.ShippingAddress.Country.Name));
}
else
if (details.InitialOrder.PickupAddress != null)
details.PickupAddress = (Address)details.InitialOrder.PickupAddress.Clone();
details.ShippingMethodName = details.InitialOrder.ShippingMethod;
details.ShippingRateComputationMethodSystemName = details.InitialOrder.ShippingRateComputationMethodSystemName;
details.ShippingStatus = ShippingStatus.NotYetShipped;
Expand Down Expand Up @@ -651,6 +669,7 @@ protected virtual PlaceOrderContainter PrepareRecurringOrderDetails(ProcessPayme
ShippingStatus = details.ShippingStatus,
ShippingMethod = details.ShippingMethodName,
PickUpInStore = details.PickUpInStore,
PickupAddress = details.PickupAddress,
ShippingRateComputationMethodSystemName = details.ShippingRateComputationMethodSystemName,
CustomValuesXml = processPaymentRequest.SerializeCustomValues(),
VatNumber = details.VatNumber,
Expand Down

0 comments on commit b644bad

Please sign in to comment.