Created
January 29, 2010 07:42
-
-
Save iley/289537 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary>константы для месяцев</summary> | |
/// <remarks> | |
/// Добавлены исключительно для повышения читаемости кода. | |
/// В реальном проекте подобные константы должны быть вынесены в отдельный модуль. | |
/// </remarks> | |
static class Months { | |
public const int January = 1, | |
February = 2, | |
March = 3, | |
April = 4, | |
May = 5, | |
June = 6, | |
July = 7, | |
August = 8, | |
September = 9, | |
October = 10, | |
November = 11, | |
December = 12; | |
} | |
// В реальном проекте вместо явного задания значений в виде констант стоит | |
// использовать загрузку параметров из конфигурационного файла, однако это | |
// выходит за рамки задания. | |
// Также в реальном проекте я бы придерживался принятых в компании | |
// соглашений об именовании переменных, функций и типов. Здесь же | |
// я выбирал имена исходя из интуитивных соображений. Не исключено, | |
// что я допустил ряд неточностей в именах из-за недостаточного знакомства с | |
// предметной областью. Надеюсь, это не повлияет на оценку. | |
/// <summary>скидка для VIP клиентов (доля от базисной цены)</summary> | |
const decimal VIPDiscount = 0.10M; | |
/// <summary>стоимость доставки для VIP (доля от базисной цены)</summary> | |
const decimal VIPDeliveryCostPart = 0.11M; | |
/// <summary>минимальная стоимость доставки для VIP (у.е.)</summary> | |
const decimal VIPMinDeliveryCost = 50.00M; | |
/// <summary>сумма, начиная с которой увеличивается скидка в летний период (у.е.)</summary> | |
const decimal SummerDiscountLimit = 1000.00M; | |
/// <summary>сумма, выше которой увеличивается скидка в зимний период (у.е.)</summary> | |
const decimal WinterDiscountLimit = 1100.00M; | |
/// <summary>не повышенная скидка в летний период (доля от базисной цены)</summary> | |
const decimal SummerDiscountLow = 0.02M; | |
/// <summary>повышенная скидка в летний период (доля от базисной цены)</summary> | |
const decimal SummerDiscountHigh = 0.03M; | |
/// <summary>не повышенная скидка в зимний период (доля от базисной цены)</summary> | |
const decimal WinterDiscountLow = 0.00M; | |
/// <summary>повышенная скидка в зимний период (доля от базисной цены)</summary> | |
const decimal WinterDiscountHigh = 0.03M; | |
/// <summary>количество товара, выше которого даётся скидка за объём (шт.)</summary> | |
const int VolumeDiscountLimit = 500; | |
/// <summary>скидка за объём (доля от базисной цены товара свыше VolumeDiscountLimit)</summary> | |
const decimal VolumeDiscount = 0.05M; | |
/// <summary>стоимость доставки в зимний период (доля от базисной цены)</summary> | |
const decimal WinterDeliveryCostPart = 0.11M; | |
/// <summary>минимальная стоимость доставки в зимний период (у.е.)</summary> | |
const decimal WinterMinDeliveryCost = 110.00M; | |
/// <summary>стоимость доставки в летний период (доля от базисной цены)</summary> | |
const decimal SummerDeliveryCostPart = 0.10M; | |
/// <summary>минимальная стоимость доставки в летний период (у.е.)</summary> | |
const decimal SummerMinDeliveryCost = 100.00M; | |
/// <summary>период года (сезон)</summary> | |
enum Season { | |
Summer, Winter | |
} | |
/// <summary>получение периода (зимний/летний) по дате</summary> | |
/// <param name="date">дата</param> | |
/// <returns>период</returns> | |
static Season GetSeason(DateTime date) { | |
if ((Months.April <= date.Month) && (date.Month <= Months.September)) | |
return Season.Summer; | |
else | |
return Season.Winter; | |
} | |
/// <summary>Функция для расчёта стоимости товара</summary> | |
/// <param name="isVIPClient">признак VIP клиента</param> | |
/// <param name="purchaseDate">дата счёта</param> | |
/// <param name="unitCount">количество товара (в шт.)</param> | |
/// <param name="unitPrice">стоимость товара (в у.е.)</param> | |
/// <returns>стоимость (в у.е.)</returns> | |
static decimal GetCost(bool isVIPClient, DateTime purchaseDate, int unitCount, decimal unitPrice) { | |
decimal basePrice = unitPrice * unitCount; //базисная цена | |
if (isVIPClient) { | |
//стоимость доставки не должна быть меньше VIPMinDeliveryCost | |
decimal deliveryCost = Math.Max(VIPMinDeliveryCost, VIPDeliveryCostPart * basePrice); | |
return basePrice - (basePrice * VIPDiscount) + deliveryCost; | |
} else { | |
var season = GetSeason(purchaseDate); //период, зимний или летний | |
decimal costDiscount; //скидка по цене | |
decimal deliveryCost; //стоимость доставки | |
if (season == Season.Summer) { | |
//обратите внимание, здесь строгое неравенство | |
if (basePrice < SummerDiscountLimit) | |
costDiscount = SummerDiscountLow; | |
else | |
costDiscount = SummerDiscountHigh; | |
deliveryCost = Math.Max(SummerMinDeliveryCost, SummerDeliveryCostPart * basePrice); | |
} else { | |
//обратите внимание, здесь нестрогое неравенство | |
if (basePrice <= WinterDiscountLimit) | |
costDiscount = WinterDiscountLow; | |
else | |
costDiscount = WinterDiscountHigh; | |
deliveryCost = Math.Max(WinterMinDeliveryCost, WinterDeliveryCostPart * basePrice); | |
} | |
decimal volumeDiscountValue; //скидка за объём | |
if (unitCount > VolumeDiscountLimit) | |
volumeDiscountValue = VolumeDiscount * (unitCount - VolumeDiscountLimit) * unitPrice; | |
else | |
volumeDiscountValue = 0; | |
return basePrice - (costDiscount * basePrice) - volumeDiscountValue + deliveryCost; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment