0
0
RhSolutions-Api/RhSolutions.Api/Services/ClosedXMLParser.cs

134 lines
3.2 KiB
C#
Raw Normal View History

2022-12-14 09:53:10 +03:00
using ClosedXML.Excel;
2023-05-11 07:55:26 +03:00
using RhSolutions.Models;
2022-12-14 09:53:10 +03:00
namespace RhSolutions.Api.Services
{
public class ClosedXMLParser : IPricelistParser
{
2024-08-08 16:38:23 +03:00
public IEnumerable<Product> GetProducts(IFormFile? file)
2022-12-14 09:53:10 +03:00
{
2024-08-08 16:38:23 +03:00
if (file == null)
2022-12-14 09:53:10 +03:00
{
2024-08-08 16:38:23 +03:00
yield break;
}
using XLWorkbook wb = new XLWorkbook(file.OpenReadStream());
var table = GetTable(wb);
var rows = table.DataRange.Rows();
foreach (var row in rows)
{
if (ProductSku.TryParse(row.Field("Актуальный материал")
.GetString(), out _))
2022-12-14 09:53:10 +03:00
{
2024-08-08 16:38:23 +03:00
yield return ParseRow(row);
2022-12-14 09:53:10 +03:00
}
}
}
private IXLTable GetTable(XLWorkbook wb)
{
var ws = wb.Worksheets.First();
ws.AutoFilter.IsEnabled = false;
try
{
var firstCellAddress = ws.Search("Программа", System.Globalization.CompareOptions.IgnoreCase)
.First()
2024-08-26 18:07:50 +03:00
.CellLeft()
2022-12-14 09:53:10 +03:00
.Address;
2024-08-26 18:07:50 +03:00
var lastCellAddress = ws.Search("Цена брутто", System.Globalization.CompareOptions.IgnoreCase)
.First()
.WorksheetColumn()
.LastCellUsed()
.Address;
2022-12-14 09:53:10 +03:00
return ws.Range(firstCellAddress, lastCellAddress).AsTable();
}
catch (Exception ex)
{
throw new Exception($"Exception on parsing {ws.Name}:\n{ex.Message}");
}
}
private Product ParseRow(IXLTableRow row)
{
string productLine = row.Field("Программа")
.GetString();
string productName = row.Field("Наименование")
.GetString()
.Split('\n')
.First();
2023-05-11 07:55:26 +03:00
ProductSku.TryParse(row.Field("Актуальный материал")
.GetString(), out IEnumerable<ProductSku> productSkus);
ProductSku.TryParse(row.Field("Прежний материал")
.GetString(), out IEnumerable<ProductSku> deprecatedSkus);
2022-12-14 09:53:10 +03:00
string measureField = new string(row.Field("Ед. изм.")
.GetString()
.ToLower()
.Where(c => char.IsLetterOrDigit(c))
.ToArray());
Measure productMeasure;
switch (measureField)
{
case "кг":
productMeasure = Measure.Kg;
break;
case "м":
productMeasure = Measure.M;
break;
case "м2":
productMeasure = Measure.M2;
break;
case "шт":
productMeasure = Measure.P;
break;
default:
throw new ArgumentException();
}
string shippingSizeField = row.Field("Единица поставки")
.GetString();
if (!double.TryParse(shippingSizeField, out double productWarehouseCount))
{
productWarehouseCount = 0.0;
}
2024-08-26 18:07:50 +03:00
string onWarehouseField = row.Field(0)
2022-12-14 09:53:10 +03:00
.GetString();
2023-05-11 07:55:26 +03:00
bool IsOnWarehouse;
2022-12-14 09:53:10 +03:00
switch (onWarehouseField)
{
2024-08-26 18:07:50 +03:00
case "N":
2022-12-14 09:53:10 +03:00
IsOnWarehouse = true;
break;
2024-08-26 18:07:50 +03:00
case "Z":
2022-12-14 09:53:10 +03:00
IsOnWarehouse = false;
break;
default:
2023-05-11 07:55:26 +03:00
IsOnWarehouse = false;
2022-12-14 09:53:10 +03:00
break;
}
string priceField = row.Field("Цена брутто \nЕВРО\nбез НДС")
.GetString();
if (!decimal.TryParse(priceField, out decimal price))
{
price = 0.0M;
}
2023-05-11 07:55:26 +03:00
return new Product(productSkus.First())
2022-12-14 09:53:10 +03:00
{
2023-05-11 07:55:26 +03:00
ProductLines = new List<string>() { productLine },
2022-12-14 09:53:10 +03:00
Name = productName,
2023-05-11 07:55:26 +03:00
DeprecatedSkus = deprecatedSkus.ToList(),
2022-12-14 09:53:10 +03:00
ProductMeasure = productMeasure,
DeliveryMakeUp = productWarehouseCount,
IsOnWarehouse = IsOnWarehouse,
Price = price
};
}
}
}