Example #1
0
        protected override UpdateResult Execute()
        {
            var updateResult = UpdateResult.OK;
            var user         = Session.Query <User>().First();

            Progress.OnNext(new Progress("Соединение", 100, 0));
            Client.BaseAddress = ConfigureHttp() ?? Client.BaseAddress;
            Progress.OnNext(new Progress("Отправка заказов", 0, 50));
            var orders = Session.Query <Order>().ReadyToSend(address).ToList();

            Log.InfoFormat("Попытка отправить заказы, всего заказов к отправке {0}", orders.Count);
            var specialMarkupProducts = SpecialMarkupCatalog.Load(Session.Connection);

            try {
                foreach (var order in orders)
                {
                    Log.InfoFormat("Попытка отправки заказа {0} по прайсу {1} ({2}) от {3} с кол-вом позиций {4}",
                                   order.Id, order.PriceName, order.Price.Id.PriceId, order.Price.PriceDate, order.Lines.Count);
                    order.Lines.Each(x => x.CalculateRetailCost(Settings.Markups, specialMarkupProducts, user));
                }
            }
            catch (Exception e) {
                Log.Error("Ошибка протоколирования", e);
            }
            var clientOrders = orders.Select(o => o.ToClientOrder(Session)).Where(o => o != null).ToArray();

            if (clientOrders.Length == 0)
            {
                throw new EndUserError("Не заказов для отправки");
            }

            uint requestId = 0;
            var  response  = Wait("Orders",
                                  Client.PostAsync("Orders", new SyncRequest(clientOrders, Force), Formatter, Token), ref requestId);

            var results = response.Content.ReadAsAsync <OrderResult[]>().Result
                          ?? new OrderResult[0];

            CheckResult(Client.PutAsJsonAsync("Orders", new ConfirmRequest(requestId), Token));
            Log.InfoFormat("Заказы отправлены успешно");

            orders.Each(o => o.Apply(results.FirstOrDefault(r => r.ClientOrderId == o.Id)));
            var acceptedOrders = orders.Where(o => o.IsAccepted).ToArray();
            var rejectedOrders = orders.Where(o => !o.IsAccepted).ToArray();
            var sentOrders     = acceptedOrders.Select(o => new SentOrder(o)).ToArray();

            acceptedOrders.Where(o => o.Limit != null).Each(o => o.Limit.Value -= o.Sum);
            foreach (var order in orders)
            {
                if (order.IsAccepted)
                {
                    Log.InfoFormat("Заказ {0} успешно отправлен, Id заказа на сервере: {1}", order.Id, order.ServerId);
                }
                else
                {
                    Log.InfoFormat("Заказ {0} отвергнут сервером, причина: {1}", order.Id, order.SendError);
                }
            }

            Session.SaveEach(sentOrders);
            Session.DeleteEach(acceptedOrders);

            Progress.OnNext(new Progress("Отправка заказов", 100, 100));

            if (rejectedOrders.Any())
            {
                //если мы получили заказ без номера заказа с сервера значит он не принят
                //тк включена опция предзаказа и есть проблемы с другими заказами
                //если сервер уже знает что опция включена а клиент еще нет
                if (!user.IsPreprocessOrders)
                {
                    user.IsPreprocessOrders = rejectedOrders
                                              .SelectMany(r => r.Lines)
                                              .Any(l => l.SendResult != LineResultStatus.OK) ||
                                              rejectedOrders.Any(o => o.SendResult == OrderResultStatus.OK && o.ServerId == 0);
                }

                if (!user.IsPreprocessOrders)
                {
                    var resultText = rejectedOrders.Implode(
                        o => $"прайс-лист {o.Price.Name} - {o.SendError}",
                        Environment.NewLine);
                    var text = new TextViewModel(resultText)
                    {
                        Header      = "Данные заказы НЕ ОТПРАВЛЕНЫ",
                        DisplayName = "Не отправленные заказы"
                    };
                    Results.Add(new DialogResult(text));
                }
                else
                {
                    Results.Add(new DialogResult(new Correction(address.Id), fullScreen: true));
                }
                updateResult = UpdateResult.NotReload;
            }
            if (sentOrders.Length > 0)
            {
                if (Settings.PrintOrdersAfterSend)
                {
                    Results.Add(new PrintResult("Отправленные заказы", sentOrders.Select(o => {
                        var lines = o.Lines.ToList();
                        if (SortComparer != null)
                        {
                            lines.Sort(SortComparer);
                        }
                        return(new OrderDocument(o, lines.ToArray()));
                    })));
                }
                if (user.SaveOrders)
                {
                    try {
                        var dir = Settings.InitAndMap("Orders");
                        foreach (var sentOrder in sentOrders)
                        {
                            var name = Path.Combine(dir, sentOrder.ServerId + ".txt");
                            using (var writer = new StreamWriter(name, false, Encoding.Default)) {
                                writer.WriteLine("Номер;Аптека;Дата;Код;Товар;ЗаводШК;Производитель;Количество;Приоритет;Цена;Поставщик");
                                foreach (var line in sentOrder.Lines)
                                {
                                    var payload   = new string[0];
                                    var orderLine = orders.SelectMany(o => o.Lines).FirstOrDefault(l => l.ExportId == line.ServerId);
                                    if (orderLine != null && orderLine.ExportBatchLineId != null)
                                    {
                                        var batchline = StatelessSession.Query <BatchLine>()
                                                        .FirstOrDefault(b => b.ExportId == orderLine.ExportBatchLineId.Value);
                                        if (batchline != null)
                                        {
                                            payload = (batchline.ParsedServiceFields.GetValueOrDefault("ReportData") ?? "").Split(';');
                                        }
                                    }

                                    writer.WriteLine("{0};{1};{2};{3};{4};{5};{6};{7};{8};{9};{10}",
                                                     GetIndexOrDefault(payload, 0),
                                                     GetIndexOrDefault(payload, 1),
                                                     sentOrder.SentOn,
                                                     GetIndexOrDefault(payload, 3),
                                                     line.ProductSynonym,
                                                     GetIndexOrDefault(payload, 5),
                                                     line.ProducerSynonym,
                                                     line.Count,
                                                     GetIndexOrDefault(payload, 9),
                                                     GetIndexOrDefault(payload, 10),
                                                     line.Order.Price.Name);
                                }
                            }
                        }
                    }
                    catch (Exception e) {
#if DEBUG
                        throw;
#else
                        Log.Error("Ошибка при сохранении заявок", e);
#endif
                    }
                }
            }

            return(updateResult);
        }
