context: /* Author: David Carroll
   * Copyright (c) 2008, 2009 Bellevue Baptist Church 
   * Licensed under the GNU General Public License (GPL v2)
   * you may not use this code except in compliance with the License.
   * You may obtain a copy of the License at http://bvcms.codeplex.com/license 
   */
  using System;
  using System.Collections.Generic;
  using System.Data;
  using System.Linq;
  using System.Data.Linq;
  using System.Web;
  using System.Web.Mvc;
  using System.Web.Routing;
  using CmsData.Registration;
  using MoreLinq;
  using UtilityExtensions;
  using System.Text;
  using CmsData;
  using System.Data.Linq.SqlClient;
  using CmsData.Codes;
  
  namespace CmsWeb.Models
  {
      public class CouponModel
      {
          public string regid { get; set; }
          public decimal amount { get; set; }
          public string name { get; set; }
          public string couponcode { get; set; }
  
          public int useridfilter { get; set; }
          public string regidfilter { get; set; }
          public string usedfilter { get; set; }
          public string date { get; set; }
  
          public string Registration()
          {
              return OnlineRegs().Single(r => r.Value == regid).Text;
          }
  
          public IEnumerable<CouponInfo> Coupons()
          {
          	var roles = DbUtil.Db.CurrentUser.UserRoles.Select(uu => uu.Role.RoleName).ToArray();
              var q = from c in DbUtil.Db.Coupons
  					let o = c.Organization
  					where o.LimitToRole == null || roles.Contains(o.LimitToRole)
                      where c.DivOrg == regidfilter || regidfilter == "0" || regidfilter == null
                      where c.UserId == useridfilter || useridfilter == 0
                      select c;
              switch (usedfilter)
              {
                  case "Used":
                      q = q.Where(c => c.Used != null && c.Canceled == null);
                      break;
                  case "UnUsed":
                      q = q.Where(c => c.Used == null && c.Canceled == null);
                      break;
                  case "Canceled":
                      q = q.Where(c => c.Canceled != null);
                      break;
              }
              if (name.HasValue())
                  q = q.Where(c => c.Name.Contains(name) || c.Person.Name.Contains(name));
              if (date.HasValue())
              {
                  DateTime bd;
                  if (DateTime.TryParse(date, out bd))
                      q = q.Where(c => c.Created.Date == bd);
              }
  
              var q2 = from c in q
                       orderby c.Created descending
                       select new CouponInfo
                       {
                           Amount = c.Amount,
                           Canceled = c.Canceled,
                           Code = c.Id,
                           Created = c.Created,
                           OrgDivName = c.OrgId != null ? c.Organization.OrganizationName : c.Division.Name,
                           Used = c.Used,
                           PeopleId = c.PeopleId,
                           Name = c.Name,
                           Person = c.Person.Name,
                           UserId = c.UserId,
                           UserName = c.User.Name,
                           RegAmt = c.RegAmount
                       };
              return q2.Take(200);
          }
          public DataTable Coupons2()
          {
          	var roles = DbUtil.Db.CurrentUser.UserRoles.Select(uu => uu.Role.RoleName).ToArray();
              var q = from c in DbUtil.Db.Coupons
  					let o = c.Organization
  					where o.LimitToRole == null || roles.Contains(o.LimitToRole)
                      where c.DivOrg == regidfilter || regidfilter == "0" || regidfilter == null
                      where c.UserId == useridfilter || useridfilter == 0
                      select c;
              switch (usedfilter)
              {
                  case "Used":
                      q = q.Where(c => c.Used != null && c.Canceled == null);
                      break;
                  case "UnUsed":
                      q = q.Where(c => c.Used == null && c.Canceled == null);
                      break;
                  case "Canceled":
                      q = q.Where(c => c.Canceled != null);
                      break;
              }
              if (name.HasValue())
                  q = q.Where(c => c.Name.Contains(name) || c.Person.Name.Contains(name));
              if (date.HasValue())
              {
                  DateTime bd;
                  if (DateTime.TryParse(date, out bd))
                      q = q.Where(c => c.Created.Date == bd);
              }
  
  
              var q2 = from c in q
                       orderby c.Created descending
                       select new CouponInfo2
                       {
                           Amount = c.Amount ?? 0,
                           Canceled = c.Canceled ?? DateTime.Parse("1/1/80"),
                           Code = c.Id,
                           Created = c.Created,
                           OrgDivName = c.OrgId != null ? c.Organization.OrganizationName : c.Division.Name,
                           Used = c.Used ?? DateTime.Parse("1/1/80"),
                           PeopleId = c.PeopleId ?? 0,
                           Name = c.Name,
                           Person = c.Person.Name,
                           UserId = c.UserId ?? 0,
                           UserName = c.User.Name,
                           RegAmt = c.RegAmount ?? 0
                       };
              return q2.Take(200).ToDataTable();
          }
  		public List<SelectListItem> OnlineRegs()
  		{
  			var roles = DbUtil.Db.CurrentUser.UserRoles.Select(uu => uu.Role.RoleName).ToArray();
  			var organizations = from o in DbUtil.Db.Organizations
  								where o.LimitToRole == null || roles.Contains(o.LimitToRole)
  								select o;
  			var orgregtypes = new int[]
  			{
  				RegistrationTypeCode.JoinOrganization,
          		RegistrationTypeCode.UserSelectsOrganization2,
          		RegistrationTypeCode.ComputeOrganizationByAge2,
  			};
  
  			var q = (from o in organizations
  					 where orgregtypes.Contains(o.RegistrationTypeId.Value)
  					 where (o.ClassFilled ?? false) != true
  					 where (o.RegistrationClosed ?? false) == false
  					 select new { DivisionName = o.Division.Name, o.OrganizationName, o.RegSetting, o.OrganizationId, o.RegistrationTypeId }).ToList();
  
  			var qq = from i in q
  					 let os = new Settings(i.RegSetting, DbUtil.Db, i.OrganizationId)
  					 where orgregtypes.Contains(i.RegistrationTypeId.Value)
                           || os.Fee > 0
  						 || os.AskItems.Where(aa => aa.Type == "AskDropdown").Any(aa => ((AskDropdown)aa).list.Any(dd => dd.Fee > 0))
  						 || os.AskItems.Where(aa => aa.Type == "AskCheckboxes").Any(aa => ((AskCheckboxes)aa).list.Any(dd => dd.Fee > 0))
  					 select new SelectListItem
  					 {
  						 Text = i.DivisionName + ":" + i.OrganizationName,
  						 Value = "org." + i.OrganizationId
  					 };
  
  			var list = qq.OrderBy(n => n.Text).ToList();
  
  			list.Insert(0, new SelectListItem { Text = "(not specified)", Value = "0" });
  			return list;
  		}
          public List<SelectListItem> Users()
          {
              var q = from c in DbUtil.Db.Coupons
                      where c.UserId != null
                      group c by c.UserId into g
                      select new SelectListItem
                      {
                          Value = g.Key.ToString(),
                          Text = g.First().User.Name,
                      };
              var list = q.ToList();
              list.Insert(0, new SelectListItem { Text = "(not specified)", Value = "0" });
              return list;
          }
          public List<SelectListItem> CouponStatus()
          {
              return new List<SelectListItem>
              {
                  new SelectListItem { Text = "(not specified)" },
                  new SelectListItem { Text = "Used" },
                  new SelectListItem { Text = "UnUsed" },
                  new SelectListItem { Text = "Canceled" },
              };
          }
          public static bool IsExisting(string code)
          {
              bool existing = DbUtil.Db.Coupons.Any(cp => cp.Id == code && cp.Used == null && cp.Canceled == null);
              return existing;
          }
          public Coupon CreateCoupon()
          {
              string code = couponcode;
              if (!couponcode.HasValue())
              {
                  do
                  {
                      code = Util.RandomPassword(12);
                  }
                  while (IsExisting(code));
              }
  
              var c = new Coupon
              {
                  Id = code,
                  Created = DateTime.Now,
                  Amount = amount,
                  Name = name,
                  UserId = Util.UserId,
              };
              SetDivOrgIds(c);
              DbUtil.Db.Coupons.InsertOnSubmit(c);
              DbUtil.Db.SubmitChanges();
              couponcode = Util.fmtcoupon(c.Id);
  
              return c;
          }
          private void SetDivOrgIds(Coupon c)
          {
              if (regid.HasValue())
              {
  
gt:                 var a = regid.Split('.');