/// <summary>
        /// Updates an AUSale
        /// </summary>
        /// <param name="oldsale">AUSaleRecord - has ID to update</param>
        /// <param name="newsale">AUSaleRecord</param>
        public virtual void UpdateSale(AUSaleRecord oldsale, AUSaleRecord newsale)
        {

            oldsale.AUSaleNbr = newsale.AUSaleNbr;
            oldsale.SaleTitle = newsale.SaleTitle;
            oldsale.SaleDesc = newsale.SaleDesc;
            oldsale.SaleStartDateTime = newsale.SaleStartDateTime;
            oldsale.SaleEndDateTime = newsale.SaleEndDateTime;
            oldsale.SaleStoreID = newsale.SaleStoreID;
            oldsale.SaleIsPublished = newsale.SaleIsPublished;
            oldsale.CreatedOnDT = System.DateTime.UtcNow;
            oldsale.UpdatedOnDT = System.DateTime.UtcNow;

            var CurrentCustomer = _authenticationService.GetAuthenticatedCustomer();
            oldsale.UpdatedBy = CurrentCustomer.Username;                    

            _saleRepo.Update(oldsale);
        }
        /// <summary>
        /// Inserts an AUSale
        /// </summary>
        /// <param name="sale">AUSaleRecord</param>
        public virtual void InsertSale(AUSaleRecord sale)
        {
            var CurrentCustomer = _authenticationService.GetAuthenticatedCustomer();
            sale.CreatedBy = CurrentCustomer.Username;
            sale.UpdatedBy = CurrentCustomer.Username;
            sale.CreatedOnDT = System.DateTime.UtcNow;
            sale.UpdatedOnDT = System.DateTime.UtcNow;

            _saleRepo.Insert(sale);
        }
        protected virtual Boolean IncrementsAreGood(AUSaleRecord record)
        {
            var increments = record.AUIncrementRecords.OrderBy(a => a.FromBidAmt);

            int count = 0;
            decimal lowamt = decimal.MaxValue;
            decimal highamt = 0;
            decimal previoustoamt = 0;
            foreach (var increment in increments)
            {
                if (increment.FromBidAmt < lowamt)
                { lowamt = increment.FromBidAmt;}

                if (increment.ToBidAmt > highamt)
                { highamt = increment.ToBidAmt;}

                //must ensure each increment is well formed before doing intersection checks below
                if (increment.ToBidAmt <= increment.FromBidAmt)
                    return false;
                
                //make sure this increment is consecutive to last increment (oncrements ordered by From amt)
                if (count == 0)
                    {previoustoamt = increment.ToBidAmt;}
                else 
                    if (increment.FromBidAmt != previoustoamt + 1 )
                        {return false;}
                    else
                         {previoustoamt = increment.ToBidAmt;}

                count += 1;
            }

            //increments must begin in 0 and end in 9,999,999
            if (lowamt != 0 || highamt != 9999999) 
                {return false;}

            var increments2 = record.AUIncrementRecords.OrderBy(a => a.FromBidAmt);
            count = 0;
            int count2 = 0;
            foreach (var increment in increments)
            {

                foreach (var increment2 in increments2)
                {

                    if (((increment.FromBidAmt >= increment2.FromBidAmt && increment.FromBidAmt <= increment2.ToBidAmt) ||
                        (increment.ToBidAmt <= increment2.ToBidAmt && increment.ToBidAmt >= increment2.FromBidAmt )) &&
                        (count != count2))
                    { return false; }

                    count2 += 1;
                }

                count2 = 0;
                count += 1;
            }


            return true;
        }
        //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

         //    [HttpPost]  grid is not posting
        // the grid passes in fields in the row schema as well as the form model
        //the grid schema can containmore fields than are displayed in the columns
        //AULotID comes from the schema
        //AUSaleID comes from the model
        public ActionResult RemoveLotFromSale(int AULotID, AUSaleRecord model)
        {
           //TODO: AUTHORIZE
            //if (!_permissionService.Authorize(StandardPermissionProvider.ManageCategories))
            //    return AccessDeniedView();

            var lot = _lotRepo.GetById(AULotID);
            if (lot == null)
            {
                throw new NopException("Lot not found");
            }

            var CurrentCustomer = _authenticationService.GetAuthenticatedCustomer();
            var currTime = System.DateTime.UtcNow;
            string logError = "";
            int totalerrors = 0;

            if (lot.IsLotSold ||
                (!lot.IsLotSold && model.SaleStartDateTime < currTime && model.SaleEndDateTime > currTime && lot.LastBidAmt != 0) ||
                (!lot.IsLotSold && model.SaleStartDateTime > currTime && model.SaleEndDateTime > currTime && lot.LastBidAmt != 0)
                )
            {
                logError = string.Format("Remove Lot from Sale by user {2} : Can not remove this lot id# {0}/ Sku# {1} is sold or is in an active or future sale and has had bids", lot.AULotID, lot.Sku, CurrentCustomer.Username);
                _logger.InsertLog(LogLevel.Error, logError);
                totalerrors++;
            }
            else
            {
                //remove lot from to sale and record lot history for MOVE (RM if before sale closed, RH if after sale closed)
                _consignorService.DeleteSaleLotByLotId(AULotID, model.AUSaleID);

            }


            
            //if (productCategory == null)
            //    throw new ArgumentException("No product category mapping found with the specified id");

            ////var categoryId = productCategory.CategoryId;
            //_categoryService.DeleteProductCategory(productCategory);

            return new NullJsonResult();
        }
        //public ActionResult CreateUpdateSale(AUSaleRecord record, string save)
        public ActionResult CreateUpdateSale(AUSaleRecord record)

        {
            //if (save.Equals("Award Sale")) //see http://stackoverflow.com/questions/19650345/mvc-razor-form-with-multiple-different-submit-buttons
            if (Request.Form["AwardSale"] != null)
            {

                var query = from c in _maxbidjobcontrolRepo.Table
                            select c;
                var control = query.FirstOrDefault();
                if (!control.IsMaxBidJobRunning)
                {
                    _consignorService.AwardSale(record.AUSaleID, record.SaleStoreID);
                    //TempData["notice"] = "Sale Successfully Awarded";   --from google
                    SuccessNotification("Sale Awarded!!");  //seems to be nop admin convention
                    //return RedirectToAction("CreateUpdateSale");
                    return RedirectToAction("CreateUpdateSale", new { SaleId = record.AUSaleID });
                }
                else
                {
                    ErrorNotification("Could not award sale because Max Bid Process is still running!!");  //seems to be nop admin convention
                    //return RedirectToAction("CreateUpdateSale");
                    return RedirectToAction("CreateUpdateSale", new { SaleId = record.AUSaleID });
                }
            }



            //%%%%%the nav properties are gone, but the form values are there! reget the nav properties with getbyid before testing

            if (ModelState.IsValid)
            {
                        AUSaleRecord sale = _saleRepo.GetById(record.AUSaleID);

                        if (sale == null)
                        {
                            if (!record.SaleIsPublished)
                                {
                                    _consignorService.InsertSale(record);
                                    SuccessNotification("Sale Created Successfully!");
                                    return RedirectToRoute(new
                                    {
                                        Action = "CreateUpdateSale",
                                        Controller = "AUConsignor",
                                        SaleId = record.AUSaleID
                                    });
                                }
                            else
                                {
                                    ErrorNotification("Insert of new sale not successful - trying to publish sale but you need to store the sale and create sessions and increments first.");
                                    return View("~/Views/AUConsignor/CreateUpdateSale.cshtml", record);
                                }
                        }
                        else  //sale already exists so this will be an update. Use latest consignor record to update with most up-do-date data rather than stale record
                        {
                            sale.AUSaleNbr = record.AUSaleNbr;
                            sale.SaleTitle = record.SaleTitle;
                            sale.SaleDesc = record.SaleDesc;
                            sale.SaleStartDateTime = record.SaleStartDateTime;
                            sale.SaleEndDateTime = record.SaleEndDateTime;
                            sale.SaleStoreID = record.SaleStoreID;
                            sale.SaleIsAwarded = record.SaleIsAwarded;
                            sale.SaleType = record.SaleType;

                            sale.CreatedOnDT = System.DateTime.UtcNow;
                            sale.UpdatedOnDT = sale.CreatedOnDT;  //make sure dates are the same on insert
                            //sale.UpdatedOnDT = System.DateTime.UtcNow;
                            var CurrentCustomer = _authenticationService.GetAuthenticatedCustomer();
                            sale.UpdatedBy = CurrentCustomer.Username;
                            
                            if (!record.SaleIsPublished) //not trying to publish sale so no further checking needed
                            {
                                //_consignorService.UpdateSale(sale,record);
                               // _cacheManager.Clear();

                                sale.SaleIsPublished = record.SaleIsPublished;
                                _saleRepo.Update(sale);

                                SuccessNotification("Changes to Sale saved!");
                                //return View(consignment); //now with customer view engine
                                return View("~/Views/AUConsignor/CreateUpdateSale.cshtml", sale); //BAD
                            }
                            else if (IncrementsAreGood(sale))
                            {
                                //_consignorService.UpdateSale(sale,record);

                                sale.SaleIsPublished = record.SaleIsPublished;
                                _saleRepo.Update(sale);
                                //_cacheManager.Clear();
                                SuccessNotification("Changes to Sale saved!");
                                //return View(consignment); //now with customer view engine
                                return View("~/Views/AUConsignor/CreateUpdateSale.cshtml", sale); //BAD
                            }
                            else
                            {
                                ModelState.Remove("SaleIsPublished");
                                sale.SaleIsPublished = false;
                                //ModelState.Remove("SaleIsPublished");
                               
                                
                                ErrorNotification("Update sale not successful - trying to publish sale but something is wrong with your sale increments. Fix increments before trying to publish. The publish flag has been negated.");
                               return View("~/Views/AUConsignor/CreateUpdateSale.cshtml", sale);
                            }
                        }
            }
            else  //model state is not valid
            {

                ErrorNotification("Invalid Model - Update not applied.");
                return View("~/Views/AUConsignor/CreateUpdateSale.cshtml", record);
                //return View();
                //return View("~/Views/PromoSlider/CreateUpdatePromoSlider.cshtml"); //not hit first time?
                //return View("~/Plugins/Widgets.PromoSlider/Views/PromoSlider/CreateUpdatePromoSlider.cshtml");
            }
        }
        public ActionResult CreateUpdateSale(int SaleId = 0)
        {
            AUSaleRecord sale = new AUSaleRecord();
            if (SaleId > 0)
            {
                sale = _saleRepo.GetById(SaleId); //this will have all the sessions and addresses!!!!!
            }
            else
            {
                sale.SaleIsPublished = false;
            }

            ViewBag.SaleIsPublished = sale.SaleIsPublished;
            ViewBag.SaleIsAwarded = sale.SaleIsAwarded;

            return View("~/Views/AUConsignor/CreateUpdateSale.cshtml", sale); 

            // WORKS!! return View("CreateUpdateSale", sale); //This is what works with the view engine!!!!
            
        }