Skip to content

Commit

Permalink
VAT calculation and rounding
Browse files Browse the repository at this point in the history
  • Loading branch information
Markus Falk committed Dec 27, 2016
1 parent 1bc55ac commit 8223f93
Show file tree
Hide file tree
Showing 67 changed files with 73,960 additions and 926 deletions.
70 changes: 58 additions & 12 deletions src/Libraries/Nop.Core/Domain/Orders/Order.cs
Expand Up @@ -26,9 +26,10 @@ public partial class Order : BaseEntity

#region Utilities

protected virtual SortedDictionary<decimal, decimal> ParseTaxRates(string taxRatesStr)
protected virtual SortedDictionary<decimal, TaxRateRec> ParseTaxRates(string taxRatesStr)
{
var taxRatesDictionary = new SortedDictionary<decimal, decimal>();
//var taxRatesDictionary = new SortedDictionary<decimal, decimal>();
var taxRatesDictionary = new SortedDictionary<decimal, TaxRateRec>();
if (String.IsNullOrEmpty(taxRatesStr))
return taxRatesDictionary;

Expand All @@ -39,13 +40,20 @@ public partial class Order : BaseEntity
continue;

string[] taxes = line.Split(new [] { ':' });
if (taxes.Length == 2)
if (taxes.Length == 6)
{
try
{
decimal taxRate = decimal.Parse(taxes[0].Trim(), CultureInfo.InvariantCulture);
decimal taxValue = decimal.Parse(taxes[1].Trim(), CultureInfo.InvariantCulture);
taxRatesDictionary.Add(taxRate, taxValue);
decimal rate = decimal.Parse(taxes[0].Trim(), CultureInfo.InvariantCulture);
taxRatesDictionary.Add(rate, new TaxRateRec()
{
VatRate = rate,
Amount = decimal.Parse(taxes[1].Trim(), CultureInfo.InvariantCulture),
DiscountAmount = decimal.Parse(taxes[2].Trim(), CultureInfo.InvariantCulture),
BaseAmount = decimal.Parse(taxes[3].Trim(), CultureInfo.InvariantCulture),
VatAmount = decimal.Parse(taxes[4].Trim(), CultureInfo.InvariantCulture),
AmountIncludingVAT = decimal.Parse(taxes[5].Trim(), CultureInfo.InvariantCulture)
});
}
catch (Exception exc)
{
Expand All @@ -56,7 +64,15 @@ public partial class Order : BaseEntity

//add at least one tax rate (0%)
if (!taxRatesDictionary.Any())
taxRatesDictionary.Add(decimal.Zero, decimal.Zero);
taxRatesDictionary.Add(decimal.Zero, new TaxRateRec()
{
VatRate = decimal.Zero,
Amount = decimal.Zero,
DiscountAmount = decimal.Zero,
BaseAmount = decimal.Zero,
VatAmount = decimal.Zero,
AmountIncludingVAT = decimal.Zero
});

return taxRatesDictionary;
}
Expand Down Expand Up @@ -196,7 +212,7 @@ public partial class Order : BaseEntity
public decimal OrderDiscount { get; set; }

/// <summary>
/// Gets or sets the order total
/// Gets or sets the order total to pay
/// </summary>
public decimal OrderTotal { get; set; }

Expand All @@ -209,7 +225,7 @@ public partial class Order : BaseEntity
/// Gets or sets the reward points history entry identifier when reward points were earned (gained) for placing this order
/// </summary>
public int? RewardPointsHistoryEntryId { get; set; }

/// <summary>
/// Gets or sets the checkout attribute description
/// </summary>
Expand Down Expand Up @@ -309,7 +325,7 @@ public partial class Order : BaseEntity
/// Gets or sets the paid date and time
/// </summary>
public DateTime? PaidDateUtc { get; set; }

/// <summary>
/// Gets or sets the shipping method
/// </summary>
Expand All @@ -335,6 +351,24 @@ public partial class Order : BaseEntity
/// </summary>
public DateTime CreatedOnUtc { get; set; }

/// <summary>
/// Gets or sets the invoice ID
/// </summary>
public string InvoiceId { get; set; }
/// <summary>
/// Gets or sets the invoice date UTC
/// </summary>
public DateTime? InvoiceDateUtc { get; set; }

/// <summary>
/// Gets or sets the order total base amount excl. tax
/// </summary>
public decimal OrderAmount { get; set; } //MF 09.12.16

/// <summary>
/// Gets or sets the order total amount incl. tax
/// </summary>
public decimal OrderAmountIncl { get; set; } //MF 09.12.16
#endregion

#region Navigation properties
Expand Down Expand Up @@ -476,14 +510,26 @@ public TaxDisplayType CustomerTaxDisplayType
/// <summary>
/// Gets the applied tax rates
/// </summary>
public SortedDictionary<decimal, decimal> TaxRatesDictionary
public SortedDictionary<decimal, TaxRateRec> TaxRatesDictionary
{
get
{
return ParseTaxRates(this.TaxRates);
}
}

#endregion
}

#region Nested classes
public partial class TaxRateRec
{
public decimal VatRate { get; set; }
public decimal Amount { get; set; }
public decimal DiscountAmount { get; set; }
public decimal BaseAmount { get; set; }
public decimal VatAmount { get; set; }
public decimal AmountIncludingVAT { get; set; }
}
#endregion
}
7 changes: 6 additions & 1 deletion src/Libraries/Nop.Core/Domain/Orders/OrderItem.cs
Expand Up @@ -75,7 +75,7 @@ public partial class OrderItem : BaseEntity
/// Gets or sets the product attributes in XML format
/// </summary>
public string AttributesXml { get; set; }

