From 1ec08919c353d1459c524442b81538fd57fe5e83 Mon Sep 17 00:00:00 2001 From: Serghei Cebotari Date: Mon, 28 Apr 2025 16:43:14 +0300 Subject: Refactor parsers to include logging functionality and update tests accordingly --- .../Services/CommonExcelParser.cs | 137 ++++++++++++--------- 1 file changed, 76 insertions(+), 61 deletions(-) (limited to 'RhSolutions.SkuParser.Api/Services/CommonExcelParser.cs') diff --git a/RhSolutions.SkuParser.Api/Services/CommonExcelParser.cs b/RhSolutions.SkuParser.Api/Services/CommonExcelParser.cs index eb4e1bb..2815a3c 100644 --- a/RhSolutions.SkuParser.Api/Services/CommonExcelParser.cs +++ b/RhSolutions.SkuParser.Api/Services/CommonExcelParser.cs @@ -1,4 +1,5 @@ using ClosedXML.Excel; +using Microsoft.Extensions.Logging; using RhSolutions.SkuParser.Abstractions; using RhSolutions.SkuParser.Models; @@ -6,75 +7,89 @@ namespace RhSolutions.SkuParser.Services; public class CommonExcelParser : ISkuParser { - public Dictionary ParseProducts(IFormFile file) - { - using XLWorkbook workbook = new(file.OpenReadStream()); - IXLWorksheet ws = workbook.Worksheets.FirstOrDefault(ws => ws.TabActive) ?? workbook.Worksheet(1); + private readonly ILogger logger; - var leftTop = ws.FirstCellUsed()?.Address; - var rightBottom = ws.LastCellUsed()?.Address; - if (new object?[] { leftTop, rightBottom }.Any(x => x == null)) - { - throw new ArgumentException($"Таблица пуста: {file.FileName}"); - } + public CommonExcelParser(ILogger logger) + { + this.logger = logger; + } - var lookupRange = ws.Range(leftTop, rightBottom).RangeUsed(); - var columns = lookupRange.Columns(); + public Dictionary ParseProducts(IFormFile file) + { + using XLWorkbook workbook = new(file.OpenReadStream()); + IXLWorksheet ws = workbook.Worksheets.FirstOrDefault(ws => ws.TabActive) ?? workbook.Worksheet(1); - var skuColumnQuantity = columns - .Select(column => new - { - Column = column, - Products = column.CellsUsed() - .Select(cell => !cell.HasFormula && Product.TryParse(cell.Value.ToString(), out Product? p) ? p : null) - }) - .Select(c => new { c.Column, SkuCount = c.Products.Count(p => p != null) }) - .Aggregate((l, r) => l.SkuCount > r.SkuCount ? l : r); - var skuColumn = skuColumnQuantity.SkuCount > 0 ? skuColumnQuantity.Column : null; + var leftTop = ws.FirstCellUsed()?.Address; + var rightBottom = ws.LastCellUsed()?.Address; + if (new object?[] { leftTop, rightBottom }.Any(x => x == null)) + { + throw new ArgumentException($"Таблица пуста: {file.FileName}"); + } - if (skuColumn == null) - { - throw new ArgumentException($"Столбец с артикулом не определен: {file.FileName}"); - } + var lookupRange = ws.Range(leftTop, rightBottom).RangeUsed(); + var columns = lookupRange.Columns(); - var quantityColumn = lookupRange.Columns().Skip(skuColumn.ColumnNumber()) - .Select(column => new - { - Column = column, - IsColumnWithNumbers = column.CellsUsed() - .Count(cell => cell.Value.IsNumber == true) > column.CellsUsed().Count() / 4 - }) - .First(x => x.IsColumnWithNumbers) - .Column; + var skuColumnQuantity = columns + .Select(column => new + { + Column = column, + Products = column.CellsUsed() + .Select(cell => !cell.HasFormula && Product.TryParse(cell.Value.ToString(), out Product? p) ? p : null) + }) + .Select(c => new { c.Column, SkuCount = c.Products.Count(p => p != null) }) + .Aggregate((l, r) => l.SkuCount > r.SkuCount ? l : r); + var skuColumn = skuColumnQuantity.SkuCount > 0 ? skuColumnQuantity.Column : null; - if (quantityColumn == null) - { - throw new ArgumentException($"Столбец с количеством не определен: {file.FileName}"); - } + if (skuColumn == null) + { + throw new ArgumentException($"Столбец с артикулом не определен: {file.FileName}"); + } - Dictionary result = new(); - var rows = quantityColumn.CellsUsed().Select(x => x.Address.RowNumber); + var quantityColumn = lookupRange.Columns().Skip(skuColumn.ColumnNumber()) + .Select(column => new + { + Column = column, + IsColumnWithNumbers = column.CellsUsed() + .Count(cell => cell.Value.IsNumber == true) > column.CellsUsed().Count() / 4 + }) + .First(x => x.IsColumnWithNumbers) + .Column; - foreach (var row in rows) - { - var quantity = quantityColumn.Cell(row).Value; - var sku = skuColumn.Cell(row).Value; + if (quantityColumn == null) + { + throw new ArgumentException($"Столбец с количеством не определен: {file.FileName}"); + } - if (quantity.IsNumber - && Product.TryParse(sku.ToString(), out Product? p) - && p != null) - { - if (result.ContainsKey(p)) - { - result[p] += (double)quantity; - } - else - { - result.Add(p, (double)quantity); - } - } - } + Dictionary result = new(); + var rows = quantityColumn.CellsUsed().Select(x => x.Address.RowNumber); - return result; - } + foreach (var row in rows) + { + var quantity = quantityColumn.Cell(row).Value; + var sku = skuColumn.Cell(row).Value; + + if (quantity.IsNumber + && Product.TryParse(sku.ToString(), out Product? p) + && p != null) + { + if (result.ContainsKey(p)) + { + result[p] += (double)quantity; + } + else + { + result.Add(p, (double)quantity); + } + } + } + + logger.LogInformation("Parsed {Count} products from file {FileName}.", result.Count, file.FileName); + foreach (var (product, quantity) in result) + { + logger.LogInformation("Product: {Sku}, Name: {Name}, Quantity: {Quantity}, Price: {Price}, ProductLine: {ProductLine}", + product.Sku, product.Name, quantity, product.Price, product.ProductLine); + } + + return result; + } } -- cgit v1.2.3