Skip to content

Instantly share code, notes, and snippets.

@maxlord
Created May 31, 2016 10:15
Show Gist options
  • Save maxlord/849e018142197a6cd4dccb1533875ca4 to your computer and use it in GitHub Desktop.
Save maxlord/849e018142197a6cd4dccb1533875ca4 to your computer and use it in GitHub Desktop.
MyPrice Import PriceList
// Создаем запись о новом прайс-листе в БД
var pricelistDate = DateTime.Now;
var pricelistColumns = new Dictionary<string, object>()
{
{"Date", pricelistDate},
{"LoadType", (int) PriceListLoadType},
{"LoadTypeData", PriceListLoadTypeData},
{"Name", PriceListFileName},
{"FileSize", PriceListFileSize},
{"NameMd5Hash", PriceListFileMd5Hash}
};
long pricelistId = db.Insert("pa_pricelist", pricelistColumns);
result.PricelistId = (int) pricelistId;
// Привязываем прайс-лист к текущему магазину
db.Insert("pa_provider_pricelist", new Dictionary<string, object>()
{
{"ProviderId", ProviderId},
{"PricelistId", pricelistId},
{"IsLink", false}
}, "PricelistId");
// Для этого магазина устанавливаем актуальный прайслист
db.Update("pa_provider", new Dictionary<string, object>
{
{ "Id", ProviderId }
}, new Dictionary<string, object>
{
{ "ActualPricelistId", pricelistId }
});
// Добавляем ссылку для привязанных магазинов в режиме "по ссылке"
foreach (long linkedProviderId in linkedProviderIds)
{
db.Insert("pa_provider_pricelist", new Dictionary<string, object>()
{
{"ProviderId", linkedProviderId},
{"PricelistId", pricelistId},
{"IsLink", true}
}, "PricelistId");
// Для этого магазина устанавливаем актуальный прайслист
db.Update("pa_provider", new Dictionary<string, object>
{
{ "Id", linkedProviderId }
}, new Dictionary<string, object>
{
{ "ActualPricelistId", pricelistId }
});
}
Logger.LogMessage("Total Rows: " + ReadingResults.GetTotalRows() + "; LIMIT: " + limitPricelistVolume);
if (ReadingResults.GetTotalRows() <= limitPricelistVolume)
{
int TotalRowsInPriceList = 0;
//3. Записываем найденные прайс-листы
var DBProviderItemNumber = 0;
foreach (DataTable NextTable in this.ReadingResults.ParsedData.Tables)
{
var stockRows = new List<Dictionary<string, object>>();
foreach (DataRow NextRow in NextTable.Rows)
{
int rowIndex = NextRow[PricelistParser.ROWINDEX_COLUMN].To<int>(0);
string Name = NextRow[PricelistParser.NAME_COLUMN] + "";
string Article = NextRow[PricelistParser.ARTICLE_COLUMN] + "";
string Manufacturer = NextRow[PricelistParser.MANUFACTURER_COLUMN] + "";
string Description = NextRow[PricelistParser.DESCRIPTION_COLUMN] + "";
string Crosses = NextRow[PricelistParser.CROSSES_COLUMN] + "";
decimal PriceBase = 0m;
decimal PriceSell = 0m;
int? Stock = null;
bool Defect = NextRow[PricelistParser.DEFECT_COLUMN].To<bool>();
bool SecondHand = NextRow[PricelistParser.SECOND_HAND_COLUMN].To<bool>();
Name = DataInvariantUnifizer.NormalizeBrandAndModel(DataTypesNormalizer.NormalizeLength(Name.Trim()));
Article = DataTypesNormalizer.NormalizeItemArticle(DataTypesNormalizer.NormalizeLength(Article.Trim()));
Manufacturer = DataInvariantUnifizer.NormalizeManufacturerForCodeEvaluation(DataTypesNormalizer.NormalizeLength(Manufacturer.Trim()));
Description = DataInvariantUnifizer.NormalizeAnyDescription(DataTypesNormalizer.NormalizeLength(Description.Trim()));
Crosses = Crosses.Trim();
if (Name.Length > 1000) Name = Name.Substring(0, 1000); // IN DB: VARCHAR(2044)
//if (Description.Length > 200) Description = Description.Substring(0, 200); // Compressing to TINYTEXT max length
//if (ManufCode.Length > 20) ManufCode = string.Empty; // Protection from wrong manufacturer code
//if (BarCode.Length > 20) BarCode = string.Empty; // Protection from wrong bar code
string priceBaseStr = NextRow[PricelistParser.PRICE_BASE_COLUMN] + "";
string priceSellStr = NextRow[PricelistParser.PRICE_SELL_COLUMN] + "";
if (priceBaseStr.Length > 0) PriceBase = priceBaseStr.Replace(",", ".").To<decimal>();
if (priceSellStr.Length > 0) PriceSell = priceSellStr.Replace(",", ".").To<decimal>();
string stockStr = NextRow[PricelistParser.STOCK_COLUMN] + "";
if (stockStr.Length > 0) Stock = stockStr.To<int>();
if (Stock == 0) Stock = null;
var hasPrice = PriceBase > 0m || PriceSell > 0m;
if (hasPrice)
{
if (PriceBase > 0m && PriceBase > 5000000)
{
hasPrice = false;
}
if (PriceSell > 0m && PriceSell > 5000000)
{
hasPrice = false;
}
}
if (!hasPrice)
{
UnsavedItemsCount_ErrorInItemData++;
continue;
}
// Проверка товара на дубликат
// проверяем дубликат по связке артикул + название товара + производитель + описание + базовая цена
string complexName = string.Format("[{0}] {1} ({2}) {3} {{{4};{5}}}", Article, Name, Manufacturer, Description, priceBaseStr, priceSellStr);
if (PushedItems.ContainsKey(complexName))
{
result.NumberDuplicateRows++;
if (!result.DuplicateRows.ContainsKey(PushedItems[complexName]))
{
result.DuplicateRows.Add(PushedItems[complexName], new List<string>());
}
result.DuplicateRows[PushedItems[complexName]].Add(string.Format("[ДУБЛЬ][Лист: '{0}', Строка: {1}] {2}",
NextTable.TableName, rowIndex, complexName));
continue;
}
else
{
PushedItems.Add(complexName, string.Format("[Лист: '{0}', Строка: {1}] {2}",
NextTable.TableName, rowIndex, complexName));
}
if (Manufacturer.Length > 26)
Manufacturer = "Неизвестный производитель";
//3.1. Получаем идентификатор производителя
uint ManufacturerId = 0;
uint? ManufacturerSearchingResult = ManufHashAccessor.Search(Manufacturer);
if (ManufacturerSearchingResult.HasValue)
{
//3.1.А. Производитель с указанным названием существует в базе, получаем его идентификатор
ManufacturerId = ManufacturerSearchingResult.Value;
}
else
{
//3.1.Б. Производитель с указанным названием не существует в базе. Добавляем информацию о нем
ManufacturerId = Convert.ToUInt32(db.Insert("pa_manufacturer", new Dictionary<string, object>() {
{ "Name", Manufacturer }
}));
Global.EntitiesStorage.PCMManufacturersHashStorage.AddEntry(Manufacturer, ManufacturerId);
}
//3.2. Получаем идентификатор артикула
uint ArticleId = 0;
uint? ArticleSearchingResults = ArticlesHashAccessor.Search(Article);
if (ArticleSearchingResults.HasValue)
{
//3.2.А. Артикул с указанным кодом существует в базе, получаем его идентификатор
ArticleId = ArticleSearchingResults.Value;
}
else
{
//3.2.Б. Артикула с указанным кодом не существует в базе. Добавляеми нформацию о нем
ArticleId = Convert.ToUInt32(db.Insert("pa_article", new Dictionary<string, object>() {
{ "Article", Article }
}));
Global.EntitiesStorage.PCMArticlesHashStorage.AddEntry(Article, ArticleId);
}
// Находим ArtLookupId
DirectLookupResults CurrentWriteIndex = art_lookup_writer.DirectLookup(db, Article, Name, Manufacturer);
//3.3. Добавляем запись в таблицу остатков
// Название, Производитель, номер
long itemId = 0;
var nameRows = db.GetRows("pa_stock_item", new Dictionary<string, object>()
{
{"ManufacturerId", ManufacturerId},
{"Name", Name},
{"Number", DBProviderItemNumber},
}, new List<string>() { "Id" });
if (nameRows.RowsCount > 0)
{
itemId = nameRows[0].GetValue<long>("Id");
}
else
{
itemId = db.Insert("pa_stock_item", new Dictionary<string, object>()
{
{"ManufacturerId", ManufacturerId},
{"Name", Name},
{"Number", DBProviderItemNumber}
});
}
// Описание
long? itemDescriptionId = null;
if (!Description.IsEmpty())
{
var descriptionRows = db.GetRows("pa_stock_item_description", new Dictionary<string, object>()
{
{"Name", Description}
}, new List<string>() { "Id" });
if (descriptionRows.RowsCount > 0)
{
itemDescriptionId = descriptionRows[0].GetValue<long>("Id");
}
else
{
itemDescriptionId = db.Insert("pa_stock_item_description", new Dictionary<string, object>()
{
{"Name", Description}
});
}
}
stockRows.Add(new Dictionary<string, object>
{
{"ArticleId", ArticleId},
{"PricelistId", pricelistId},
{"ItemId", itemId},
{"Stock", Stock},
{"PriceSell", PriceSell},
{"PriceBase", PriceBase},
{"UpdateDate", DateTime.Now},
{"ItemDescriptionId", itemDescriptionId},
{"IsDefected", Defect ? 1 : 0},
{"IsSecHand", SecondHand ? 1 : 0},
{"ArtLookupId", CurrentWriteIndex.ArtLookupId}
});
if (stockRows.Count == Constants.StockBulkRowsCount)
{
db.BulkInsert("pa_stock", stockRows);
stockRows.Clear();
}
DBProviderItemNumber++;
// наращиваем счетчик сохраненных позиций
result.NumberSavedRows++;
List<string> CurrentRowCrosses = CAnalysingInterface.GetCrossesFromSpecifiedValues(Crosses);
if (CurrentRowCrosses.Count > 0)
{
if (FoundedCrosses.Where(item => { return item.Key[0] == ArticleId && item.Key[1] == ManufacturerId; }).Count() == 0)
{
FoundedCrosses.Add(new uint[] { ArticleId, ManufacturerId }, CurrentRowCrosses);
}
else
{
FoundedCrosses.Where(item => { return item.Key[0] == ArticleId && item.Key[1] == ManufacturerId; }).First().Value.AddRange(CurrentRowCrosses);
}
}
TotalRowsInPriceList++;
Logger.LogMessage("«" + PriceListFileName + "» → " + Article + " saved to DB (item #" + TotalRowsInPriceList + ").");
}
if (stockRows.Count > 0)
{
db.BulkInsert("pa_stock", stockRows);
stockRows.Clear();
}
}
//4. Сохраняем все найденные кроссы
Logger.LogMessage("«" + PriceListFileName + "» → Saving crosses...");
if (FoundedCrosses.Count > 0)
{
//this.DBEventWriter.InsertEvent(db, this.AssignedStatusId, DateTime.Now, "Запись найденных позиций в базу данных завершена. Запуск записи кроссов...", 5,
// this.DepartmentId, this.ProviderId);
int WritedCrossesCount = 0;
int NewCrosses = 0;
foreach (KeyValuePair<uint[], List<string>> CrossPair in FoundedCrosses)
{
if (CrossPair.Value.Count > 0)
{
int CrossesLimiter = 0;
foreach (string Cross in CrossPair.Value)
{
if (Cross.Length > 20)
continue;
//Получаем идентификатор Кросса
uint CrossArticleId = 0;
uint? CrossArticleSearchingResults = ArticlesHashAccessor.Search(Cross);
if (CrossArticleSearchingResults.HasValue)
{
// Кросс с указанным кодом существует в базе, получаем его идентификатор
CrossArticleId = CrossArticleSearchingResults.Value;
}
else
{
//Кросс с указанным кодом не существует в базе. Добавляеми нформацию о нем
CrossArticleId = Convert.ToUInt32(db.Insert("pa_article", new Dictionary<string, object>() {
{ "Article", Cross }
}));
Global.EntitiesStorage.PCMArticlesHashStorage.AddEntry(Cross, CrossArticleId);
}
if (CrossArticleId == CrossPair.Key[0])
{
//Cross, who linking to himself. Skip information.
continue;
}
var CheckCrossAlreadyWrittenRows = db.GetRows("SELECT COUNT(\"ArticleId\") FROM pa_crosses WHERE \"CArticleId\" = " + CrossArticleId + " AND \"ArticleId\" = " + CrossPair.Key[0]);
if (CheckCrossAlreadyWrittenRows.GetValue<int>(0, 0) == 0)
{
db.Insert("pa_crosses", new Dictionary<string, object> {
{ "ArticleId", CrossPair.Key[0] },
{ "CArticleId", CrossArticleId }
}, "ArticleId");
NewCrosses++;
CrossesLimiter++;
if (CrossesLimiter > 20) //Allowed only 10 crosses for each row
break;
}
}
}
Logger.LogMessage("Saving crosses information #" + (++WritedCrossesCount));
}
//this.DBEventWriter.InsertEvent(db, this.AssignedStatusId, DateTime.Now, "Запись кроссов завершена. Всего проанализировано кроссов - " +
// FoundedCrosses.Count + ", найдено новых кроссов - " + NewCrosses, 5, this.DepartmentId, this.ProviderId);
}
else
{
//this.DBEventWriter.InsertEvent(db, this.AssignedStatusId, DateTime.Now, "Запись найденных позиций в базу данных завершена",
// 5, this.DepartmentId, this.ProviderId);
}
//this.DBEventWriter.InsertEvent(db, this.AssignedStatusId, DateTime.Now, "Запись данных по данному файлу завершена. Обновление статистической информации...",
// 5, this.DepartmentId, this.ProviderId);
//this.DBEventWriter.InsertEvent(db, this.AssignedStatusId, DateTime.Now, "Успешно сохранено " + TotalRowsInPriceList + " позиций, не удалось сохранить "
// + UnsavedItemsCount_ErrorInItemData + " позиций, пропущено " + IdenticalArticles_ErrorCount + " позиций с одинаковыми артикулами", 5, this.DepartmentId, this.ProviderId);
Logger.LogMessage("«" + PriceListFileName + "» → Refreshing provider total stat information...");
//5. Обновляем информацию, статусы и статистику по магазинам
List<long> allProviders = new List<long>();
allProviders.AddRange(linkedProviderIds);
allProviders.Add(ProviderId);
foreach (long providerId in allProviders)
{
db.Update("pa_provider", new Dictionary<string, object>()
{
{"Id", providerId}
}, new Dictionary<string, object>()
{
{"LoadPriceLastDate", pricelistDate}
});
}
// Пишем в "События системы" факт загрузки прайс-листа
long logId = db.Insert("ws_log", new Dictionary<string, object>()
{
{"EventId", (int) Constants.LogEvent.ProcessPricelist},
{"Date", DateTime.Now},
{"UserId", userId},
{"Ip", 0},
{"Message", string.Format("Обработан и загружен в систему прайс-лист '{0}' ({1} позиций)", PriceListFileName, TotalRowsInPriceList)}
});
db.Insert("ws_log_pricelist", new Dictionary<string, object>()
{
{"LogId", logId},
{"StockCount", TotalRowsInPriceList}
});
// Устанавливаем флаг успешной загрузки
if (TotalRowsInPriceList > 0)
{
result.Success = true;
}
//tran.Commit();
}
else
{
result.ErrorRows.Insert(0, string.Format("Количество позиций прайс-листа {0}, что превышает допустимое количество {1}", ReadingResults.GetTotalRows(), limitPricelistVolume));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment