/// <summary>
        /// Inserts an AULot
        /// </summary>
        /// <param name="lot">AULotRecord</param>
        public virtual void InsertLot(AULotRecord lot)
        {
            if (lot == null)
                throw new ArgumentNullException("lot");

            //TODO: make a transaction
            //TODO: this should go into calling function
            lot.BidPostDateTime = new DateTime(1970, 01, 01);

            _lotRepo.Insert(lot);

            AULotLastBidChangeRecord lastbid = new AULotLastBidChangeRecord();
            lastbid.AULotId = lot.AULotID;
            lastbid.AUProductId = lot.AUProductID;
            lastbid.BidderId = lot.LastBidId;
            lastbid.LastBidChangeDT = new DateTime(1970, 01, 01);
            lastbid.LastMaxJobRunDT = new DateTime(1970, 01, 01);

            _lotlastbidchangeRepo.Insert(lastbid);


            //TODO: ADD LOT CACHE CONTROL AND PUBLISHING
            ////clear cache
            //_cacheManager.RemoveByPattern(PRODUCTS_PATTERN_KEY);

            ////event notification
            //_eventPublisher.EntityInserted(product);
        }
        //TODO: copy lot provide option to copy fees and/or current active sale.
        /// <summary>
        /// Create a copy of lot associated to product. The new lot will remain within the same consignment as the old lot but
        /// we will not will not copy lot fees or any sale-lot or reference-lot junctions. The new lot will also remain within the same 
        /// country and stateprovince as the old lot. 
        /// </summary>
        /// <param name="product">The product associated to the lot to copy</param>
        /// <param name="newSKu">The new sku of product duplicate</param>
        /// <returns>The new AULotRecord copy</returns>
        /// 
        public virtual AULotRecord CopyLot(Product origProduct, string newSku)
        {
            if (origProduct == null)
                throw new ArgumentNullException("Original Product missing");

            if (String.IsNullOrEmpty(newSku))
                throw new ArgumentException("New Product sku is required");

            var newProduct = _productService.GetProductBySku(newSku);

            var origLot = _consignorService.GetLotByProductId(origProduct.Id);
            if (origLot == null)
                throw new ArgumentException("New Product sku is required");

            var currDate = System.DateTime.UtcNow;
            var currentCustomer = _authenticationService.GetAuthenticatedCustomer();

            var newLot = new AULotRecord()
            {
                AUProductID = newProduct.Id,
                Sku = newSku,
                CreatedOnDateTime = currDate,
                UpdatedOnDateTime = currDate,  //make sure dates are the same on insert
                CreatedByUsername = currentCustomer.Username,
                UpdatedByUsername = currentCustomer.Username,

                //TODO: Make this a view model - forcing this in though it doesn't hit the DB
                ConsignmentID = 999999999

            };

            //_consignorService.InsertLot(newLot);  
            //TODO: MAKE InsertLot return the new lot record so can fully subsume data layer
            //TODO: Make transaction
            _lotRepo.Insert(newLot);

            AULotLastBidChangeRecord lastbid = new AULotLastBidChangeRecord();
            lastbid.AULotId = newLot.AULotID;
            lastbid.AUProductId = newLot.AUProductID;
            lastbid.BidderId = newLot.LastBidId;
            lastbid.LastBidChangeDT = newLot.CreatedOnDateTime;
            lastbid.LastMaxJobRunDT = newLot.CreatedOnDateTime;
            _lotlastbidchangeRepo.Insert(lastbid);

            //create junction record to track lot copies, splits,consolidates
            CreateLotLot(origProduct.Id, newProduct.Id, origLot.AULotID,  newLot.AULotID);

            var newConsignmentLot = new AUConsignmentLotRecord()
                {
                    AULotID = newLot.AULotID
                };

            foreach (var consignment in origLot.AUConsignmentRecords)
            {
                newConsignmentLot.AUConsignmentID = consignment.AUConsignmentID;
                _consignmentlotRepo.Insert(newConsignmentLot);
            }


            var newCountryLot = new AUCountryLotRecord()
            {
                AULotID = newLot.AULotID
            };

            foreach (var country in origLot.AUCountryRecords)
            {
                newCountryLot.AUCountryID = country.AUCountryID;
                _countrylotRepo.Insert(newCountryLot);
            }


            var newStateProvinceLot = new AUStateProvinceLotRecord()
            {
                AULotID = newLot.AULotID
            };

            foreach (var stateprovince in origLot.AUStateProvinceRecords)
            {
                newStateProvinceLot.AUStateProvinceID = stateprovince.AUStateProvinceID;
                _stateprovincelotRepo.Insert(newStateProvinceLot);
            }

            return newLot;
        }
        public ActionResult CreateUpdateLot(AULotRecord record)
        {
            if (ModelState.IsValid)
            {
                AULotRecord lot = _lotRepo.GetById(record.AULotID);
                var CurrentCustomer = _authenticationService.GetAuthenticatedCustomer();

                if (lot == null)
                {

                   
                    record.CreatedByUsername = CurrentCustomer.Email;
                    record.UpdatedByUsername = CurrentCustomer.Email;

                    record.CreatedOnDateTime = System.DateTime.UtcNow;
                    record.UpdatedOnDateTime = record.CreatedOnDateTime; //Make updated by same as created by date for initial store

                    record.BidPostDateTime = new DateTime(1970, 01, 01);

                    //TODO: make transaction
                    _lotRepo.Insert(record);

                    AULotLastBidChangeRecord lastbid = new AULotLastBidChangeRecord();
                    lastbid.AULotId = record.AULotID;
                    lastbid.AUProductId = record.AUProductID;
                    lastbid.BidderId = record.LastBidId;
                    lastbid.LastBidChangeDT = new DateTime(1970, 01, 01);
                    lastbid.LastMaxJobRunDT = new DateTime(1970, 01, 01);
                    _lotlastbidchangeRepo.Insert(lastbid);

                    //Populate ConsignmentID relationship
                    var consignment = _consignorService.GetConsignmentById(record.ConsignmentID); //this will be populated by the insert above
                    if (consignment != null)
                    {
                        //if (lot.AUSaleRecords.FirstOrDefault(x => x.AUSaleID == sale.AUSaleID) == null) //%%%%Value cn not be null?????
                        var cl = consignment.AULotRecords.FirstOrDefault(x => x.AULotID == record.AULotID);
                        if (cl == null) //Consignment exists but the junction AUConsignmentLot record doesn't
                        {
                            var consignmentLot = new AUConsignmentLotRecord
                            {
                                AUConsignmentID = consignment.AUConsignmentID,
                                AULotID = record.AULotID,
                            };
                            _consignorService.InsertConsignmentLot(consignmentLot); 
                        }

                       

                        //else - Relationship already exists so nothing more to do                                            
                    }

                    SuccessNotification("Lot Created Successfully - please review fees!");
                    
                    //TODO: do you want to make this conditional as might come from lot maintenance as well as from product maintenance?
                    return RedirectToRoute(new
                    {
                        Action = "Edit",
                        Controller = "Product",
                        Area = "Admin",
                        id = record.AUProductID
                    });
                }
            else  //found the existing lot
                {

                    var consignment = _consignorService.GetConsignmentById(record.ConsignmentID);

                    //&&&TODO: determine changes that occurred
                    lot.AUProductType = record.AUProductType;

                    //use latest lot record to update with most up-do-date data rather than stale record
                    lot.EstimatedLowBidAmt = record.EstimatedLowBidAmt;
                    lot.EstimatedHighBidAmt = record.EstimatedHighBidAmt;
                    lot.EstimatedRealizationAmt = record.EstimatedRealizationAmt;
                    lot.DisplayOrder = record.DisplayOrder;
                    lot.OpeningBidAmt = record.OpeningBidAmt;
                    lot.ReserveAmt = record.ReserveAmt;
                    lot.UpdatedByUsername = CurrentCustomer.Username;
                    lot.UpdatedOnDateTime = System.DateTime.UtcNow;

                    //TODO: this is needed to get around record edits - maybe another reason to make this a view model
                    lot.ConsignmentID = record.ConsignmentID;

                    _lotRepo.Update(lot);   //NJM: don't need to reflect aulotbidchange here

                    //for some reason you can't Remove the consignment relationship once you've established one - it doesn't like a null relationship
                    //this is why you get it and update it - the rule is a lot must always be related to a consignment
                    //when you combine multiple lots into a new lot, the consignment relationship will inherit from the original lots
                    var consignmentlot = lot.AUConsignmentRecords.First();
                    if (consignmentlot != null)
                    {
                        if (consignmentlot.AUConsignmentID != lot.ConsignmentID)   //only do a database update operation if in fact the consignment has changed
                        {
                        //TODO: how to alert if the _feesRepo hierarchy changes and/OrderedParallelQuery if the lot has fees
                            int origConsignmentId = consignmentlot.AUConsignmentID;
                            consignmentlot.AUConsignmentID = lot.ConsignmentID;
                            _consignorService.UpdateConsignmentLot(consignmentlot, origConsignmentId);  //%%%% lotconsignment move history here
                        }
                    }

                    //TODO - how to design this so it's one EF transaction
                   // lot.AUConsignmentRecords.Remove(lot.AUConsignmentRecords.First()); //TODO: review design for lot can only belong to one consignment


                    //var consignmentLot = new AUConsignmentLotRecord
                    //{
                    //    AUConsignmentID = record.ConsignmentID,
                    //    AULotID = record.AULotID,
                    //    AULotRecord = lot,
                    //    AUConsignmentRecord = consignment

                    //};

                    //lot.AUConsignmentRecords.Add(consignmentLot);

                    
                    //_consignorService.InsertConsignmentLot(consignmentLot);

                    SuccessNotification("Changed Saved!");

                    //TODO: do you want to make this conditional as might come from lot maintenance as well as from product maintenance?
                    return RedirectToRoute(new
                    {
                        Action = "Edit",
                        Controller = "Product",
                        Area = "Admin",
                        id = record.AUProductID
                    });
                }
            }
            else
            {
                return View();
                //return View("~/Views/PromoSlider/CreateUpdatePromoSlider.cshtml"); //not hit first time?
                //return View("~/Plugins/Widgets.PromoSlider/Views/PromoSlider/CreateUpdatePromoSlider.cshtml");
            }
        }