Skip to content

Commit b096a50

Browse files
committed
Product bundle: Lots of refactoring. ShoppingCartItem and ProductBundleItem are now processed using encapsulated objects. Otherwise object references could lead to wrong results in price calculation.
1 parent 452632b commit b096a50

58 files changed

Lines changed: 666 additions & 578 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Libraries/SmartStore.Core/Domain/Catalog/ProductBundleData.cs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,18 @@
88

99
namespace SmartStore.Core.Domain.Catalog
1010
{
11-
public partial class ProductBundleData
11+
public partial class ProductBundleItemData
12+
{
13+
public ProductBundleItemData(ProductBundleItem item)
14+
{
15+
Item = item; // can be null... test with IsValid
16+
}
17+
18+
public ProductBundleItem Item { get; private set; }
19+
public decimal AdditionalCharge { get; set; }
20+
}
21+
22+
public partial class ProductBundleItemOrderData
1223
{
1324
public int BundleItemId { get; set; }
1425
public int ProductId { get; set; }
@@ -37,7 +48,7 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c
3748
{
3849
if (value is string)
3950
{
40-
List<ProductBundleData> bundleData = null;
51+
List<ProductBundleItemOrderData> bundleData = null;
4152
string rawValue = value as string;
4253

4354
if (rawValue.HasValue())
@@ -46,8 +57,8 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c
4657
{
4758
using (var reader = new StringReader(rawValue))
4859
{
49-
var xml = new XmlSerializer(typeof(List<ProductBundleData>));
50-
bundleData = (List<ProductBundleData>)xml.Deserialize(reader);
60+
var xml = new XmlSerializer(typeof(List<ProductBundleItemOrderData>));
61+
bundleData = (List<ProductBundleItemOrderData>)xml.Deserialize(reader);
5162
}
5263
}
5364
catch { }
@@ -60,15 +71,15 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul
6071
{
6172
if (destinationType == typeof(string))
6273
{
63-
var bundleData = value as List<ProductBundleData>;
74+
var bundleData = value as List<ProductBundleItemOrderData>;
6475

6576
if (bundleData == null)
6677
return "";
6778

6879
var sb = new StringBuilder();
6980
using (var writer = new StringWriter(sb))
7081
{
71-
var xml = new XmlSerializer(typeof(List<ProductBundleData>));
82+
var xml = new XmlSerializer(typeof(List<ProductBundleItemOrderData>));
7283
xml.Serialize(writer, value);
7384
return sb.ToString();
7485
}

src/Libraries/SmartStore.Core/Domain/Catalog/ProductBundleItem.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ public partial class ProductBundleItem : BaseEntity, ILocalizedEntity, ICloneabl
9494
[DataMember]
9595
public DateTime UpdatedOnUtc { get; set; }
9696

97-
public decimal AdditionalCharge { get; set; }
98-
9997
/// <summary>
10098
/// Gets the product
10199
/// </summary>
@@ -128,6 +126,7 @@ public ProductBundleItem Clone()
128126
DiscountPercentage = this.DiscountPercentage,
129127
Name = this.Name,
130128
ShortDescription = this.ShortDescription,
129+
FilterAttributes = this.FilterAttributes,
131130
HideThumbnail = this.HideThumbnail,
132131
Visible = this.Visible,
133132
Published = this.Published,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using SmartStore.Core.Domain.Catalog;
4+
5+
namespace SmartStore.Core.Domain.Orders
6+
{
7+
public partial class OrganizedShoppingCartItem
8+
{
9+
public OrganizedShoppingCartItem(ShoppingCartItem item)
10+
{
11+
if (item == null)
12+
throw new ArgumentNullException("item");
13+
14+
Item = item; // must not be null
15+
ChildItems = new List<OrganizedShoppingCartItem>();
16+
BundleItemData = new ProductBundleItemData(item.BundleItem);
17+
}
18+
19+
public ShoppingCartItem Item { get; private set; }
20+
public IList<OrganizedShoppingCartItem> ChildItems { get; set; }
21+
public ProductBundleItemData BundleItemData { get; set; }
22+
}
23+
}

src/Libraries/SmartStore.Core/Domain/Orders/ShoppingCartItem.cs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ public ShoppingCartType ShoppingCartType
9595
/// </summary>
9696
public virtual ProductBundleItem BundleItem { get; set; }
9797

98-
public IList<ShoppingCartItem> ChildItems { get; set; }
99-
10098
/// <summary>
10199
/// Gets a value indicating whether the shopping cart item is free shipping
102100
/// </summary>
@@ -125,32 +123,6 @@ public bool IsShipEnabled
125123
}
126124
}
127125

128-
/// <summary>
129-
/// Gets the additional shipping charge
130-
/// </summary>
131-
public decimal AdditionalShippingCharge
132-
{
133-
get
134-
{
135-
decimal additionalShippingCharge = decimal.Zero;
136-
var product = this.Product;
137-
138-
if (product != null)
139-
{
140-
if (product.ProductType == ProductType.BundledProduct && product.BundlePerItemShipping)
141-
{
142-
if (ChildItems != null)
143-
ChildItems.Each(x => additionalShippingCharge += (x.AdditionalShippingCharge * x.Quantity));
144-
}
145-
else
146-
{
147-
additionalShippingCharge = product.AdditionalShippingCharge * Quantity;
148-
}
149-
}
150-
return additionalShippingCharge;
151-
}
152-
}
153-
154126
/// <summary>
155127
/// Gets a value indicating whether the shopping cart item is tax exempt
156128
/// </summary>

src/Libraries/SmartStore.Core/Infrastructure/CommonStartupTask.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ public void Execute()
1818
TypeDescriptor.AddAttributes(typeof(ShippingOption), new TypeConverterAttribute(typeof(ShippingOptionTypeConverter)));
1919
TypeDescriptor.AddAttributes(typeof(List<ShippingOption>), new TypeConverterAttribute(typeof(ShippingOptionListTypeConverter)));
2020
TypeDescriptor.AddAttributes(typeof(IList<ShippingOption>), new TypeConverterAttribute(typeof(ShippingOptionListTypeConverter)));
21-
TypeDescriptor.AddAttributes(typeof(List<ProductBundleData>), new TypeConverterAttribute(typeof(ProductBundleDataListTypeConverter)));
22-
TypeDescriptor.AddAttributes(typeof(IList<ProductBundleData>), new TypeConverterAttribute(typeof(ProductBundleDataListTypeConverter)));
21+
TypeDescriptor.AddAttributes(typeof(List<ProductBundleItemOrderData>), new TypeConverterAttribute(typeof(ProductBundleDataListTypeConverter)));
22+
TypeDescriptor.AddAttributes(typeof(IList<ProductBundleItemOrderData>), new TypeConverterAttribute(typeof(ProductBundleDataListTypeConverter)));
2323
}
2424

2525
public int Order

src/Libraries/SmartStore.Core/SmartStore.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158
<Compile Include="Domain\Common\SocialSettings.cs" />
159159
<Compile Include="Domain\Directory\DeliveryTime.cs" />
160160
<Compile Include="Domain\Orders\OrderExtensions.cs" />
161+
<Compile Include="Domain\Orders\OrganizedShoppingCartItem.cs" />
161162
<Compile Include="Domain\Stores\IStoreMappingSupported.cs" />
162163
<Compile Include="Domain\Stores\Store.cs" />
163164
<Compile Include="Domain\Stores\StoreExtensions.cs" />

src/Libraries/SmartStore.Data/Mapping/Catalog/ProductBundleItemMap.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ public ProductBundleItemMap()
1313
this.Property(pbi => pbi.Discount).HasPrecision(18, 4).IsOptional();
1414
this.Property(pbi => pbi.Name).HasMaxLength(400);
1515
this.Property(pbi => pbi.ShortDescription).IsMaxLength();
16-
17-
this.Ignore(pbi => pbi.AdditionalCharge);
1816

1917
this.HasRequired(pbi => pbi.Product)
2018
.WithMany()

src/Libraries/SmartStore.Data/Mapping/Orders/ShoppingCartItemMap.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ public ShoppingCartItemMap()
1515
this.Ignore(sci => sci.ShoppingCartType);
1616
this.Ignore(sci => sci.IsFreeShipping);
1717
this.Ignore(sci => sci.IsShipEnabled);
18-
this.Ignore(sci => sci.AdditionalShippingCharge);
1918
this.Ignore(sci => sci.IsTaxExempt);
20-
this.Ignore(sci => sci.ChildItems);
2119

2220
this.HasRequired(sci => sci.Customer)
2321
.WithMany(c => c.ShoppingCartItems)

src/Libraries/SmartStore.Services/Catalog/CopyProductService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ public virtual Product CopyProduct(Product product, string newName, bool isPubli
517517

518518
foreach (var bundledItem in bundledItems)
519519
{
520-
var newBundledItem = bundledItem.Clone();
520+
var newBundledItem = bundledItem.Item.Clone();
521521
newBundledItem.BundleProductId = productCopy.Id;
522522
newBundledItem.CreatedOnUtc = utcNow;
523523
newBundledItem.UpdatedOnUtc = utcNow;

src/Libraries/SmartStore.Services/Catalog/IPriceCalculationService.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ decimal GetFinalPrice(Product product,
6565
decimal additionalCharge,
6666
bool includeDiscounts,
6767
int quantity,
68-
ProductBundleItem bundleItem = null);
68+
ProductBundleItemData bundleItem = null);
6969

7070
/// <summary>
7171
/// Gets the final price including bundle per-item pricing
@@ -78,8 +78,8 @@ decimal GetFinalPrice(Product product,
7878
/// <param name="quantity">Shopping cart item quantity</param>
7979
/// <param name="bundleItem">A product bundle item</param>
8080
/// <returns>Final price</returns>
81-
decimal GetFinalPrice(Product product, IList<ProductBundleItem> bundleItems,
82-
Customer customer, decimal additionalCharge, bool includeDiscounts, int quantity, ProductBundleItem bundleItem = null);
81+
decimal GetFinalPrice(Product product, IList<ProductBundleItemData> bundleItems,
82+
Customer customer, decimal additionalCharge, bool includeDiscounts, int quantity, ProductBundleItemData bundleItem = null);
8383

8484
/// <summary>
8585
/// Gets discount amount
@@ -136,7 +136,7 @@ decimal GetDiscountAmount(Product product,
136136
decimal additionalCharge,
137137
int quantity,
138138
out Discount appliedDiscount,
139-
ProductBundleItem bundleItem = null);
139+
ProductBundleItemData bundleItem = null);
140140

141141

142142
/// <summary>
@@ -145,15 +145,15 @@ decimal GetDiscountAmount(Product product,
145145
/// <param name="shoppingCartItem">The shopping cart item</param>
146146
/// <param name="includeDiscounts">A value indicating whether include discounts or not for price computation</param>
147147
/// <returns>Shopping cart item sub total</returns>
148-
decimal GetSubTotal(ShoppingCartItem shoppingCartItem, bool includeDiscounts);
148+
decimal GetSubTotal(OrganizedShoppingCartItem shoppingCartItem, bool includeDiscounts);
149149

150150
/// <summary>
151151
/// Gets the shopping cart unit price (one item)
152152
/// </summary>
153153
/// <param name="shoppingCartItem">The shopping cart item</param>
154154
/// <param name="includeDiscounts">A value indicating whether include discounts or not for price computation</param>
155155
/// <returns>Shopping cart unit price (one item)</returns>
156-
decimal GetUnitPrice(ShoppingCartItem shoppingCartItem, bool includeDiscounts);
156+
decimal GetUnitPrice(OrganizedShoppingCartItem shoppingCartItem, bool includeDiscounts);
157157

158158

159159

@@ -163,15 +163,15 @@ decimal GetDiscountAmount(Product product,
163163
/// </summary>
164164
/// <param name="shoppingCartItem">The shopping cart item</param>
165165
/// <returns>Discount amount</returns>
166-
decimal GetDiscountAmount(ShoppingCartItem shoppingCartItem);
166+
decimal GetDiscountAmount(OrganizedShoppingCartItem shoppingCartItem);
167167

168168
/// <summary>
169169
/// Gets discount amount
170170
/// </summary>
171171
/// <param name="shoppingCartItem">The shopping cart item</param>
172172
/// <param name="appliedDiscount">Applied discount</param>
173173
/// <returns>Discount amount</returns>
174-
decimal GetDiscountAmount(ShoppingCartItem shoppingCartItem, out Discount appliedDiscount);
174+
decimal GetDiscountAmount(OrganizedShoppingCartItem shoppingCartItem, out Discount appliedDiscount);
175175

176176
}
177177
}

0 commit comments

Comments
 (0)