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); }
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); }