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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        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.");
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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"]));
            }
        }