Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建动态优惠券检查器_C#_Algorithm_While Loop - Fatal编程技术网

C# 创建动态优惠券检查器

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

我正在尝试创建一个优惠券计数器,用于检查可用于减少发票金额的组合优惠券的可用性

如果可用优惠券等于所需优惠券,则不需要发票

例如:

XYZ公司需要为他们的发票支付100美元(金额总是可以除以25,剩余为0),但他们可以使用优惠券支付

一张优惠券值25美元,因此我需要检查公司是否在动态选择的月份内储蓄了4美元

我的优惠券表如下所示:

总息票数量

  • 身份证
  • 公司ID
  • 总息票数
示例cont:

XYZ公司3月有0张优惠券,4月有1张,5月有0张,6月有2张,7月1日有2张

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;
                    }
                }
            }
//发票所需的优惠券金额小于可用优惠券总额
同时(所需优惠券=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