C# 创建动态优惠券检查器
我正在尝试创建一个优惠券计数器,用于检查可用于减少发票金额的组合优惠券的可用性 如果可用优惠券等于所需优惠券,则不需要发票 例如: XYZ公司需要为他们的发票支付100美元(金额总是可以除以25,剩余为0),但他们可以使用优惠券支付 一张优惠券值25美元,因此我需要检查公司是否在动态选择的月份内储蓄了4美元 我的优惠券表如下所示: 总息票数量C# 创建动态优惠券检查器,c#,algorithm,while-loop,C#,Algorithm,While Loop,我正在尝试创建一个优惠券计数器,用于检查可用于减少发票金额的组合优惠券的可用性 如果可用优惠券等于所需优惠券,则不需要发票 例如: XYZ公司需要为他们的发票支付100美元(金额总是可以除以25,剩余为0),但他们可以使用优惠券支付 一张优惠券值25美元,因此我需要检查公司是否在动态选择的月份内储蓄了4美元 我的优惠券表如下所示: 总息票数量 身份证 公司ID 月 总息票数 年 示例cont: XYZ公司3月有0张优惠券,4月有1张,5月有0张,6月有2张,7月1日有2张 XYZ公司可以在3
- 身份证
- 公司ID
- 月
- 总息票数
- 年
- 获取公司可以为其保存优惠券的月数(在本例中为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;
}
}
}
//发票所需的优惠券金额小于可用优惠券总额
同时(所需优惠券=int.Parse(DateTime.Now.Month.ToString());i++)
{
int amountForMonth=GetCouponAmountByMonth(公司ID,i);
if(月数>=所需优惠券)
{
//数量足够了,我们可以停下来
结果+=“从”+新日期时间(DateTime.Now.Year,i,1)到字符串(“MMMM”)+“金额:”+金额为个月;
//为了保存数据,我们从当月减去所需的优惠券
减去优惠券(公司ID,i,月数);
}
其他的
{
//该月的金额不够(或为零),我们需要减去它,得到剩余金额并继续到下个月)
如果(月数!=0)
{
减去优惠券(公司ID,i,月数);
结果+=“从”+新日期时间(DateTime.Now.Year,i,1)到字符串(“MMMM”)+“金额:”+金额为个月;
所需优惠券=所需优惠券-月数;
}
}
}
我还没有测试我的代码,但我知道我没有走上正确的道路,因为我没有考虑以下因素:
- 如果使用了所有优惠券,但仍需要支付款项,则剩余价值
- 我的代码明年一月份能用吗
- 我的while循环,我是否应该继续循环直到我有足够的凭证(当然不是)
不过,我想我就快到了。我只是想知道如何实现一个rest变量,以检查在旅程结束时,是否所有优惠券都已用完,其余的还需要支付。为了帮助生成和打印发票,我创建了以下几个模型:
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; }
}
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
检查可用优惠券的数量,并根据需要使用subtractcoups
减去它们。注意,我修改了这些函数,将年和月作为输入。同时,跟踪优惠券的总数在invoice.UsedCouponCount
变量中。当使用的计数等于所需的数字时,循环自动中断。我创建了一些与问题对应的类,然后是一个经理,可以获得有效优惠券,首先是最旧的优惠券,然后根据未使用的有效优惠券计算发票金额。您可以更改mon的金额这表明优惠券是有效的,代码将根据需要作出反应
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;
}
}
减去所有优惠券后剩下的不是你的“剩余”吗值?您可以说,但是我如何指定我的while
循环?我如何在while
-循环中指定我需要继续,直到我没有剩余的优惠券,并且剩余的优惠券将被支付?从subtractcoups
方法返回减法的结果,并在while条件?while(减法结果>0)
?@RobertHarvey不能使用while,因为在减法任何东西之前都是如此……感谢您的回答,但是否可能您没有按金额计算剩余价值(当没有更多优惠券用于发票时)我想你的回答只考虑到公司总是有足够的优惠券。我知道优惠券可能并不总是足够的您要查找的值是totalcouponneeded-UsedCouponCount
。当a)使用了足够的优惠券,或者b)总月数用完时,循环将中断。在ToString
函数中,您可以看到一条生成“X美元仍需由客户支付”的语句。对不起,我还有一个问题,如果我想从当前月份开始并返回到最早的月份(从本月开始减法,每月返回)。将DateTime.Now.AddMonths(I-maxMonths+1)
更改为DateTime。现在。AddMonths(-I)
应该这样做。
double invoice = CouponManager.CalculateInvoice(CouponManager.GetMockedCompany(), 1400); //returns 1070