我正在尝试创建优惠券计数器,以检查可用于减少发票的可组合优惠券的可用性。
如果可用的优惠券等于所需的优惠券,则不需要发票。
示例:
XYZ公司需要为发票支付100美元(金额始终可以除以0,剩下的25除),但是他们可以使用优惠券付款。
一张优惠券价值25美元,所以我需要检查公司是否在动态选择的月份内保存了4张。
我的优惠券表如下:
总优惠券计数
示例续:
XYZ公司3月有0张优惠券,4月1日,5月0日,6月2日,7月1日有优惠券。
XYZ公司最多可以保存3个月的优惠券(因此优惠券可以是5月,6月,7月)
该示例的结果必须为:
已使用3张优惠券(6月2日,7月1日),客户仍需支付25美元。
我的程序需要做的是
获取公司可以保存优惠券的月数(在这种情况下为3)
减去优惠券,直到它们为0
这是我现在拥有的代码:
//While the needed amount of coupons for the invoice is smaller than the total available coupons
while(neededCoupons < cv.combinableAmount)
{
//We start at the earliest month we can go back to (this month - the combinable months)
for (int i = int.Parse(DateTime.Now.AddMonths(DateTime.Now.Month - cv.monthsCombinable).ToString()); i >= int.Parse(DateTime.Now.Month.ToString()) ; i++ )
{
int amountForMonth = GetCouponAmountByMonth(companyID, i);
if (amountForMonth >= neededCoupons)
{
//The amount is enough, we can stop
Result += "Coupons used from " + new DateTime(DateTime.Now.Year, i, 1).ToString("MMMM") + " amount: " + amountForMonth;
//To save the data, we subtract the neededCoupons from that month
SubtractCoupons(companyID, i, amountForMonth);
}
else
{
//The amount for that month is not enough (or zero), we need to subtract it, get the remaining and continue to the following month)
if (amountForMonth != 0)
{
SubtractCoupons(companyID, i, amountForMonth);
Result += "Coupons used from " + new DateTime(DateTime.Now.Year, i, 1).ToString("MMMM") + " amount: " + amountForMonth;
neededCoupons = neededCoupons - amountForMonth;
}
}
}
我还没有测试我的代码,但是我知道我没有走正确的路,因为我没有考虑以下因素:
我认为我快到了。我只是想知道如何实现一个rest变量,以检查骑行结束时是否所有优惠券都已用完,仍然需要付款。
答案 0 :(得分:3)
为了帮助生成和打印发票,我创建了以下两个模型:
public class Invoice
{
public int TotalCouponsNeeded { get; set; }
public int UsedCouponCount { get; set; }
public List<UsedCouponsForMonth> UsedCoupons { get; set; }
public override string ToString()
{
StringBuilder sb = new StringBuilder();
if (UsedCouponCount == 0)
{
sb.Append("0 coupons have been used");
}
else
{
sb.AppendFormat("{0} have been used ({1})",
UsedCouponCount,
String.Join(", ", UsedCoupons.Select(x => String.Format("{0} in {1:MMM yyyy}", x.Count, new DateTime(x.Year, x.Month, 1))))
);
}
sb.AppendFormat(", {0} dollars still needs to be paid by client.", 25 * (TotalCouponsNeeded - UsedCouponCount));
return sb.ToString();
}
}
public class UsedCouponsForMonth
{
public int Month { get; set; }
public int Year { get; set; }
public int Count { get; set; }
}
Invoice
包含需要多少张优惠券以及使用了多少张。它还知道如何以所需的格式打印自己。
生成发票的算法如下:
public Invoice GenerateInvoice(int companyId, int maxMonths, int couponsNeeded)
{
Invoice invoice = new Invoice
{
TotalCouponsNeeded = couponsNeeded,
UsedCouponCount = 0,
UsedCoupons = new List<UsedCouponsForMonth>(),
};
for (int i = 0; i < maxMonths && invoice.UsedCouponCount < invoice.TotalCouponsNeeded; i++)
{
DateTime month = DateTime.Now.AddMonths(i - maxMonths + 1);
int availableForMonth = GetCouponAmountByMonth(companyId, month.Year, month.Month);
if (availableForMonth <= 0)
{
continue;
}
int usedThisMonth = (invoice.UsedCouponCount + availableForMonth < invoice.TotalCouponsNeeded)
? availableForMonth
: (couponsNeeded - invoice.UsedCouponCount);
invoice.UsedCouponCount += usedThisMonth;
SubtractCoupons(companyId, month.Year, month.Month, usedThisMonth);
}
return invoice;
}
想法是从最早的月份开始,使用GetCouponAmountByMonth
检查可用优惠券的数量,并根据需要使用SubtractCoupons
减去它们。注意,我修改了这些函数以将year
和month
用作输入。同时,在invoice.UsedCouponCount
变量中跟踪优惠券的总数。当使用的计数等于所需的数量时,循环会自动中断。
答案 1 :(得分:2)
我制作了一些与问题对应的类,然后是一个经理,该经理可以获取最旧的有效凭单,然后从未使用的有效凭单计算发票金额。您可以更改优惠券有效的月数,并且代码会根据需要做出反应。
public class Company
{
public int ID { get; set; }
public string Name { get; set; }
public List<Coupon> Coupons { get; set; }
public Company()
{
Coupons = new List<Coupon>();
}
}
public class Coupon
{
public bool IsUsed { get; set; }
public double Amount { get; set; }
public DateTime Date { get; set; }
}
public static class CouponManager
{
public const int MONTHS_BACK = 3;
/// <summary>
/// Returns all coupons within X months not used by the company
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public static List<Coupon> GetValidCoupons(Company c)
{
return c.Coupons.Where(
t => !t.IsUsed &&
(Math.Abs((DateTime.Now.Month - t.Date.Month) + 12 * (DateTime.Now.Year - t.Date.Year))< MONTHS_BACK))
.OrderBy(t=>t.Date).ToList();
}
/// <summary>
/// Find valid coupons, subtract from invoice each coupon amount until invoice is 0
/// </summary>
/// <param name="company"></param>
/// <param name="invoice"></param>
/// <returns></returns>
public static double CalculateInvoice(Company company, double invoice)
{
double amountOwed = invoice;
List<Coupon> coupons = GetValidCoupons(company);
coupons.ForEach(c => {
if(invoice <= 0) //we are done with coupons
{ return; }
if (c.Amount > invoice) //no credits to give
{ return; }
invoice = invoice - c.Amount; //subtract amount from invoice
c.IsUsed = true; //mark coupon as used then update in db later
});
return invoice;
}
public static Company GetMockedCompany()
{
//mock data
Company myCompany = new Company();
bool used = false;
for (int i = 0; i < 215; i++)
{
Coupon c = new Coupon();
c.Date = DateTime.Now.AddDays(-i);
c.Amount = 5.00;
c.IsUsed = used;
used = !used;
myCompany.Coupons.Add(c);
Coupon d = new Coupon();
d.Date = DateTime.Now.AddDays(-i * 4);
d.Amount = 5.00;
d.IsUsed = used;
used = !used;
myCompany.Coupons.Add(d);
}
return myCompany;
}
}
然后您可以通过模拟的公司测试例程,如下所示:
double invoice = CouponManager.CalculateInvoice(CouponManager.GetMockedCompany(), 1400); //returns 1070