public static Inspection AddComment(
     int InspectionId,
     string Comment,
     UserAccess ua)
 {
     Comment = Comment.Trim();
     if (ua.current_access == UserAccess.access_type.public_access)
     {
         return(null);
     }
     else
     {
         string sp = "dbo.add_inspection_comment";
         var    dp = new DynamicParameters();
         dp.Add("@Username", ua.display_name);
         dp.Add("@InspectionId", InspectionId);
         dp.Add("@FirstComment", Comment);
         int i;
         try // This function is for stored procedures
         {
             string cs = Constants.Get_ConnStr("WATSC" + (Constants.UseProduction() ? "Prod" : "QA"));
             using (IDbConnection db = new SqlConnection(cs))
             {
                 i = db.Execute(sp, dp, commandType: CommandType.StoredProcedure);
             }
         }
         catch (Exception ex)
         {
             Constants.Log(ex, "");
             i = 0;
         }
         //int i = Constants.Exec_Query_SP(sp, dp);
         if (i == -1)
         {
             Inspection isnp = Get(InspectionId);
             return(isnp);
         }
         else
         {
             return(null);
         }
     }
 }
        public List <string> Validate(UserAccess.access_type CurrentAccess,
                                      List <InspType> inspTypes)
        {
            // List of things that need to be validated:
            // 0) Make sure the permit is able to be scheduled to be inspected.
            // 1) Make sure this permit is valid
            // 2) Make sure the date is in the range expected
            // 3) Make sure the inspection type matches the permit type.
            // 4) Make sure the inspection type is a valid inspection type.
            // 5) Make sure the inspection type isn't already scheduled for this permit.
            // 6) Need to ensure an Inspection cannot be saved if a final inspection result is 'A' or 'P'
            List <string> Errors = new List <string>();

            // 0)
            List <InspType> finals = (from it in inspTypes
                                      where it.Final == true
                                      select it).ToList();

            List <string> finalInspectionCodes = (from it in inspTypes
                                                  where it.Final == true
                                                  select it.InspCd).ToList();

            var currentInspectionType = (from i in inspTypes
                                         where i.InspCd == InspectionCd
                                         select i).ToList().First();

            // DoImpactFeesMatter is how we indicate to the permit that the impact fees matter.
            this.DoImpactFeesMatter = finals.Any(f => f.InspCd == InspectionCd);
            if (currentInspectionType.InspCd == "205")
            {
                this.DoImpactFeesMatter = true;
            }
            //foreach (var f in finals)
            //{
            //  if (f.InspCd == this.InspectionCd)
            //    this.TryingToScheduleFinal = true;
            //}
            //Console.Write("Finals: ", finals);

            //= (List<InspType>)MyCache.GetItem("inspectiontypes,"+IsExternalUser.ToString());

            var Permits =
                (from p in Permit.Get(
                     this.PermitNo,
                     CurrentAccess,
                     $@"NewInspection.Validate();
                 User Access Level: {CurrentAccess};
                 PermitNo: {this.PermitNo}",
                     currentInspectionType,
                     DoImpactFeesMatter)
                 select p).ToList();


            Permit CurrentPermit = (from p in Permits
                                    where p.PermitNo == this.PermitNo
                                    select p).FirstOrDefault();



            if (CurrentPermit == null)
            {
                Errors.Add($"Permit number {PermitNo} was not found.");

                // If permit is not found, then exit
                // no need to validate other data
                return(Errors);
            }
            else
            {
                if (CurrentPermit.ErrorText.Length > 0)
                {
                    Errors.Add(CurrentPermit.ErrorText);
                }

                bool canSchedule = false;


                var mp = (from p in Permits
                          where p.CoClosed == 0
                          select p).DefaultIfEmpty(new Permit()).First();
                canSchedule = this.DoImpactFeesMatter && mp.CorrectImpactFeeCount && mp.TotalImpactFeesDue == 0;



                if (!canSchedule && this.DoImpactFeesMatter)
                {
                    List <string> newList = new List <string>();
                    newList.Add($@"A {currentInspectionType.InsDesc} cannot be scheduled if there are unpaid impact fees.
                          Please contact the building department for assistance.");
                    Errors = newList;
                    // TODO: add call to function here that will assess the Solid Waste Fee
                }

                // validate user selected date
                var start    = DateTime.Parse(CurrentPermit.Dates.minDate_string);
                var end      = DateTime.Parse(CurrentPermit.Dates.maxDate_string);
                var badDates = (from d in CurrentPermit.Dates.badDates_string
                                where DateTime.Parse(d) != start &&
                                DateTime.Parse(d) != end
                                select d).ToList <string>();

                // Is the scheduled date between the start and end date?
                if (SchecDateTime.Date < start ||
                    SchecDateTime.Date > end)
                {
                    Errors.Add("Invalid Date Selected");
                }
                // Is the scheduled date one of the dates they aren't allowed to use?
                if (badDates.Contains(SchecDateTime.ToShortDateString()))
                {
                    Errors.Add("Invalid Date Selected");
                }
                // Is the inspection type valid?
                if (!(from i in inspTypes
                      where i.InspCd == InspectionCd
                      select i).Any())
                {
                    Errors.Add("Invalid Inspection Type");
                }
                else
                {
                    // Does the inspection type match the permit type
                    var permitType = ' ';

                    switch (PermitNo[0])
                    {
                    case '1':
                    case '9':
                    case '0':
                        permitType = '1';
                        break;

                    default:
                        permitType = PermitNo[0];
                        break;
                    }


                    if (InspectionCd[0] != permitType)
                    {
                        Errors.Add("Invalid Inspection for this permit type");
                    }

                    List <Inspection> inspections = Inspection.Get(CurrentPermit.PermitNo);
                    CurrentPermit.Holds = Hold.Get(new List <string>()
                    {
                        CurrentPermit.PermitNo
                    });

                    var needsFireInspection = (from h in CurrentPermit.Holds
                                               where h.HldCd == "FD05"
                                               select h.HldCd.ToString()).ToList();

                    if (CurrentPermit.TotalFinalInspections > 0 && needsFireInspection.Count() == 0 && CurrentPermit.PermitNo[0] != '6')
                    {
                        Errors.Add($"Permit #{CurrentPermit.PermitNo} has passed final inspection");
                    }


                    var PassedOrScheduledInspections = (from ic in inspections
                                                        where (ic.ResultADC != "C" &&
                                                               ic.ResultADC != "D" &&
                                                               ic.ResultADC != "N")
                                                        select ic).ToList();

                    foreach (var i in PassedOrScheduledInspections)
                    {
                        if (this.PermitNo == i.PermitNo && this.InspectionCd == i.InspectionCode && string.IsNullOrEmpty(i.ResultADC))
                        {
                            Errors.Add("Inspection type exists on permit");
                        }
                        // commenting out debug code
                        //var IncompleteInspection = (from ic in PassedOrScheduledInspections
                        //                            where i.InspectionCode == this.InspectionCd &&
                        //                            string.IsNullOrEmpty(i.ResultADC)
                        //                            select ic).ToList();

                        //Console.Write(IncompleteInspection);
                    }



                    //Adds functionality to return error when saving an inspection for permit that has already passed a final inspection.

                    // To schedule a building final:
                    // 1. All fees, including Road impact and school impact fees, must be paid; AND
                    // 2. All associated permits must have a final inspection either scheduled, or passed.
                    // 3. The Final Building Inspection cannot be scheduled for any time before the latest incomplete
                    //    associated permit's final inspection.
                    var    PermitsWithScheduledOrPassedFinals   = new List <string>();
                    var    permitsWithNoFinalsScheduledOrPassed = new List <string>();
                    string masterPermit = "";
                    foreach (var f in finals)
                    {
                        PermitsWithScheduledOrPassedFinals.AddRange(from ic in PassedOrScheduledInspections
                                                                    where ic.InspectionCode == f.InspCd &&
                                                                    (ic.ResultADC != "C" &&
                                                                     ic.ResultADC != "D" &&
                                                                     ic.ResultADC != "N") &&
                                                                    !PermitsWithScheduledOrPassedFinals.Contains(ic.PermitNo)
                                                                    select ic.PermitNo);
                    }

                    foreach (var p in Permits)
                    {
                        if (p.GetIsVoided())
                        {
                            continue;
                        }
                        if (p.CoClosed != -1)
                        {
                            masterPermit = p.PermitNo;
                        }
                        var currentCheck = (from pf in PermitsWithScheduledOrPassedFinals
                                            where pf == p.PermitNo
                                            select pf).FirstOrDefault();

                        if (currentCheck == null)
                        {
                            permitsWithNoFinalsScheduledOrPassed.Add(p.PermitNo);
                        }
                        else
                        {
                            if (p.PermitNo == this.PermitNo)
                            {
                                Errors.Add($@"Permit {p.PermitNo} has a scheduled final inspection.");
                            }
                        }
                    }

                    foreach (var p in Permits)
                    {
                        if (p.CoClosed != -1)
                        {
                            permitsWithNoFinalsScheduledOrPassed.Remove(p.PermitNo);

                            if (Permits.Count > 1 &&
                                finalInspectionCodes.Contains(this.InspectionCd) &&
                                permitsWithNoFinalsScheduledOrPassed.Count > 0 &&
                                this.PermitNo.Trim() == masterPermit.Trim())
                            {
                                Errors.Add($@"All permits associated with permit #{p.PermitNo}
                           must have final inspections scheduled or passed, 
                           before a Building final can be scheduled.");
                            }
                            else if (this.InspectionCd == "123" && this.PermitNo == masterPermit && p.NoFinalInspections == true)
                            {
                                Errors.Add($@"Permit {masterPermit} has existing holds, 
                           this is preventing the Building Final
                           from being scheduled.");
                            }
                        }
                    }
                }
            }
            return(Errors);
        }
        private bool Validate(string PermitNumber, Inspection currentInspection, string ResultCode, string UserRemarks, UserAccess User)
        {
            if (User.current_access == UserAccess.access_type.contract_access)
            {
                List <Inspector> inspList = Inspector.GetCached();

                var inspectors = (from i in inspList
                                  where i.NTUsername == User.user_name
                                  select i).ToList();
                if (inspectors.Count() == 0)
                {
                    Errors.Add("Inspector not found.");
                }
                if (inspectors.First().Name != currentInspection.InspectorName)
                {
                    Errors.Add("This inspection is not assigned to this inspector.");
                }
            }
            if (PermitNumber != PermitNo)
            {
                Errors.Add("The permit number does not match the inspection, please check your request and try again.");
                return(false);
            }
            switch (ResultCode.Trim())
            {
            case "A":
            case "": // result is not set
            case "D":
            case "P":
            case "N":
                // only inspectors can change the result
                if (User.current_access == UserAccess.access_type.public_access)
                {
                    Errors.Add("Unauthorized Access.");
                    return(false);
                }

                if (ResultCode == "A" || ResultCode == "D")
                {
                    if (PrivateProviderInspectionRequestId > 0)
                    {
                        Errors.Add("Private provider inspections must be marked as Not Performed or Performed.");
                        return(false);
                    }
                }

                // If they are trying to change something that was completed before today.
                if (currentInspection.ResultADC != "" &&
                    InspDateTime != DateTime.MinValue.Date &&
                    InspDateTime.Date < DateTime.Today.AddDays(-2).Date)
                {
                    Errors.Add("Inspections completed more than two days ago cannot be changed.");
                    return(false);
                }
                if (currentInspection.ResultADC != "" &&
                    InspDateTime != DateTime.MinValue.Date &&
                    User.current_access == UserAccess.access_type.contract_access)
                {
                    Errors.Add("Completed inspections cannot be changed. Please contact the Building departent for assistance.");
                    return(false);
                }
                if (ResultCode == "D" & UserRemarks.Length == 0)
                {
                    Errors.Add("Disapprovals must have remarks included in order to be saved.");
                    return(false);
                }
                return(true);

            case "C":
                if (User.current_access == UserAccess.access_type.public_access ||
                    User.current_access == UserAccess.access_type.basic_access ||
                    User.current_access == UserAccess.access_type.inspector_access ||
                    User.current_access == UserAccess.access_type.contract_access)
                {
                    if (ResultADC.Length != 0 && InspDateTime.ToLocalTime() < DateTime.Today.AddDays(-2))
                    {
                        Errors.Add("Cannot cancel a completed inspection.  This inspection was completed on: " + InspDateTime.ToShortDateString());
                        return(false);
                    }
                    if (UserRemarks.Trim().Length == 0 && User.current_access != UserAccess.access_type.public_access)
                    {
                        Errors.Add("You must include a reason why this inspection is being canceled in the Remarks field.");
                        return(false);
                    }
                    return(true);
                }
                else
                {
                    Errors.Add("Unauthorized Access.");
                    return(false);
                }

            default:
                Errors.Add("Unauthorized Access.");
                return(false);
            }
        }
        public static Inspection UpdateInspectionResult(
            string PermitNumber,
            int InspectionId,
            string ResultCode,
            string Remarks,
            string Comments,
            UserAccess User)
        {
            PermitNumber = PermitNumber.Trim();
            ResultCode   = ResultCode.Trim();
            Remarks      = Remarks.Trim();
            Comments     = Comments.Trim();
            try
            {
                Inspection current = Get(InspectionId);
                if (current == null)
                {
                    return(null);
                }

                if (current.Validate(PermitNumber, current, ResultCode, Remarks, User))
                {
                    // let's do some saving
                    switch (ResultCode)
                    {
                    case "A":
                    case "P":
                    case "N":
                    case "C":
                    case "":
                        if (current.ResultADC == "D")
                        {
                            if (IsREIPaid(current.InspReqID))
                            {
                                current.UpdateError = ("The REI has already been paid, you cannot change the result of this inspection.");
                                break;
                            }
                        }

                        if (!UpdateStatus(InspectionId, ResultCode, current.ResultADC, Remarks, Comments, current.PrivateProviderInspectionRequestId, User))
                        {
                            current.UpdateError = ("Error saving your changes, please try again. If this message recurs, please contact the helpdesk.");
                        }
                        break;


                    case "D":
                        string HoldInput = current.PermitNo + " " + current.InspectionCode + " $35";
                        if (!UpdateStatus(InspectionId, ResultCode, current.ResultADC, Remarks, Comments, current.PrivateProviderInspectionRequestId, User, PermitNumber, HoldInput))
                        {
                            current.UpdateError = ("Error saving your changes, please try again. If this message recurs, please contact the helpdesk.");
                        }
                        break;
                    }
                }

                Inspection i = Get(InspectionId);
                return(i);
            }
            catch (Exception ex)
            {
                Constants.Log(ex, "");
                return(null);
            }
        }