/// <summary>
/// Gets or sets the download count
/// </summary>
Expand Down Expand Up @@ -125,5 +125,10 @@ public virtual ICollection<GiftCard> AssociatedGiftCards
get { return _associatedGiftCards ?? (_associatedGiftCards = new List<GiftCard>()); }
protected set { _associatedGiftCards = value; }
}

/// <summary>
/// VAT% of product
/// </summary>
public decimal VatRate { get; set; } //MF 25.11.16
}
}
9 changes: 8 additions & 1 deletion src/Libraries/Nop.Core/Domain/Orders/OrderSettings.cs
Expand Up @@ -120,6 +120,13 @@ public class OrderSettings : ISettings
/// Gets or sets a value indicating whether an order status should be set to "Complete" only when its shipping status is "Delivered". Otherwise, "Shipped" status will be enough.
/// </summary>
public bool CompleteOrderWhenDelivered { get; set; }

/// <summary>
/// Last issued Invoice Id
/// </summary>
public int InvoiceIdent { get; set; }
/// <summary>
/// Last issued Invoice Date
/// </summary>
public int InvoiceYear { get; set; }
}
}
19 changes: 16 additions & 3 deletions src/Libraries/Nop.Core/Domain/Orders/ShoppingCartItem.cs
Expand Up @@ -43,7 +43,6 @@ public partial class ShoppingCartItem : BaseEntity
/// Gets or sets the quantity
/// </summary>
public int Quantity { get; set; }

/// <summary>
/// Gets or sets the rental product start date (null if it's not a rental product)
/// </summary>
Expand All @@ -63,7 +62,7 @@ public partial class ShoppingCartItem : BaseEntity
/// Gets or sets the date and time of instance update
/// </summary>
public DateTime UpdatedOnUtc { get; set; }

/// <summary>
/// Gets the log type
/// </summary>
Expand Down Expand Up @@ -119,7 +118,7 @@ public bool IsShipEnabled

/// <summary>
/// Gets the additional shipping charge
/// </summary>
/// </summary>
public decimal AdditionalShippingCharge
{
get
Expand All @@ -145,5 +144,19 @@ public bool IsTaxExempt
return false;
}
}
//fields for restored cart
/// <summary>
/// VatRate for restored cart. Only used by UpdateOrderTotal and can be null
/// </summary>
public decimal? VatRate { get; set; }
/// <summary>
/// Subtotal of item with tax
/// </summary>
public decimal? SubTotalInclTax { get; set; }

