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

159 lines
3.7 KiB
C#
Raw Normal View History

2022-12-14 09:53:10 +03:00
using ClosedXML.Excel;
using RhSolutions.Api.Models;
namespace RhSolutions.Api.Services
{
public class ClosedXMLParser : IPricelistParser
{
// HttpContext? context;
// XLWorkbook? wb;
// public ClosedXMLParser(IHttpContextAccessor accessor)
// {
// this.context = accessor.HttpContext;
// }
// public void Dispose()
// {
// wb?.Dispose();
// }
public async IAsyncEnumerable<Product> GetProducts(HttpContext context)
{
using (var memoryStream = new MemoryStream())
{
if (context == null)
{
yield break;
}
await context.Request.Body.CopyToAsync(memoryStream);
using (var wb = new XLWorkbook(memoryStream))
{
var table = GetTable(wb);
var rows = table.DataRange.Rows();
var enumerator = rows.GetEnumerator();
while (enumerator.MoveNext())
{
if (Sku.TryParse(enumerator.Current.Field("Актуальный материал")
.GetString(), out IEnumerable<Sku> skus))
{
yield return ParseRow(enumerator.Current);
}
}
yield break;
}
}
}
// private async Task<XLWorkbook> GetWorkbook(HttpContext context)
// {
// using var memoryStream = new MemoryStream();
// return ;
// }
private IXLTable GetTable(XLWorkbook wb)
{
var ws = wb.Worksheets.First();
ws.AutoFilter.IsEnabled = false;
try
{
var firstCellAddress = ws.Search("Программа", System.Globalization.CompareOptions.IgnoreCase)
.First()
.Address;
var lastCellAddress = ws.LastCellUsed().Address;
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();
Sku.TryParse(row.Field("Актуальный материал")
.GetString(), out IEnumerable<Sku> productSkus);
Sku.TryParse(row.Field("Прежний материал")
.GetString(), out IEnumerable<Sku> deprecatedSkus);
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;
}
string onWarehouseField = row.Field("Складская программа")
.GetString();
bool? IsOnWarehouse;
switch (onWarehouseField)
{
case "x":
IsOnWarehouse = true;
break;
case "под заказ":
IsOnWarehouse = false;
break;
default:
IsOnWarehouse = null;
break;
}
string priceField = row.Field("Цена брутто \nЕВРО\nбез НДС")
.GetString();
if (!decimal.TryParse(priceField, out decimal price))
{
price = 0.0M;
}
return new Product
{
ProductLine = productLine,
Name = productName,
ProductSku = productSkus.First().Id,
DeprecatedSkus = deprecatedSkus.Select(s => s.Id).ToList(),
ProductMeasure = productMeasure,
DeliveryMakeUp = productWarehouseCount,
IsOnWarehouse = IsOnWarehouse,
Price = price
};
}
}
}