< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 174
Coverable lines: 174
Total lines: 329
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 76
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()0%506220%
TryLoadSystemFonts()0%2040%
BuildHeader(...)100%210%
BuildOrdersTable(...)100%210%
SetOrdersStock(...)100%210%
GetPdf()0%2352480%
CreateFallbackPdf(...)0%620%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/Builders/PdfBuilder/Builders/OrderedToSupplierPdfBuilder.cs

#LineLine coverage
 1using iText.IO.Font;
 2using iText.Kernel.Font;
 3using iText.Kernel.Pdf;
 4using iText.Layout;
 5using iText.Layout.Element;
 6using iText.IO.Image;
 7using System.IO;
 8using iText.IO.Font.Constants;
 9using iText.Layout.Properties;
 10using iText.Kernel.Colors;
 11using OzonDomains;
 12using OzonDomains.Models;
 13using OzonDomains.Models.BitrixModels;
 14
 15public class ShippedToSellerPdfBuilder : IPdfBuilder
 16{
 17    private MemoryStream _memoryStream = null!;
 18    private PdfWriter _writer = null!;
 19    private PdfDocument _pdf = null!;
 20    private Document _document = null!;
 21    private PdfFont _font = null!;
 22    private PdfFont _boldFont = null!;
 23    private Transaction _transaction = null!;
 24    private ICollection<Order> _orders = null!;
 25    private Dictionary<int, List<StockInfo>> _stocks = null!;
 26
 027    public ShippedToSellerPdfBuilder()
 28    {
 029        _memoryStream = new MemoryStream();
 030        _writer = new PdfWriter(_memoryStream);
 031        _pdf = new PdfDocument(_writer);
 032        _document = new Document(_pdf);
 033        _document.SetMargins(40, 40, 40, 40);
 34
 35        try
 36        {
 37            // Попробуем использовать шрифты, которые точно поддерживают кириллицу
 038            string[] knownCyrillicFonts = {
 039                "times.ttf", "timesbd.ttf",               // Times New Roman
 040                "dejavu-sans.ttf", "dejavu-sans-bold.ttf", // DejaVu Sans
 041                "liberation-sans.ttf", "liberation-sans-bold.ttf", // Liberation Sans
 042                "freesans.ttf", "freesansbold.ttf",       // FreeSans
 043                "arial.ttf", "arialbd.ttf"                // Arial
 044            };
 45
 046            string? regularFontPath = null;
 047            string? boldFontPath = null;
 48
 49            // Ищем папку со шрифтами
 050            string[] possibleFontFolders = {
 051                Path.Combine(Directory.GetCurrentDirectory(), "Fonts"),
 052                Path.Combine(Directory.GetCurrentDirectory(), "fonts"),
 053                Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "fonts"),
 054                Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Fonts"),
 055                Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fonts")
 056            };
 57
 058            foreach (var folder in possibleFontFolders)
 59            {
 060                if (Directory.Exists(folder))
 61                {
 062                    foreach (var fontFile in knownCyrillicFonts)
 63                    {
 064                        string path = Path.Combine(folder, fontFile);
 065                        if (File.Exists(path))
 66                        {
 067                            if (fontFile.Contains("bold") || fontFile.Contains("bd"))
 68                            {
 069                                boldFontPath = path;
 70                            }
 071                            else if (!fontFile.Contains("bold") && !fontFile.Contains("bd"))
 72                            {
 073                                regularFontPath = path;
 74                            }
 75                        }
 76                    }
 77
 078                    if (regularFontPath != null) break;
 79                }
 80            }
 81
 082            if (regularFontPath != null)
 83            {
 084                _font = PdfFontFactory.CreateFont(regularFontPath, PdfEncodings.IDENTITY_H);
 085                _boldFont = boldFontPath != null
 086                    ? PdfFontFactory.CreateFont(boldFontPath, PdfEncodings.IDENTITY_H)
 087                    : PdfFontFactory.CreateFont(regularFontPath, PdfEncodings.IDENTITY_H);
 88
 089                Console.WriteLine($"Успешно загружены шрифты: {regularFontPath}");
 90            }
 91            else
 92            {
 093                TryLoadSystemFonts();
 94            }
 095        }
 096        catch (Exception ex)
 97        {
 098            TryLoadSystemFonts();
 099            Console.WriteLine($"Ошибка загрузки шрифтов: {ex.Message}");
 0100        }
 0101    }
 102
 103    private void TryLoadSystemFonts()
 104    {
 105        try
 106        {
 107            // Пути к шрифтам в Linux
 0108            string[] linuxFontPaths = {
 0109                "/usr/share/fonts/truetype/freefont/FreeSans.ttf",
 0110                "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
 0111                "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
 0112                "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf"
 0113            };
 114
 0115            foreach (var path in linuxFontPaths)
 116            {
 0117                if (File.Exists(path))
 118                {
 0119                    _font = PdfFontFactory.CreateFont(path, PdfEncodings.IDENTITY_H);
 0120                    _boldFont = PdfFontFactory.CreateFont(path, PdfEncodings.IDENTITY_H);
 0121                    Console.WriteLine($"Используем системный шрифт: {path}");
 0122                    return;
 123                }
 124            }
 125
 126            // Если ничего не найдено, используем стандартные шрифты
 0127            _font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
 0128            _boldFont = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLD);
 0129            Console.WriteLine("Используются стандартные шрифты Helvetica (кириллица не поддерживается)");
 0130        }
 0131        catch
 132        {
 0133            _font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
 0134            _boldFont = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLD);
 0135        }
 0136    }
 137    public void BuildHeader(Transaction transaction)
 138    {
 0139        _transaction = transaction;
 0140    }
 141
 142    public void BuildOrdersTable(ICollection<Order> orders)
 143    {
 0144        _orders = orders;
 0145    }
 146
 147    public void SetOrdersStock(Dictionary<int, List<StockInfo>> stocks)
 148    {
 0149        _stocks = stocks;
 0150    }
 151
 152    public byte[] GetPdf()
 153    {
 154        try
 155        {
 156            // Заголовок документа
 0157            _document.Add(new Paragraph($"{_transaction.Type?.GetDisplayName()} № {_transaction.Id} от {_transaction.For
 0158                .SetFont(_boldFont)
 0159                .SetFontSize(14)
 0160                .SetTextAlignment(TextAlignment.LEFT));
 161
 162           // Информация об отправителе (остается одна для всех заказов)
 0163            var sender = _orders?.FirstOrDefault()?.ShipmentWarehouse?.Name ?? "Не указан";
 0164            _document.Add(new Paragraph($"Отправитель: {sender}")
 0165                .SetFont(_font)
 0166                .SetFontSize(11));
 167
 168            // Группируем заказы по клиентам
 0169            var ordersByClient = _orders?
 0170                .Where(o => o.OzonClient != null)
 0171                .GroupBy(o => o.OzonClient)
 0172                .ToList();
 173
 0174            if (ordersByClient != null && ordersByClient.Any())
 175            {
 0176                foreach (var clientGroup in ordersByClient)
 177                {
 0178                    var client = clientGroup.Key;
 0179                    var clientOrders = clientGroup.ToList();
 0180                    var receiver = client?.WarehouseName ?? "Не указан";
 181
 182                    // Добавляем заголовок для клиента
 0183                    _document.Add(new Paragraph($"Получатель: {receiver} ({client?.Name ?? "—"})")
 0184                        .SetFont(_font)
 0185                        .SetFontSize(11)
 0186                        .SetMarginTop(15)
 0187                        .SetMarginBottom(5));
 188
 189                    // Таблица с товарами для текущего клиента
 0190                    Table table = new Table(UnitValue.CreatePercentArray(new float[] { 6, 12, 12, 35, 10, 25 }))
 0191                        .UseAllAvailableWidth()
 0192                        .SetWidth(UnitValue.CreatePercentValue(100));
 193
 194                    // Стиль для заголовков таблицы
 0195                    var headerStyle = new Style()
 0196                        .SetBackgroundColor(ColorConstants.LIGHT_GRAY)
 0197                        .SetPadding(5)
 0198                        .SetTextAlignment(TextAlignment.CENTER)
 0199                        .SetFont(_boldFont)
 0200                        .SetFontSize(8);
 201
 202                    // Стиль для ячеек с данными
 0203                    var cellStyle = new Style()
 0204                        .SetPadding(5)
 0205                        .SetTextAlignment(TextAlignment.LEFT)
 0206                        .SetFont(_font)
 0207                        .SetFontSize(7);
 208
 209                    // Заголовки таблицы
 0210                    table.AddHeaderCell(new Cell().Add(new Paragraph("№").SetTextAlignment(TextAlignment.CENTER)).AddSty
 0211                    table.AddHeaderCell(new Cell().Add(new Paragraph("Код").SetTextAlignment(TextAlignment.CENTER)).AddS
 0212                    table.AddHeaderCell(new Cell().Add(new Paragraph("Производитель").SetTextAlignment(TextAlignment.CEN
 0213                    table.AddHeaderCell(new Cell().Add(new Paragraph("Товары").SetTextAlignment(TextAlignment.CENTER)).A
 0214                    table.AddHeaderCell(new Cell().Add(new Paragraph("Количество").SetTextAlignment(TextAlignment.CENTER
 0215                    table.AddHeaderCell(new Cell().Add(new Paragraph("Остаток на складе").SetTextAlignment(TextAlignment
 216
 217                    // Данные таблицы для текущего клиента
 0218                    int rowNumber = 1;
 0219                    foreach (var order in clientOrders)
 220                    {
 221                        // №
 0222                        table.AddCell(new Cell()
 0223                            .Add(new Paragraph(rowNumber.ToString()).SetTextAlignment(TextAlignment.CENTER))
 0224                            .AddStyle(cellStyle));
 225
 226                        // Код товара
 0227                        table.AddCell(new Cell()
 0228                            .Add(new Paragraph(order.ProductKey ?? ""))
 0229                            .AddStyle(cellStyle));
 230
 231                        // Производитель
 0232                        var producerName = order.EtProducer?.Name ?? "";
 0233                        table.AddCell(new Cell()
 0234                            .Add(new Paragraph(producerName))
 0235                            .AddStyle(cellStyle));
 236
 237                        // Название товара
 0238                        var productName = string.IsNullOrEmpty(order.ProductName) ? "" : order.ProductName;
 0239                        table.AddCell(new Cell()
 0240                            .Add(new Paragraph(productName))
 0241                            .AddStyle(cellStyle));
 242
 243                        // Количество
 0244                        table.AddCell(new Cell()
 0245                            .Add(new Paragraph($"{order.Quantity} шт").SetTextAlignment(TextAlignment.CENTER))
 0246                            .AddStyle(cellStyle));
 247
 248                        // Остаток на складе
 0249                        var stockCell = new Cell().AddStyle(cellStyle);
 250
 0251                        if (_stocks != null && _stocks.TryGetValue(order.Id, out var stockInfos) && stockInfos != null &
 252                        {
 253                            // Создаем список остатков для этого заказа
 0254                            foreach (var stock in stockInfos)
 255                            {
 0256                                stockCell.Add(new Paragraph($"{stock.StoreTitle}: {stock.Amount} шт")
 0257                                    .SetFontSize(6)
 0258                                    .SetMargin(0)
 0259                                    .SetPadding(0));
 260                            }
 261                        }
 262                        else
 263                        {
 0264                            stockCell.Add(new Paragraph("Нет данных").SetFontSize(6));
 265                        }
 266
 0267                        table.AddCell(stockCell);
 268
 0269                        rowNumber++;
 270                    }
 271
 0272                    _document.Add(table);
 273
 274                    // Добавляем отступ между таблицами клиентов
 0275                    _document.Add(new Paragraph(" ").SetMarginBottom(10));
 276                }
 277            }
 278            else
 279            {
 0280                _document.Add(new Paragraph("Получатель: Не указан")
 0281                    .SetFont(_font)
 0282                    .SetFontSize(11)
 0283                    .SetMarginBottom(10));
 284
 0285                _document.Add(new Paragraph("Нет данных о заказах")
 0286                    .SetFont(_font)
 0287                    .SetFontSize(10)
 0288                    .SetFontColor(ColorConstants.RED));
 289            }
 290
 291            // Добавляем комментарий если есть
 0292            if (!string.IsNullOrEmpty(_transaction.Comment))
 293            {
 0294                _document.Add(new Paragraph($"Примечание: {_transaction.Comment}")
 0295                    .SetFont(_font)
 0296                    .SetFontSize(10)
 0297                    .SetMarginTop(10));
 298            }
 299
 0300            _document.Close();
 0301            return _memoryStream.ToArray();
 302        }
 0303        catch (Exception ex)
 304        {
 0305            return CreateFallbackPdf(ex.Message);
 306        }
 0307    }
 308
 309    private byte[] CreateFallbackPdf(string? errorMessage = null)
 310    {
 0311        var fallbackStream = new MemoryStream();
 0312        var fallbackWriter = new PdfWriter(fallbackStream);
 0313        var fallbackPdf = new PdfDocument(fallbackWriter);
 0314        var fallbackDoc = new Document(fallbackPdf);
 315
 0316        fallbackDoc.Add(new Paragraph("Перемещение запасов").SetFontSize(16));
 317
 0318        if (!string.IsNullOrEmpty(errorMessage))
 319        {
 0320            fallbackDoc.Add(new Paragraph($"Ошибка: {errorMessage}").SetFontColor(ColorConstants.RED));
 321        }
 322
 0323        fallbackDoc.Add(new Paragraph($"№ {_transaction.Id}"));
 0324        fallbackDoc.Add(new Paragraph($"Дата: {_transaction.FormattedCreatedTimeDateTime}"));
 325
 0326        fallbackDoc.Close();
 0327        return fallbackStream.ToArray();
 328    }
 329}