protected override void OnInitialize() { base.OnInitialize(); AddressSelector.Init(); AddressSelector.Description = "Все накладные"; Bus.Listen <string>("reload").Cast <object>() .Merge(DbReloadToken) .Merge(StatusFilter.FilterChanged()) .Merge(AddressSelector.FilterChanged.Cast <object>()) .Merge(OnlyRejected.Changed()) .SelectMany(_ => RxQuery(x => { var query = x.Query <Stock>().Where(y => y.Quantity != 0 || y.ReservedQuantity != 0); if (StatusFilter.IsFiltred()) { var values = StatusFilter.GetValues(); query = query.Where(y => values.Contains(y.Status)); } if (OnlyRejected.Value) { query = query.Where(r => r.RejectStatus == RejectStatus.Defective || r.RejectStatus == RejectStatus.Perhaps); } var addresses = AddressSelector.GetActiveFilter().Select(y => y.Id); query = query.Where(y => addresses.Contains(y.Address.Id)); return(query.Fetch(y => y.Address).OrderBy(y => y.Product).ToList()); })) .Subscribe(Items, CloseCancellation.Token); }
internal IPEndPoint GetIPEndpoint() { if (Address != null) { return(new IPEndPoint(Address, Port)); } if (string.IsNullOrEmpty(HostNameOrAddress)) { throw new InvalidOperationException("No endpoint address provided for connection."); } IPAddress[] addresses; try { addresses = Dns.GetHostAddresses(HostNameOrAddress); } catch (ArgumentException e) { throw new TransportException(e.Message, e); } catch (SocketException e) { throw new TransportException(e.Message, e); } var address = AddressSelector?.Invoke(addresses) ?? addresses[0]; return(new IPEndPoint(address, Port)); }
public WaybillsViewModel() { DisplayName = "Документы"; InitFields(); SelectedWaybills = new List <Waybill>(); Waybills.PropertyChanged += Waybills_PropertyChanged; WaybillsTotal = new ObservableCollection <WaybillTotal>(); WaybillsTotal.Add(new WaybillTotal { TotalSum = 0.0m, TotalRetailSum = 0.0m }); Begin = new NotifyValue <DateTime>(DateTime.Today.AddMonths(-3).FirstDayOfMonth()); End = new NotifyValue <DateTime>(DateTime.Today); IsFilterByDocumentDate = new NotifyValue <bool>(true); CanDelete = CurrentWaybill.Select(v => v != null && v.Status != Models.Inventory.DocStatus.Posted).ToValue(); AddressSelector = new AddressSelector(this) { Description = "Все адреса" }; Persist(IsFilterByDocumentDate, "IsFilterByDocumentDate"); Persist(IsFilterByWriteTime, "IsFilterByWriteTime"); PrintMenuItems = new ObservableCollection <MenuItem>(); IsView = true; }
private StoreClient GetMockStoreClient() { Mock <IAddressResolver> mockAddressCache = this.GetMockAddressCache(); AddressSelector addressSelector = new AddressSelector(mockAddressCache.Object, Protocol.Tcp); TransportClient mockTransportClient = this.GetMockTransportClient(); ISessionContainer sessionContainer = new SessionContainer(string.Empty); StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); // setup max replica set size on the config reader ReplicationPolicy replicationPolicy = new ReplicationPolicy(); replicationPolicy.MaxReplicaSetSize = 4; Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); mockServiceConfigReader.SetupGet(x => x.UserReplicationPolicy).Returns(replicationPolicy); return(new StoreClient( mockAddressCache.Object, sessionContainer, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, Protocol.Tcp, mockTransportClient)); }
private StoreClient GetMockStoreClient() { Mock <IAddressResolver> mockAddressCache = this.GetMockAddressCache(); AddressSelector addressSelector = new AddressSelector(mockAddressCache.Object, Protocol.Tcp); TransportClient mockTransportClient = this.GetMockTransportClient(); ISessionContainer sessionContainer = new SessionContainer(string.Empty); StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, new AddressEnumerator(), sessionContainer); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); mockAuthorizationTokenProvider.Setup(provider => provider.AddSystemAuthorizationHeaderAsync( It.IsAny <DocumentServiceRequest>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(0)); // setup max replica set size on the config reader ReplicationPolicy replicationPolicy = new ReplicationPolicy(); replicationPolicy.MaxReplicaSetSize = 4; Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); mockServiceConfigReader.SetupGet(x => x.UserReplicationPolicy).Returns(replicationPolicy); return(new StoreClient( mockAddressCache.Object, sessionContainer, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, Protocol.Tcp, mockTransportClient)); }
protected override void OnDeactivate(bool close) { AddressSelector.OnDeactivate(); if (close) { LastSelectedLine = CurrentReportLine.Value?.BatchLine?.Id ?? 0; if (Settings.Value.GetVarRoot() != lastUsedDir) { Shell.PersistentContext["BatchDir"] = lastUsedDir; } } base.OnDeactivate(close); }
protected override void OnInitialize() { base.OnInitialize(); AddressesToMove = new List <Address>(); AddressSelector.Init(); AddressSelector.FilterChanged.Cast <object>() .Merge(Prices.SelectMany(x => x?.Select(p => p.Changed()).Merge().Throttle(Consts.FilterUpdateTimeout, UiScheduler) ?? Observable.Empty <EventPattern <PropertyChangedEventArgs> >())) .Merge(Prices.Where(x => x != null)) .Subscribe(_ => Update(), CloseCancellation.Token); RxQuery(s => s.Query <Price>().OrderBy(x => x.Name).Select(x => new Selectable <Price>(x)).ToList()) .Subscribe(Prices, CloseCancellation.Token); }
protected override void OnInitialize() { base.OnInitialize(); DbReloadToken .Merge(Begin.Select(x => (object)x)) .Merge(End.Select(x => (object)x)) .SelectMany(_ => RxQuery(s => s.Query <Check>() .Where(x => x.Clerk != null && x.Date <= End.Value.AddDays(1) && x.Date >= Begin.Value) .Select(x => x.Clerk) .Distinct().ToList() .Select(x => new Selectable <string>(x)).ToList())) .Subscribe(Users); AddressSelector.Init(); AddressSelector.FilterChanged.Cast <object>() .Merge(DbReloadToken) .Merge(Begin.Select(x => (object)x)) .Merge(End.Select(x => (object)x)) .Merge(Users.SelectMany(x => x?.Select(p => p.Changed()).Merge() ?? Observable.Empty <EventPattern <PropertyChangedEventArgs> >())) .Throttle(Consts.FilterUpdateTimeout, UiScheduler) .SelectMany(_ => RxQuery(s => { var query = s.Query <Check>() .Where(c => c.Date <= End.Value.AddDays(1) && c.Date >= Begin.Value && AddressSelector.GetActiveFilter().Contains(c.Address)); var selectedUsers = Users.Value.Where(x => x.IsSelected).Select(x => x.Item).ToArray(); if (selectedUsers.Length != Users.Value.Count && Users.Value.Count > 0) { query = query.Where(x => selectedUsers.Contains(x.Clerk)); } return(query.OrderByDescending(x => x.Date) .Fetch(x => x.Address) .ToList()); })) .Subscribe(Items); }
public Stocks() { DisplayName = "Товарные запасы"; AddressSelector = new AddressSelector(this); Items.PropertyChanged += Items_PropertyChanged; ItemsTotal = new ObservableCollection <StockTotal>(); ItemsTotal.Add(new StockTotal { Total = "Итого", }); Name = User?.FullName ?? ""; StatusFilter.Value = DescriptionHelper.GetDescriptions(typeof(StockStatus)) .Select(x => new Selectable <StockStatus>((StockStatus)x.Value, x.Name)) .ToList(); QuickSearch = new QuickSearch <Stock>(UiScheduler, t => Items?.Value.FirstOrDefault(p => p.Product.IndexOf(t, StringComparison.CurrentCultureIgnoreCase) >= 0), CurrentItem); TrackDb(typeof(Stock)); PrintMenuItems = new ObservableCollection <MenuItem>(); IsView = true; CurrentItem.Select(x => x?.WaybillId != null).Subscribe(CanOpenWaybill); }
public Checks() { Dialog = false; DialogCancelled = true; Begin.Value = DateTime.Today.AddDays(-7); End.Value = DateTime.Today; ChangeDate.Value = DateTime.Today; SearchBehavior = new SearchBehavior(this); AddressSelector = new AddressSelector(this); DisplayName = "Чеки"; TrackDb(typeof(Check)); PrintMenuItems = new ObservableCollection <MenuItem>(); IsView = true; var stat = new ChecksStat(); Stat = new List <ChecksStat> { stat }; Items.Subscribe(x => { stat.Sum = x?.Sum(y => y.CheckType == CheckType.CheckReturn ? -y.Sum : y.Sum) ?? 0; stat.RetailSum = x?.Sum(y => y.CheckType == CheckType.CheckReturn ? -y.RetailSum : y.RetailSum) ?? 0; }); }
public void StoreReaderBarrierTest() { // create a real document service request DocumentServiceRequest entity = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey); // set request charge tracker - this is referenced in store reader (ReadMultipleReplicaAsync) DocumentServiceRequestContext requestContext = new DocumentServiceRequestContext { ClientRequestStatistics = new ClientSideRequestStatistics(), RequestChargeTracker = new RequestChargeTracker() }; entity.RequestContext = requestContext; // also setup timeout helper, used in store reader entity.RequestContext.TimeoutHelper = new TimeoutHelper(new TimeSpan(2, 2, 2)); // when the store reader throws Invalid Partition exception, the higher layer should // clear this target identity. entity.RequestContext.TargetIdentity = new ServiceIdentity("dummyTargetIdentity1", new Uri("http://dummyTargetIdentity1"), false); entity.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange(); AddressInformation[] addressInformation = this.GetMockAddressInformationDuringUpgrade(); Mock <IAddressResolver> mockAddressCache = this.GetMockAddressCache(addressInformation); // validate that the mock works PartitionAddressInformation partitionAddressInformation = mockAddressCache.Object.ResolveAsync(entity, false, new CancellationToken()).Result; IReadOnlyList <AddressInformation> addressInfo = partitionAddressInformation.AllAddresses; Assert.IsTrue(addressInfo[0] == addressInformation[0]); AddressSelector addressSelector = new AddressSelector(mockAddressCache.Object, Protocol.Tcp); Tuple <Uri, AddressCacheToken> primaryAddress = addressSelector.ResolvePrimaryUriAsync(entity, false /*forceAddressRefresh*/).Result; // check if the address return from Address Selector matches the original address info Assert.IsTrue(primaryAddress.Item1.Equals(addressInformation[0].PhysicalUri)); // get mock transport client that returns a sequence of responses to simulate upgrade TransportClient mockTransportClient = this.GetMockTransportClientDuringUpgrade(addressInformation); // get response from mock object StoreResponse response = mockTransportClient.InvokeResourceOperationAsync(new Uri(addressInformation[0].PhysicalUri), entity).Result; // validate that the LSN matches Assert.IsTrue(response.LSN == 50); response.TryGetHeaderValue(WFConstants.BackendHeaders.ActivityId, out string activityId); // validate that the ActivityId Matches Assert.IsTrue(activityId == "ACTIVITYID1_1"); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); ConnectionStateListener connectionStateListener = new ConnectionStateListener(null); // create store reader with mock transport client, real address selector (that has mock address cache), and real session container StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer, connectionStateListener); // reads always go to read quorum (2) replicas int replicaCountToRead = 2; IList <StoreResult> result = storeReader.ReadMultipleReplicaAsync( entity, false /*includePrimary*/, replicaCountToRead, true /*requiresValidLSN*/, false /*useSessionToken*/, ReadMode.Strong).Result; // make sure we got 2 responses from the store reader Assert.IsTrue(result.Count == 2); }
public void MockStoreClientTest() { // create a real document service request (with auth token level = god) DocumentServiceRequest entity = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, AuthorizationTokenType.PrimaryMasterKey); // set request charge tracker - this is referenced in store reader (ReadMultipleReplicaAsync) var requestContext = new DocumentServiceRequestContext(); requestContext.RequestChargeTracker = new RequestChargeTracker(); entity.RequestContext = requestContext; // set a dummy resource id on the request. entity.ResourceId = "1-MxAPlgMgA="; // set consistency level on the request to Bounded Staleness entity.Headers[HttpConstants.HttpHeaders.ConsistencyLevel] = ConsistencyLevel.BoundedStaleness.ToString(); // also setup timeout helper, used in store reader entity.RequestContext.TimeoutHelper = new TimeoutHelper(new TimeSpan(2, 2, 2)); // when the store reader throws Invalid Partition exception, the higher layer should // clear this target identity. entity.RequestContext.TargetIdentity = new ServiceIdentity("dummyTargetIdentity1", new Uri("http://dummyTargetIdentity1"), false); entity.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange(); AddressInformation[] addressInformation = GetMockAddressInformationDuringUpgrade(); var mockAddressCache = GetMockAddressCache(addressInformation); // validate that the mock works PartitionAddressInformation partitionAddressInformation = mockAddressCache.Object.ResolveAsync(entity, false, new CancellationToken()).Result; var addressInfo = partitionAddressInformation.AllAddresses; Assert.IsTrue(addressInfo[0] == addressInformation[0]); AddressSelector addressSelector = new AddressSelector(mockAddressCache.Object, Protocol.Tcp); var primaryAddress = addressSelector.ResolvePrimaryUriAsync(entity, false /*forceAddressRefresh*/).Result; // check if the address return from Address Selector matches the original address info Assert.IsTrue(primaryAddress.Equals(addressInformation[0].PhysicalUri)); // get mock transport client that returns a sequence of responses to simulate upgrade var mockTransportClient = GetMockTransportClientDuringUpgrade(addressInformation); // get response from mock object var response = mockTransportClient.InvokeResourceOperationAsync(new Uri(addressInformation[0].PhysicalUri), entity).Result; // validate that the LSN matches Assert.IsTrue(response.LSN == 50); string activityId; response.TryGetHeaderValue(WFConstants.BackendHeaders.ActivityId, out activityId); // validate that the ActivityId Matches Assert.IsTrue(activityId == "ACTIVITYID1_1"); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); // create store reader with mock transport client, real address selector (that has mock address cache), and real session container StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); // setup max replica set size on the config reader ReplicationPolicy replicationPolicy = new ReplicationPolicy(); replicationPolicy.MaxReplicaSetSize = 4; Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); mockServiceConfigReader.SetupGet(x => x.UserReplicationPolicy).Returns(replicationPolicy); try { StoreClient storeClient = new StoreClient( mockAddressCache.Object, sessionContainer, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, Protocol.Tcp, mockTransportClient); ServerStoreModel storeModel = new ServerStoreModel(storeClient); var result = storeModel.ProcessMessageAsync(entity).Result; // if we have reached this point, there was a successful request. // validate if the target identity has been cleared out. // If the target identity is null and the request still succeeded, it means // that the very first read succeeded without a barrier request. Assert.IsNull(entity.RequestContext.TargetIdentity); Assert.IsNull(entity.RequestContext.ResolvedPartitionKeyRange); } catch (Exception e) { Assert.IsTrue(e.InnerException is ServiceUnavailableException || e.InnerException is ArgumentNullException || e.InnerException is ServiceUnavailableException || e.InnerException is NullReferenceException); } }
protected override void OnInitialize() { base.OnInitialize(); lastUsedDir = (string)Shell.PersistentContext.GetValueOrDefault("BatchDir", Settings.Value.GetVarRoot()); CurrentReportLine .Subscribe(_ => { CurrentElementAddress = Addresses.FirstOrDefault(a => a.Id == CurrentReportLine.Value?.Address.Id); }); CurrentReportLine .Throttle(Consts.ScrollLoadTimeout, UiScheduler) .Merge(DbReloadToken) .SelectMany(x => Env.RxQuery(s => { if (CurrentReportLine.Value?.ProductId == null) { return(new List <Offer>()); } var productId = CurrentReportLine.Value.ProductId; return(s.Query <Offer>() .Fetch(o => o.Price) .Where(o => o.ProductId == productId) .OrderBy(o => o.Cost) .ToList() .OrderBy(o => o.ResultCost) .ToList()); })).Subscribe(UpdateOffers, CloseCancellation.Token); AddressSelector.Init(); AddressSelector.FilterChanged .Merge(DbReloadToken) .SelectMany(_ => Env.RxQuery(s => { var ids = AddressSelector.GetActiveFilter().Select(a => a.Id).ToArray(); return(s.Query <BatchLine>() .Fetch(l => l.Address) .Where(l => ids.Contains(l.Address.Id)) .ToList()); })).CatchSubscribe(BuildLineViews, CloseCancellation); if (LastSelectedLine > 0) { CurrentReportLine.Value = CurrentReportLine.Value ?? ReportLines.Value.FirstOrDefault(v => v.BatchLine?.Id == LastSelectedLine); } if (Address != null) { Bus.RegisterMessageSource(Address.StatSubject); } CurrentReportLine .Throttle(Consts.ScrollLoadTimeout, Env.Scheduler) .SelectMany(x => Env.RxQuery(s => { if (x?.CatalogId == null) { return(null); } var catalogId = x.CatalogId; return(s.Query <Catalog>() .Fetch(c => c.Name) .ThenFetch(n => n.Mnn) .First(c => c.Id == catalogId)); })) .Subscribe(CurrentCatalog, CloseCancellation.Token); ReportLines .Select(v => v.Changed()) .Switch() .Where(e => e.EventArgs.Action == NotifyCollectionChangedAction.Remove) .Select(x => x.EventArgs.OldItems.Cast <BatchLineView>().Select(b => b.BatchLine).Where(y => y != null).ToArray()) .Where(x => x.Length > 0) .SelectMany(x => Observable.FromAsync(() => Env.Query(s => s.DeleteEach(x)))) .CatchSubscribe(_ => {}); }
protected override void OnDeactivate(bool close) { base.OnDeactivate(close); AddressSelector.OnDeactivate(); }
public Batch() { NavigateOnShowCatalog = true; DisplayName = "АвтоЗаказ"; AddressSelector = new AddressSelector(this); Filter = new[] { "Все", "Заказано", " Минимальные", " Не минимальные", " Присутствующие в замороженных заказах", " Ограничен лимитом", "Не заказано", " Нет предложений", " Нулевое количество", " Прочее", " Не сопоставлено", " Лимит исчерпан" }; CurrentFilter = new NotifyValue <string>("Все"); SearchBehavior = new SearchBehavior(this); Lines = new NotifyValue <ObservableCollection <BatchLineView> >(new ObservableCollection <BatchLineView>()); ReportLines = new NotifyValue <ObservableCollection <BatchLineView> >(() => { var query = Lines.Value.Where(l => l.Product.CultureContains(SearchBehavior.ActiveSearchTerm.Value) && (l.OrderLine != null || !l.BatchLine.Status.HasFlag(ItemToOrderStatus.Ordered))); if (CurrentFilter.Value == Filter[1]) { query = query.Where(l => !l.IsNotOrdered); } else if (CurrentFilter.Value == Filter[2]) { query = query.Where(l => !l.IsNotOrdered && l.IsMinCost); } else if (CurrentFilter.Value == Filter[3]) { query = query.Where(l => !l.IsNotOrdered && !l.IsMinCost); } else if (CurrentFilter.Value == Filter[4]) { query = query.Where(l => !l.IsNotOrdered && l.ExistsInFreezed); } else if (CurrentFilter.Value == Filter[5]) { query = query.Where(l => l.IsSplitByLimit); } else if (CurrentFilter.Value == Filter[6]) { query = query.Where(l => l.IsNotOrdered); } else if (CurrentFilter.Value == Filter[7]) { query = query.Where(l => l.IsNotOrdered && !l.BatchLine.Status.HasFlag(ItemToOrderStatus.OffersExists)); } else if (CurrentFilter.Value == Filter[8]) { query = query.Where(l => l.IsNotOrdered && l.BatchLine.Quantity == 0); } else if (CurrentFilter.Value == Filter[9]) { query = query.Where(l => l.IsNotOrdered && l.BatchLine.Quantity > 0 && l.BatchLine.ProductId != null && l.BatchLine.Status.HasFlag(ItemToOrderStatus.OffersExists)); } else if (CurrentFilter.Value == Filter[10]) { query = query.Where(l => l.IsNotOrdered && l.BatchLine.ProductId == null); } else if (CurrentFilter.Value == Filter[11]) { query = query.Where(l => l.IsLimited); } return(query.OrderBy(l => l.Product).ToObservableCollection()); }, CurrentFilter, SearchBehavior.ActiveSearchTerm); CurrentReportLine = new NotifyValue <BatchLineView>(); CanDelete = CurrentReportLine.Select(l => l != null).ToValue(); SelectedReportLines = new List <BatchLineView>(); CanClear = Lines.CollectionChanged() .Select(e => e.Sender as ObservableCollection <BatchLineView>) .Select(v => v != null && v.Count > 0).ToValue(); CanReload = Lines.CollectionChanged() .Select(e => e.Sender as ObservableCollection <BatchLineView>) .Select(v => CanUpload && v != null && v.Count > 0).ToValue(); WatchForUpdate(CurrentReportLine.Select(l => l?.BatchLine)); ActivePrint = new NotifyValue <string>(); ActivePrint.Subscribe(ExcelExporter.ActiveProperty); CurrentFilter.Subscribe(_ => SearchBehavior.ActiveSearchTerm.Value = ""); ReportEditor = new ReportEditor(this); PrintMenuItems = new ObservableCollection <MenuItem>(); IsView = true; }
protected override void OnInitialize() { base.OnInitialize(); OnlyWarningVisible = IsCurrentSelected.Select(v => v && User.IsPreprocessOrders).ToValue(); ProductInfo = new ProductInfo(this, CurrentLine); ProductInfo2 = new ProductInfo(this, SelectedSentLine); AddressSelector.Init(); AddressSelector.FilterChanged .Merge(Prices.Select(p => p.Changed()).Merge().Throttle(Consts.FilterUpdateTimeout, UiScheduler)) .Merge(DbReloadToken) .Merge(OrdersReloadToken) .Merge(FilterItems.Select(p => p.Changed()).Merge().Throttle(Consts.FilterUpdateTimeout, UiScheduler)) .Where(_ => IsCurrentSelected && Session != null) .Select(_ => { var orders = AddressSelector.GetActiveFilter().SelectMany(o => o.Orders) .Where(x => Prices.Where(y => y.IsSelected).Select(y => y.Item.Id).Contains(x.Price.Id)).ToList(); var activeOrders = orders.Where(x => !x.Frozen).ToList(); var lines = activeOrders.SelectMany(o => o.Lines) .OrderBy(l => l.Id) .ToObservableCollection(); lines.Each(l => { l.Settings = Settings; l.Order.CalculateStyle(Address); if (l.Order.IsAddressExists()) { l.CalculateRetailCost(Settings.Value.Markups, Shell?.SpecialMarkupProducts.Value, User); } }); // #48323 Присутствует в замороженных заказах var productInFrozenOrders = orders.Where(x => x.Frozen).SelectMany(x => x.Lines) .Select(x => x.ProductId).Distinct().ToList(); lines.Where(x => productInFrozenOrders.Contains(x.ProductId)) .Each(x => x.InFrozenOrders = true); var selected = FilterItems.Where(p => p.IsSelected).Select(p => p.Item.Item1).ToArray(); if (selected.Count() != FilterItems.Count()) { var ids = new List <uint>(); if (selected.Contains("InFrozenOrders")) { ids.AddRange(lines.Where(x => x.InFrozenOrders).Select(x => x.Id)); } if (selected.Contains("IsMinCost")) { ids.AddRange(lines.Where(x => x.IsMinCost).Select(x => x.Id)); } if (selected.Contains("IsNotMinCost")) { ids.AddRange(lines.Where(x => !x.IsMinCost).Select(x => x.Id)); } if (selected.Contains("OnlyWarning")) { ids.AddRange(lines.Where(x => x.SendResult != LineResultStatus.OK).Select(x => x.Id)); } return(lines.Where(x => ids.Contains(x.Id)).ToObservableCollection()); } return(lines); }) .Subscribe(Lines, CloseCancellation.Token); IsSentSelected.Where(v => v) .Select(v => (object)v) .Merge(Begin.Select(d => (object)d)) .Merge(End.Select(d => (object)d)) .Merge(Prices.Select(p => p.Changed()).Merge().Throttle(Consts.FilterUpdateTimeout, UiScheduler)) .Merge(AddressSelector.FilterChanged) .Merge(DbReloadToken) .Do(_ => { IsLoading.Value = true; }) //защита от множества запросов .Throttle(TimeSpan.FromMilliseconds(30), Scheduler) .Where(_ => IsSentSelected) .Select(_ => RxQuery(s => { var begin = Begin.Value; var end = End.Value.AddDays(1); var addressIds = AddressSelector.GetActiveFilter().Select(a => a.Id).ToArray(); var query = s.Query <SentOrderLine>() .Fetch(l => l.Order) .ThenFetch(o => o.Address) .Fetch(o => o.Order) .ThenFetch(o => o.Price) .Where(l => l.Order.SentOn > begin && l.Order.SentOn < end) .Where(l => addressIds.Contains(l.Order.Address.Id)); query = Util.Filter(query, l => l.Order.Price.Id, Prices); var lines = query.OrderBy(l => l.ProductSynonym) .ThenBy(l => l.ProductSynonym) .Take(1000) .ToList(); if (Settings.Value.HighlightUnmatchedOrderLines) { var lookup = MatchedWaybills.GetLookUp(s, lines); lines.Each(l => l.Order.CalculateStyle(Address)); lines.Each(l => l.Configure(User, lookup)); } else { lines.Each(l => l.Order.CalculateStyle(Address)); lines.Each(l => l.Configure(User)); } return(lines); })) .Switch() .Do(_ => IsLoading.Value = false) .Subscribe(SentLines, CloseCancellation.Token); CurrentLine .Throttle(Consts.ScrollLoadTimeout, UiScheduler) .Merge(DbReloadToken) .Subscribe(_ => UpdateAsync(), CloseCancellation.Token); CurrentLine .Throttle(Consts.LoadOrderHistoryTimeout, Scheduler) .SelectMany(x => Env.RxQuery(s => LoadOrderHistory(s, Cache, Settings.Value, x, ActualAddress))) .Subscribe(HistoryOrders, CloseCancellation.Token); }
public void GlobalStrongConsistentWriteMockTest() { // create a real document service request (with auth token level = god) DocumentServiceRequest entity = DocumentServiceRequest.Create(OperationType.Create, ResourceType.Document, AuthorizationTokenType.SystemAll); // set request charge tracker - this is referenced in store reader (ReadMultipleReplicaAsync) DocumentServiceRequestContext requestContext = new DocumentServiceRequestContext { RequestChargeTracker = new RequestChargeTracker() }; entity.RequestContext = requestContext; // set a dummy resource id on the request. entity.ResourceId = "1-MxAPlgMgA="; // set consistency level on the request to Bounded Staleness entity.Headers[HttpConstants.HttpHeaders.ConsistencyLevel] = ConsistencyLevel.Strong.ToString(); // also setup timeout helper, used in store reader entity.RequestContext.TimeoutHelper = new TimeoutHelper(new TimeSpan(2, 2, 2)); // when the store reader throws Invalid Partition exception, the higher layer should // clear this target identity. entity.RequestContext.TargetIdentity = new ServiceIdentity("dummyTargetIdentity1", new Uri("http://dummyTargetIdentity1"), false); entity.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange(); AddressInformation[] addressInformation = this.GetMockAddressInformationDuringUpgrade(); Mock <IAddressResolver> mockAddressCache = this.GetMockAddressCache(addressInformation); // validate that the mock works PartitionAddressInformation partitionAddressInformation = mockAddressCache.Object.ResolveAsync(entity, false, new CancellationToken()).Result; IReadOnlyList <AddressInformation> addressInfo = partitionAddressInformation.AllAddresses; Assert.IsTrue(addressInfo[0] == addressInformation[0]); AddressSelector addressSelector = new AddressSelector(mockAddressCache.Object, Protocol.Tcp); Tuple <Uri, AddressCacheToken> primaryAddress = addressSelector.ResolvePrimaryUriAsync(entity, false /*forceAddressRefresh*/).Result; // check if the address return from Address Selector matches the original address info Assert.IsTrue(primaryAddress.Item1.Equals(addressInformation[0].PhysicalUri)); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); ConnectionStateListener connectionStateListener = new ConnectionStateListener(null); Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); mockAuthorizationTokenProvider.Setup(provider => provider.AddSystemAuthorizationHeaderAsync( It.IsAny <DocumentServiceRequest>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(0)); for (int i = 0; i < addressInformation.Length; i++) { TransportClient mockTransportClient = this.GetMockTransportClientForGlobalStrongWrites(addressInformation, i, false, false, false); StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer, connectionStateListener); ConsistencyWriter consistencyWriter = new ConsistencyWriter(addressSelector, sessionContainer, mockTransportClient, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, connectionStateListener, false); StoreResponse response = consistencyWriter.WriteAsync(entity, new TimeoutHelper(TimeSpan.FromSeconds(30)), false).Result; Assert.AreEqual(100, response.LSN); //globalCommittedLsn never catches up in this case mockTransportClient = this.GetMockTransportClientForGlobalStrongWrites(addressInformation, i, true, false, false); consistencyWriter = new ConsistencyWriter(addressSelector, sessionContainer, mockTransportClient, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, connectionStateListener, false); try { response = consistencyWriter.WriteAsync(entity, new TimeoutHelper(TimeSpan.FromSeconds(30)), false).Result; Assert.Fail(); } catch (Exception) { } mockTransportClient = this.GetMockTransportClientForGlobalStrongWrites(addressInformation, i, false, true, false); consistencyWriter = new ConsistencyWriter(addressSelector, sessionContainer, mockTransportClient, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, connectionStateListener, false); response = consistencyWriter.WriteAsync(entity, new TimeoutHelper(TimeSpan.FromSeconds(30)), false).Result; Assert.AreEqual(100, response.LSN); mockTransportClient = this.GetMockTransportClientForGlobalStrongWrites(addressInformation, i, false, true, true); consistencyWriter = new ConsistencyWriter(addressSelector, sessionContainer, mockTransportClient, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, connectionStateListener, false); response = consistencyWriter.WriteAsync(entity, new TimeoutHelper(TimeSpan.FromSeconds(30)), false).Result; Assert.AreEqual(100, response.LSN); mockTransportClient = this.GetMockTransportClientForGlobalStrongWrites(addressInformation, i, false, false, true); consistencyWriter = new ConsistencyWriter(addressSelector, sessionContainer, mockTransportClient, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object, connectionStateListener, false); response = consistencyWriter.WriteAsync(entity, new TimeoutHelper(TimeSpan.FromSeconds(30)), false).Result; Assert.AreEqual(100, response.LSN); } }
public void GlobalStrongConsistencyMockTest() { // create a real document service request (with auth token level = god) DocumentServiceRequest entity = DocumentServiceRequest.Create(OperationType.Read, ResourceType.Document, AuthorizationTokenType.SystemAll); // set request charge tracker - this is referenced in store reader (ReadMultipleReplicaAsync) DocumentServiceRequestContext requestContext = new DocumentServiceRequestContext { RequestChargeTracker = new RequestChargeTracker() }; entity.RequestContext = requestContext; // set a dummy resource id on the request. entity.ResourceId = "1-MxAPlgMgA="; // set consistency level on the request to Bounded Staleness entity.Headers[HttpConstants.HttpHeaders.ConsistencyLevel] = ConsistencyLevel.BoundedStaleness.ToString(); // also setup timeout helper, used in store reader entity.RequestContext.TimeoutHelper = new TimeoutHelper(new TimeSpan(2, 2, 2)); // when the store reader throws Invalid Partition exception, the higher layer should // clear this target identity. entity.RequestContext.TargetIdentity = new ServiceIdentity("dummyTargetIdentity1", new Uri("http://dummyTargetIdentity1"), false); entity.RequestContext.ResolvedPartitionKeyRange = new PartitionKeyRange(); AddressInformation[] addressInformation = this.GetMockAddressInformationDuringUpgrade(); Mock <IAddressResolver> mockAddressCache = this.GetMockAddressCache(addressInformation); // validate that the mock works PartitionAddressInformation partitionAddressInformation = mockAddressCache.Object.ResolveAsync(entity, false, new CancellationToken()).Result; IReadOnlyList <AddressInformation> addressInfo = partitionAddressInformation.AllAddresses; Assert.IsTrue(addressInfo[0] == addressInformation[0]); AddressSelector addressSelector = new AddressSelector(mockAddressCache.Object, Protocol.Tcp); Tuple <Uri, AddressCacheToken> primaryAddress = addressSelector.ResolvePrimaryUriAsync(entity, false /*forceAddressRefresh*/).Result; // check if the address return from Address Selector matches the original address info Assert.IsTrue(primaryAddress.Item1.Equals(addressInformation[0].PhysicalUri)); // Quorum Met scenario { // get mock transport client that returns a sequence of responses to simulate upgrade TransportClient mockTransportClient = this.GetMockTransportClientForGlobalStrongReads(addressInformation, ReadQuorumResultKind.QuorumMet); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); ConnectionStateListener connectionStateListener = new ConnectionStateListener(null); // create store reader with mock transport client, real address selector (that has mock address cache), and real session container StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer, connectionStateListener); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); mockAuthorizationTokenProvider.Setup(provider => provider.AddSystemAuthorizationHeaderAsync( It.IsAny <DocumentServiceRequest>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(0)); // setup max replica set size on the config reader ReplicationPolicy replicationPolicy = new ReplicationPolicy { MaxReplicaSetSize = 4 }; Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); mockServiceConfigReader.SetupGet(x => x.UserReplicationPolicy).Returns(replicationPolicy); QuorumReader reader = new QuorumReader(mockTransportClient, addressSelector, storeReader, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object); entity.RequestContext.OriginalRequestConsistencyLevel = Documents.ConsistencyLevel.Strong; entity.RequestContext.ClientRequestStatistics = new ClientSideRequestStatistics(); StoreResponse result = reader.ReadStrongAsync(entity, 2, ReadMode.Strong).Result; Assert.IsTrue(result.LSN == 100); result.TryGetHeaderValue(WFConstants.BackendHeaders.GlobalCommittedLSN, out string globalCommitedLSN); long nGlobalCommitedLSN = long.Parse(globalCommitedLSN, CultureInfo.InvariantCulture); Assert.IsTrue(nGlobalCommitedLSN == 90); } // Quorum Selected scenario { // get mock transport client that returns a sequence of responses to simulate upgrade TransportClient mockTransportClient = this.GetMockTransportClientForGlobalStrongReads(addressInformation, ReadQuorumResultKind.QuorumSelected); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); ConnectionStateListener connectionStateListener = new ConnectionStateListener(null); // create store reader with mock transport client, real address selector (that has mock address cache), and real session container StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer, connectionStateListener); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); mockAuthorizationTokenProvider.Setup(provider => provider.AddSystemAuthorizationHeaderAsync( It.IsAny <DocumentServiceRequest>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(0)); // setup max replica set size on the config reader ReplicationPolicy replicationPolicy = new ReplicationPolicy { MaxReplicaSetSize = 4 }; Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); mockServiceConfigReader.SetupGet(x => x.UserReplicationPolicy).Returns(replicationPolicy); QuorumReader reader = new QuorumReader(mockTransportClient, addressSelector, storeReader, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object); entity.RequestContext.OriginalRequestConsistencyLevel = Documents.ConsistencyLevel.Strong; entity.RequestContext.ClientRequestStatistics = new ClientSideRequestStatistics(); entity.RequestContext.QuorumSelectedLSN = -1; entity.RequestContext.GlobalCommittedSelectedLSN = -1; try { StoreResponse result = reader.ReadStrongAsync(entity, 2, ReadMode.Strong).Result; Assert.IsTrue(false); } catch (AggregateException ex) { if (ex.InnerException is GoneException) { DefaultTrace.TraceInformation("Gone exception expected!"); } } Assert.IsTrue(entity.RequestContext.QuorumSelectedLSN == 100); Assert.IsTrue(entity.RequestContext.GlobalCommittedSelectedLSN == 100); } // Quorum not met scenario { // get mock transport client that returns a sequence of responses to simulate upgrade TransportClient mockTransportClient = this.GetMockTransportClientForGlobalStrongReads(addressInformation, ReadQuorumResultKind.QuorumNotSelected); // create a real session container - we don't need session for this test anyway ISessionContainer sessionContainer = new SessionContainer(string.Empty); ConnectionStateListener connectionStateListener = new ConnectionStateListener(null); // create store reader with mock transport client, real address selector (that has mock address cache), and real session container StoreReader storeReader = new StoreReader(mockTransportClient, addressSelector, sessionContainer, connectionStateListener); Mock <IAuthorizationTokenProvider> mockAuthorizationTokenProvider = new Mock <IAuthorizationTokenProvider>(); mockAuthorizationTokenProvider.Setup(provider => provider.AddSystemAuthorizationHeaderAsync( It.IsAny <DocumentServiceRequest>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(0)); // setup max replica set size on the config reader ReplicationPolicy replicationPolicy = new ReplicationPolicy { MaxReplicaSetSize = 4 }; Mock <IServiceConfigurationReader> mockServiceConfigReader = new Mock <IServiceConfigurationReader>(); mockServiceConfigReader.SetupGet(x => x.UserReplicationPolicy).Returns(replicationPolicy); QuorumReader reader = new QuorumReader(mockTransportClient, addressSelector, storeReader, mockServiceConfigReader.Object, mockAuthorizationTokenProvider.Object); entity.RequestContext.PerformLocalRefreshOnGoneException = true; entity.RequestContext.OriginalRequestConsistencyLevel = Documents.ConsistencyLevel.Strong; entity.RequestContext.ClientRequestStatistics = new ClientSideRequestStatistics(); StoreResponse result = reader.ReadStrongAsync(entity, 2, ReadMode.Strong).Result; Assert.IsTrue(result.LSN == 100); result.TryGetHeaderValue(WFConstants.BackendHeaders.GlobalCommittedLSN, out string globalCommitedLSN); long nGlobalCommitedLSN = long.Parse(globalCommitedLSN, CultureInfo.InvariantCulture); Assert.IsTrue(nGlobalCommitedLSN == 90); } }
public override void Update() { //до загрузки прайс-листов избегаем выбирать данные что бы не делать лишних запросов if (Prices.Value == null) { return; } var priceIds = Prices.Value.Where(x => x.IsSelected).Select(x => x.Item.Id).ToArray(); if (IsSentSelected) { var filterAddresses = AddressSelector.GetActiveFilter().Select(a => a.Id).ToArray(); var begin = Begin.Value; var end = End.Value.AddDays(1); Env.RxQuery(s => { var query = s.Query <SentOrder>() .Fetch(o => o.Price) .Fetch(o => o.Address) .Where(o => o.SentOn >= begin && o.SentOn < end && filterAddresses.Contains(o.Address.Id)); query = Util.Filter(query, o => o.Price.Id, Prices.Value); return(query .OrderByDescending(o => o.SentOn) .Take(1000) .ToObservableCollection()); }).CatchSubscribe(x => { for (var i = 0; i < x.Count; i++) { x[i].CalculateStyle(Address); } SentOrders = x; }); } if (IsDeletedSelected) { Env.RxQuery(s => { var result = s.Query <DeletedOrder>() .Fetch(o => o.Price) .Fetch(o => o.Address) .OrderByDescending(o => o.DeletedOn) .ToList(); if (CurrentDeletedOrder != null) { CurrentDeletedOrder = result.FirstOrDefault(x => x.Id == CurrentDeletedOrder.Id); } return(new ReactiveCollection <DeletedOrder>(result) { ChangeTrackingEnabled = true }); }).CatchSubscribe(x => { DeletedOrders = x; }); } //обновить данные нужно в нескольких ситуациях //изменился фильтр //изменились данные в базе //если изменился фильтры данные загружать не нужно //если изменились данные то нужно загрузить данные повторно if (IsCurrentSelected || UpdateOnActivate) { if (UpdateOnActivate) { RebuildSessionIfNeeded(); } //этот вызов должен быть после RebuildSessionIfNeeded //тк он перезагрузить объекты var orders = new List <Order>(); if (IsSelectedAllAddress() && AddressSelector.All) { orders = Session.Query <Order>().ToList() .Where(x => priceIds.Contains(x.Price.Id) || IsSelectedAllPrices()) .OrderBy(o => o.PriceName) .ToList(); orders.Each(o => o.CalculateStyle(Address)); } else { orders = AddressSelector.GetActiveFilter() .SelectMany(a => a.Orders) .Where(x => priceIds.Contains(x.SafePrice.Id) || IsSelectedAllPrices()) .OrderBy(o => o.PriceName) .ToList(); orders.Each(o => o.CalculateStyle(Address)); } if (CurrentOrder != null) { CurrentOrder = orders.FirstOrDefault(x => x.Id == CurrentOrder.Id); SetAddressesToMove(); } Orders = new ReactiveCollection <Order>(orders) { ChangeTrackingEnabled = true }; Price.LoadOrderStat(Env, orders.Select(o => o.Price), Address).LogResult(); } }
public OrdersViewModel() { DisplayName = "Заказы"; InitFields(); AddressSelector = new AddressSelector(this); SelectedOrders = new List <Order>(); SelectedSentOrders = new List <SentOrder>(); SelectedDeletedOrders = new List <DeletedOrder>(); deletedOrders = new ReactiveCollection <DeletedOrder>(); OnCloseDisposable.Add(this.ObservableForProperty(m => (object)m.CurrentOrder) .Merge(this.ObservableForProperty(m => (object)m.IsCurrentSelected.Value)) .Subscribe(_ => { SetAddressesToMove(); NotifyOfPropertyChange(nameof(CanDelete)); NotifyOfPropertyChange(nameof(CanFreeze)); NotifyOfPropertyChange(nameof(CanUnfreeze)); NotifyOfPropertyChange(nameof(CanReorder)); NotifyOfPropertyChange(nameof(CanMove)); })); OnCloseDisposable.Add(IsSentSelected .Subscribe(_ => { NotifyOfPropertyChange(nameof(RestoreOrderVisible)); NotifyOfPropertyChange(nameof(CanReorder)); NotifyOfPropertyChange(nameof(EditableOrder)); })); OnCloseDisposable.Add(IsCurrentSelected .Subscribe(_ => { NotifyOfPropertyChange(nameof(FreezeVisible)); NotifyOfPropertyChange(nameof(UnfreezeVisible)); NotifyOfPropertyChange(nameof(MoveVisible)); NotifyOfPropertyChange(nameof(EditableOrder)); })); OnCloseDisposable.Add(IsDeletedSelected .Subscribe(_ => { NotifyOfPropertyChange(nameof(UnDeleteVisible)); NotifyOfPropertyChange(nameof(ReorderVisible)); })); OnCloseDisposable.Add(this.ObservableForProperty(m => m.CurrentDeletedOrder) .Subscribe(_ => { NotifyOfPropertyChange(nameof(CanDelete)); NotifyOfPropertyChange(nameof(CanUnDelete)); })); OnCloseDisposable.Add(this.ObservableForProperty(m => m.CurrentSentOrder) .Subscribe(_ => { NotifyOfPropertyChange(nameof(CanDelete)); NotifyOfPropertyChange(nameof(CanRestoreOrder)); NotifyOfPropertyChange(nameof(CanReorder)); })); OnCloseDisposable.Add(this.ObservableForProperty(m => m.CurrentOrder.Frozen) .Subscribe(_ => { NotifyOfPropertyChange(nameof(CanFreeze)); NotifyOfPropertyChange(nameof(CanUnfreeze)); })); var ordersChanged = this.ObservableForProperty(m => m.Orders); var update = ordersChanged .SelectMany(e => e.Value.ItemChanged.Cast <Object>().Merge(e.Value.Changed)); var observable = ordersChanged.Cast <object>() .Merge(update) .Throttle(Consts.RefreshOrderStatTimeout, UiScheduler) .Select(e => new Stat(Address)); OnCloseDisposable.Add(Bus.RegisterMessageSource(observable)); IsCurrentSelected .Select(v => v ? "Orders" : "SentOrders") .Subscribe(ExcelExporter.ActiveProperty); PrintMenuItems = new ObservableCollection <MenuItem>(); IsView = true; }
public OrderLinesViewModel() { DisplayName = "Сводный заказ"; InitFields(); Lines = new NotifyValue <ObservableCollection <OrderLine> >(new ObservableCollection <OrderLine>()); SentLines = new NotifyValue <List <SentOrderLine> >(new List <SentOrderLine>()); IsCurrentSelected = new NotifyValue <bool>(true); Begin = new NotifyValue <DateTime>(DateTime.Today.AddMonths(-3).FirstDayOfMonth()); End = new NotifyValue <DateTime>(DateTime.Today); AddressSelector = new AddressSelector(this); FilterItems = new List <Selectable <Tuple <string, string> > >(); FilterItems.Add(new Selectable <Tuple <string, string> >(Tuple.Create("InFrozenOrders", "Позиции присутствуют в замороженных заказах"))); FilterItems.Add(new Selectable <Tuple <string, string> >(Tuple.Create("IsMinCost", "Позиции по мин.ценам"))); FilterItems.Add(new Selectable <Tuple <string, string> >(Tuple.Create("IsNotMinCost", "Позиции не по мин.ценам"))); FilterItems.Add(new Selectable <Tuple <string, string> >(Tuple.Create("OnlyWarning", "Только позиции с корректировкой"))); CanDelete = CurrentLine.CombineLatest(IsCurrentSelected, (l, s) => l != null && s).ToValue(); BeginEnabled = IsSentSelected.ToValue(); EndEnabled = IsSentSelected.ToValue(); IsCurrentSelected.Subscribe(_ => NotifyOfPropertyChange(nameof(CanPrint))); IsCurrentSelected.Subscribe(_ => NotifyOfPropertyChange(nameof(CanExport))); Sum = new NotifyValue <decimal>(() => { if (IsCurrentSelected) { return(Lines.Value.Sum(l => l.MixedSum)); } return(SentLines.Value.Sum(l => l.MixedSum)); }, SentLines, Lines, IsCurrentSelected); OrderWarning = new InlineEditWarning(UiScheduler, Manager); QuickSearch = new QuickSearch <OrderLine>(UiScheduler, s => Lines.Value.FirstOrDefault(l => l.ProductSynonym.IndexOf(s, StringComparison.CurrentCultureIgnoreCase) >= 0), CurrentLine); QuickSearch2 = new QuickSearch <SentOrderLine>(UiScheduler, s => SentLines.Value.FirstOrDefault(l => l.ProductSynonym.IndexOf(s, StringComparison.CurrentCultureIgnoreCase) >= 0), SelectedSentLine); Editor = new Editor(OrderWarning, Manager, CurrentLine, Lines.Cast <IList>().ToValue()); var currentLinesChanged = this.ObservableForProperty(m => m.CurrentLine.Value.Count) .Throttle(Consts.RefreshOrderStatTimeout, UiScheduler) .Select(e => new Stat(Address)); OnCloseDisposable.Add(Bus.RegisterMessageSource(currentLinesChanged)); OnCloseDisposable.Add(currentLinesChanged.Subscribe(_ => Sum.Recalculate())); Settings.Subscribe(_ => CalculateOrderLine()); if (Session != null) { Prices = Session.Query <Price>().OrderBy(p => p.Name).ToList() .Select(p => new Selectable <Price>(p)) .ToList(); } else { Prices = new List <Selectable <Price> >(); } MatchedWaybills = new MatchedWaybills(this, SelectedSentLine, IsSentSelected); IsCurrentSelected .Select(v => v ? "Lines" : "SentLines") .Subscribe(ExcelExporter.ActiveProperty); Observable.Merge(IsCurrentSelected.Select(x => (object)x), Lines, SentLines, currentLinesChanged) .Select(_ => { if (IsCurrentSelected) { return(Lines.Value?.Count ?? 0); } return(SentLines.Value?.Count ?? 0); }) .Subscribe(LinesCount); IsLoading = new NotifyValue <bool>(); IsCurrentSelected.Where(v => v) .Select(_ => false) .Subscribe(IsLoading); SessionValue(Begin, GetType().Name + ".Begin"); SessionValue(End, GetType().Name + ".End"); SessionValue(IsSentSelected, GetType().Name + ".IsSentSelected"); Persist(IsExpanded, "IsExpanded"); PrintMenuItems = new ObservableCollection <MenuItem>(); IsView = true; }