Esempio n. 1
0
        public void initCardView()
        {
            cardView.Items.Clear();
            cardView.View          = View.Details;
            cardView.GridLines     = true;
            cardView.FullRowSelect = true;

            cardView.BackColor = Color.WhiteSmoke;

            cardView.Columns.Add("ProductID", 60);
            cardView.Columns.Add("Card Name", 220);
            cardView.Columns.Add("Edition", 120);

            dj = new DataTable();

            // note - we have expansions only for MTG cards, so non-mtg will not have the expansion name
            var inventorySinglesOnly = MKMDbManager.Instance.InventorySinglesOnly.CopyToDataTable();

            dj = MKMDbManager.JoinDataTables(inventorySinglesOnly, MKMDbManager.Instance.Expansions,
                                             (row1, row2) => row1.Field <string>(MKMDbManager.InventoryFields.ExpansionID) == row2.Field <string>(MKMDbManager.ExpansionsFields.ExpansionID));

            foreach (DataRow row in dj.Rows)
            {
                var item = new ListViewItem(row[MKMDbManager.InventoryFields.ProductID].ToString());

                item.SubItems.Add(row[MKMDbManager.InventoryFields.Name].ToString());
                item.SubItems.Add(row[MKMDbManager.ExpansionsFields.Name].ToString());

                cardView.Items.Add(item);
            }
        }
Esempio n. 2
0
        private void buttonExport_Click(object sender, EventArgs e)
        {
            SaveFileDialog sf = new SaveFileDialog();

            sf.Filter = "csv files (*.csv)|*.csv|All files (*.*)|*.*";
            if (sf.ShowDialog() == DialogResult.OK)
            {
                MainView.Instance.LogMainWindow("Exporting external list...");
                // start with the same columns as there were in import
                DataTable export = new DataTable();
                foreach (DataColumn dc in importedColumns)
                {
                    export.Columns.Add(dc.ColumnName);
                }
                // now add additional columns based on what checkboxes are checked
                if (!checkBoxExportAll.Checked)
                {
                    if (checkBoxExportPriceGuide.Checked)
                    {
                        export.Columns.Add(MCAttribute.PriceGuideAVG);
                        export.Columns.Add(MCAttribute.PriceGuideLOW);
                        export.Columns.Add(MCAttribute.PriceGuideLOWEX);
                        export.Columns.Add(MCAttribute.PriceGuideLOWFOIL);
                        export.Columns.Add(MCAttribute.PriceGuideSELL);
                        export.Columns.Add(MCAttribute.PriceGuideTREND);
                        export.Columns.Add(MCAttribute.PriceGuideTRENDFOIL);
                    }
                    if (checkBoxExportToolPrices.Checked)
                    {
                        export.Columns.Add(MCAttribute.MKMToolPrice);
                        export.Columns.Add(MCAttribute.PriceCheapestSimilar);
                    }
                }
                foreach (MKMMetaCard mc in importedAll)
                {
                    if (checkBoxExportOnlyAppraised.Checked)
                    {
                        // price guides are not generated or the card does not have them or the user does not want them
                        bool priceGuidesSkip = (!checkBoxExportPriceGuide.Checked || !priceGuidesGenerated || !mc.HasPriceGuides);
                        if (toolPriceGenerated)
                        {
                            if ((mc.GetAttribute(MCAttribute.MKMToolPrice) == "" && mc.GetAttribute(MCAttribute.PriceCheapestSimilar) == "") && // toolPrices not present for this card
                                priceGuidesSkip)
                            {
                                continue;
                            }
                        }
                        else if (priceGuidesSkip)
                        {
                            continue;
                        }
                    }
                    mc.WriteItselfIntoTable(export, checkBoxExportAll.Checked, checkBoxExportFormatDeckbox.Checked ? MCFormat.Deckbox : MCFormat.MKM);
                }

                MKMDbManager.WriteTableAsCSV(sf.FileName, export);

                MainView.Instance.LogMainWindow("Exporting finished.");
            }
        }
