private Collection ConvertCollection(Collection collection, ConvertConfig config) { Collection result = new Collection(); result.name = collection.name; List<Product> products = new List<Product>(); foreach (Product product in collection.products) products.Add((Product)product.Clone()); products.Sort(CompareProductsByCode); Dictionary<Product, MergeInfo> mergesByProduct = new Dictionary<Product, MergeInfo>(); Dictionary<string, MergeInfo> mergesByIndex = new Dictionary<string, MergeInfo>(); // Определяем группы товаров for (int productIndex = 0; productIndex < products.Count; ++productIndex) { Product product = products[productIndex]; // Проверяем выполнение регулярных выражений for (int groupIndex = 0; groupIndex < config.groups.Length; ++groupIndex) { ConvertConfig.GroupConfig groupConfig = config.groups[groupIndex]; Dictionary<string, string> values = groupConfig.inputExpression.Parse(product.name); if (null != values) { if (null != groupConfig.merge) { if (null != groupConfig.textExpression) product.name = groupConfig.textExpression.Format(values).Trim(); string mid = product.name + ":" + product.cost.ToString(); if (!mergesByIndex.ContainsKey(mid)) { MergeInfo mergeInfo = new MergeInfo(product); mergesByIndex.Add(mid, mergeInfo); mergesByProduct.Add(product, mergeInfo); } else { mergesByProduct.Add(product, null); } mergesByIndex[mid].codes.Add(product.code); } else if (null != groupConfig.groupExpression) { product.groupName = groupConfig.groupExpression.Format(values).Trim(); product.shortName = groupConfig.textExpression.Format(values).Trim(); } else { product.name = groupConfig.textExpression.Format(values).Trim(); } break; } } } // Группируем товары for (int productIndex = 0; productIndex < products.Count; ++productIndex) { Product product = products[productIndex]; if (null == product) continue; if (mergesByProduct.ContainsKey(product)) { MergeInfo mergeInfo = mergesByProduct[product]; if (null == mergeInfo) continue; product.code = 0; StringBuilder name = new StringBuilder(); name.Append(product.name); name.Append(" ("); mergeInfo.codes.Sort(); int codeStartIndex = 0; for (int codeIndex = 1; codeIndex <= mergeInfo.codes.Count; ++codeIndex) { if (codeIndex < mergeInfo.codes.Count && mergeInfo.codes[codeIndex] == mergeInfo.codes[codeStartIndex] + codeIndex - codeStartIndex) continue; if (codeStartIndex != 0) name.Append(", "); name.Append(mergeInfo.codes[codeStartIndex]); if (codeIndex - codeStartIndex > 1) { name.Append("-"); name.Append(mergeInfo.codes[codeIndex - 1]); } codeStartIndex = codeIndex; } name.Append(")"); product.name = name.ToString(); result.products.Add(product); } else if (null != product.shortName && null != product.groupName) { // Создаем группу товаров for (int i = productIndex; i < products.Count; ++i) { Product inputProduct = products[i]; if (null == inputProduct) continue; if (inputProduct.groupName == product.groupName) { result.products.Add(inputProduct); products[i] = null; } } } else { // Помещаем товар в список result.products.Add(product); } } // Прогоняем подгруппы foreach (Collection subCollection in collection.collections) result.collections.Add(ConvertCollection(subCollection, config)); return result; }
/** * Создает омский прайс на основе новосибирского прайса, * выполняя следующие преобразования: * 1) Группирует товары в соответствии с конфигурацией; * 2) Сортирует товары по кодам, сохраняя группировку. */ public Price(Price source, ConvertConfig config) { root = ConvertCollection(source.root, config); }