< Summary

Information
Class: Services.Builders.PdfBuilder.Builders.ShippedBySupplierPdfBuilder
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/Builders/PdfBuilder/Builders/ShippedBySupplierPdfBuilder.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 205
Coverable lines: 205
Total lines: 376
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 92
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%4160640%
CreateFallbackPdf(...)0%620%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/Builders/PdfBuilder/Builders/ShippedBySupplierPdfBuilder.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
 15namespace Services.Builders.PdfBuilder.Builders;
 16
 17public class ShippedBySupplierPdfBuilder: IPdfBuilder
 18{
 19    private MemoryStream _memoryStream = null!;
 20    private PdfWriter _writer = null!;
 21    private PdfDocument _pdf = null!;
 22    private Document _document = null!;
 23    private PdfFont _font = null!;
 24    private PdfFont _boldFont = null!;
 25    private Transaction _transaction = null!;
 26    private ICollection<Order> _orders = null!;
 27    private Dictionary<int, List<StockInfo>> _stocks = null!;
 28
 029    public ShippedBySupplierPdfBuilder()
 30    {
 031        _memoryStream = new MemoryStream();
 032        _writer = new PdfWriter(_memoryStream);
 033        _pdf = new PdfDocument(_writer);
 034        _document = new Document(_pdf);
 035        _document.SetMargins(40, 40, 40, 40);
 36
 37        try
 38        {
 39            // Попробуем использовать шрифты, которые точно поддерживают кириллицу
 040            string[] knownCyrillicFonts = {
 041                "times.ttf", "timesbd.ttf",               // Times New Roman
 042                "dejavu-sans.ttf", "dejavu-sans-bold.ttf", // DejaVu Sans
 043                "liberation-sans.ttf", "liberation-sans-bold.ttf", // Liberation Sans
 044                "freesans.ttf", "freesansbold.ttf",       // FreeSans
 045                "arial.ttf", "arialbd.ttf"                // Arial
 046            };
 47
 048            string? regularFontPath = null;
 049            string? boldFontPath = null;
 50
 51            // Ищем папку со шрифтами
 052            string[] possibleFontFolders = {
 053                Path.Combine(Directory.GetCurrentDirectory(), "Fonts"),
 054                Path.Combine(Directory.GetCurrentDirectory(), "fonts"),
 055                Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "fonts"),
 056                Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Fonts"),
 057                Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fonts")
 058            };
 59
 060            foreach (var folder in possibleFontFolders)
 61            {
 062                if (Directory.Exists(folder))
 63                {
 064                    foreach (var fontFile in knownCyrillicFonts)
 65                    {
 066                        string path = Path.Combine(folder, fontFile);
 067                        if (File.Exists(path))
 68                        {
 069                            if (fontFile.Contains("bold") || fontFile.Contains("bd"))
 70                            {
 071                                boldFontPath = path;
 72                            }
 073                            else if (!fontFile.Contains("bold") && !fontFile.Contains("bd"))
 74                            {
 075                                regularFontPath = path;
 76                            }
 77                        }
 78                    }
 79
 080                    if (regularFontPath != null) break;
 81                }
 82            }
 83
 084            if (regularFontPath != null)
 85            {
 086                _font = PdfFontFactory.CreateFont(regularFontPath, PdfEncodings.IDENTITY_H);
 087                _boldFont = boldFontPath != null
 088                    ? PdfFontFactory.CreateFont(boldFontPath, PdfEncodings.IDENTITY_H)
 089                    : PdfFontFactory.CreateFont(regularFontPath, PdfEncodings.IDENTITY_H);
 90
 091                Console.WriteLine($"Успешно загружены шрифты: {regularFontPath}");
 92            }
 93            else
 94            {
 095                TryLoadSystemFonts();
 96            }
 097        }
 098        catch (Exception ex)
 99        {
 0100            TryLoadSystemFonts();
 0101            Console.WriteLine($"Ошибка загрузки шрифтов: {ex.Message}");
 0102        }
 0103    }
 104
 105    private void TryLoadSystemFonts()
 106    {
 107        try
 108        {
 109            // Пути к шрифтам в Linux
 0110            string[] linuxFontPaths = {
 0111                "/usr/share/fonts/truetype/freefont/FreeSans.ttf",
 0112                "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
 0113                "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
 0114                "/usr/share/fonts/truetype/msttcorefonts/Arial.ttf"
 0115            };
 116
 0117            foreach (var path in linuxFontPaths)
 118            {
 0119                if (File.Exists(path))
 120                {
 0121                    _font = PdfFontFactory.CreateFont(path, PdfEncodings.IDENTITY_H);
 0122                    _boldFont = PdfFontFactory.CreateFont(path, PdfEncodings.IDENTITY_H);
 0123                    Console.WriteLine($"Используем системный шрифт: {path}");
 0124                    return;
 125                }
 126            }
 127
 128            // Если ничего не найдено, используем стандартные шрифты
 0129            _font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
 0130            _boldFont = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLD);
 0131            Console.WriteLine("Используются стандартные шрифты Helvetica (кириллица не поддерживается)");
 0132        }
 0133        catch
 134        {
 0135            _font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
 0136            _boldFont = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLD);
 0137        }
 0138    }
 139    public void BuildHeader(Transaction transaction)
 140    {
 0141        _transaction = transaction;
 0142    }
 143
 144    public void BuildOrdersTable(ICollection<Order> orders)
 145    {
 0146        _orders = orders;
 0147    }
 148
 149    public void SetOrdersStock(Dictionary<int, List<StockInfo>> stocks)
 150    {
 0151        _stocks = stocks;
 0152    }
 153
 154    public byte[] GetPdf()
 155    {
 156        try
 157        {
 158            // Заголовок документа
 0159            _document.Add(new Paragraph($"{_transaction.Type?.GetDisplayName()} № {_transaction.Id} от {_transaction.For
 0160                .SetFont(_boldFont)
 0161                .SetFontSize(14)
 0162                .SetTextAlignment(TextAlignment.LEFT));
 163
 164           // Информация об отправителе (остается одна для всех заказов)
 0165            var sender = _orders?.FirstOrDefault()?.ShipmentWarehouse?.Name ?? "Не указан";
 0166            _document.Add(new Paragraph($"Отправитель: {sender}")
 0167                .SetFont(_font)
 0168                .SetFontSize(11));
 169
 170            // Информация об поставщике
 0171            var supplier = _orders?.FirstOrDefault()?.Supplier;
 0172            var supplierName = supplier?.Name ?? "Не указан";
 0173            string ndsData = string.Empty;
 0174            if (supplier != null && supplier.IsVatApplicable)
 175            {
 0176                ndsData = "C налогом (НДС)";
 177            }
 178            else
 179            {
 0180                ndsData = "Без налога (НДС)";
 181            }
 0182            _document.Add(new Paragraph($"Поставщик: {supplierName}")
 0183                .SetFont(_font)
 0184                .SetFontSize(11));
 185
 186
 187
 188            // Группируем заказы по клиентам
 0189            var ordersByClient = _orders?
 0190                .Where(o => o.OzonClient != null)
 0191                .GroupBy(o => o.OzonClient)
 0192                .ToList();
 0193            decimal? total = 0;
 0194            if (ordersByClient != null && ordersByClient.Any())
 195            {
 0196                foreach (var clientGroup in ordersByClient)
 197                {
 0198                    var client = clientGroup.Key;
 0199                    var clientOrders = clientGroup.ToList();
 0200                    var receiver = client?.WarehouseName ?? "Не указан";
 201
 202                    // Добавляем заголовок для клиента
 0203                    _document.Add(new Paragraph($"Покупатель: {receiver} ({client?.Name ?? "—"})")
 0204                        .SetFont(_font)
 0205                        .SetFontSize(11)
 0206                        .SetMarginTop(15)
 0207                        .SetMarginBottom(5));
 208
 209                    // Таблица с товарами для текущего клиента
 0210                    Table table = new Table(UnitValue.CreatePercentArray(new float[] { 4, 10, 12, 28, 8, 12, 12, 10 }))
 0211                        .UseAllAvailableWidth();
 212
 213
 214                    // Стиль для заголовков таблицы
 0215                    var headerStyle = new Style()
 0216                        .SetBackgroundColor(ColorConstants.LIGHT_GRAY)
 0217                        .SetPadding(5)
 0218                        .SetTextAlignment(TextAlignment.CENTER)
 0219                        .SetFont(_boldFont)
 0220                        .SetFontSize(8);
 221
 222                    // Стиль для ячеек с данными
 0223                    var cellStyle = new Style()
 0224                        .SetPadding(5)
 0225                        .SetTextAlignment(TextAlignment.LEFT)
 0226                        .SetFont(_font)
 0227                        .SetFontSize(7);
 228
 229                    // Заголовки таблицы
 0230                    table.AddHeaderCell(new Cell().Add(new Paragraph("№")).AddStyle(headerStyle));
 0231                    table.AddHeaderCell(new Cell().Add(new Paragraph("Код")).AddStyle(headerStyle));
 0232                    table.AddHeaderCell(new Cell().Add(new Paragraph("Производитель")).AddStyle(headerStyle));
 0233                    table.AddHeaderCell(new Cell().Add(new Paragraph("Товары")).AddStyle(headerStyle));
 0234                    table.AddHeaderCell(new Cell().Add(new Paragraph("Количество")).AddStyle(headerStyle));
 0235                    table.AddHeaderCell(new Cell().Add(new Paragraph("Остаток")).AddStyle(headerStyle));
 0236                    table.AddHeaderCell(new Cell().Add(new Paragraph("Цена")).AddStyle(headerStyle));
 0237                    table.AddHeaderCell(new Cell().Add(new Paragraph("Сумма")).AddStyle(headerStyle));
 238
 239                    // Данные таблицы для текущего клиента
 0240                    int rowNumber = 1;
 0241                    foreach (var order in clientOrders)
 242                    {
 243                        // №
 0244                        table.AddCell(new Cell()
 0245                            .Add(new Paragraph(rowNumber.ToString()).SetTextAlignment(TextAlignment.CENTER))
 0246                            .AddStyle(cellStyle));
 247
 248                        // Код товара
 0249                        table.AddCell(new Cell()
 0250                            .Add(new Paragraph(order.ProductKey ?? ""))
 0251                            .AddStyle(cellStyle));
 252
 253                        // Производитель
 0254                        var producerName = order.EtProducer?.Name ?? "";
 0255                        table.AddCell(new Cell()
 0256                            .Add(new Paragraph(producerName))
 0257                            .AddStyle(cellStyle));
 258
 259                        // Название товара
 0260                        var productName = string.IsNullOrEmpty(order.ProductName) ? "" : order.ProductName;
 0261                        table.AddCell(new Cell()
 0262                            .Add(new Paragraph(productName))
 0263                            .AddStyle(cellStyle));
 264
 265                        // Количество
 0266                        table.AddCell(new Cell()
 0267                            .Add(new Paragraph($"{order.Quantity} шт").SetTextAlignment(TextAlignment.CENTER))
 0268                            .AddStyle(cellStyle));
 269
 270                        // Остаток на складе
 0271                        var stockCell = new Cell().AddStyle(cellStyle);
 272
 0273                        if (_stocks != null && _stocks.TryGetValue(order.Id, out var stockInfos) && stockInfos != null &
 274                        {
 275                            // Создаем список остатков для этого заказа
 0276                            foreach (var stock in stockInfos)
 277                            {
 0278                                stockCell.Add(new Paragraph($"{stock.StoreTitle}: {stock.Amount} шт")
 0279                                    .SetFontSize(6)
 0280                                    .SetMargin(0)
 0281                                    .SetPadding(0));
 282                            }
 283                        }
 284                        else
 285                        {
 0286                            stockCell.Add(new Paragraph("Нет данных").SetFontSize(6));
 287                        }
 288
 0289                        table.AddCell(stockCell);
 290
 0291                        var purchasePrice = order.PurchasePrice ?? 0m;
 0292                        var sum = (order.Quantity ?? 0) * purchasePrice;
 0293                        total += sum;
 0294                        table.AddCell(new Cell().Add(
 0295                            new Paragraph(purchasePrice.ToString("N2"))
 0296                                .SetFontSize(7)
 0297                                .SetTextAlignment(TextAlignment.RIGHT)
 0298                                .SetFont(_font)
 0299                        ));
 300
 0301                        table.AddCell(new Cell().Add(
 0302                            new Paragraph(((decimal)sum).ToString("N2"))
 0303                                .SetFontSize(7)
 0304                                .SetTextAlignment(TextAlignment.RIGHT)
 0305                                .SetFont(_font)
 0306                        ));
 307
 308
 0309                        rowNumber++;
 310                    }
 311
 0312                    _document.Add(table);
 313
 314                    // Добавляем отступ между таблицами клиентов
 0315                    _document.Add(new Paragraph(" ").SetMarginBottom(10));
 316                }
 317            }
 318            else
 319            {
 0320                _document.Add(new Paragraph("Получатель: Не указан")
 0321                    .SetFont(_font)
 0322                    .SetFontSize(11)
 0323                    .SetMarginBottom(10));
 324
 0325                _document.Add(new Paragraph("Нет данных о заказах")
 0326                    .SetFont(_font)
 0327                    .SetFontSize(10)
 0328                    .SetFontColor(ColorConstants.RED));
 329            }
 330
 0331            _document.Add(new Paragraph($"Итого: {total:N2} руб. {ndsData}.")
 0332                .SetFont(_boldFont)
 0333                .SetTextAlignment(TextAlignment.RIGHT));
 334
 0335            _document.Add(new Paragraph($"Всего наименований {_orders?.Count ?? 0}, на сумму {total:N2} руб.")
 0336                .SetFont(_font));
 337
 338            // Добавляем комментарий если есть
 0339            if (!string.IsNullOrEmpty(_transaction.Comment))
 340            {
 0341                _document.Add(new Paragraph($"Примечание: {_transaction.Comment}")
 0342                    .SetFont(_font)
 0343                    .SetFontSize(10)
 0344                    .SetMarginTop(10));
 345            }
 346
 0347            _document.Close();
 0348            return _memoryStream.ToArray();
 349        }
 0350        catch (Exception ex)
 351        {
 0352            return CreateFallbackPdf(ex.Message);
 353        }
 0354    }
 355
 356    private byte[] CreateFallbackPdf(string? errorMessage = null)
 357    {
 0358        var fallbackStream = new MemoryStream();
 0359        var fallbackWriter = new PdfWriter(fallbackStream);
 0360        var fallbackPdf = new PdfDocument(fallbackWriter);
 0361        var fallbackDoc = new Document(fallbackPdf);
 362
 0363        fallbackDoc.Add(new Paragraph("Перемещение запасов").SetFontSize(16));
 364
 0365        if (!string.IsNullOrEmpty(errorMessage))
 366        {
 0367            fallbackDoc.Add(new Paragraph($"Ошибка: {errorMessage}").SetFontColor(ColorConstants.RED));
 368        }
 369
 0370        fallbackDoc.Add(new Paragraph($"№ {_transaction.Id}"));
 0371        fallbackDoc.Add(new Paragraph($"Дата: {_transaction.FormattedCreatedTimeDateTime}"));
 372
 0373        fallbackDoc.Close();
 0374        return fallbackStream.ToArray();
 375    }
 376}