Created
May 31, 2016 10:15
-
-
Save maxlord/849e018142197a6cd4dccb1533875ca4 to your computer and use it in GitHub Desktop.
MyPrice Import PriceList
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Создаем запись о новом прайс-листе в БД | |
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