private static void Main(string[] args) { try { RegisterServices(); AddConfiguration(); // todo: replace with real data provider and put into DI for better usage. var mockContext = new MockDbContextDto { Barcodes = _barcodes, Catalog = _catalogs, Supplier = _suppliers, ConsolidatedCatalog = _consolidatedCatalogs, Company = _companies }; GetDataSource(mockContext); ProcessProducts(mockContext); PrintProcessedData(mockContext); } catch (Exception e) { Logger.Error(e); } Console.WriteLine("Press enter to exist."); Console.ReadLine(); DisposeServices(); }
private static void PrintProcessedData(MockDbContextDto context) { var csvSvc = _serviceProvider.GetService <ICsvServices>(); if (csvSvc == null) { throw new Exception("Fail to initial service(s)."); } csvSvc.WriteOutput(context.ConsolidatedCatalog, _config["OutputFilePath"]); }
private static void ProcessProducts(MockDbContextDto mockContext) { Logger.Info("Processing data."); var _service = _serviceProvider.GetService <IProductService>(); if (_service == null) { throw new Exception("Fail to initial IProductService."); } _service.ProcessProduct(mockContext); }
/// <summary> /// Steps for processing products: /// 1. Product barcode is provided by manufacturers, which is unique. /// 2. When two lines contain same barcode, take the line with smaller source Id (company id) /// 3. Group data by SKU (internal product code), Source Id (Company) /// </summary> /// <param name="mockContext"></param> /// <exception cref="NotImplementedException"></exception> public void ProcessProduct(MockDbContextDto mockContext) { // Step 1, group by barcode due to barcode is unique var barcodeList = GetBarcodeList(mockContext); // Step 2, extract SKU associated with supplier. If there's two supplier, take smaller source Id. var consolidatedList = GetCatalogList(barcodeList); // Step 3, Build data set. var result = BuildConsolidatedCatalog(consolidatedList, mockContext); mockContext.ConsolidatedCatalog.AddRange(result); }
public void Test1() { // Arrange var bc1 = new SupplierProductBarcode { Barcode = barcode1, DataSourceId = dataSourceId1, Sku = sku1, SupplierId = supplierId1 }; // Same barcode, we consider same product, even they are not the same sku. var SameBarcodeWithBc1 = new SupplierProductBarcode { Barcode = barcode1, DataSourceId = dataSourceId2, Sku = sku2, SupplierId = supplierId2 }; var SameSkuWithBc1DiffBarcode = new SupplierProductBarcode { Barcode = barcode2, DataSourceId = dataSourceId1, Sku = sku1, SupplierId = supplierId1 }; // Prevent context shared across test and mess up result. var context = new MockDbContextDto { Barcodes = new List <SupplierProductBarcode> { bc1, SameBarcodeWithBc1, SameSkuWithBc1DiffBarcode }, Catalog = new List <Catalog>(), Supplier = new List <Supplier>(), ConsolidatedCatalog = new List <ConsolidatedCatalog>() }; // Action List <BarcodeDto> result = null; var exception = Record.Exception(() => { result = _service.GetBarcodeList(context); }); // Assert Assert.Null(exception); Assert.NotNull(result); Assert.True(result.Count == 2, "Should only return one barcode."); Assert.True(result.First().Skus.Count == 2, $"Barcode {result.First().Barcode} should contain 2 SKUs."); }
public IEnumerable <ConsolidatedCatalog> BuildConsolidatedCatalog( IEnumerable <ConsolidatedCatalog> consolidatedList, MockDbContextDto mockContext) { var result = (from cList in consolidatedList join company in mockContext.Company on cList.DataSourceId equals company.SourceId join product in mockContext.Catalog on new { cList.Sku, cList.DataSourceId } equals new { product.Sku, product.DataSourceId } select new ConsolidatedCatalog { Sku = cList.Sku, Description = product.Description, DataSourceId = cList.DataSourceId, Source = company.SourceName }).ToList(); return(result); }
public List <BarcodeDto> GetBarcodeList(MockDbContextDto mockDbContext) { var barcodeList = ( from bc in mockDbContext.Barcodes group bc by bc.Barcode into groupList select new BarcodeDto { Barcode = groupList.Key, Skus = groupList.Select(g => new SkuDto { Sku = g.Sku, DataSourceId = g.DataSourceId, SupplierId = g.SupplierId }).OrderBy(g => g.DataSourceId).ToList() }).ToList(); return(barcodeList); }
public void Test1() { #region Data Mock var company1 = new Company { SourceId = 1, SourceName = "Company A" }; var company2 = new Company { SourceId = 2, SourceName = "B" }; var product1 = new Catalog { DataSourceId = 1, Description = "Fake product 1", Sku = "FAKE-PRD-1" }; var product2 = new Catalog { DataSourceId = 2, Description = "Fake product 2", Sku = "FAKE-PRD-2" }; #endregion var input = new List <ConsolidatedCatalog> { new ConsolidatedCatalog { DataSourceId = 1, Sku = "FAKE-PRD-1" }, new ConsolidatedCatalog { DataSourceId = 2, Sku = "FAKE-PRD-2" } }; var context = new MockDbContextDto { Company = new List <Company> { company1, company2 }, Catalog = new List <Catalog> { product1, product2 } }; List <ConsolidatedCatalog> result = null; var exception = Record.Exception(() => { result = _service.BuildConsolidatedCatalog(input, context).ToList(); }); Assert.Null(exception); Assert.True(result.Count == 2, "Should return 2 items."); var result1 = result.First(); var result2 = result.Skip(1).First(); Assert.Equal("FAKE-PRD-1", result1.Sku); Assert.Equal(1, result1.DataSourceId); Assert.Equal("Company A", result1.Source); Assert.Equal("FAKE-PRD-2", result2.Sku); Assert.Equal(2, result2.DataSourceId); Assert.Equal("B", result2.Source); }
private static void GetDataSource(MockDbContextDto context) { var csvSvc = _serviceProvider.GetService <ICsvServices>(); var datasourceService = _serviceProvider.GetService <IDatasourceService>(); if (csvSvc == null || datasourceService == null) { throw new Exception("Fail to initial service(s)."); } // read file names var fileNames = Directory.GetFiles(_config["InputFilePath"]) .Select(Path.GetFileName) .ToArray(); var dataSources = new List <DataSourceDto>(); foreach (var fileName in fileNames) { var sourceName = datasourceService.GetDataSourceName(fileName, out var dataSourceType); var exist = dataSources.FirstOrDefault(d => string.Equals(d.SourceName, sourceName)); if (exist == null) { dataSources.Add(new DataSourceDto(dataSources.Count + 1, sourceName, fileName, dataSourceType)); } else { exist.SetupFileName(fileName, dataSourceType); } } // Log incomplete data source. var incompleteDataSource = dataSources.Where(d => !d.GotAllDataSource()).ToList(); if (incompleteDataSource.Any()) { Logger.Info("** Following data source will be skip due to missing data source file;"); foreach (var dataSource in incompleteDataSource) { var msg = $"Data Source: {dataSource.SourceName}" + $"{(string.IsNullOrWhiteSpace(dataSource.BarcodeFilename) ? Environment.NewLine + "Barcode file." : string.Empty)}" + $"{(string.IsNullOrWhiteSpace(dataSource.BarcodeFilename) ? Environment.NewLine + "Barcode file." : string.Empty)}" + $"{(string.IsNullOrWhiteSpace(dataSource.BarcodeFilename) ? Environment.NewLine + "Barcode file." : string.Empty)}"; Logger.Info(msg); } } foreach (var source in dataSources.Where(d => d.GotAllDataSource())) { Logger.Info($"Adding data source from {source.SourceName}, sourceId: {source.SourceId}"); context.Company.Add(_mapper.Map <DataSourceDto, Company>(source)); context.Catalog.AddRange(csvSvc.ReadCatalogs(source.CatalogFilename, source.SourceId, _config["InputFilePath"])); context.Supplier.AddRange(csvSvc.ReadSuppliers(source.SupplierFileName, source.SourceId, _config["InputFilePath"])); context.Barcodes.AddRange(csvSvc.ReadBarcodes(source.BarcodeFilename, source.SourceId, _config["InputFilePath"])); } }