Esempio n. 3
0
        private void buttonExport_Click(object sender, EventArgs e)
        {
            SaveFileDialog sf = new SaveFileDialog();

            sf.Filter = "csv files (*.csv)|*.csv|All files (*.*)|*.*";
            if (sf.ShowDialog() == DialogResult.OK)
            {
                MainView.Instance.LogMainWindow("Exporting inventory...");
                MKMDbManager.WriteTableAsCSV(sf.FileName, (DataTable)stockGridView.DataSource);
                MainView.Instance.LogMainWindow("Inventory exported.");
            }
        }
Esempio n. 4
0
        // reload data each time the form is made visible in case the user's stock has changed so they can reload the stockview this way
        private void StockView_VisibleChanged(object sender, EventArgs e)
        {
            if (Visible)
            {
                int start    = 1;
                var articles = new DataTable();
                try
                {
                    while (true)
                    {
                        var doc = MKMInteract.RequestHelper.readStock(start);
                        if (doc.HasChildNodes)
                        {
                            var result       = doc.GetElementsByTagName("article");
                            int elementCount = 0;
                            foreach (XmlNode article in result)
                            {
                                if (article["condition"] != null) // is null for articles that are not cards (boosters etc.) - don't process those
                                {
                                    MKMMetaCard m = new MKMMetaCard(article);
                                    m.WriteItselfIntoTable(articles, true, MCFormat.MKM);
                                    elementCount++;
                                }
                            }
                            if (elementCount != 100)
                            {
                                break;
                            }
                            start += elementCount;
                        }
                        else
                        {
                            break;  // document is empty -> end*/
                        }
                    }

                    // Remove columns we don't want showing
                    // TODO - what is and isn't shown should probably be customizable and left to the user to choose in some way
                    articles.Columns.Remove(MCAttribute.ArticleID);
                    articles.Columns.Remove(MCAttribute.ProductID);
                    articles.Columns.Remove(MCAttribute.LanguageID);
                    articles.Columns.Remove(MCAttribute.CardNumber);

                    var dj = MKMDbManager.JoinDataTables(articles, MKMDbManager.Instance.Expansions,
                                                         (row1, row2) => row1.Field <string>(MKMDbManager.InventoryFields.ExpansionID) == row2.Field <string>(MKMDbManager.ExpansionsFields.ExpansionID));

                    dj.Columns.Remove(MCAttribute.ExpansionID);                   // duplicated
                    dj.Columns.Remove(MKMDbManager.ExpansionsFields.ExpansionID); // ...and we don't want it anyway
                    dj.Columns.Remove(MKMDbManager.ExpansionsFields.Name);        // duplicated

                    dj.Columns[dj.Columns.IndexOf(MCAttribute.Name)].SetOrdinal(0);
                    dj.Columns[dj.Columns.IndexOf(MCAttribute.Expansion)].SetOrdinal(1);
                    dj.Columns[dj.Columns.IndexOf(MCAttribute.Language)].SetOrdinal(2);

                    stockGridView.DataSource = dj;

                    buttonExport.Enabled = true;
                }
                catch (Exception eError)
                {
                    MKMHelpers.LogError("listing stock in Stock View", eError.Message, true);
                }
            }
        }
Esempio n. 5
0
        // reload data each time the form is made visible in case the user's stock has changed so they can reload the stockview this way
        private void stockView_VisibleChanged(object sender, EventArgs e)
        {
            if (Visible)
            {
                var articles = new DataTable();
                try
                {
                    // getAllStockSingles creates a DataTable and converts it to list of cards, so theoretically we are wasting some work
                    // but it also filters out non-singles and converting to MKMcard will make sure we use the primary column names rather than synonyms
                    var cards = MKMInteract.RequestHelper.GetAllStockSingles(MainView.Instance.Config.UseStockGetFile);
                    if (cards.Count == 0)
                    {
                        MainView.Instance.LogMainWindow("Stock is empty. Did you select correct idGame in config.xml?");
                        return;
                    }
                    foreach (var card in cards)
                    {
                        card.WriteItselfIntoTable(articles, true, MCFormat.MKM, true);
                    }
                    // Remove columns we don't want showing
                    // TODO - what is and isn't shown should probably be customizable and left to the user to choose in some way
                    if (articles.Columns.Contains(MCAttribute.ArticleID))
                    {
                        articles.Columns.Remove(MCAttribute.ArticleID);
                    }
                    if (articles.Columns.Contains(MCAttribute.LanguageID))
                    {
                        articles.Columns.Remove(MCAttribute.LanguageID);
                    }
                    if (articles.Columns.Contains(MCAttribute.MetaproductID))
                    {
                        articles.Columns.Remove(MCAttribute.MetaproductID);
                    }
                    if (articles.Columns.Contains("onSale"))
                    {
                        articles.Columns.Remove("onSale"); // don't even know what this one is supposed to be, it's not even in the API documentation
                    }
                    if (articles.Columns.Contains(MCAttribute.MKMCurrencyCode))
                    {
                        articles.Columns.Remove(MCAttribute.MKMCurrencyCode);
                    }
                    if (articles.Columns.Contains(MCAttribute.MKMCurrencyId))
                    {
                        articles.Columns.Remove(MCAttribute.MKMCurrencyId);
                    }

                    var dj = MKMDbManager.JoinDataTables(articles, MKMDbManager.Instance.Expansions,
                                                         (row1, row2) => row1.Field <string>(MCAttribute.ExpansionID) == row2.Field <string>(MKMDbManager.ExpansionsFields.ExpansionID));

                    if (dj.Columns.Contains(MCAttribute.ExpansionID))
                    {
                        dj.Columns.Remove(MCAttribute.ExpansionID); // duplicated
                    }
                    if (dj.Columns.Contains(MKMDbManager.ExpansionsFields.ExpansionID))
                    {
                        dj.Columns.Remove(MKMDbManager.ExpansionsFields.ExpansionID); // ...and we don't want it anyway
                    }
                    if (dj.Columns.Contains(MKMDbManager.ExpansionsFields.Name))
                    {
                        dj.Columns.Remove(MKMDbManager.ExpansionsFields.Name); // duplicated
                    }
                    // use the same order with or without UseStockGetFile
                    System.Collections.Generic.List <string> attsOrdered = new System.Collections.Generic.List <string>
                    {
                        MCAttribute.Name, MCAttribute.Expansion, MCAttribute.Language, MCAttribute.ProductID,
                        MCAttribute.MKMPrice, MCAttribute.Condition, MCAttribute.Comments, MCAttribute.Foil,
                        MCAttribute.Altered, MCAttribute.Signed, MCAttribute.Playset, MCAttribute.Count,
                        MCAttribute.Rarity, MCAttribute.ExpansionAbb
                    };
                    int ordinal = 0;
                    foreach (string att in attsOrdered)
                    {
                        if (dj.Columns.Contains(att))
                        {
                            dj.Columns[dj.Columns.IndexOf(att)].SetOrdinal(ordinal++);
                        }
                    }

                    // convert columns with numerical data from string so that sorting works correctly
                    if (dj.Columns.Contains(MCAttribute.ProductID))
                    {
                        convertNumberColumn(dj, MCAttribute.ProductID, false);
                    }
                    if (dj.Columns.Contains(MCAttribute.Count))
                    {
                        convertNumberColumn(dj, MCAttribute.Count, false);
                    }
                    if (dj.Columns.Contains(MCAttribute.MKMPrice))
                    {
                        convertNumberColumn(dj, MCAttribute.MKMPrice, true);
                    }

                    stockGridView.DataSource = dj;

                    buttonExport.Enabled = true;
                }
                catch (Exception eError)
                {
                    MKMHelpers.LogError("listing stock in Stock View", eError.Message, true);
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Imports and processes the input CSV file, i.e. fills the internal MetaCard hash tables and fetches product info from MKM if necessary.
        /// Intended to run in a separate thread.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        private void importRun(string filePath, string defaultFoil, string defaultPlayset, string defaultSigned, string defaultAltered,
                               string defaultCondition, string defaultExpansion, string defaultLanguageID)
        {
            DataTable dt;

            try
            {
                dt = MKMDbManager.ConvertCSVtoDataTable(filePath);
            }
            catch (Exception eError)
            {
                LogError("importing file " + filePath, eError.Message, true);
                return;
            }
            importedColumns = dt.Columns;
            MainView.Instance.LogMainWindow("Loaded file with " + dt.Rows.Count + " articles, processing...");

            importedAll.Clear();
            importedValidOnly.Clear();
            int counter = 0, failed = 0, hasPriceGuide = 0;
            // if we search for products based on their locName, we have to make a product query for each of them - store the result to reuse in case there are more of those cards later in the list
            Dictionary <string, string> locNameProducts = new Dictionary <string, string>();

            foreach (DataRow row in dt.Rows)
            {
                MKMMetaCard mc = new MKMMetaCard(row);
                importedAll.Add(mc); // add it no matter if it can be correctly processed or not so that we can export it
                counter++;
                string productID  = mc.GetAttribute(MCAttribute.ProductID);
                string name       = mc.GetAttribute(MCAttribute.Name);
                string languageID = mc.GetAttribute(MCAttribute.LanguageID);
                if (languageID == "" && defaultLanguageID != "")
                {
                    languageID = defaultLanguageID;
                    mc.SetLanguageID(languageID);
                }
                if (name == "" && productID == "") // we have neither name or productID - we have to hope we have locName and language
                {
                    string locName = mc.GetAttribute(MCAttribute.LocName).ToLower();
                    if (locName == "" || languageID == "")
                    {
                        LogError("importing line #" + (counter + 1) + ", article will be ignored",
                                 "Neither product ID, English name, or localized name + language was found, cannot identify the card.", false);
                        failed++;
                        continue;
                    }
                    // have to use search on MKM to get the English name
                    string hash = "" + locName + languageID;          // technically it is unlikely that two different languages would have the same name, but could happen
                    if (!locNameProducts.TryGetValue(hash, out name)) // we haven't had a product like this in the list yet, use MKM API to find it
                    {
                        int            start = 0;
                        List <XmlNode> found = new List <XmlNode>();
                        try
                        {
                            XmlNodeList products;
                            do
                            {
                                XmlDocument doc = MKMInteract.RequestHelper.findProducts(locName, languageID, start);
                                products = doc.GetElementsByTagName("product");
                                // we still want to insert empty string in the hash table - this way we know in the future that this name is invalid
                                locNameProducts[hash] = "";
                                foreach (XmlNode product in products)
                                {
                                    // only take exact matches, otherwise we get all kinds of garbage like sleeves etc. that use the name of the card
                                    if (product["locName"].InnerText.ToLower() == locName)
                                    {
                                        found.Add(product);
                                    }
                                }
                                start += products.Count;
                            } while (products.Count == 100);
                        }
                        catch (Exception eError)
                        {
                            LogError("importing line #" + (counter + 1) + ", trying to find product by its localized name "
                                     + locName + ", article will be ignored", eError.Message, false);
                            failed++;
                            continue;
                        }
                        if (found.Count < 1)
                        {
                            LogError("importing line #" + (counter + 1) + ", trying to find product by its localized name "
                                     + locName + ", article will be ignored", "No article called " + locName + " in "
                                     + mc.GetAttribute(MCAttribute.Language) + " language found on MKM.", false);
                            failed++;
                            continue;
                        }
                        locNameProducts[hash] = name = found[0]["enName"].InnerText;
                        mc.SetAttribute(MCAttribute.Name, name);
                    }
                    else if (name != "")
                    {
                        mc.SetAttribute(MCAttribute.Name, name);
                    }
                    else
                    {
                        LogError("importing line #" + (counter + 1) + ", trying to find product by its localized name "
                                 + locName + ", article will be ignored", "" + locName + " is not a valid name", false);
                        failed++;
                        continue;
                    }
                }
                // process foil and condition now as it can be useful in determining expansion
                string temp = mc.GetAttribute(MCAttribute.Foil);
                Bool3  isFoil;
                if (temp == "")
                {
                    mc.SetBoolAttribute(MCAttribute.Foil, defaultFoil);
                    isFoil = ParseBool3(mc.GetAttribute(MCAttribute.Foil));
                }
                else
                {
                    isFoil = ParseBool3(temp);
                }

                string condition = mc.GetAttribute(MCAttribute.Condition);
                if (condition == "")
                {
                    condition = defaultCondition;
                    mc.SetCondition(condition);
                }

                if (productID == "")                                         // we now know we have the name, but we have to find out which expansion it is from to get the productID
                {
                    string expID = mc.GetAttribute(MCAttribute.ExpansionID); // if the Expansion would be set, ExpansionID would be set as well in constructor of MKMMetaCard
                    if (expID == "")                                         // we have to determine the expansion
                    {
                        DataRow[] all = MKMDbManager.Instance.GetCardByName(name);
                        // options are: Latest, Oldest, Cheapest, Median Price, Most Expensive
                        if (all.Length > 0)
                        {
                            // used for prices based on price guide (cheapest, median, most expensive):
                            // for non-foil, compare the LOWEX+ for EX+ items, LOW for worse conditions, for foil compare the LOWFOIL, for "any foil" compare SELL
                            string priceGuidePrice;
                            if (isFoil == Bool3.True)
                            {
                                priceGuidePrice = "LOWFOIL";
                            }
                            else if (isFoil == Bool3.Any)
                            {
                                priceGuidePrice = "SELL";
                            }
                            else
                            {
                                if (IsBetterOrSameCondition(condition, "EX"))
                                {
                                    priceGuidePrice = "LOWEX+";
                                }
                                else
                                {
                                    priceGuidePrice = "LOW";
                                }
                            }
                            switch (defaultExpansion)
                            {
                            // for latest and oldest, we can just check local database
                            case "Latest":
                                DateTime latestTime = new DateTime(0);
                                foreach (DataRow dr in all)
                                {
                                    string tempExpID   = dr[MKMDbManager.InventoryFields.ExpansionID].ToString();
                                    string releaseDate = MKMDbManager.Instance.GetExpansionByID(
                                        tempExpID)[MKMDbManager.ExpansionsFields.ReleaseDate].ToString();
                                    DateTime rel = DateTime.Parse(releaseDate, CultureInfo.InvariantCulture);
                                    if (latestTime < rel)
                                    {
                                        latestTime = rel;
                                        expID      = tempExpID;
                                    }
                                }
                                mc.SetAttribute(MCAttribute.ExpansionID, expID);
                                mc.SetAttribute(MCAttribute.Expansion,
                                                MKMDbManager.Instance.GetExpansionByID(expID)[MKMDbManager.ExpansionsFields.Name].ToString());
                                break;

                            case "Oldest":
                                DateTime oldestTime = DateTime.Now;
                                foreach (DataRow dr in all)
                                {
                                    string tempExpID   = dr[MKMDbManager.InventoryFields.ExpansionID].ToString();
                                    string releaseDate = MKMDbManager.Instance.GetExpansionByID(
                                        tempExpID)[MKMDbManager.ExpansionsFields.ReleaseDate].ToString();
                                    DateTime rel = DateTime.Parse(releaseDate, CultureInfo.InvariantCulture);
                                    if (oldestTime > rel)
                                    {
                                        latestTime = rel;
                                        expID      = tempExpID;
                                    }
                                }
                                mc.SetAttribute(MCAttribute.ExpansionID, expID);
                                mc.SetAttribute(MCAttribute.Expansion,
                                                MKMDbManager.Instance.GetExpansionByID(expID)[MKMDbManager.ExpansionsFields.Name].ToString());
                                break;

                            // for the others we have to do product queries for each possibility
                            case "Cheapest":
                                XmlNode cheapestProduct = null;     // we know all has at least one item so this will either get assigned or an exception is thrown and caught inside the foreach cycle
                                double  cheapestPrice   = double.MaxValue;
                                foreach (DataRow dr in all)
                                {
                                    try
                                    {
                                        // there should always be exactly one product in the list
                                        XmlNode product = MKMInteract.RequestHelper.getProduct(
                                            dr[MKMDbManager.InventoryFields.ProductID].ToString()).GetElementsByTagName("product")[0];
                                        double price = double.Parse(product["priceGuide"][priceGuidePrice].InnerText);
                                        if (price < cheapestPrice)
                                        {
                                            cheapestPrice   = price;
                                            cheapestProduct = product;
                                        }
                                    }
                                    catch (Exception eError)
                                    {
                                        LogError("importing line #" + (counter + 1) + ", could not identify cheapest expansion for " + name + ", article will be ignored",
                                                 eError.Message, false);
                                        failed++;
                                        continue;
                                    }
                                }
                                mc.FillProductInfo(cheapestProduct);
                                hasPriceGuide++;
                                break;

                            case "Median Price":
                                SortedList <double, XmlNode> prices = new SortedList <double, XmlNode>();
                                foreach (DataRow dr in all)
                                {
                                    try
                                    {
                                        // there should always be exactly one product in the list
                                        XmlNode product = MKMInteract.RequestHelper.getProduct(
                                            dr[MKMDbManager.InventoryFields.ProductID].ToString()).GetElementsByTagName("product")[0];
                                        double price = double.Parse(product["priceGuide"][priceGuidePrice].InnerText);
                                        prices.Add(price, product);
                                    }
                                    catch (Exception eError)
                                    {
                                        LogError("importing line #" + (counter + 1) + ", could not identify median price expansion for " + name + ", article will be ignored",
                                                 eError.Message, false);
                                        failed++;
                                        continue;
                                    }
                                }
                                mc.FillProductInfo(prices.Values[prices.Count / 2]);
                                hasPriceGuide++;
                                break;

                            case "Most Expensive":
                                XmlNode mostExpProduct = null;     // we know all has at least one item so this will either get assigned or an exception is thrown and caught inside the foreach cycle
                                double  highestPrice   = double.MinValue;
                                foreach (DataRow dr in all)
                                {
                                    try
                                    {
                                        // there should always be exactly one product in the list
                                        XmlNode product = MKMInteract.RequestHelper.getProduct(
                                            dr[MKMDbManager.InventoryFields.ProductID].ToString()).GetElementsByTagName("product")[0];
                                        double price = double.Parse(product["priceGuide"][priceGuidePrice].InnerText);
                                        if (price > highestPrice)
                                        {
                                            highestPrice   = price;
                                            mostExpProduct = product;
                                        }
                                    }
                                    catch (Exception eError)
                                    {
                                        LogError("importing line #" + (counter + 1) + ", could not identify cheapest expansion for " + name + ", article will be ignored",
                                                 eError.Message, false);
                                        failed++;
                                        continue;
                                    }
                                }
                                mc.FillProductInfo(mostExpProduct);
                                hasPriceGuide++;
                                break;
                            }
                        }
                        else
                        {
                            LogError("importing line #" + (counter + 1) + ", identifying expansion for " + name + ", article will be ignored",
                                     "No expansion found.", false);
                            failed++;
                            continue;
                        }
                        // TODO - determine whether the expansion is foil only / cannot be foil and based on the isFoil flag of the current article choose the correct set
                    }
                    // now we have expID and English name -> we can determine the product ID
                    string[] ids = MKMDbManager.Instance.GetProductID(name, mc.GetAttribute(MCAttribute.ExpansionID));
                    if (ids.Length == 0)
                    {
                        LogError("importing line #" + (counter + 1) + ", article will be ignored",
                                 "The specified " + name + " and expansion ID " + expID + " do not match - product cannot be identified.", false);
                        failed++;
                        continue;
                    }
                    else if (ids.Length > 1)
                    {
                        string cardNumber = mc.GetAttribute(MCAttribute.CardNumber);
                        if (cardNumber == "")
                        {
                            LogError("importing line #" + (counter + 1) + ", article will be ignored", "The specified " + name +
                                     " and expansion ID " + expID + " match multiple products - please provide Card Number to identify which one it is.", false);
                            failed++;
                            continue;
                        }
                        // search for the matching item
                        int start = 0;
                        try
                        {
                            XmlNodeList products;
                            do
                            {
                                XmlDocument doc = MKMInteract.RequestHelper.findProducts(name, "1", start);
                                products = doc.GetElementsByTagName("product");
                                string expansion = mc.GetAttribute(MCAttribute.Expansion);
                                foreach (XmlNode product in products)
                                {
                                    if (product["number"].InnerText == cardNumber && product["expansionName"].InnerText == expansion)
                                    {
                                        productID = product["idProduct"].InnerText;
                                        // since we already have it, why not fill the product info in the MetaCard
                                        mc.FillProductInfo(product);
                                        break;
                                    }
                                }
                                start += products.Count;
                            } while (products.Count == 100 && productID == "");
                        }
                        catch (Exception eError)
                        {
                            LogError("importing line #" + (counter + 1) + ", trying to find product ID for "
                                     + name + " based on its card number and expansion, article will be ignored", eError.Message, false);
                            failed++;
                            continue;
                        }
                        if (productID == "")
                        {
                            LogError("importing line #" + (counter + 1) + ", article will be ignored", "The specified " + name +
                                     " and expansion ID " + expID
                                     + " match multiple products, Card Number was used to find the correct article, but no match was found, verify the data is correct.", false);
                            failed++;
                            continue;
                        }
                    }
                    else
                    {
                        productID = ids[0];
                    }
                    mc.SetAttribute(MCAttribute.ProductID, productID);
                }

                // if the defaults are "Any", there is not point in checking whether that attribute has been set or not
                if (defaultPlayset != "")
                {
                    temp = mc.GetAttribute(MCAttribute.Playset);
                    if (temp == "")
                    {
                        mc.SetBoolAttribute(MCAttribute.Playset, defaultPlayset);
                    }
                }
                if (defaultSigned != "")
                {
                    temp = mc.GetAttribute(MCAttribute.Signed);
                    if (temp == "")
                    {
                        mc.SetBoolAttribute(MCAttribute.Signed, defaultSigned);
                    }
                }
                if (defaultAltered != "")
                {
                    temp = mc.GetAttribute(MCAttribute.Altered);
                    if (temp == "")
                    {
                        mc.SetBoolAttribute(MCAttribute.Altered, defaultAltered);
                    }
                }

                importedValidOnly.Add(mc);
                if (checkBoxImportLog.Checked)
                {
                    MainView.Instance.LogMainWindow("Imported line #" + (counter + 1) + ", " + name);
                }
            }

            MainView.Instance.LogMainWindow("Card list " + filePath + " imported. Successfully imported " + importedValidOnly.Count +
                                            " articles, failed to import: " + failed + ", articles that include MKM Price Guide: " + hasPriceGuide);
            if (hasPriceGuide > 0)
            {
                priceGuidesGenerated = true;
            }
        }