public void Add(AssetList list) { foreach(Asset asset in list) { this.Add(asset); } }
/// <summary> /// This ensures that items in sell orders appear in the list of the player's assets. /// It is called just after new asset XML from the API has been processed but before /// the update is applied to the database. /// </summary> public static void ProcessSellOrders(EMMADataSet.AssetsDataTable assetData, AssetList changes, long ownerID) { List<int> itemIDs = new List<int>(); itemIDs.Add(0); List<long> stationIDs = new List<long>(); stationIDs.Add(0); List<AssetAccessParams> accessParams = new List<AssetAccessParams>(); accessParams.Add(new AssetAccessParams(ownerID)); // Get active sell orders OrdersList sellOrders = Orders.LoadOrders(accessParams, itemIDs, stationIDs, 999, "Sell"); EMMADataSet.AssetsRow changedAsset = null; // Note that modifiedAssets is indexed first by itemID and second by stationID Dictionary<int, Dictionary<long, AssetInfo>> modifiedAssets = new Dictionary<int, Dictionary<long, AssetInfo>>(); foreach (Order sellOrder in sellOrders) { bool foundMatch = false; long assetID = 0; // If there is already an asset row with a state of 'ForSaleViaMarket' in the same location, // and with the same item type then check quantity. // If it matches then just set to processed and move on. // If it does not then record the difference in quantities and go to the next order. // If we can't find a match then add a new asset row and record the items gained. if (Assets.AssetExists(assetData, ownerID, sellOrder.StationID, sellOrder.ItemID, (int)AssetStatus.States.ForSaleViaMarket, false, 0, false, false, true, true, true, 0, ref assetID)) { foundMatch = true; } else { DataRow[] data = assetData.Select("ItemID = " + sellOrder.ItemID + " AND OwnerID = " + ownerID.ToString() + " AND LocationID = " + sellOrder.StationID + " AND Status = " + (int)AssetStatus.States.ForSaleViaMarket); if (data != null && data.Length > 0) { foundMatch = true; assetID = ((EMMADataSet.AssetsRow)data[0]).ID; } } if (foundMatch) { changedAsset = assetData.FindByID(assetID); if (changedAsset.Quantity != sellOrder.RemainingVol) { // If the quantities do not match then store how many units we are removing // from the stack, the most likely cause is more than one sell order for // this item in this location and if we know how many units we've removed // We can make sure that the other order(s) quantity matches up. Dictionary<long, AssetInfo> itemDeltaVol = new Dictionary<long, AssetInfo>(); if (modifiedAssets.ContainsKey(sellOrder.ItemID)) { itemDeltaVol = modifiedAssets[sellOrder.ItemID]; } else { modifiedAssets.Add(sellOrder.ItemID, itemDeltaVol); } if (itemDeltaVol.ContainsKey(sellOrder.StationID)) { AssetInfo info = itemDeltaVol[sellOrder.StationID]; info.quantity += sellOrder.RemainingVol - changedAsset.Quantity; itemDeltaVol[sellOrder.StationID] = info; changedAsset.Quantity += sellOrder.RemainingVol; } else { AssetInfo info = new AssetInfo(); info.quantity = sellOrder.RemainingVol - changedAsset.Quantity; info.assetID = changedAsset.ID; itemDeltaVol.Add(sellOrder.StationID, info); changedAsset.Quantity = sellOrder.RemainingVol; } } changedAsset.Processed = true; // Also set it to processed in the database. SetProcessedFlag(changedAsset.ID, true); } // We havn't managed to match the order to an existing 'ForSaleViaMarket' stack in // the database or in memory. // As such, we need to create a new one. if (!foundMatch) { // Create the new asset row.. changedAsset = assetData.NewAssetsRow(); changedAsset.AutoConExclude = true; changedAsset.ContainerID = 0; changedAsset.CorpAsset = false; // Set cost to zero for now, it will be worked out later when gains/losses are reconciled. changedAsset.Cost = 0; changedAsset.CostCalc = false; changedAsset.IsContainer = false; changedAsset.ItemID = sellOrder.ItemID; changedAsset.EveItemID = 0; changedAsset.LocationID = sellOrder.StationID; changedAsset.OwnerID = sellOrder.OwnerID; changedAsset.Processed = true; changedAsset.Quantity = sellOrder.RemainingVol; changedAsset.RegionID = sellOrder.RegionID; changedAsset.ReprocExclude = true; changedAsset.SystemID = sellOrder.SystemID; changedAsset.BoughtViaContract = false; changedAsset.Status = (int)AssetStatus.States.ForSaleViaMarket; assetData.AddAssetsRow(changedAsset); // Store the changes we are making to quantities Dictionary<long, AssetInfo> itemDeltaVol = new Dictionary<long, AssetInfo>(); if (modifiedAssets.ContainsKey(sellOrder.ItemID)) { itemDeltaVol = modifiedAssets[sellOrder.ItemID]; } else { modifiedAssets.Add(sellOrder.ItemID, itemDeltaVol); } if (itemDeltaVol.ContainsKey(sellOrder.StationID)) { AssetInfo info = itemDeltaVol[sellOrder.StationID]; info.quantity += sellOrder.RemainingVol; itemDeltaVol[sellOrder.StationID] = info; } else { AssetInfo info = new AssetInfo(); info.quantity = sellOrder.RemainingVol; info.assetID = changedAsset.ID; itemDeltaVol.Add(sellOrder.StationID, info); } } } // Once we've finished processing all the orders, store the overall quantity changes. Dictionary<int, Dictionary<long, AssetInfo>>.Enumerator enumerator = modifiedAssets.GetEnumerator(); while (enumerator.MoveNext()) { Dictionary<long, AssetInfo>.Enumerator enumerator2 = enumerator.Current.Value.GetEnumerator(); while(enumerator2.MoveNext()) { Asset change = new Asset(); change.ID = enumerator2.Current.Value.assetID; change.ItemID = enumerator.Current.Key; change.LocationID = enumerator2.Current.Key; change.Quantity = enumerator2.Current.Value.quantity; change.StatusID = (int)AssetStatus.States.ForSaleViaMarket; change.IsContainer = false; change.Container = null; change.AutoConExclude = true; change.OwnerID = ownerID; change.UnitBuyPrice = 0; change.UnitBuyPricePrecalculated = false; changes.Add(change); } } }
private void DisplayAssets() { if (ContinueWithoutSave()) { Cursor = Cursors.WaitCursor; try { _change = false; _modifiedIndicies = new List<int>(); _itemID = short.Parse(cmbItem.Tag.ToString()); long locationID = 0, systemID = 0; List<long> regionIDs = new List<long>(); Asset container = null; BuildAccessList(); if (assetsTree.SelectedNode != null) { AssetViewNode tag = assetsTree.SelectedNode.Tag as AssetViewNode; if (tag != null) { switch (tag.Type) { case AssetViewNodeType.All: break; case AssetViewNodeType.Region: regionIDs.Add((long)tag.Id); break; case AssetViewNodeType.System: systemID = (long)tag.Id; break; case AssetViewNodeType.Station: locationID = (long)tag.Id; break; case AssetViewNodeType.Container: container = tag.Data as Asset; break; default: break; } } } //ListSortDirection sortDirection = ListSortDirection.Descending; //DataGridViewColumn sortColumn = AssetsGrid.SortedColumn; //if (AssetsGrid.SortOrder == SortOrder.Ascending) sortDirection = ListSortDirection.Ascending; List<SortInfo> sortInfo = AssetsGrid.GridSortInfo; if (container == null) { _assets = Assets.LoadAssets(_accessParams, regionIDs, _itemID, locationID, systemID, false, 0, true, false); } else { _assets = Assets.LoadAssets(container, _itemID); } _assetsBindingSource.DataSource = _assets; //AssetsGrid.AutoResizeColumns(); //AssetsGrid.AutoResizeRows(); //if (sortColumn != null) //{ // AssetsGrid.Sort(sortColumn, sortDirection); //} AssetsGrid.GridSortInfo = sortInfo; Text = "Viewing " + _assetsBindingSource.Count + " assets"; } finally { Cursor = Cursors.Default; } } }
public Asset(EMMADataSet.AssetsRow dataRow) { if (dataRow != null) { _id = dataRow.ID; _ownerID = dataRow.OwnerID; if (dataRow.CorpAsset) { _corpAsset = true; _ownerID = UserAccount.CurrentGroup.GetCharacter(_ownerID).CorpID; } _locationID = dataRow.LocationID; _itemID = dataRow.ItemID; _quantity = dataRow.Quantity; _autoConExclude = dataRow.AutoConExclude; _reprocExclude = dataRow.ReprocExclude; _processed = dataRow.Processed; _statusID = dataRow.Status; _isContainer = dataRow.IsContainer; _container = null; _containerID = dataRow.ContainerID; _regionID = dataRow.RegionID; _systemID = dataRow.SystemID; _contents = new AssetList(); _unitBuyPrice = dataRow.Cost; _pureUnitBuyPrice = _unitBuyPrice; _gotUnitBuyPrice = dataRow.CostCalc; _unitBuyPricePrecalc = dataRow.CostCalc; _eveItemInstanceID = dataRow.EveItemID; } }
private static void LookForAssetMatch(Contract contract, bool updateAssets, ref long qToFind, ref decimal itemBuyPrice, AssetList assets, bool ignoreOwner) { foreach (Asset a in assets) { if (ignoreOwner || a.OwnerID == contract.OwnerID) { if (qToFind > 0) { long deltaQ = Math.Min(qToFind, a.Quantity); itemBuyPrice += a.UnitBuyPrice * deltaQ; qToFind -= deltaQ; a.Quantity -= deltaQ; // Update the database with changes to the asset row. if (updateAssets) { EMMADataSet.AssetsRow data = Assets.GetAssetDetail(a.ID); data.Quantity -= deltaQ; if (data.Quantity == 0) { data.Delete(); } Assets.UpdateDatabase(data); } } } } }
/// <summary> /// Recursive method to update the supplied assets data table based upon the supplied xml node list. /// </summary> /// <param name="assetData"></param> /// <param name="assetList"></param> /// <param name="locationID"></param> /// <param name="corc"></param> /// <param name="containerID"></param> /// <param name="expectedChanges"></param> private void UpdateAssets(EMMADataSet.AssetsDataTable assetData, XmlNodeList assetList, long locationID, CharOrCorp corc, long containerID, AssetList changes) { int counter = 0; if (containerID == 0) { UpdateStatus(counter, assetList.Count, "Getting asset data from file", "", false); } else { UpdateStatus(-1, -1, "Getting asset data from file", "", false, counter, assetList.Count, "Container progress"); } foreach (XmlNode asset in assetList) { int itemID; long assetID = 0, eveInstanceID, quantity; bool isContainer = false, needNewRow = false; XmlNode locationNode = asset.SelectSingleNode("@locationID"); if (locationNode != null) { locationID = long.Parse(locationNode.Value); // Translate location ID from a corporate office to a station ID if required. if (locationID >= 66000000 && locationID < 67000000) { // NPC station. locationID -= 6000001; } if (locationID >= 67000000 && locationID < 68000000) { // Conquerable station. locationID -= 6000000; } } itemID = int.Parse(asset.SelectSingleNode("@typeID").Value, System.Globalization.CultureInfo.InvariantCulture.NumberFormat); eveInstanceID = long.Parse(asset.SelectSingleNode("@itemID").Value, System.Globalization.CultureInfo.InvariantCulture.NumberFormat); quantity = long.Parse(asset.SelectSingleNode("@quantity").Value, System.Globalization.CultureInfo.InvariantCulture.NumberFormat); if (asset.LastChild != null && asset.LastChild.Name.Equals("rowset")) { isContainer = true; } EMMADataSet.AssetsRow assetRow; needNewRow = true; // Note that if a match is not found for the specific eve instance ID we pass in then // EMMA will automatically search for an asset matching all the other parameters. if (Assets.AssetExists(assetData, corc == CharOrCorp.Corp ? _corpID : _charID, locationID, itemID, (int)AssetStatus.States.Normal, containerID != 0, containerID, isContainer, false, !isContainer, false, true, eveInstanceID, ref assetID)) { needNewRow = false; } else if(!isContainer) { // We havn't actually updated the database with anything yet so we may already have a // matching item stack in memory but not in the database. Check for that here. DataRow[] data = assetData.Select("ItemID = " + itemID + " AND OwnerID = " + _charID + " AND CorpAsset = " + (corc == CharOrCorp.Corp ? 1 : 0) + " AND LocationID = " + locationID + " AND Status = " + (int)AssetStatus.States.Normal + " AND ContainerID = " + containerID + " AND EveItemID = " + eveInstanceID); if (data != null && data.Length > 0) { needNewRow = false; assetID = ((EMMADataSet.AssetsRow)data[0]).ID; } } Asset change = null; if (!needNewRow) { assetRow = assetData.FindByID(assetID); if (assetRow.Processed) { // Row is already in the database but has been processed so just add the current // quantity to the row. // (i.e. there are multiple stacks of the same item in the same location in-game // EMMA merges these since we don't care how things are stacked and it makes // things a little easier.) assetRow.Quantity = assetRow.Quantity + quantity; // We're stacking multiple eve item instances so just set the eve item ID to zero. assetRow.EveItemID = 0; // Store the changes that are being made to the quantity of // items here. // This means that once the update processing is complete, we // can try and work out where these items came from. #region Remember changes to item quantities changes.ItemFilter = "ID = " + assetRow.ID; if (changes.FiltredItems.Count > 0) { change = (Asset)changes.FiltredItems[0]; change.Quantity += quantity; change.EveItemInstanceID = 0; if (change.Quantity == 0) { changes.ItemFilter = ""; changes.Remove(change); } } else { change = new Asset(assetRow); change.Quantity = quantity; change.Processed = false; changes.Add(change); } #endregion } else { if (assetRow.Quantity == quantity) { // The row already exists in the database and quantity is the same so // set the processed flag on the database directly and remove the row // from the dataset without setting it to be deleted when the database // is updated. // Note the processed flag MUST be set on the database for later routines // to work correctly. (e.g. Assets.ProcessSellOrders) if (assetRow.EveItemID != 0) { Assets.SetProcessedFlag(assetID, true); assetData.RemoveAssetsRow(assetRow); } else { // If Eve instance ID is not yet set then set it. Assets.SetProcessedFlag(assetID, true); assetRow.Processed = true; assetRow.EveItemID = eveInstanceID; } } else if (assetRow.Quantity != quantity) { // The row already exists in the database, has not yet been processed // and the quantity does not match what we've got from the XML. // Store the changes that are being made to the quantity of // items here. // This means that once the update processing is complete, we // can try and work out where these items came from. #region Remember changes to item quantities change = new Asset(assetRow); change.Quantity = quantity - assetRow.Quantity; change.EveItemInstanceID = eveInstanceID; change.Processed = false; changes.Add(change); #endregion // All we need to do is update the quantity and set the processed flag. assetRow.Quantity = quantity; assetRow.Processed = true; assetRow.EveItemID = eveInstanceID; // Also set the processed flag on the database directly. This will // stop us from picking up this row later on (e.g. Assets.ProcessSellOrders) Assets.SetProcessedFlag(assetID, true); } } } else { // The row does not currently exist in the database so we need to create it. assetRow = assetData.NewAssetsRow(); //assetRow.OwnerID = _charID; assetRow.OwnerID = corc == CharOrCorp.Corp ? _corpID : _charID; assetRow.CorpAsset = corc == CharOrCorp.Corp; assetRow.ItemID = itemID; assetRow.EveItemID = eveInstanceID; assetRow.LocationID = locationID; assetRow.Status = 1; assetRow.Processed = true; assetRow.AutoConExclude = false; assetRow.ReprocExclude = false; assetRow.Cost = 0; assetRow.CostCalc = false; assetRow.BoughtViaContract = false; long systemID = 0, regionID = 0; if (locationID >= 30000000 && locationID < 40000000) { systemID = locationID; EveDataSet.mapSolarSystemsRow system = SolarSystems.GetSystem(locationID); if (system != null) { regionID = system.regionID; } else { new EMMAEveAPIException(ExceptionSeverity.Warning, "Asset row added with unknown " + "solar system ID (" + locationID + ")"); } } else { EveDataSet.staStationsRow station = null; try { station = Stations.GetStation(locationID); } catch (EMMADataMissingException) { } if (station != null) { systemID = station.solarSystemID; regionID = station.regionID; } else { new EMMAEveAPIException(ExceptionSeverity.Warning, "Asset row added with unknown " + "station ID (" + locationID + ")"); } } assetRow.SystemID = systemID; assetRow.RegionID = regionID; assetRow.Quantity = quantity; assetRow.ContainerID = containerID; assetRow.IsContainer = isContainer; if (isContainer) { // If this asset is a container and has child assets then we must add it to the // database now and get the correct ID number. // (Because IDs are assigned by the database itself) assetID = Assets.AddRowToDatabase(assetRow); } else { // Otherwise, we can just add it to the data table to be stored later along with // everything else. assetData.AddAssetsRow(assetRow); } // Store the changes that are being made to the quantity of // items here. // This means that once the update processing is complete, we // can try and work out where these items came from. #region Remember changes to item quantities change = new Asset(assetRow); if (isContainer) { change.ID = assetID; } change.Quantity = quantity; change.Processed = false; changes.Add(change); #endregion } if (isContainer) { XmlNodeList contained = asset.SelectNodes("rowset/row"); UpdateAssets(assetData, contained, locationID, corc, assetID, changes); } counter++; if (containerID == 0) { UpdateStatus(counter, assetList.Count, "Getting asset data from file", "", false); } else { UpdateStatus(-1, -1, "Getting asset data from file", "", false, counter, assetList.Count, "Container progress"); } } }
/// <summary> /// This is called after an import of XML asset data but before the changes are commited /// to the database. /// The aim is to try to work out which assets have simply moved location and which have /// been added or lost. Additionally, if items have moved, update the cost of the item /// stack appropriately. /// </summary> /// <param name="assetData">The datatable containing the changes that will be applied to the assets database</param> /// <param name="charID"></param> /// <param name="corp"></param> /// <param name="changes">Contains changes in quantities of item stacks that were in the XML.</param> /// <param name="gained">A list of items that have been gained from 'nowhere'</param> /// <param name="lost">A list of items that have been totally lost from the owner's asset data.</param> public static void AnalyseChanges(EMMADataSet.AssetsDataTable assetData, long ownerID, AssetList changes, out AssetList gained, out AssetList lost) { // Note that 'changes' will only include items that exist in the XML from the API. i.e. Any // stacks that have been completely removed from a location will not show up. // To get these removed assets, we need to retrieve any 'unprocessed' assets from the // assetData table. gained = new AssetList(); lost = new AssetList(); // Add any unprocessed asset stacks to the 'changes' collection. // Although the main data changes have not yet been supplied to the database, // the processed flags have been set for the relevant asset rows. // This means that we can get the list of unprocessed assets direct from // the database. List<AssetAccessParams> accessParams = new List<AssetAccessParams>(); accessParams.Add(new AssetAccessParams(ownerID)); EMMADataSet.AssetsDataTable unprocMatches = new EMMADataSet.AssetsDataTable(); Assets.GetAssets(unprocMatches, accessParams, 0, 0, 0, 0, false); foreach (EMMADataSet.AssetsRow unprocMatch in unprocMatches) { Asset change = new Asset(unprocMatch); // Ignore any assets 'for sale via contract' or 'in transit' if (change.Quantity != 0 && change.StatusID != (int)AssetStatus.States.ForSaleViaContract && change.StatusID != (int)AssetStatus.States.InTransit) { change.Quantity *= -1; // These assets are effectively missing so invert the quantity. changes.Add(change); } } // Note 'changes2' is a list of the same items as 'changes'. // It is needed because the filter functionallity changes the list which we cannot // do within the main foreach loop. AssetList changes2 = new AssetList(); foreach (Asset change in changes) { changes2.Add(change); } // See if any of our 'missing' assets match transactions that are marked to have thier profit // calculated during an assets update. #region Update transactions with CalcProfitFromAssets flag EMMADataSet.TransactionsDataTable transData = new EMMADataSet.TransactionsDataTable(); Transactions.AddTransByCalcProfitFromAssets(transData, UserAccount.CurrentGroup.GetFinanceAccessParams(APIDataType.Transactions), 0, true); foreach (EMMADataSet.TransactionsRow trans in transData) { long quantityRemaining = trans.Quantity; decimal totalBuyPrice = 0; changes.ItemFilter = "ItemID = " + trans.ItemID + " AND Quantity < 0"; foreach (Asset change in changes.FiltredItems) { // If we get a match then use the missing items's cost to calculate the // transaction's profit. // Note that we don't need to adjust any item quantities since either the // changes have already been made or the item stack is 'unprocessed' and will // be cleared out anyway. long deltaQ = Math.Min(Math.Abs(change.Quantity), quantityRemaining); // Adjust the quantity of the 'missing' items. change.Quantity += deltaQ; quantityRemaining -= deltaQ; // Because this transaction's asset quantity change will have been made // back when the transaction was processed, we will have some unexpected // added items as well. // // E.g. Consider station A and B. At A, there are 2 units of item X, at B // there is nothing. // At a later date, the player moves 2 of X from A to B and sells it. // When the sell transaction is processed, station B will be set to -2 // units of X and the transaction will be set as 'CalcProfitFromAssets'. // When the asset update occurs, it will show zero for both locations so // they will be unprocessed. // This will result in 2 unexplained units gained at station B and 2 lost // at station A. (We've gone from A=2,B=-2 to A=0 B=0) changes2.ItemFilter = "ItemID = " + trans.ItemID + " AND LocationID = " + trans.StationID + " AND Status = 1"; if (changes2.FiltredItems.Count > 0) { // We've already accounted for the cost of items, etc so just reduce the // quantity. changes2[0].Quantity -= deltaQ; } totalBuyPrice += (change.UnitBuyPrice * deltaQ); if (quantityRemaining != trans.Quantity) { // We've found enough missing items to match this transaction either completely // or partially so calculate it's profit and set it as completed. trans.CalcProfitFromAssets = false; trans.SellerUnitProfit = trans.Price - (totalBuyPrice / trans.Quantity); } } } /* foreach (Asset change in changes) { // Note: because we are changing quantity within the foreach loop // we don't use the filter on the AssetList. // Instead, just use this if condition each time around. if (change.Quantity < 0 && !noTransItemIDs.Contains(change.ItemID)) { // If we get a match then use the missing items's cost to calculate the // transaction's profit. // Note that we don't need to adjust any item quantities since either the // changes have already been made or the item stack is 'unprocessed' and will // be cleared out anyway. Transactions.AddTransByCalcProfitFromAssets(transData, UserAccount.CurrentGroup.GetFinanceAccessParams(APIDataType.Transactions), change.ItemID, true); if (transData.Count == 0) { noTransItemIDs.Add(change.ItemID); } foreach (EMMADataSet.TransactionsRow trans in transData) { if (trans.ItemID == change.ItemID && !completedTrans.Contains(trans.ID)) { long quantityRemaining = trans.Quantity; TransProcessData data = new TransProcessData(); if (processData.ContainsKey(trans.ID)) { data = processData[trans.ID]; quantityRemaining = data.QuantityRemaining; } else { data.QuantityMatched = 0; data.QuantityRemaining = trans.Quantity; data.TotalBuyPrice = 0; processData.Add(trans.ID, data); } long deltaQ = Math.Min(Math.Abs(change.Quantity), quantityRemaining); // Adjust the quantity of the 'missing' items. change.Quantity += deltaQ; // Because this transaction's asset quantity change will have been made // back when the transaction was processed, we will have some unexpected // added items as well. // // E.g. Consider station A and B. At A, there are 2 units of item X, at B // there is nothing. // At a later date, the player moves 2 of X from A to B and sells it. // When the sell transaction is processed, station B will be set to -2 // units of X and the transaction will be set as 'CalcProfitFromAssets'. // When the asset update occurs, it will show zero for both locations so // they will be unprocessed. // This will result in 2 unexplained units gained at station B and 2 lost // at station A. (We've gone from A=2,B=-2 to A=0 B=0) changes2.ItemFilter = "ItemID = " + trans.ItemID + " AND LocationID = " + trans.StationID; foreach (Asset change2 in changes2) { if (change2.Quantity > 0) { // We've already accounted for the cost of items, etc so just reduce the // quantity. change2.Quantity -= deltaQ; } } data.QuantityRemaining = data.QuantityRemaining - deltaQ; data.QuantityMatched = data.QuantityMatched + deltaQ; data.TotalBuyPrice = data.TotalBuyPrice + (change.UnitBuyPrice * deltaQ); if (data.QuantityRemaining == 0) { // We've found enough missing items to match this transaction completely // so calculate it's profit and set it as completed. trans.CalcProfitFromAssets = false; trans.SellerUnitProfit = trans.Price - (data.TotalBuyPrice / data.QuantityMatched); completedTrans.Add(trans.ID); if (uncompletedTrans.Contains(trans.ID)) { uncompletedTrans.Remove(trans.ID); } } else { // We havn't found enough missing items to completely match this transaction // yet so add to to the list of uncompleted transactions. uncompletedTrans.Add(trans.ID); } } } } } // Calculate profits as best we can for any 'uncompleted' transactions. // i.e. those that we did not have enough missing items to match completely. foreach (long transID in uncompletedTrans) { EMMADataSet.TransactionsRow trans = transData.FindByID(transID); if (trans != null && processData.ContainsKey(transID)) { TransProcessData data = processData[transID]; trans.CalcProfitFromAssets = false; trans.SellerUnitProfit = trans.Price - (data.TotalBuyPrice / data.QuantityMatched); } } * */ // Update transactions database Transactions.Store(transData); #endregion // Work through the list of changes. // // If items have been added then see if there is a matching quantity that has been removed // somwhere. If so, use the old asset stack cost to set the cost for the new asset stack. // If we can't find a match for any added items then add them to the 'gained' list. // // By definititon, any items that have been removed and match stacks added elsewhere will // be matched by the above process. Any removed items that are left over are added to the // 'lost' list of assets. changes.ItemFilter = ""; // If we're in manufacturing mode then we don't want to try and match // lost assets with gained assets until after the user has selected // what has been built, etc. if (!UserAccount.Settings.ManufacturingMode) { #region Try and match gains in one place against losses in another. List<int> zeroLossItemIDs = new List<int>(); foreach (Asset change in changes) { if (change.Quantity > 0 && !zeroLossItemIDs.Contains(change.ItemID)) { int itemID = change.ItemID; long locationID = change.LocationID; changes2.ItemFilter = "ItemID = " + itemID + " AND Quantity < 0"; if (changes2.FiltredItems.Count == 0) { if (!zeroLossItemIDs.Contains(change.ItemID)) { zeroLossItemIDs.Add(change.ItemID); } } foreach (Asset change2 in changes2.FiltredItems) { if (change.Quantity > 0 && change2.Quantity < 0) { // Get the asset data lines associated with the two changes in asset quantities // that we have found. //bool got1 = Assets.AssetExists(assetData, charID, corp, locationID, itemID, // change.StatusID, change.ContainerID != 0, change.ContainerID, change.IsContainer, // true, true, change.AutoConExclude, ref assetID1); //bool got2 = Assets.AssetExists(assetData, charID, corp, change2.LocationID, itemID, // change2.StatusID, change2.ContainerID != 0, change2.ContainerID, change2.IsContainer, // true, true, change2.AutoConExclude, ref assetID2); Assets.AddAssetToTable(assetData, change.ID); Assets.AddAssetToTable(assetData, change2.ID); EMMADataSet.AssetsRow row1 = assetData.FindByID(change.ID); EMMADataSet.AssetsRow row2 = assetData.FindByID(change2.ID); Asset a1 = new Asset(row1, null); Asset a2 = new Asset(row2, null); long thisAbsDeltaQ = Math.Min(Math.Abs(change.Quantity), Math.Abs(change2.Quantity)); // If the rows are processed then the actual movement of items has already happened // so we don't need to adjust quantities. // If they are not processed then we need to adjust the quantities now. if (!row1.Processed) { row1.Quantity += thisAbsDeltaQ; } if (!row2.Processed) { row2.Quantity -= thisAbsDeltaQ; } // If the stack we're adding to now has zero items in it then we can just // remove it. Otherwise we need to work out the value of the new stack. if (row1.Quantity > 0) { // Calculate the cost of items in the new stack based on the // cost of items from the old stack. decimal newCost = 0; newCost = ((a1.TotalBuyPrice) + (a2.UnitBuyPrice * thisAbsDeltaQ)) / (a1.Quantity + thisAbsDeltaQ); row1.Cost = newCost; row1.CostCalc = true; } else if (row1.Quantity == 0) { row1.Delete(); } if (row2.Quantity == 0) { row2.Delete(); } change.Quantity -= thisAbsDeltaQ; change2.Quantity += thisAbsDeltaQ; } } } } #endregion } // We have some items left over that could not be accounted for from losses/gains // elsewhere. Add these to the appropriate 'lost' or 'gained' list. #region Add remaining unexplained changes to the appropriate lost/gained list foreach (Asset change in changes) { if (change.Quantity != 0) { Asset unexplained = new Asset(); unexplained.ID = change.ID; unexplained.ItemID = change.ItemID; unexplained.LocationID = change.LocationID; unexplained.Quantity = change.Quantity; unexplained.StatusID = change.StatusID; unexplained.IsContainer = change.IsContainer; unexplained.Container = change.Container; unexplained.AutoConExclude = change.AutoConExclude; unexplained.OwnerID = change.OwnerID; if (change.UnitBuyPricePrecalculated) { unexplained.UnitBuyPrice = change.UnitBuyPrice; unexplained.UnitBuyPricePrecalculated = true; } else { unexplained.UnitBuyPrice = 0; unexplained.UnitBuyPricePrecalculated = false; } if (change.Quantity > 0) { // If the unexplained assets are for sale via contract or in transit then we // would expect them not to show up if they are in the same state as before. // This being the case, we do not need to add them to the list of unexplained items. if (change.StatusID != (int)AssetStatus.States.ForSaleViaContract && change.StatusID != (int)AssetStatus.States.InTransit) { gained.Add(unexplained); } } else { // If the unexplained assets are for sale via contract or in transit then we // would expect them not to show up if they are in the same state as before. // This being the case, we do not need to add them to the list of unexplained items. if (change.StatusID != (int)AssetStatus.States.ForSaleViaContract && change.StatusID != (int)AssetStatus.States.InTransit) { lost.Add(unexplained); } } } } #endregion }
/// <summary> /// Update the assets table based on the transactions meeting the specified criteria. /// </summary> /// <param name="charID"></param> /// <param name="corpID"></param> /// <param name="useCorp"></param> /// <param name="minimumTransID"></param> /// <param name="includeTransAfter"></param> /// <returns></returns> private static long UpdateFromTransactions(EMMADataSet.AssetsDataTable assetsData, AssetList changes, long charID, long corpID, bool useCorp, long minimumTransID, DateTime includeTransAfter) { long maxID = 0; long ownerID = useCorp ? corpID : charID; EMMADataSet.TransactionsDataTable transactions = new EMMADataSet.TransactionsDataTable(); transactions = GetTransactions(charID, corpID, useCorp, minimumTransID, includeTransAfter); foreach (EMMADataSet.TransactionsRow trans in transactions) { // If the ID is greater than 9000000000000000000 then it must have been created by EMMA as part of // an item exchange contract. These should be ignored here. if (trans.ID < 9000000000000000000) { int deltaQuantity = trans.Quantity; if (trans.SellerID == ownerID) { deltaQuantity *= -1; } // Change this to not actually make the change in the database. Instead, use the // asset data table passed in and record the changes made in the 'changes' list. /*ChangeAssets(charID, useCorp, trans.StationID, trans.ItemID, 0, (int)AssetStatus.States.Normal, false, deltaQuantity, (deltaQuantity > 0 ? trans.Price : 0), deltaQuantity > 0);*/ long assetID = 0; EMMADataSet.AssetsRow asset = null; AssetExists(assetsData, ownerID, trans.StationID, trans.ItemID, (int)AssetStatus.States.Normal, false, 0, false, false, true, false, true, 0, ref assetID); if (assetID != 0) { // Asset stack already exists in database and/or datatable, modify it // based upon the transaction data. asset = assetsData.FindByID(assetID); asset.Quantity += deltaQuantity; if (deltaQuantity > 0) { Asset logicalAsset = new Asset(asset); asset.CostCalc = true; asset.Cost = (logicalAsset.TotalBuyPrice + (trans.Price * trans.Quantity)) / (logicalAsset.Quantity + trans.Quantity); } Asset chg = new Asset(asset); chg.Quantity = deltaQuantity; changes.Add(chg); } else { // Asset does not exist in database so add it to the datatable. asset = assetsData.NewAssetsRow(); asset.Quantity = deltaQuantity; asset.AutoConExclude = false; asset.ContainerID = 0; asset.CorpAsset = useCorp; asset.Cost = trans.Price; asset.CostCalc = true; asset.IsContainer = false; asset.ItemID = trans.ItemID; asset.EveItemID = 0; asset.LocationID = trans.StationID; asset.OwnerID = charID; asset.Processed = true; asset.RegionID = trans.RegionID; asset.ReprocExclude = false; asset.Status = (int)AssetStatus.States.Normal; asset.SystemID = Stations.GetStation(trans.StationID).solarSystemID; asset.BoughtViaContract = false; assetsData.AddAssetsRow(asset); changes.Add(new Asset(asset)); } if (trans.ID > maxID) { maxID = trans.ID; } } } return maxID; }
public void PopulateLists() { if (!this.InvokeRequired) { this.StatusChange += new StatusChangeHandler(ViewUnacknowledgedAssets_StatusChange); Thread t0 = new Thread(new ThreadStart(PopulateLists)); t0.Start(); } else { HideData(); if (_lostAssets == null) { _lostAssets = new AssetList(); } if (_gainedAssets == null) { _gainedAssets = new AssetList(); } // Build complete lists of unacknowledged gained/lost assets for all // characters and corps within the report group. foreach (EVEAccount account in UserAccount.CurrentGroup.Accounts) { foreach (APICharacter character in account.Chars) { if (character.UnacknowledgedGains != null && character.UnacknowledgedGains.Count > 0) { _gainedAssets.Add(character.UnacknowledgedGains); character.UnacknowledgedGains = null; } if (character.CorpUnacknowledgedGains != null && character.CorpUnacknowledgedGains.Count > 0) { _gainedAssets.Add(character.CorpUnacknowledgedGains); character.CorpUnacknowledgedGains = null; } if (character.UnacknowledgedLosses != null && character.UnacknowledgedLosses.Count > 0) { _lostAssets.Add(character.UnacknowledgedLosses); character.UnacknowledgedLosses = null; } if (character.CorpUnacknowledgedLosses != null && character.CorpUnacknowledgedLosses.Count > 0) { _lostAssets.Add(character.CorpUnacknowledgedLosses); character.CorpUnacknowledgedLosses = null; } } } // Only cross check if we are not in manufacturing mode if (!UserAccount.Settings.ManufacturingMode) { CrossCheckAssetChanges(false); } ShowData(); this.StatusChange -= ViewUnacknowledgedAssets_StatusChange; } }
private void MaterialsFilterData() { if (this.InvokeRequired) { this.Invoke(new Callback(MaterialsFilterData)); } else { if (grpMaterials.Enabled) { this.Cursor = Cursors.WaitCursor; try { AssetList tmpAssets = new AssetList(); foreach (TempAssetKey material in lstMaterials.Items) { _lostAssets.ItemFilter = "ItemID = " + material.ItemID; foreach (Asset a in _lostAssets.FiltredItems) { tmpAssets.Add(a); } } lostItemsGrid.DataSource = tmpAssets; _lostAssets.ItemFilter = ""; } finally { this.Cursor = Cursors.Default; } } else { //SetContainerFilter(); //lostItemsGrid.DataSource = _lostAssets.FiltredItems; lostItemsGrid.DataSource = _lostAssets; } } }
private void ViewItemDetail_Load(object sender, EventArgs e) { try { chkOwners.ItemCheck += new ItemCheckEventHandler(chkOwners_ItemCheck); chkOwners.SelectedIndexChanged += new EventHandler(chkOwners_SelectedIndexChanged); RefreshCharList(); EveDataSet.invTypesDataTable allitems = UserAccount.CurrentGroup.TradedItems.GetAllItems(); ItemInfo[] info = new ItemInfo[allitems.Count]; for(int i = 0 ; i < allitems.Count; i++) { EveDataSet.invTypesRow item = allitems[i]; info[i] = new ItemInfo(item.typeID, item.typeName); } chkItems.Sorted = true; chkItems.Items.AddRange(info); DataGridViewCellStyle style = new DataGridViewCellStyle(BuyOrderPriceColumn.DefaultCellStyle); style.Format = IskAmount.FormatString(); BuyOrderPriceColumn.DefaultCellStyle = style; SellOrderPriceColumn.DefaultCellStyle = style; TransactionsPriceColumn.DefaultCellStyle = style; TransactionsTotalColumn.DefaultCellStyle = style; TransactionsGrossProfitColumn.DefaultCellStyle = style; TransactionsGrossUnitProfit.DefaultCellStyle = style; buyOrdersView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; buyOrdersView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; buyOrdersView.AutoGenerateColumns = false; BuyOrderDateTimeColumn.DataPropertyName = "Date"; BuyOrderItemColumn.DataPropertyName = "Item"; BuyOrderMovement12HoursColumn.DataPropertyName = "TwelveHourMovement"; BuyOrderMovement2DaysColumn.DataPropertyName = "TwoDayMovement"; BuyOrderMovement7DaysColumn.DataPropertyName = "SevenDayMovement"; BuyOrderOwnerColumn.DataPropertyName = "Owner"; BuyOrderPriceColumn.DataPropertyName = "Price"; BuyOrderRangeColumn.DataPropertyName = "RangeText"; BuyOrderRegionColumn.DataPropertyName = "Region"; BuyOrderRemainingUnits.DataPropertyName = "RemainingVol"; BuyOrderStationColumn.DataPropertyName = "Station"; BuyOrderStatus.DataPropertyName = "State"; BuyOrderSystemColumn.DataPropertyName = "System"; BuyOrderTotaUnits.DataPropertyName = "TotalVol"; BuyOrderPercentageCompleteColumn.DataPropertyName = "PercentageCompleted"; sellOrdersView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; sellOrdersView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; sellOrdersView.AutoGenerateColumns = false; SellOrderDateColumn.DataPropertyName = "Date"; SellOrderItemColumn.DataPropertyName = "Item"; SellOrderMovement12HoursColumn.DataPropertyName = "TwelveHourMovement"; SellOrderMovement2DaysColumn.DataPropertyName = "TwoDayMovement"; SellOrderMovement7DaysColumn.DataPropertyName = "SevenDayMovement"; SellOrderOwnerColumn.DataPropertyName = "Owner"; SellOrderPriceColumn.DataPropertyName = "Price"; SellOrderRangeColumn.DataPropertyName = "RangeText"; SellOrderRegionColumn.DataPropertyName = "Region"; SellOrderRemainingUnitsColumn.DataPropertyName = "RemainingVol"; SellOrderStationColumn.DataPropertyName = "Station"; SellOrderStatusColumn.DataPropertyName = "State"; SellOrderSystemColumn.DataPropertyName = "System"; SellOrderTotalUnitsColumn.DataPropertyName = "TotalVol"; SellOrderPercentageCompleteColumn.DataPropertyName = "PercentageCompleted"; SellOrderLocalStockAvailable.DataPropertyName = "LocalStockAvailable"; SellOrderMatchingBuyOrderExistsColumn.DataPropertyName = "BuyOrderExistsForThisItem"; transactionsView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; transactionsView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; transactionsView.AutoGenerateColumns = false; TransactionsBuyerCharacterColumn.DataPropertyName = "BuyerChar"; TransactionsBuyerColumn.DataPropertyName = "Buyer"; TransactionsBuyerWalletColumn.DataPropertyName = "BuyerWallet"; TransactionsDateTimeColumn.DataPropertyName = "Datetime"; TransactionsItemColumn.DataPropertyName = "Item"; TransactionsPriceColumn.DataPropertyName = "Price"; TransactionsQuantityColumn.DataPropertyName = "Quantity"; TransactionsSellerCharacterColumn.DataPropertyName = "SellerChar"; TransactionsSellerColumn.DataPropertyName = "Seller"; TransactionsSellerWalletColumn.DataPropertyName = "SellerWallet"; TransactionsStationColumn.DataPropertyName = "Station"; TransactionsTotalColumn.DataPropertyName = "Total"; TransactionsGrossProfitColumn.DataPropertyName = "GrossProfit"; TransactionsGrossUnitProfit.DataPropertyName = "GrossUnitProfit"; inventoryView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; inventoryView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; inventoryView.AutoGenerateColumns = false; InventoryItemColumn.DataPropertyName = "Item"; InventoryQuantityColumn.DataPropertyName = "Quantity"; InventoryRegionColumn.DataPropertyName = "Region"; InventoryLocationColumn.DataPropertyName = "Location"; InventorySystemColumn.DataPropertyName = "System"; InventoryOwnerColumn.DataPropertyName = "Owner"; _transactions = new TransactionList(); _inventory = new AssetList(); transactionsView.DataSource = _transactions; inventoryView.DataSource = _inventory; } catch (Exception ex) { EMMAException emmaEx = ex as EMMAException; if (emmaEx == null) { new EMMAException(ExceptionSeverity.Error, "Problem loading item detail view", ex); } MessageBox.Show("Problem loading item detail view:\r\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void UpdateInventory() { try { string groupBy = "None"; if (rdbOwner.Checked) { groupBy = "Owner"; } if (rdbRegion.Checked) { groupBy = "Region"; } if (rdbSystem.Checked) { groupBy = "System"; } Assets.BuildResults(_assetParams, _itemIDs, groupBy); _inventoryDataVisible = true; RefreshGUI(); int pageSize = 100; int startRow = 1; AssetList inventory = new AssetList(); while (Assets.GetResultsPage(startRow, pageSize, ref inventory)) { AddInventory(inventory); startRow += pageSize; inventory = new AssetList(); } AddInventory(inventory); _inventoryGettingData = false; RefreshGUI(); } catch (ThreadAbortException) { // User has aborted, just drop out. } catch (Exception ex) { new EMMAException(ExceptionSeverity.Error, "Error when updating inventory data in item detail", ex); } }
private void StartUpdate() { Cursor = Cursors.WaitCursor; try { _ordersDataVisible = false; _inventoryDataVisible = false; _transactionsDataVisible = false; _ordersGettingData = true; _inventoryGettingData = true; _transactionsGettingData = true; RefreshGUI(); _inventory = new AssetList(); _transactions = new TransactionList(); inventoryView.DataSource = _inventory; transactionsView.DataSource = _transactions; // Generate finance access parameters _finParams = new List<FinanceAccessParams>(); Dictionary<long, List<int>>.Enumerator enumerator = _useDataFrom.GetEnumerator(); while (enumerator.MoveNext()) { // If we are accessing all wallets for a corp then no need to bether with this // as the default is to access everything when a blank list is supplied. List<short> walletIDs = new List<short>(); if (enumerator.Current.Value.Count < 7) { foreach (short walletId in enumerator.Current.Value) { walletIDs.Add(walletId); } } _finParams.Add(new FinanceAccessParams(enumerator.Current.Key, walletIDs)); } // Generate asset access parameters _assetParams = new List<AssetAccessParams>(); foreach (object item in chkOwners.CheckedItems) { bool done = false; CharCorpOption owner = (CharCorpOption)item; foreach (AssetAccessParams character in _assetParams) { if (character.OwnerID == owner.Data.ID) { // If the specified ownerID is already in the access parameter list then // don't add it again. done = true; } } if (!done) { _assetParams.Add(new AssetAccessParams(owner.Data.ID)); } } _itemIDs = new List<int>(); foreach (object item in chkItems.CheckedItems) { _itemIDs.Add(((ItemInfo)item).ID); } _orderPlaceholderType = OrderPlaceholderType.None; if (rdbItemPlaceholders.Checked) { _orderPlaceholderType = OrderPlaceholderType.PerItem; } else if (rdbAllPlaceholders.Checked) { _orderPlaceholderType = OrderPlaceholderType.PerItemPerEntity; } // Kick off the threads that will do the updating of the data tables. _ordersUpdateThread = new Thread(new ThreadStart(UpdateOrders)); _ordersUpdateThread.Start(); _transactionsUpdateThread = new Thread(new ThreadStart(UpdateTransactions)); _transactionsUpdateThread.Start(); _inventoryUpdateThread = new Thread(new ThreadStart(UpdateInventory)); _inventoryUpdateThread.Start(); } catch (Exception ex) { new EMMAException(ExceptionSeverity.Error, "Error when starting data update in item detail", ex); } finally { Cursor = Cursors.Default; } }
private void AddInventory(AssetList inventory) { if (this.InvokeRequired) { AddInventoryCallback callback = new AddInventoryCallback(AddInventory); object[] parameters = new object[1]; parameters[0] = inventory; this.Invoke(callback, parameters); } else { foreach (Asset asset in inventory) { _inventory.Add(asset); } //inventoryView.Refresh(); } }
private void ViewAssets_Load(object sender, EventArgs e) { Diagnostics.ResetAllTimers(); try { Diagnostics.StartTimer("ViewAssets"); Diagnostics.StartTimer("ViewAssets.Part1"); DataGridViewCellStyle style = new DataGridViewCellStyle(CostColumn.DefaultCellStyle); style.Format = IskAmount.FormatString(); CostColumn.DefaultCellStyle = style; _assets = new AssetList(); _assetsBindingSource = new BindingSource(); _assetsBindingSource.DataSource = _assets; AssetsGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; AssetsGrid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; AssetsGrid.DataSource = _assetsBindingSource; OwnerColumn.DataPropertyName = "Owner"; ItemColumn.DataPropertyName = "Item"; LocationColumn.DataPropertyName = "Location"; QuantityColumn.DataPropertyName = "Quantity"; AutoConExcludeColumn.DataPropertyName = "AutoConExclude"; ReprocessorExcludeColumn.DataPropertyName = "ReprocessorExclude"; StatusColumn.DataPropertyName = "Status"; CostColumn.DataPropertyName = UserAccount.Settings.CalcCostInAssetView ? "UnitBuyPrice" : "PureUnitBuyPrice"; //_regularStyle = OwnerColumn.DefaultCellStyle.Clone(); //_inTransitStyle = OwnerColumn.DefaultCellStyle.Clone(); //_inTransitStyle.BackColor = Color.Yellow; UserAccount.Settings.GetColumnWidths(this.Name, AssetsGrid); _recentItems.Sort(); cmbItem.Items.AddRange(_recentItems.ToArray()); cmbItem.AutoCompleteSource = AutoCompleteSource.ListItems; cmbItem.AutoCompleteMode = AutoCompleteMode.Suggest; cmbItem.KeyDown += new KeyEventHandler(cmbItem_KeyDown); cmbItem.SelectedIndexChanged += new EventHandler(cmbItem_SelectedIndexChanged); cmbItem.Tag = 0; Diagnostics.StopTimer("ViewAssets.Part1"); Diagnostics.StartTimer("ViewAssets.Part2"); List<CharCorpOption> charcorps = UserAccount.CurrentGroup.GetCharCorpOptions(APIDataType.Assets); _corporateOwners = new List<long>(); _personalOwners = new List<long>(); foreach (CharCorpOption chop in charcorps) { if (chop.Corp) { _corporateOwners.Add(chop.CharacterObj.CorpID); } else { _personalOwners.Add(chop.CharacterObj.CharID); } } cmbOwner.DisplayMember = "Name"; cmbOwner.ValueMember = "Data"; charcorps.Sort(); cmbOwner.DataSource = charcorps; cmbOwner.SelectedValue = 0; cmbOwner.Enabled = false; cmbOwner.SelectedIndexChanged += new EventHandler(cmbOwner_SelectedIndexChanged); chkIngoreOwner.Checked = true; chkIngoreOwner.CheckedChanged += new EventHandler(chkIngoreOwner_CheckedChanged); chkCalcCost.Checked = UserAccount.Settings.CalcCostInAssetView; chkCalcCost.CheckedChanged += new EventHandler(chkCalcCost_CheckedChanged); Diagnostics.StopTimer("ViewAssets.Part2"); Diagnostics.StartTimer("ViewAssets.Part3"); //DisplayAssets(); BuildAccessList(); DisplayTree(); Diagnostics.StopTimer("ViewAssets.Part3"); assetsTree.AfterExpand += new TreeViewEventHandler(assetsTree_AfterExpand); assetsTree.AfterSelect += new TreeViewEventHandler(assetsTree_AfterSelect); this.FormClosing += new FormClosingEventHandler(ViewAssets_FormClosing); Diagnostics.StopTimer("ViewAssets"); Diagnostics.DisplayDiag("View assets setup time: " + Diagnostics.GetRunningTime("ViewAssets").ToString() + "\r\n Initalise: " + Diagnostics.GetRunningTime("ViewAssets.Part1").ToString() + "\r\n Setup owners: " + Diagnostics.GetRunningTime("ViewAssets.Part2").ToString() + "\r\n Display Tree: " + Diagnostics.GetRunningTime("ViewAssets.Part3").ToString()); } catch (Exception ex) { // Creating new EMMAexception will cause error to be logged. EMMAException emmaex = ex as EMMAException; if (emmaex == null) { emmaex = new EMMAException(ExceptionSeverity.Critical, "Error setting up assets form", ex); } MessageBox.Show("Problem setting up assets view.\r\nCheck " + Globals.AppDataDir + "Logging\\ExceptionLog.txt" + " for details.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Update the assets table based on the transactions meeting the specified criteria. /// </summary> /// <param name="charID"></param> /// <param name="corpID"></param> /// <param name="useCorp"></param> /// <param name="minimumTransID"></param> /// <returns></returns> public static long UpdateFromTransactions(EMMADataSet.AssetsDataTable assetsData, AssetList changes, long charID, long corpID, bool useCorp, long minimumTransID) { return UpdateFromTransactions(assetsData, changes, charID, corpID, useCorp, minimumTransID, DateTime.MaxValue); }
/// <summary> /// Update the assets table based on the transactions meeting the specified criteria. /// </summary> /// <param name="charID"></param> /// <param name="corpID"></param> /// <param name="useCorp"></param> /// <param name="includeTransAfter"></param> /// <returns></returns> public static long UpdateFromTransactions(EMMADataSet.AssetsDataTable assetsData, AssetList changes, long charID, long corpID, bool useCorp, DateTime includeTransAfter) { return UpdateFromTransactions(assetsData, changes, charID, corpID, useCorp, -1, includeTransAfter); }
private void RefreshItemList() { Cursor = Cursors.WaitCursor; try { DataGridViewColumn sortColumn = ItemsToReprocessView.SortedColumn; ListSortDirection sortDirection = ListSortDirection.Ascending; if (ItemsToReprocessView.SortOrder == SortOrder.Descending) { sortDirection = ListSortDirection.Descending; } _assets = new AssetList(); _reprocessJob = null; Asset container = null; if (cmbContainers.SelectedItem != null) { container = ((ContainerItem)cmbContainers.SelectedItem).Data; } if ((long)txtStation.Tag != 0 && cmbDefaultReprocessor.SelectedValue != null) { CharCorp charcorp = (CharCorp)cmbDefaultReprocessor.SelectedValue; long station = (long)txtStation.Tag; _reprocessJob = new ReprocessJob(station, UserAccount.CurrentGroup.ID, charcorp.ID); _reprocessJob.SetDefaultResultPrices(_resultPrices); if (container == null) { _assets = Assets.LoadReprocessableAssets(charcorp.ID, station, 1, false, true); } else { _assets = container.Contents; } foreach (Asset asset in _assets) { asset.ForceNoReproValAsUnitVal = true; } } ItemsToReprocessView.DataSource = _assets; decimal total = 0; foreach (Asset asset in _assets) { if (asset.Selected) { total += asset.TotalValue; } } lblValueBefore.Tag = total; lblValueBefore.Text = new IskAmount(total).ToString(); if (sortColumn != null) { ItemsToReprocessView.Sort(sortColumn, sortDirection); } } catch (Exception ex) { new EMMAException(ExceptionSeverity.Error, "Problem refreshing available assets", ex); MessageBox.Show("Problem refreshing available assets.\r\nSee Logging/exceptionlog.txt" + " for details.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { Cursor = Cursors.Default; } }
/// <summary> /// Return the assets stored at the specified station /// </summary> /// <param name="stationID"></param> /// <returns></returns> /*static public EMMADataSet.AssetsDataTable GetAssetsAt(List<AccessParams> accessParams, int stationID) { EMMADataSet.AssetsDataTable retVal = new EMMADataSet.AssetsDataTable(); assetsTableAdapter.FillByItemAndLocation(retVal, BuildAccessList(accessParams), "", stationID, 0); return retVal; }*/ public static AssetList GetAssets(List<AssetAccessParams> accessParams, int itemID, List<long> stationIDs, List<long> regionIDs, bool includeInTransit, bool includeContainers, bool includeSingletons) { AssetList retVal = new AssetList(); EMMADataSet.AssetsDataTable data = new EMMADataSet.AssetsDataTable(); if (regionIDs == null || regionIDs.Count == 0) { regionIDs = new List<long>(); regionIDs.Add(0); } if (stationIDs == null || stationIDs.Count == 0) { stationIDs = new List<long>(); stationIDs.Add(0); } StringBuilder regionString = new StringBuilder(""); StringBuilder stationString = new StringBuilder(""); foreach (int regionID in regionIDs) { if (regionString.Length > 0) { regionString.Append(","); } regionString.Append(regionID); } foreach (int stationID in stationIDs) { if (stationString.Length > 0) { stationString.Append(","); } stationString.Append(stationID); } lock (assetsTableAdapter) { assetsTableAdapter.FillByItem(data, AssetAccessParams.BuildAccessList(accessParams), regionString.ToString(), stationString.ToString(), itemID, includeInTransit, includeContainers, includeSingletons); } foreach (EMMADataSet.AssetsRow asset in data) { retVal.Add(new Asset(asset)); } return retVal; }
private void Reprocessor_Load(object sender, EventArgs e) { try { List<CharCorpOption> charcorps = UserAccount.CurrentGroup.GetCharCorpOptions(); cmbDefaultReprocessor.DisplayMember = "Name"; cmbDefaultReprocessor.ValueMember = "Data"; charcorps.Sort(); cmbDefaultReprocessor.DataSource = charcorps; cmbDefaultReprocessor.SelectedIndexChanged += new EventHandler(cmbDefaultReprocessor_SelectedIndexChanged); cmbDefaultReprocessor.SelectedIndex = 0; _recentStations = UserAccount.CurrentGroup.Settings.RecentStations; _recentStations.Sort(); AutoCompleteStringCollection stations = new AutoCompleteStringCollection(); stations.AddRange(_recentStations.ToArray()); txtStation.AutoCompleteCustomSource = stations; txtStation.AutoCompleteSource = AutoCompleteSource.CustomSource; txtStation.AutoCompleteMode = AutoCompleteMode.Suggest; txtStation.Leave += new EventHandler(txtStation_Leave); txtStation.KeyDown += new KeyEventHandler(txtStation_KeyDown); txtStation.Tag = (long)0; txtStation.Text = ""; DataGridViewCellStyle iskStyle = new DataGridViewCellStyle(UnitValueColumn.DefaultCellStyle); iskStyle.Format = IskAmount.FormatString(); UnitValueColumn.DefaultCellStyle = iskStyle; TotalValueColumn.DefaultCellStyle = iskStyle; ResultValueColumn.DefaultCellStyle = iskStyle; ResultTotalValueColumn.DefaultCellStyle = iskStyle; ReprocessValueColumn.DefaultCellStyle = iskStyle; _assets = new AssetList(); ItemsToReprocessView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; ItemsToReprocessView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; ItemsToReprocessView.AutoGenerateColumns = false; ItemColumn.DataPropertyName = "Item"; QuantityColumn.DataPropertyName = "Quantity"; UnitValueColumn.DataPropertyName = "UnitValue"; TotalValueColumn.DataPropertyName = "TotalValue"; ReprocessColumn.DataPropertyName = "Selected"; ReprocessValueColumn.DataPropertyName = "ReprocessValue"; ItemsToReprocessView.DataSource = _assets; ReprocessResultsView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; ReprocessResultsView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; ReprocessResultsView.AutoGenerateColumns = false; ResultItemColumn.DataPropertyName = "Item"; ResultMaxQuantityColumn.DataPropertyName = "MaxQuantity"; ResultActualQuantityColumn.DataPropertyName = "ActualQuantity"; StationTakesQuantityColumn.DataPropertyName = "StationTakes"; ResultFinalQuantityColumn.DataPropertyName = "Quantity"; ResultValueColumn.DataPropertyName = "UnitSellPrice"; ResultTotalValueColumn.DataPropertyName = "EstSellPrice"; lblValueAfter.Text = "0.00 ISK"; lblValueBefore.Tag = 0.0m; lblValueBefore.Text = "0.00 ISK"; this.FormClosing += new FormClosingEventHandler(Reprocessor_FormClosing); RefreshContainerList(); RefreshItemList(); cmbContainers.SelectedIndexChanged += new EventHandler(cmbContainers_SelectedIndexChanged); } catch (Exception ex) { EMMAException emmaEx = ex as EMMAException; if (emmaEx == null) { new EMMAException(ExceptionSeverity.Error, "Problem loading reprocessor", ex); } MessageBox.Show("Problem loading reprocessor:\r\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// /// </summary> /// <param name="itemID"></param> /// <param name="quantity"></param> /// <returns>Return the assets required to build the specified item. (Assuming perfect skills, /// efficiency, etc).</returns> public static AssetList GetBillOfMaterials(int itemID, long quantity) { AssetList retVal = new AssetList(); throw new NotImplementedException(); return retVal; }
public static bool GetResultsPage(int startPos, int pageSize, ref AssetList assets) { if (startPos <= 0) startPos = 1; EMMADataSet.AssetsDataTable table = new EMMADataSet.AssetsDataTable(); lock (assetsTableAdapter) { assetsTableAdapter.FillByResultsPage(table, startPos, pageSize); } foreach (EMMADataSet.AssetsRow asset in table) { assets.Add(new Asset(asset, null)); } return table.Count == pageSize; }
private void UpdateAssetsFromXML(CharOrCorp corc, XmlDocument xml) { DateTime earliestUpdate = GetLastAPIUpdateTime(corc, APIDataType.Assets).AddHours(23); EMMADataSet.AssetsDataTable assetData = new EMMADataSet.AssetsDataTable(); DateTime dataDate = DateTime.MinValue; try { XmlNodeList assetList = null; UpdateStatus(0, 1, "Getting asset data from file", "", false); dataDate = EveAPI.GetDataTime(xml); DateTime assetsEffectiveDate = corc == CharOrCorp.Char ? Settings.CharAssetsEffectiveDate : Settings.CorpAssetsEffectiveDate; if (dataDate.CompareTo(assetsEffectiveDate) < 0) { UpdateStatus(1, 1, "Error", "This data in this file is from " + dataDate.ToString() + ". EMMA has already imported asset data dated " + assetsEffectiveDate + " therefore the" + " database will not be updated.", true); assetList = null; } else { assetList = EveAPI.GetResults(xml); UpdateStatus(1, 1, "", assetList.Count + " asset data lines found.", false); } if (assetList != null) { // Set the 'processed' flag to false for all of this char/corp's assets. Assets.SetProcessedFlag(corc == CharOrCorp.Corp ? _corpID : _charID, (int)AssetStatus.States.Normal, false); Assets.SetProcessedFlag(corc == CharOrCorp.Corp ? _corpID : _charID, (int)AssetStatus.States.ForSaleViaMarket, false); Assets.SetProcessedFlag(corc == CharOrCorp.Corp ? _corpID : _charID, (int)AssetStatus.States.ForSaleViaContract, false); Assets.SetProcessedFlag(corc == CharOrCorp.Corp ? _corpID : _charID, (int)AssetStatus.States.InTransit, false); AssetList changes = new AssetList(); // Create an in-memory datatable with all of the changes required to the assets // database in order to reflect the data in the xml file. UpdateAssets(assetData, assetList, 0, corc, 0, changes); // Use the currently active sell order to account for assets that appear to be // missing. UpdateStatus(0, 0, "Processing active sell orders", "", false); Assets.ProcessSellOrders(assetData, changes, corc == CharOrCorp.Corp ? _corpID : _charID); UpdateStatus(0, 0, "", "Complete", false); // Use transactions that occured after the effective date of the asset data file // to ensure that the asset list is as up-to-date as possible. UpdateStatus(0, 0, "Updating assets from transactions that occur after " + "the asset file's effective date", "", false); long maxID = Assets.UpdateFromTransactions(assetData, changes, _charID, _corpID, corc == CharOrCorp.Corp, dataDate); if (corc == CharOrCorp.Char) { Settings.CharAssetsTransUpdateID = maxID; } else { Settings.CorpAssetsTransUpdateID = maxID; } UpdateStatus(0, 0, "", "Complete", false); AssetList gained = new AssetList(); AssetList lost = new AssetList(); if ((corc == CharOrCorp.Char && Settings.FirstUpdateDoneAssetsChar) || (corc == CharOrCorp.Corp && Settings.FirstUpdateDoneAssetsCorp)) { UpdateStatus(0, 0, "Analysing changes to assets", "", false); Assets.AnalyseChanges(assetData, corc == CharOrCorp.Corp ? _corpID : _charID, changes, out gained, out lost); UpdateStatus(0, 0, "", "Complete", false); } // If this is the first assets update then we want to try and assign sensible cost // values to assets that we have not yet got a value for. if ((corc == CharOrCorp.Char && !Settings.FirstUpdateDoneAssetsChar) || (corc == CharOrCorp.Corp && !Settings.FirstUpdateDoneAssetsCorp)) { Assets.AssignApproxCosts(assetData, corc == CharOrCorp.Corp ? _corpID : _charID); } if (corc == CharOrCorp.Char) { _unacknowledgedGains = gained; _unacknowledgedLosses = lost; } else { _corpUnacknowledgedGains = gained; _corpUnacknowledgedLosses = lost; } UpdateStatus(0, 0, "Updating assets database", "", false); Assets.UpdateDatabase(assetData); UpdateStatus(0, 0, "", "Complete", false); // Set all 'for sale via contract' and 'in transit' assets in the database to processed. // These types of assets would not be expected to show up in either the XML from the // API or the list of current market orders. // Any assets of these types that have been moved to a different state (e.g. in transit // items that have arrived or contracts that have expired) will have been updated already // in this method or ProcessSellOrders. // Therefore, the ones that are left are still in the same situation as before. // i.e. either 'for sale via contract' or 'in transit'. // We set them to processed to prevent them from being removed along with other // unprocessed assets. Assets.SetProcessedFlag(corc == CharOrCorp.Corp ? _corpID : _charID, (int)AssetStatus.States.ForSaleViaContract, true); Assets.SetProcessedFlag(corc == CharOrCorp.Corp ? _corpID : _charID, (int)AssetStatus.States.InTransit, true); // Clear any remaining assets that have not been processed. Assets.ClearUnProcessed(corc == CharOrCorp.Corp ? _corpID : _charID, false); Assets.SetProcessedFlag(corc == CharOrCorp.Corp ? _corpID : _charID, 0, false); UpdateStatus(0, 0, assetData.Count + " asset database entries modified.", "", false); // Update the assets effective date setting. // Also set the 'FirstUpdateDone' flag if (corc == CharOrCorp.Char) { Settings.CharAssetsEffectiveDate = dataDate; Settings.FirstUpdateDoneAssetsChar = true; } else { Settings.CorpAssetsEffectiveDate = dataDate; if (!Settings.FirstUpdateDoneAssetsCorp) { Settings.FirstUpdateDoneAssetsCorp = true; foreach (EVEAccount account in UserAccount.CurrentGroup.Accounts) { foreach (APICharacter character in account.Chars) { if (character.CharID != _charID && character.CorpID == _corpID) { Settings.FirstUpdateDoneAssetsCorp = true; } } } } } UpdateStatus(1, 1, "", "Complete", true); } } catch (Exception ex) { EMMAException emmaEx = ex as EMMAException; if (emmaEx == null) { // If we've caught a standard exception rather than an EMMA one then log it be creating a // new exception. // Note that we don't need to actually throw it.. emmaEx = new EMMAException(ExceptionSeverity.Error, "Error when processing assets data", ex); } UpdateStatus(-1, -1, "Error", ex.Message, true); SetLastAPIUpdateError(corc, APIDataType.Assets, ex.Message); } if (UpdateEvent != null) { if (_unacknowledgedLosses == null) { _unacknowledgedLosses = new AssetList(); } if (_unacknowledgedGains == null) { _unacknowledgedGains = new AssetList(); } if (_corpUnacknowledgedLosses == null) { _corpUnacknowledgedLosses = new AssetList(); } if (_corpUnacknowledgedGains == null) { _corpUnacknowledgedGains = new AssetList(); } if ((corc == CharOrCorp.Char && _unacknowledgedLosses.Count + _unacknowledgedGains.Count == 0) || (corc == CharOrCorp.Corp && _corpUnacknowledgedGains.Count + _corpUnacknowledgedLosses.Count == 0)) { UpdateEvent(this, new APIUpdateEventArgs(APIDataType.Assets, corc == CharOrCorp.Char ? _charID : _corpID, APIUpdateEventType.UpdateCompleted)); } else { SetLastAPIUpdateError(corc, APIDataType.Assets, "AWAITING ACKNOWLEDGEMENT"); UpdateEvent(this, new APIUpdateEventArgs(APIDataType.Assets, corc == CharOrCorp.Char ? _charID : _corpID, APIUpdateEventType.AssetsAwaitingAcknowledgement)); } } }
/// <summary> /// Retrieve assets that are stored in the specified container /// </summary> /// <param name="container"></param> /// <returns></returns> public static AssetList LoadAssets(Asset container, int itemID) { AssetList retVal = new AssetList(); EMMADataSet.AssetsDataTable table = new EMMADataSet.AssetsDataTable(); lock (assetsTableAdapter) { assetsTableAdapter.FillByContainerID(table, container.ID, itemID); } foreach (EMMADataSet.AssetsRow row in table) { Asset asset = new Asset(row, container); retVal.Add(asset); } return retVal; }
public Asset(XmlNode apiAssetData, long ownerID, bool corpAsset, Asset container) { _id = 0; _ownerID = ownerID; _corpAsset = corpAsset; XmlNode locationNode = apiAssetData.SelectSingleNode("@locationID"); if (locationNode != null) { _locationID = long.Parse(locationNode.Value); // Translate location ID from a corporate office to a station ID if required. if (_locationID >= 66000000 && _locationID < 67000000) { // NPC station. _locationID -= 6000001; } if (_locationID >= 67000000 && _locationID < 68000000) { // Conquerable station. _locationID -= 6000000; } } _itemID = int.Parse(apiAssetData.SelectSingleNode("@typeID").Value); _eveItemInstanceID = long.Parse(apiAssetData.SelectSingleNode("@itemID").Value); _quantity = int.Parse(apiAssetData.SelectSingleNode("@quantity").Value); if (apiAssetData.LastChild != null && apiAssetData.LastChild.Name.Equals("rowset")) { _isContainer = true; } _autoConExclude = false; _reprocExclude = false; _processed = false; _statusID = 1; _contents = new AssetList(); _container = container; _containerID = container.ID; _contents = new AssetList(); _unitBuyPrice = 0; _pureUnitBuyPrice = _unitBuyPrice; _gotUnitBuyPrice = false; _unitBuyPricePrecalc = false; if (_isContainer) { XmlNodeList contents = apiAssetData.SelectNodes("rowset/row"); foreach (XmlNode asset in contents) { _contents.Add(new Asset(asset, ownerID, corpAsset, this)); } } }
/// <summary> /// Return a list of assets that meet the specified parameters. /// Note that the list does NOT include assets stored within other containers, ships, etc. /// </summary> /// <param name="accessParams"></param> /// <param name="regionIDs"></param> /// <param name="itemID"></param> /// <param name="locationID"></param> /// <returns></returns> public static AssetList LoadAssetsByItemAndContainersOfItem(List<AssetAccessParams> accessParams, List<long> regionIDs, int itemID, long locationID, long systemID, bool containersOnly, int status, bool excludeContainers) { AssetList retVal = new AssetList(); EMMADataSet.AssetsDataTable table = new EMMADataSet.AssetsDataTable(); string regionString = ""; // Do not do this, just pass in an empty list and it'll match all regions. //if (regionIDs.Count == 0) { regionIDs.Add(0); } foreach (int region in regionIDs) { regionString = regionString + (regionString.Length == 0 ? "" : ",") + region; } lock (assetsTableAdapter) { assetsTableAdapter.FillByItemAndContainersOfItem(table, AssetAccessParams.BuildAccessList(accessParams), regionString, systemID, locationID, itemID, containersOnly, false, status); } foreach (EMMADataSet.AssetsRow row in table) { if (row.Quantity > 0 && (!row.IsContainer || !excludeContainers)) { Asset asset = new Asset(row, null); retVal.Add(asset); } } return retVal; }
/// <summary> /// Return a list of assets that meet the specified parameters. /// </summary> public static AssetList LoadReprocessableAssets(long ownerID, long stationID, int status, bool includeContainers, bool includeNonContainers) { AssetList retVal = new AssetList(); EMMADataSet.AssetsDataTable table = new EMMADataSet.AssetsDataTable(); lock (assetsTableAdapter) { assetsTableAdapter.FillByReprocessables(table, ownerID, stationID, status, includeContainers, includeNonContainers); } foreach (EMMADataSet.AssetsRow row in table) { if (row.Quantity > 0) { Asset asset = new Asset(row, null); retVal.Add(asset); } } return retVal; }
private void ClearAssets() { List<SortInfo> sortInfo = AssetsGrid.GridSortInfo; _assets = new AssetList(); _assetsBindingSource.DataSource = _assets; AssetsGrid.GridSortInfo = sortInfo; Text = "Viewing " + _assetsBindingSource.Count + " assets"; }