protected void Load(ProtekServiceConfig config)
        {
            WithService(config.Url, service => {
                _logger.InfoFormat("Запрос накладных, clientId = {0} instanceId = {1}", config.ClientId, config.InstanceId);
                var responce  = service.getBladingHeaders(new getBladingHeaders(config.ClientId, config.InstanceId));
                var sessionId = [email protected];

                try {
                    if ([email protected] == null)
                    {
                        return;
                    }

                    _logger.InfoFormat("Получили накладные, всего {0} для сессии {1}", [email protected], sessionId);
                    foreach (var blading in [email protected])
                    {
                        var blanding = service.getBladingBody(new getBladingBody(sessionId, config.ClientId, config.InstanceId, blading.bladingId.Value));
                        _logger.InfoFormat("Загрузил накладную {0}({1})", blading.bladingId, blading.baseId);
                        foreach (var body in [email protected])
                        {
                            using (var scope = new TransactionScope(OnDispose.Rollback)) {
                                var document = ToDocument(body, config);
                                if (document == null)
                                {
                                    continue;
                                }

                                WaybillFormatDetector.Process(document, orders);
                                document.Log.Save();
                                document.Save();
                                try {
                                    document.CreateCertificateTasks();
                                }
                                catch (Exception e) {
                                    _logger.Error(String.Format("Не удалось создать задачи для загрузки сертификатов по накладной {0}", document.Log.Id), e);
                                }

                                Exporter.SaveProtek(document);
                                scope.VoteCommit();
                            }
                            _logger.InfoFormat("Разобрана накладная {0} для заказа {1}", body.baseId, body.@uint);
                        }
                        Ping();
                    }
                }
                finally {
                    service.closeBladingSession(new closeBladingSession(sessionId, config.ClientId, config.InstanceId));
                    Ping();                     // чтобы монитор не перезапустил рабочий поток
                }
            });
        }
        public Document ToDocument(blading blading, ProtekServiceConfig config)
        {
            Dump(ConfigurationManager.AppSettings["DebugProtekPath"], blading);

            var      order    = GetOrder(blading);
            Supplier supplier = null;
            Address  address  = null;

            if (order != null)
            {
                supplier = order.Price.Supplier;
                address  = order.Address;
            }
            else if (!String.IsNullOrEmpty(blading.recipientId.ToString()))
            {
                var query = new AddressIdQuery(config.SupplierId, false)
                {
                    SupplierDeliveryId = blading.recipientId.ToString(),
                };
                var addressIds = query.Query();
                if (addressIds.Count > 0)
                {
                    supplier = Supplier.Find(config.SupplierId);
                    address  = Address.Find(addressIds.First());
                }
            }

            if (address == null)
            {
                _logger.WarnFormat("Для накладной {0}({1}) не удалось определить получателя код клиента {2} код доставки {3}",
                                   blading.bladingId,
                                   blading.baseId,
                                   blading.payerId,
                                   blading.recipientId);
                return(null);
            }

            var log = new DocumentReceiveLog(supplier, address, DocType.Waybill)
            {
                IsFake  = true,
                Comment = "Получен через сервис Протек"
            };

            var document = new Document(log, "ProtekHandler")
            {
                OrderId            = order?.Id,
                ProviderDocumentId = blading.baseId,
                DocumentDate       = blading.date0,
            };

            document.SetInvoice();
            var invoice = document.Invoice;

            invoice.InvoiceDate             = blading.date0;
            invoice.InvoiceNumber           = blading.baseId;
            invoice.SellerName              = blading.protekNameAddr;
            invoice.SellerINN               = blading.protekInnKpp;
            invoice.ShipperInfo             = blading.protekAddr;
            invoice.RecipientId             = blading.recipientId;
            invoice.RecipientName           = blading.recipientName;
            invoice.RecipientAddress        = blading.recipientAddr;
            invoice.PaymentDocumentInfo     = blading.baseId;
            invoice.BuyerId                 = blading.payerId;
            invoice.BuyerName               = blading.payerName;
            invoice.BuyerINN                = blading.payerInn;
            invoice.CommissionFee           = (decimal?)blading.ksMin;
            invoice.CommissionFeeContractId = blading.ncontr2;
            invoice.AmountWithoutNDS        = (decimal?)blading.sumbyWonds;
            invoice.AmountWithoutNDS10      = (decimal?)blading.sumbyNdsrate10;
            invoice.NDSAmount10             = (decimal?)blading.nds10;
            invoice.AmountWithoutNDS18      = (decimal?)blading.sumbyNdsrate18;
            invoice.NDSAmount18             = (decimal?)blading.nds20;
            invoice.Amount = (decimal?)blading.rprice;
            invoice.DelayOfPaymentInBankDays = blading.dbd;
            invoice.DelayOfPaymentInDays     = blading.dkd;

            foreach (var bladingItem in blading.bladingItems)
            {
                var line = document.NewLine();
                line.Code     = bladingItem.itemId.ToString();
                line.Product  = bladingItem.itemName;
                line.Producer = bladingItem.manufacturerName;
                line.Quantity = (uint?)bladingItem.bitemQty;
                line.Country  = bladingItem.country;

                line.ExpireInMonths    = bladingItem.expiry;
                line.Period            = bladingItem.prodexpiry?.ToShortDateString();
                line.DateOfManufacture = bladingItem.proddt;

                line.RegistryCost = (decimal?)bladingItem.reestrPrice;
                line.RegistryDate = bladingItem.reestrDate;

                line.SupplierPriceMarkup = (decimal?)bladingItem.distrProc;
                line.NdsAmount           = (decimal?)bladingItem.sumVat;
                line.Nds = (uint?)bladingItem.vat;
                line.SupplierCostWithoutNDS = (decimal?)bladingItem.distrPriceWonds;
                line.SupplierCost           = (decimal?)bladingItem.distrPriceNds;
                line.ProducerCostWithoutNDS = (decimal?)bladingItem.prodPriceWonds;
                line.VitallyImportant       = bladingItem.vitalMed != null && bladingItem.vitalMed.Value == 1;
                line.Amount            = (decimal?)bladingItem.positionsum;
                line.SerialNumber      = bladingItem.prodseria;
                line.EAN13             = NullableConvert.ToUInt64(bladingItem.prodsbar);
                line.CountryCode       = bladingItem.countryCode;
                line.BillOfEntryNumber = bladingItem.gtdn;
                line.UnitCode          = bladingItem.cvpItemOkei.ToString();
                if (bladingItem.bladingItemSeries != null)
                {
                    var certificates = bladingItem.bladingItemSeries
                                       .Where(s => s.bladingItemSeriesCertificates != null)
                                       .SelectMany(s => s.bladingItemSeriesCertificates)
                                       .Where(c => c != null);

                    line.ProtekDocIds = certificates
                                        .Select(c => c.docId)
                                        .Where(id => id != null)
                                        .Select(id => new ProtekDoc(line, id.Value))
                                        .ToList();

                    line.Certificates         = certificates.FirstOrDefault()?.regNo;
                    line.CertificateAuthority = certificates.FirstOrDefault()?.regOrg;
                    line.CertificatesDate     = certificates.FirstOrDefault()?.regd?.ToString();
                    line.CertificatesEndDate  = certificates.FirstOrDefault()?.dateExpire;
                }
            }

            return(document);
        }