Example #2
0
        public override void Execute()
        {
            //перед импортом нужно очистить сессию, тк в процессе импорта могут быть удалены данные которые содержатся в сессии
            //например прайс-листы если на каком то этапе эти данные изменятся и сессия попытается сохранить изменения
            //это приведет к ошибке
            var adresesBeforeImport = Session.Query <Address>().OrderBy(a => a.Name).ToList();

            Session.Clear();
            Reporter.Stage("Импорт данных");
            Reporter.Weight(data.Count);
            ITransaction trx = null;

            if (!Session.Transaction.IsActive)
            {
                trx = Session.BeginTransaction();
            }

            try {
                Session.CreateSQLQuery(@"
drop temporary table if exists UpdatedWaybills;
create temporary table UpdatedWaybills (
	DownloadId int unsigned not null,
	primary key(DownloadId));"    )
                .ExecuteUpdate();
                ImportTables(new [] { "UpdatedWaybills" });
                ChangeAdress(adresesBeforeImport);
                Session.CreateSQLQuery(@"
update Waybills w
join UpdatedWaybills u on u.DownloadId = w.Id
set w.Status = 1;
drop table if exists UpdatedWaybills;")
                .ExecuteUpdate();
                trx?.Commit();
                trx = null;
            } finally {
                trx?.Rollback();
            }

            Session.Connection.Execute(@"
update CheckLines l
	join Checks d on l.ServerDocId = d.ServerId
set l.CheckId = d.Id
where l.CheckId is null;

update DisplacementLines l
	join DisplacementDocs d on l.ServerDocId = d.ServerId
set l.DisplacementDocId = d.Id
where l.DisplacementDocId is null;

update InventoryLines l
	join InventoryDocs d on l.ServerDocId = d.ServerId
set l.InventoryDocId = d.Id
where l.InventoryDocId is null;

update ReassessmentLines l
	join ReassessmentDocs d on l.ServerDocId = d.ServerId
set l.ReassessmentDocId = d.Id
where l.ReassessmentDocId is null;

update ReturnLines l
	join ReturnDocs d on l.ServerDocId = d.ServerId
set l.ReturnDocId = d.Id
where l.ReturnDocId is null;

update UnpackingLines l
	join UnpackingDocs d on l.ServerDocId = d.ServerId
set l.UnpackingDocId = d.Id
where l.UnpackingDocId is null;

update WriteoffLines l
	join WriteoffDocs d on l.ServerDocId = d.ServerId
set l.WriteoffDocId = d.Id
where l.WriteoffDocId is null;");

            //очистка результатов автозаказа
            //после обновления набор адресов доставки может измениться нужно удаться те позиции которые не будут отображаться
            //если этого не сделать то при повторении дефектуры эти позиции будут загружен под текущим адресом
            Session.CreateSQLQuery(@"delete b
from BatchLines b
left join Addresses a on a.Id = b.AddressId
where a.Id is null;

delete m
from MarkupConfigs m
left join Addresses a on a.Id = m.AddressId
where a.Id is null;

delete s
from AddressConfigs s
left join Addresses a on a.Id = s.AddressId
where a.Id is null;

delete s
from WaybillSettings s
left join Addresses a on a.Id = s.BelongsToAddressId
where a.Id is null;

-- очищаем ожидаемые позиции если товар был удален
delete i
from AwaitedItems i
left join Catalogs c on c.Id = i.CatalogId
where c.Id is null;

delete s
from SpecialMarkupCatalogs s
left join Catalogs c on c.Id = s.CatalogId
where c.Id is null;")
            .ExecuteUpdate();

            Configure(new SanityCheck()).Check();
            var settings = Session.Query <Settings>().First();

            if (IsImported <SentOrder>())
            {
                Log.Info("Пересчет отправленных заявок");
                Session.CreateSQLQuery(@"
update SentOrderLines l
	join SentOrders o on l.ServerOrderId = o.ServerId
set l.OrderId = o.Id
where l.OrderId is null;

update SentOrders o
join (
		select sum(l.Count * l.Cost) as sm,
			count(*) as cn, l.OrderId
		from SentOrderLines l
		group by l.OrderId
	) t on t.OrderId = o.Id
set o.Sum = t.sm, o.LinesCount = t.cn
where o.Sum = 0;")
                .ExecuteUpdate();
            }

            //при каждом импорте мы пересчитываем 100 перенесенных накладных что бы избежать
            //ситуации когда после обновления версии нам нужно вычислить десятки тысяч накладных
            //пересчет должен производиться только после импорта данных
            //иначе nhibernate попробует выбрать поставщика и получить null тк база не будет заполнена
            //при сохранении накладной он запишет Null в поле supplierid
            Log.Info("Пересчет перенесенных накладных");
            var products = SpecialMarkupCatalog.Load(StatelessSession.Connection);

            ProcessBatch(
                Session.Query <Waybill>().Where(w => w.Sum == 0)
                .OrderByDescending(x => x.WriteTime).Take(100).Select(x => x.Id).ToArray(),
                (s, x) => {
                foreach (var id in x)
                {
                    s.Load <Waybill>(id).Calculate(settings, products);
                }
            });

            if (Session.Query <LoadedDocument>().Any())
            {
                Log.Info("Пересчет накладных");
                Session.CreateSQLQuery(@"
update Waybills w
	join LoadedDocuments d on d.Id = w.Id
set IsNew = 1;")
                .ExecuteUpdate();
            }
            if (IsImported <Offer>())
            {
                Log.Info("Очистка каталога");
                Session.CreateSQLQuery(@"
drop temporary table if exists ExistsCatalogs;
create temporary table ExistsCatalogs (
	CatalogId int unsigned not null,
	primary key(CatalogId)
);

insert into ExistsCatalogs
select CatalogId from Offers
group by CatalogId;

update Catalogs set HaveOffers = 0;
update CatalogNames set HaveOffers = 0;
update Mnns set HaveOffers = 0;

update ExistsCatalogs e
join Catalogs c on c.Id = e.CatalogId
	join CatalogNames cn on cn.Id = c.NameId
		left join Mnns m on m.Id = cn.MnnId
set m.HaveOffers = 1,
	cn.HaveOffers = 1,
	c.HaveOffers = 1;
drop temporary table ExistsCatalogs;")
                .ExecuteUpdate();

                Log.Info("Пересчет уценки");
                DbMaintain.CalcJunk(StatelessSession, settings);
            }

            //вычисляю таблицы в которых нужно производить чистку
            //Hidden = 1 экспортируется в том случае если позиция была удалена
            //или скрыта и не должна больше быть доступна клиенту
            var cleanupTables = Tables().Where(t => t.ColumnIterator.Any(c => c.Name.Match("Hidden")));

            foreach (var cleanupTable in cleanupTables)
            {
                var imported = data.Select(d => Path.GetFileNameWithoutExtension(d.Item1))
                               .Contains(cleanupTable.Name, StringComparer.CurrentCultureIgnoreCase);
                if (imported)
                {
                    Session.CreateSQLQuery($"delete from {cleanupTable.Name} where Hidden = 1")
                    .ExecuteUpdate();
                }
            }

            settings.LastUpdate = DateTime.Now;
            //очищаем кеш изображения что бы перезагрузить его
            Config.Cache.Clear();
            settings.ApplyChanges(Session);
        }