Skip to content

Instantly share code, notes, and snippets.

@iley
Created January 29, 2010 07:42
Show Gist options
  • Save iley/289537 to your computer and use it in GitHub Desktop.
Save iley/289537 to your computer and use it in GitHub Desktop.
/// <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