/// <summary>
/// Subtotal of item without tax
/// </summary>
public decimal? SubTotalExclTax { get; set; }
}
}
1 change: 1 addition & 0 deletions src/Libraries/Nop.Data/Mapping/Orders/OrderItemMap.cs
Expand Up @@ -17,6 +17,7 @@ public OrderItemMap()
this.Property(orderItem => orderItem.DiscountAmountExclTax).HasPrecision(18, 4);
this.Property(orderItem => orderItem.OriginalProductCost).HasPrecision(18, 4);
this.Property(orderItem => orderItem.ItemWeight).HasPrecision(18, 4);
this.Property(orderItem => orderItem.VatRate).HasPrecision(18, 4); //MF 25.11.16


this.HasRequired(orderItem => orderItem.Order)
Expand Down
6 changes: 4 additions & 2 deletions src/Libraries/Nop.Data/Mapping/Orders/OrderMap.cs
Expand Up @@ -19,6 +19,8 @@ public OrderMap()
this.Property(o => o.PaymentMethodAdditionalFeeExclTax).HasPrecision(18, 4);
this.Property(o => o.OrderTax).HasPrecision(18, 4);
this.Property(o => o.OrderDiscount).HasPrecision(18, 4);
this.Property(o => o.OrderAmount).HasPrecision(18, 4); //MF 09.12.16
this.Property(o => o.OrderAmountIncl).HasPrecision(18, 4); //MF 09.12.16
this.Property(o => o.OrderTotal).HasPrecision(18, 4);
this.Property(o => o.RefundedAmount).HasPrecision(18, 4);

Expand All @@ -27,11 +29,11 @@ public OrderMap()
this.Ignore(o => o.ShippingStatus);
this.Ignore(o => o.CustomerTaxDisplayType);
this.Ignore(o => o.TaxRatesDictionary);

this.HasRequired(o => o.Customer)
.WithMany()
.HasForeignKey(o => o.CustomerId);

//code below is commented because it causes some issues on big databases - http://www.nopcommerce.com/boards/t/11126/bug-version-20-command-confirm-takes-several-minutes-using-big-databases.aspx
//this.HasRequired(o => o.BillingAddress).WithOptional().Map(x => x.MapKey("BillingAddressId")).WillCascadeOnDelete(false);
//this.HasOptional(o => o.ShippingAddress).WithOptionalDependent().Map(x => x.MapKey("ShippingAddressId")).WillCascadeOnDelete(false);
Expand Down
3 changes: 3 additions & 0 deletions src/Libraries/Nop.Data/Mapping/Orders/ShoppingCartItemMap.cs
Expand Up @@ -16,6 +16,9 @@ public ShoppingCartItemMap()
this.Ignore(sci => sci.IsShipEnabled);
this.Ignore(sci => sci.AdditionalShippingCharge);
this.Ignore(sci => sci.IsTaxExempt);
this.Ignore(sci => sci.VatRate);
this.Ignore(sci => sci.SubTotalExclTax);
this.Ignore(sci => sci.SubTotalInclTax);

this.HasRequired(sci => sci.Customer)
.WithMany(c => c.ShoppingCartItems)
Expand Down
37 changes: 28 additions & 9 deletions src/Libraries/Nop.Services/Catalog/IPriceFormatter.cs
Expand Up @@ -43,7 +43,7 @@ public partial interface IPriceFormatter
/// <param name="showTax">A value indicating whether to show tax suffix</param>
/// <param name="language">Language</param>
/// <returns>Price</returns>
string FormatPrice(decimal price, bool showCurrency,
string FormatPrice(decimal price, bool showCurrency,
string currencyCode, bool showTax, Language language);

/// <summary>
Expand All @@ -67,7 +67,7 @@ public partial interface IPriceFormatter
/// <param name="language">Language</param>
/// <param name="priceIncludesTax">A value indicating whether price includes tax</param>
/// <returns>Price</returns>
string FormatPrice(decimal price, bool showCurrency,
string FormatPrice(decimal price, bool showCurrency,
Currency targetCurrency, Language language, bool priceIncludesTax);

/// <summary>
Expand All @@ -80,7 +80,7 @@ public partial interface IPriceFormatter
/// <param name="priceIncludesTax">A value indicating whether price includes tax</param>
/// <param name="showTax">A value indicating whether to show tax suffix</param>
/// <returns>Price</returns>
string FormatPrice(decimal price, bool showCurrency,
string FormatPrice(decimal price, bool showCurrency,
Currency targetCurrency, Language language, bool priceIncludesTax, bool showTax);

/// <summary>
Expand Down Expand Up @@ -110,7 +110,7 @@ public partial interface IPriceFormatter
/// <param name="language">Language</param>
/// <param name="priceIncludesTax">A value indicating whether price includes tax</param>
/// <returns>Price</returns>
string FormatShippingPrice(decimal price, bool showCurrency,
string FormatShippingPrice(decimal price, bool showCurrency,
Currency targetCurrency, Language language, bool priceIncludesTax);
/// <summary>
/// Formats the shipping price
Expand All @@ -122,9 +122,9 @@ public partial interface IPriceFormatter
/// <param name="priceIncludesTax">A value indicating whether price includes tax</param>
/// <param name="showTax">A value indicating whether to show tax suffix</param>
/// <returns>Price</returns>
string FormatShippingPrice(decimal price, bool showCurrency,
string FormatShippingPrice(decimal price, bool showCurrency,
Currency targetCurrency, Language language, bool priceIncludesTax, bool showTax);

/// <summary>
/// Formats the shipping price
/// </summary>
Expand All @@ -134,7 +134,7 @@ public partial interface IPriceFormatter
/// <param name="language">Language</param>
/// <param name="priceIncludesTax">A value indicating whether price includes tax</param>
/// <returns>Price</returns>
string FormatShippingPrice(decimal price, bool showCurrency,
string FormatShippingPrice(decimal price, bool showCurrency,
string currencyCode, Language language, bool priceIncludesTax);


Expand Down Expand Up @@ -169,7 +169,7 @@ public partial interface IPriceFormatter
/// <param name="priceIncludesTax">A value indicating whether price includes tax</param>
/// <param name="showTax">A value indicating whether to show tax suffix</param>
/// <returns>Price</returns>
string FormatPaymentMethodAdditionalFee(decimal price, bool showCurrency,
string FormatPaymentMethodAdditionalFee(decimal price, bool showCurrency,
Currency targetCurrency, Language language, bool priceIncludesTax, bool showTax);

/// <summary>
Expand All @@ -181,7 +181,7 @@ public partial interface IPriceFormatter
/// <param name="language">Language</param>
/// <param name="priceIncludesTax">A value indicating whether price includes tax</param>
/// <returns>Price</returns>
string FormatPaymentMethodAdditionalFee(decimal price, bool showCurrency,
string FormatPaymentMethodAdditionalFee(decimal price, bool showCurrency,
string currencyCode, Language language, bool priceIncludesTax);


Expand All @@ -192,5 +192,24 @@ public partial interface IPriceFormatter
/// <param name="taxRate">Tax rate</param>
/// <returns>Formatted tax rate</returns>
string FormatTaxRate(decimal taxRate);

/// <summary>
/// Adds tax suffix to text
/// </summary>
/// <param name="text">Text to format</param>
/// <param name="language">Language</param>
/// <param name="priceIncludesTax">A value indicating whether price includes tax</param>
/// <returns></returns>
string FormatTaxString(string text, Language language, bool priceIncludesTax);

/// <summary>
/// Adds tax suffix to text
/// </summary>
/// <param name="text">Text to format</param>
/// <param name="language">Language</param>
/// <param name="priceIncludesTax">A value indicating whether price includes tax</param>
/// <param name="showTax">Optional. A value indicating whether to show tax suffix.</param>
/// <returns></returns>
string FormatTaxString(string text, Language language, bool priceIncludesTax, bool showTax);
}
}

0 comments on commit 8223f93

Please sign in to comment.