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
|
|
|
|
|
{
|
2023-05-11 07:55:26 +03:00
|
|
|
|
public List<Product> GetProducts(HttpContext context)
|
2022-12-14 09:53:10 +03:00
|
|
|
|
{
|
|
|
|
|
using (var memoryStream = new MemoryStream())
|
|
|
|
|
{
|
|
|
|
|
if (context == null)
|
|
|
|
|
{
|
2023-05-11 07:55:26 +03:00
|
|
|
|
return new List<Product>();
|
2022-12-14 09:53:10 +03:00
|
|
|
|
}
|
2023-05-11 07:55:26 +03:00
|
|
|
|
|
|
|
|
|
context.Request.Body.CopyToAsync(memoryStream).GetAwaiter().GetResult();
|
|
|
|
|
List<Product> products = new();
|
2022-12-14 09:53:10 +03:00
|
|
|
|
using (var wb = new XLWorkbook(memoryStream))
|
|
|
|
|
{
|
2023-05-11 07:55:26 +03:00
|
|
|
|
Dictionary<ProductSku, Product> collected = new();
|
2022-12-14 09:53:10 +03:00
|
|
|
|
var table = GetTable(wb);
|
|
|
|
|
var rows = table.DataRange.Rows();
|
2023-05-11 07:55:26 +03:00
|
|
|
|
foreach (var row in rows)
|
2022-12-14 09:53:10 +03:00
|
|
|
|
{
|
2023-05-11 07:55:26 +03:00
|
|
|
|
if (ProductSku.TryParse(row.Field("Актуальный материал")
|
|
|
|
|
.GetString(), out _))
|
2022-12-14 09:53:10 +03:00
|
|
|
|
{
|
2023-05-11 07:55:26 +03:00
|
|
|
|
products.Add(ParseRow(row));
|
2022-12-14 09:53:10 +03:00
|
|
|
|
}
|
2023-05-11 07:55:26 +03:00
|
|
|
|
}
|
2022-12-14 09:53:10 +03:00
|
|
|
|
}
|
2023-05-11 07:55:26 +03:00
|
|
|
|
return products;
|
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()
|
|
|
|
|
.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();
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string onWarehouseField = row.Field("Складская программа")
|
|
|
|
|
.GetString();
|
2023-05-11 07:55:26 +03:00
|
|
|
|
bool IsOnWarehouse;
|
2022-12-14 09:53:10 +03:00
|
|
|
|
|
|
|
|
|
switch (onWarehouseField)
|
|
|
|
|
{
|
|
|
|
|
case "x":
|
|
|
|
|
IsOnWarehouse = true;
|
|
|
|
|
break;
|
|
|
|
|
case "под заказ":
|
|
|
|
|
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
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|