0
0
RhSolutions-Api/RhSolutions.Api/Services/ClosedXMLParser.cs
2022-12-18 11:58:29 +03:00

139 lines
3.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using ClosedXML.Excel;
using RhSolutions.Api.Models;
namespace RhSolutions.Api.Services
{
public class ClosedXMLParser : IPricelistParser
{
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 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
};
}
}
}