internal IValidationResult ShipFit(ShipFit shipFit)
        {
            IValidationResult validationResult = new ValidationResult();

            // Check that the ship fit has a valid account id.
            if (shipFit.AccountId < 0 || shipFit.AccountId > int.MaxValue)
            {
                validationResult.AddError("AccountId.Range_" + shipFit.ShipFitId.ToString(), "AccountId can not be less than or equal to 0. Also, the upper limit cannot exceed the max value of the int data type.");
            }

            // Null checks.
            if (shipFit.Notes == null)
            {
                validationResult.AddError("Notes.Null", "Notes cannot be null.");
            }

            if (shipFit.Name == null)
            {
                validationResult.AddError("Name.Null", "Name cannot be null.");
            }

            if (shipFit.Role == null)
            {
                validationResult.AddError("Role.Null", "Role cannot be null.");
            }

            return validationResult;
        }
 internal ShipFit CreateShipFit(ShipFit shipFit)
 {
     shipFit.ObjectState = ObjectState.Added;
     this.unitOfWork.Repository<ShipFit>().Insert(shipFit);
     return shipFit;
 }
 internal ShipFit AddShipFit(ShipFit shipFit)
 {
     this.unitOfWork.Repository<ShipFit>().Insert(shipFit);
     return shipFit;
 }
 internal void UpdateShipFit(ShipFit shipFit)
 {
     shipFit.ObjectState = ObjectState.Modified;
     this.unitOfWork.Repository<ShipFit>().Update(shipFit);
 }
 public void UpdateShipFit(ShipFit shipFit)
 {
     ShipFitOperations.UpdateShipFit(shipFit);
 }
 public ShipFit CreateShipFit(ShipFit shipFit)
 {
     return ShipFitOperations.CreateShipFit(shipFit);
 }
 public ShipFit AddShipFit(ShipFit shipFit)
 {
     return ShipFitOperations.AddShipFit(shipFit);
 }
        /// <summary>
        /// Updates a ship fit for a particular account.
        /// </summary>
        /// <param name="shipFit">A partially populated ship fit object to be updated.</param>
        /// <returns>Returns a validation result object.</returns>
        internal IValidationResult UpdateShipFit(ShipFit shipFit)
        {
            IValidationResult validationResult = new ValidationResult();

            var existingShipFit = this.doctrineShipsRepository.GetShipFit(shipFit.ShipFitId);

            if (existingShipFit != null)
            {
                if (existingShipFit.AccountId != shipFit.AccountId)
                {
                    validationResult.AddError("ShipFit.Permission", "The ship fit being modified does not belong to the requesting account.");
                }
                else
                {
                    // Map the updates to the existing ship fit.
                    existingShipFit.Name = shipFit.Name;
                    existingShipFit.Role = shipFit.Role;
                    existingShipFit.Notes = shipFit.Notes;

                    // Validate the ship fit updates.
                    validationResult = this.doctrineShipsValidation.ShipFit(existingShipFit);
                    if (validationResult.IsValid == true)
                    {
                        // Update the existing record, save and log.
                        this.doctrineShipsRepository.UpdateShipFit(existingShipFit);
                        this.doctrineShipsRepository.Save();
                        logger.LogMessage("Ship Fit '" + existingShipFit.Name + "' Successfully Updated For Account Id: " + existingShipFit.AccountId, 2, "Message", MethodBase.GetCurrentMethod().Name);
                    }
                }
            }

            return validationResult;
        }
        /// <summary>
        /// Refresh the packaged volume for a ship fit.
        /// </summary>
        /// <param name="shipFit">A doctrine ships ship fit.</param>
        internal void RefreshShipFitPackagedVolume(ShipFit shipFit)
        {
            shipFit.FitPackagedVolume = 0;

            // Ensure that there are ship fit components to be refreshed.
            if (shipFit.ShipFitComponents != null && shipFit.ShipFitComponents.Any() != false)
            {
                foreach (var item in shipFit.ShipFitComponents)
                {
                    // Add the value to the shipfit's total volume.
                    shipFit.FitPackagedVolume += item.Component.Volume * item.Quantity;
                }

                // Update the ship fit in the database.
                this.doctrineShipsRepository.UpdateShipFit(shipFit);

                // Commit changes to the database.
                this.doctrineShipsRepository.Save();
            }
        }
        /// <summary>
        /// Refresh the market details for a ship fit.
        /// </summary>
        /// <param name="shipFit">A doctrine ships ship fit.</param>
        /// <param name="settingProfile">A doctrine ships account setting profile.</param>
        internal void RefreshShipFitMarketDetails(ShipFit shipFit, SettingProfile settingProfile)
        {
            // Only update the ship fit prices if they are older than 5 minutes.
            if (Time.HasElapsed(shipFit.LastPriceRefresh, TimeSpan.FromMinutes(5)) == true)
            {
                // Update the buy and sell prices of all ship fit components.
                this.RefreshShipFitComponentsPrices(shipFit, settingProfile);

                // Ship Fit Calculations.
                shipFit.BuyPrice = shipFit.ShipFitComponents.Sum(x => (x.BuyPrice * x.Quantity));
                shipFit.SellPrice = shipFit.ShipFitComponents.Sum(x => (x.SellPrice * x.Quantity));
                shipFit.ShippingCost = shipFit.FitPackagedVolume * settingProfile.ShippingCostPerM3;
                shipFit.ContractReward = (shipFit.SellPrice * settingProfile.ContractMarkupPercentage) + shipFit.ShippingCost + settingProfile.ContractBrokerFee;
                shipFit.BuyOrderProfit = shipFit.ContractReward - shipFit.BuyPrice;
                shipFit.SellOrderProfit = shipFit.ContractReward - shipFit.SellPrice;

                // Set the ship fit's last price refresh timestamp to the current date & time.
                shipFit.LastPriceRefresh = DateTime.UtcNow;

                // Update the ship fit in the database.
                this.doctrineShipsRepository.UpdateShipFit(shipFit);

                // Commit changes to the database.
                this.doctrineShipsRepository.Save();
            }
        }
        /// <summary>
        /// Refresh the market prices of all components in a ship fit.
        /// </summary>
        /// <param name="shipFit">A doctrine ships ship fit.</param>
        /// <param name="settingProfile">A doctrine ships account setting profile.</param>
        internal void RefreshShipFitComponentsPrices(ShipFit shipFit, SettingProfile settingProfile)
        {
            double buyPrice;
            double sellPrice;
            IDictionary<int, double> buyPrices;
            IDictionary<int, double> sellPrices;

            // Ensure that there are ship fit components to be refreshed.
            if (shipFit.ShipFitComponents != null && shipFit.ShipFitComponents.Any() != false)
            {
                buyPrices = this.eveDataSource.GetStationBuyPrice(shipFit.ShipFitComponents.Select(x => x.ComponentId).ToList(), settingProfile.BuyStationId);
                sellPrices = this.eveDataSource.GetStationSellPrice(shipFit.ShipFitComponents.Select(x => x.ComponentId).ToList(), settingProfile.SellStationId);

                foreach (var item in shipFit.ShipFitComponents)
                {
                    buyPrices.TryGetValue(item.ComponentId, out buyPrice);
                    sellPrices.TryGetValue(item.ComponentId, out sellPrice);

                    item.BuyPrice = buyPrice * settingProfile.BrokerPercentage;
                    item.SellPrice = sellPrice;

                    item.ObjectState = ObjectState.Modified;
                }
            }
        }
        /// <summary>
        /// Generate and refresh the EVE IGB fitting string for a ship fit.
        /// </summary>
        /// <param name="shipFit">A doctrine ships ship fit.</param>
        internal void RefreshFittingString(ShipFit shipFit)
        {
            string fittingString = string.Empty;

            // Generate the fitting string.
            fittingString += shipFit.HullId + ":";

            foreach (var item in shipFit.ShipFitComponents)
            {
                fittingString += item.ComponentId + ";" + item.Quantity + ":";
            }

            fittingString += ":";

            // Update the fitting string and ship fit in the database.
            shipFit.FittingString = fittingString;
            this.doctrineShipsRepository.UpdateShipFit(shipFit);

            // Commit changes to the database.
            this.doctrineShipsRepository.Save();
        }
        /// <summary>
        /// Generate and refresh the fitting hash, unique to an account.
        /// </summary>
        /// <param name="shipFit">A doctrine ships ship fit.</param>
        /// <param name="accountId">The account Id for which a fitting hash should be generated.</param>
        internal void RefreshFittingHash(ShipFit shipFit, int accountId)
        {
            string concatComponents = string.Empty;
            IEnumerable<ShipFitComponent> compressedShipFitComponents = new List<ShipFitComponent>();

            if (shipFit.ShipFitComponents != null && shipFit.ShipFitComponents.Any() == true)
            {
                // Compress the ship fit components list, removing duplicates but adding the quantities.
                compressedShipFitComponents = shipFit.ShipFitComponents
                        .OrderBy(o => o.ComponentId)
                        .GroupBy(u => u.ComponentId)
                        .Select(x => new ShipFitComponent()
                        {
                            ComponentId = x.Key,
                            Quantity = x.Sum(p => p.Quantity)
                        });

                // Concatenate all components and their quantities into a single string.
                foreach (var item in compressedShipFitComponents)
                {
                    concatComponents += item.ComponentId + item.Quantity;
                }

                // Generate a hash for the fitting and salt it with the account id. This permits identical fits across accounts.
                shipFit.FittingHash = Security.GenerateHash(concatComponents, accountId.ToString());
            }
            else
            {
                // There are no components so generate a random hash.
                shipFit.FittingHash = Security.GenerateHash(Security.GenerateRandomString(32), Security.GenerateSalt(6));
            }

            // Commit changes to the database.
            this.doctrineShipsRepository.UpdateShipFit(shipFit);
            this.doctrineShipsRepository.Save();
        }
        /// <summary>
        /// Adds a Doctrine Ships ship fit.
        /// </summary>
        /// <param name="name">The name of the ship fit. E.g. 'L33t Hax0r Brutix'</param>
        /// <param name="role">The role of the ship fit. E.g. 'DPS'</param>
        /// <param name="hull">The type of the hull. E.g. 'Brutix'</param>
        /// <param name="accountId">The account for which the ship fit should be added.</param>
        /// <returns>Returns a populated ship fit object or null if the process fails.</returns>
        internal ShipFit AddShipFit(string name, string role, string hull, int accountId)
        {
            int hullId = 0;
            ShipFit shipFit = null;

            // Does the hull name successfully resolve to an id?
            hullId = eveDataSource.GetTypeId(hull);

            if (hullId != 0)
            {
                shipFit = new ShipFit();

                shipFit.HullId = hullId;

                // Resolve the hull id back to the hull name to ensure that it is correct.
                shipFit.Hull = eveDataSource.GetTypeName(hullId);
                shipFit.AccountId = accountId;
                shipFit.ThumbnailImageUrl = eveDataSource.GetTypeImageUrl(hullId, 64);
                shipFit.RenderImageUrl = eveDataSource.GetTypeRenderImageUrl(hullId);
                shipFit.Name = name;
                shipFit.Role = role;
                shipFit.ContractsAvailable = 0;
                shipFit.IsMonitored = false;
                shipFit.FitPackagedVolume = 0;
                shipFit.BuyPrice = 0;
                shipFit.SellPrice = 0;
                shipFit.ShippingCost = 0;
                shipFit.ContractReward = 0;
                shipFit.BuyOrderProfit = 0;
                shipFit.SellOrderProfit = 0;
                shipFit.FittingString = string.Empty;
                shipFit.FittingHash = string.Empty;
                shipFit.Notes = string.Empty;
                shipFit.LastPriceRefresh = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1));

                if (this.doctrineShipsValidation.ShipFit(shipFit).IsValid == true)
                {
                    // Add the new ship fit and read it back to get the auto generated primary key id.
                    shipFit = this.doctrineShipsRepository.CreateShipFit(shipFit);
                    this.doctrineShipsRepository.Save();
                }
            }

            return shipFit;
        }
 /// <summary>
 /// Updates a ship fit for a particular account.
 /// </summary>
 /// <param name="shipFit">A partially populated ship fit object to be updated.</param>
 /// <returns>Returns a validation result object.</returns>
 public IValidationResult UpdateShipFit(ShipFit shipFit)
 {
     return ShipFitManager.UpdateShipFit(shipFit);
 }
 public IValidationResult ShipFit(ShipFit shipFit)
 {
     return ShipFitCheck.ShipFit(shipFit);
 }