private static void LoadReleaseWithdrawals(DataConnection query, Order order, IStore store)
        {
            var orders =
                query.GetTable <Order>()
                .Where(x => x.LegalPersonId == order.LegalPersonId && x.BranchOfficeOrganizationUnitId == order.BranchOfficeOrganizationUnitId)
                .Where(x => x.BeginDistributionDate < order.EndDistributionDatePlan && order.BeginDistributionDate < x.EndDistributionDateFact)
                .Execute();
            var orderIds = orders.Select(x => x.Id);

            store.AddRange(orders);

            var orderPositions =
                query.GetTable <OrderPosition>()
                .Where(x => orderIds.Contains(x.OrderId))
                .Execute();
            var orderPositionIds = orderPositions.Select(x => x.Id);

            store.AddRange(orderPositions);

            var releaseWithdrawals =
                query.GetTable <ReleaseWithdrawal>()
                .Where(x => orderPositionIds.Contains(x.OrderPositionId))
                .Execute();

            store.AddRange(releaseWithdrawals);
        }
        private static void LoadAmountControlledSales(DataConnection query, Order order, IReadOnlyCollection <long> priceIds, IStore store)
        {
            // Такая хитрая номенклатура, которая не прописана как регулируемая количеством, но по факту является таковой: AdvertisementCountPerCategoryShouldBeLimited
            // todo: какого чёрта?
            const int TargetCategoryCode = 38;

            var categoryCodes =
                (from orderPosition in query.GetTable <OrderPosition>().Where(x => x.IsActive && !x.IsDeleted).Where(x => x.OrderId == order.Id)
                 from opa in query.GetTable <OrderPositionAdvertisement>().Where(x => x.OrderPositionId == orderPosition.Id)
                 from position in query.GetTable <Position>().Where(x => (x.IsControlledByAmount || x.CategoryCode == TargetCategoryCode) && x.Id == opa.PositionId)
                 select position.CategoryCode).Distinct().Execute();

            var orders =
                from interferringOrder in query.GetTable <Order>().Where(x => x.IsActive && !x.IsDeleted && new[] { 1, 2, 4, 5 }.Contains(x.WorkflowStepId))
                .Where(x => x.DestOrganizationUnitId == order.DestOrganizationUnitId && x.BeginDistributionDate < order.EndDistributionDatePlan && order.BeginDistributionDate < x.EndDistributionDatePlan)
                from orderPosition in query.GetTable <OrderPosition>().Where(x => x.IsActive && !x.IsDeleted).Where(x => x.OrderId == interferringOrder.Id)
                from opa in query.GetTable <OrderPositionAdvertisement>().Where(x => x.OrderPositionId == orderPosition.Id)
                from position in query.GetTable <Position>().Where(x => (x.IsControlledByAmount || x.CategoryCode == TargetCategoryCode) && x.Id == opa.PositionId && categoryCodes.Contains(x.CategoryCode))
                from pricePosition in query.GetTable <PricePosition>().Where(x => x.Id == orderPosition.PricePositionId)
                select new { interferringOrder, orderPosition, opa, position, pricePosition };

            store.AddRange(orders.Select(x => x.interferringOrder).Execute());
            store.AddRange(orders.Select(x => x.orderPosition).Execute());
            store.AddRange(orders.Select(x => x.opa).Execute());
            store.AddRange(orders.Select(x => x.position).Execute());
            store.AddRange(orders.Select(x => x.pricePosition).Execute()); // Нужны для PriceCOntext.Order.OrderPostion
        }
        private static void LoadFirm(DataConnection query, Order order, IReadOnlyCollection <long> additionalFirmIds, IStore store)
        {
            var firms =
                query.GetTable <Firm>()
                .Where(x => x.Id == order.FirmId)
                .Execute();

            store.AddRange(firms);
            var firmIds = firms.Select(x => x.Id);

            var firmAddresses =
                query.GetTable <FirmAddress>().Where(x => firmIds.Contains(x.FirmId))
                .Union(query.GetTable <FirmAddress>().Where(x => additionalFirmIds.Contains(x.Id)))
                .Execute();

            store.AddRange(firmAddresses);
            var firmAddressIds = firmAddresses.Select(y => y.Id).ToList();

            var categoryFirmAddresses =
                query.GetTable <CategoryFirmAddress>()
                .Where(x => firmAddressIds.Contains(x.FirmAddressId))
                .Execute();

            store.AddRange(categoryFirmAddresses);
        }
        public static void Load(ErmDataLoader.ResolvedOrderSummary orderSummary, DataConnection query, IStore store)
        {
            var rulesetDtos = query.GetTable <Ruleset>()
                              .Where(r => !r.IsDeleted && r.BeginDate <= orderSummary.BeginDate && orderSummary.BeginDate < r.EndDate)
                              .Join(query.GetTable <Ruleset.RulesetProject>(),
                                    ruleset => ruleset.Id,
                                    rulesetProject => rulesetProject.RulesetId,
                                    (ruleset, rulesetProject) => new
            {
                Ruleset        = ruleset,
                RulesetProject = rulesetProject
            })
                              .Where(x => x.RulesetProject.ProjectId == orderSummary.ProjectId)
                              .Execute();

            var rulesets = rulesetDtos.Select(x => x.Ruleset).ToList();

            store.AddRange(rulesets);
            store.AddRange(rulesetDtos.Select(x => x.RulesetProject).ToList());

            var targetRulesetsIds = rulesets.Select(r => r.Id)
                                    .ToList();

            var usedNomenclatures = orderSummary.SoldPackagesIds
                                    .Union(orderSummary.SoldPackageElementsIds)
                                    .ToList();

            // Правила на сопутствие требуются только по PositionId или AssociatedPositionId, которые есть в заказе
            var associatedRulesForOrder = query.GetTable <Ruleset.AssociatedRule>()
                                          .Where(rule => targetRulesetsIds.Contains(rule.RulesetId) &&
                                                 (orderSummary.SoldPackagesIds.Contains(rule.AssociatedNomenclatureId) ||
                                                  usedNomenclatures.Contains(rule.PrincipalNomenclatureId)))
                                          .Execute();

            store.AddRange(associatedRulesForOrder);

            // Правила на запрещение требуются только по PositionId, которые есть в заказе
            var deniedRules = query.GetTable <Ruleset.DeniedRule>()
                              .Where(rule => targetRulesetsIds.Contains(rule.RulesetId) &&
                                     usedNomenclatures.Contains(rule.NomenclatureId))                 // т.к. при импорте правил создаем симметричные, то можно фильтровать только по одной из номенклатур правила
                              .Execute();

            store.AddRange(deniedRules);

            var quantitativeRules = query.GetTable <Ruleset.QuantitativeRule>()
                                    .Where(rule => targetRulesetsIds.Contains(rule.RulesetId)) // пока не фильтруем по categorycodes
                                    .Execute();

            store.AddRange(quantitativeRules);
        }
Пример #5
0
        private static void LoadPoi(DataConnection query, Order order, IStore store)
        {
            var positions = query.GetTable <Position>()
                            .Where(x => Storage.Model.Facts.Position.CategoryCodesPoiAddressCheck.Contains(x.CategoryCode))
                            .Execute();

            var positionIds = positions.Select(x => x.Id).ToList();

            var entranceCodes = (from op in query.GetTable <OrderPosition>().Where(x => x.IsActive && !x.IsDeleted).Where(x => x.OrderId == order.Id)
                                 from opa in query.GetTable <OrderPositionAdvertisement>().Where(x => x.OrderPositionId == op.Id && positionIds.Contains(x.PositionId))
                                 from address in query.GetTable <FirmAddress>().Where(x => x.Id == opa.FirmAddressId && x.EntranceCode != null)
                                 select address.EntranceCode).Execute();

            if (!entranceCodes.Any())
            {
                return;
            }

            var correlatingOrders =
                from opa in query.GetTable <OrderPositionAdvertisement>()
                .Where(x => positionIds.Contains(x.PositionId))
                from opaAddress in query.GetTable <FirmAddress>()
                .Where(x => x.Id == opa.FirmAddressId)
                .Where(x => entranceCodes.Contains(x.EntranceCode))
                from op in query.GetTable <OrderPosition>()
                .Where(x => x.IsActive && !x.IsDeleted)
                .Where(x => x.Id == opa.OrderPositionId)
                from o in query.GetTable <Order>()
                .Where(x => new[] { 2, 4, 5 }.Contains(x.WorkflowStepId))
                .Where(x => x.IsActive && !x.IsDeleted)
                .Where(x => x.BeginDistributionDate < order.EndDistributionDatePlan &&
                       order.BeginDistributionDate < x.EndDistributionDatePlan &&
                       x.DestOrganizationUnitId == order.DestOrganizationUnitId)
                .Where(x => x.Id == op.OrderId)
                select new { Order = o, OrderPosition = op, OrderPositionAdvertisement = opa, FirmAddress = opaAddress };

            store.AddRange(positions);
            store.AddRange(correlatingOrders.Select(x => x.Order).Distinct().Execute());
            store.AddRange(correlatingOrders.Select(x => x.OrderPosition).Distinct().Execute());
            store.AddRange(correlatingOrders.Select(x => x.OrderPositionAdvertisement).Distinct().Execute());
            store.AddRange(correlatingOrders.Select(x => x.FirmAddress).Distinct().Execute());
        }
Пример #6
0
            public void AddRange <T>(IReadOnlyCollection <T> entities) where T : class
            {
                _optimizer.Processed(entities);

                if (entities.Count > 1)
                {
                    _store.AddRange(entities);
                }
                else if (entities.Count > 0)
                {
                    _store.Add(entities.First());
                }
            }
Пример #7
0
        private static void LoadAmountControlledSales(DataConnection query, Order order, IReadOnlyCollection <long> priceIds, IStore store)
        {
            var categoryCodes =
                (from orderPosition in query.GetTable <OrderPosition>().Where(x => x.IsActive && !x.IsDeleted).Where(x => x.OrderId == order.Id)
                 from opa in query.GetTable <OrderPositionAdvertisement>().Where(x => x.OrderPositionId == orderPosition.Id)
                 from position in query.GetTable <Position>().Where(x => (x.IsControlledByAmount || x.CategoryCode == Storage.Model.Facts.Position.CategoryCodeAdvertisementInCategory) && x.Id == opa.PositionId)
                 select position.CategoryCode).Distinct().Execute();

            var orders =
                from interferringOrder in query.GetTable <Order>().Where(x => x.IsActive && !x.IsDeleted && new[] { 1, 2, 4, 5 }.Contains(x.WorkflowStepId))
                .Where(x => x.DestOrganizationUnitId == order.DestOrganizationUnitId && x.AgileDistributionStartDate < order.AgileDistributionEndPlanDate && order.AgileDistributionStartDate < x.AgileDistributionEndPlanDate)
                from orderPosition in query.GetTable <OrderPosition>().Where(x => x.IsActive && !x.IsDeleted).Where(x => x.OrderId == interferringOrder.Id)
                from opa in query.GetTable <OrderPositionAdvertisement>().Where(x => x.OrderPositionId == orderPosition.Id)
                from position in query.GetTable <Position>().Where(x => (x.IsControlledByAmount || x.CategoryCode == Storage.Model.Facts.Position.CategoryCodeAdvertisementInCategory) && x.Id == opa.PositionId && categoryCodes.Contains(x.CategoryCode))
                from pricePosition in query.GetTable <PricePosition>().Where(x => x.Id == orderPosition.PricePositionId)
                select new { interferringOrder, orderPosition, opa, position, pricePosition };

            store.AddRange(orders.Select(x => x.interferringOrder).Execute());
            store.AddRange(orders.Select(x => x.orderPosition).Execute());
            store.AddRange(orders.Select(x => x.opa).Execute());
            store.AddRange(orders.Select(x => x.position).Execute());
            store.AddRange(orders.Select(x => x.pricePosition).Execute()); // Нужны для PriceCOntext.Order.OrderPostion
        }
Пример #8
0
            public override void Process(bool isEmpty)
            {
                TDataType[] data;
                if (isEmpty)
                {
                    data = Array.Empty <TDataType>();
                }
                else
                {
                    data = _accessor.GetSource().Execute();
                }

                _target.AddRange(data);
            }
        public static void Load(long orderId, DataConnection query, IStore store, out ResolvedOrderSummary orderSummary)
        {
            var checkOrderIds = new[] { orderId };

            var order = query.GetTable <Order>()
                        .Where(x => checkOrderIds.Contains(x.Id))
                        .Execute()
                        .Single();

            store.Add(order);

            LoadReleaseWithdrawals(query, order, store);

            var bargainIds = new[] { order.BargainId };
            var dealIds    = new[] { order.DealId };
            var firmIds    = new[] { order.FirmId };
            var branchOfficeOrganizationUnitIds = new[] { order.BranchOfficeOrganizationUnitId };
            var legalPersonIds = new[] { order.LegalPersonId };

            var unlimitedOrder = query.GetTable <UnlimitedOrder>()
                                 .Where(x => checkOrderIds.Contains(x.OrderId))
                                 .Execute();

            store.AddRange(unlimitedOrder);

            var orderFiles = query.GetTable <OrderFile>()
                             .Where(x => checkOrderIds.Contains(x.OrderId))
                             .Execute();

            store.AddRange(orderFiles);

            var bills = query.GetTable <Bill>()
                        .Where(x => checkOrderIds.Contains(x.OrderId))
                        .Execute();

            store.AddRange(bills);

            var bargains = query.GetTable <Bargain>()
                           .Where(x => bargainIds.Contains(x.Id))
                           .Execute();

            store.AddRange(bargains);

            var bargainFiles = query.GetTable <BargainFile>()
                               .Where(x => bargainIds.Contains(x.BargainId))
                               .Execute();

            store.AddRange(bargainFiles);

            var deals = query.GetTable <Deal>()
                        .Where(x => dealIds.Contains(x.Id))
                        .Execute();

            store.AddRange(deals);

            //
            var branchOfficeOrganizationUnits = query.GetTable <BranchOfficeOrganizationUnit>()
                                                .Where(x => branchOfficeOrganizationUnitIds.Contains(x.Id))
                                                .Execute();

            store.AddRange(branchOfficeOrganizationUnits);
            var branchOfficeIds = branchOfficeOrganizationUnits.Select(x => x.BranchOfficeId).ToList();

            var branchOffices = query.GetTable <BranchOffice>()
                                .Where(x => branchOfficeIds.Contains(x.Id))
                                .Execute();

            store.AddRange(branchOffices);

            var legalPersons = query.GetTable <LegalPerson>()
                               .Where(x => legalPersonIds.Contains(x.Id))
                               .Execute();

            store.AddRange(legalPersons);

            var legalPersonProfiles = query.GetTable <LegalPersonProfile>()
                                      .Where(x => legalPersonIds.Contains(x.LegalPersonId))
                                      .Execute();

            store.AddRange(legalPersonProfiles);

            //
            var orders = query.GetTable <Order>()
                         .Where(op => op.IsActive && !op.IsDeleted)
                         .Where(x => firmIds.Contains(x.FirmId))
                         .Where(x => new[] { 1, 2, 4, 5 }.Contains(x.WorkflowStepId))
                         .Where(x => x.BeginDistributionDate < order.EndDistributionDatePlan && order.BeginDistributionDate < x.EndDistributionDatePlan)
                         .Execute();

            store.AddRange(orders);
            var orderIds = orders.Select(x => x.Id).ToList();

            var orderPositions = query.GetTable <OrderPosition>()
                                 .Where(op => op.IsActive && !op.IsDeleted)
                                 .Where(op => orderIds.Contains(op.OrderId))
                                 .Execute();

            store.AddRange(orderPositions);
            var orderPositionIds     = orderPositions.Select(x => x.Id).ToList();
            var usedPricePositionIds = orderPositions.Select(x => x.PricePositionId).Distinct().ToList();

            var opas = query.GetTable <OrderPositionAdvertisement>()
                       .Where(op => orderPositionIds.Contains(op.OrderPositionId))
                       .Execute();

            store.AddRange(opas);
            var themeIds       = opas.Where(x => x.ThemeId.HasValue).Select(x => x.ThemeId.Value).ToList();
            var categoryIds    = opas.Where(x => x.CategoryId.HasValue).Select(x => x.CategoryId.Value).ToList();
            var firmAddressIds = opas.Where(x => x.FirmAddressId.HasValue).Select(x => x.FirmAddressId.Value).ToList(); // список привязанных адресов из-за ЗМК может превышать список адресов фирмы

            var costs = query.GetTable <OrderPositionCostPerClick>()
                        .Where(x => orderPositionIds.Contains(x.OrderPositionId))
                        .Execute();      // Можно ужесточить: только проверямый заказ, только актуальные ставки

            store.AddRange(costs);

            //
            var themes = query.GetTable <Theme>()
                         .Where(x => themeIds.Contains(x.Id))
                         .Execute();

            store.AddRange(themes);

            var themeCategories = query.GetTable <ThemeCategory>()
                                  .Where(x => themeIds.Contains(x.ThemeId))
                                  .Where(x => categoryIds.Contains(x.CategoryId))
                                  .Execute();

            store.AddRange(themeCategories);

            var themeOrganizationUnits = query.GetTable <ThemeOrganizationUnit>()
                                         .Where(x => x.OrganizationUnitId == order.DestOrganizationUnitId)
                                         .Where(x => themeIds.Contains(x.ThemeId))
                                         .Execute();

            store.AddRange(themeOrganizationUnits);

            var project = query.GetTable <Project>()
                          .Where(x => x.OrganizationUnitId == order.DestOrganizationUnitId)
                          .Take(1)
                          .Execute()
                          .Single();

            store.Add(project);

            //
            var actualPrice = query.GetTable <Price>()
                              .Where(x => !x.IsDeleted && x.IsPublished)
                              .Where(x => x.ProjectId == project.Id && x.BeginDate <= order.BeginDistributionDate)
                              .OrderByDescending(x => x.BeginDate)
                              .Take(1)
                              .Execute()
                              .SingleOrDefault();

            if (actualPrice != null)
            {
                store.Add(actualPrice);
            }

            var usedPricePositions = query.GetTable <PricePosition>()
                                     .Where(x => usedPricePositionIds.Contains(x.Id))
                                     .Execute();

            store.AddRange(usedPricePositions);
            var monthlyUsedPrices = query.GetTable <Price>()
                                    .Where(x => x.ProjectId == project.Id && x.BeginDate >= order.BeginDistributionDate && x.BeginDate <= order.EndDistributionDatePlan)
                                    .Execute();

            store.AddRange(monthlyUsedPrices);
            var usedPriceIds = usedPricePositions.Select(x => x.PriceId).Union(actualPrice != null ? new[] { actualPrice.Id } : Array.Empty <long>()).Union(monthlyUsedPrices.Select(x => x.Id)).ToList();

            var soldPackagesIds = usedPricePositions.Select(p => p.PositionId)
                                  .Distinct()
                                  .ToList();
            var soldPackageElementsIds = opas.Select(y => y.PositionId)
                                         .Distinct()
                                         .ToList();

            var usedPositionIds = soldPackagesIds.Union(soldPackageElementsIds).ToList();

            var positions = query.GetTable <Position>()
                            .Where(x => usedPositionIds.Contains(x.Id))
                            .Execute();      // Можно ограничиться проверямым заказов

            store.AddRange(positions);

            var positionChilds = query.GetTable <PositionChild>()
                                 .Where(x => usedPositionIds.Contains(x.MasterPositionId) || usedPositionIds.Contains(x.ChildPositionId))
                                 .Execute();

            store.AddRange(positionChilds);

            // Нужно ли ещё от PositionChild выбрать Position?

            var usedPrices = query.GetTable <Price>()
                             .Where(x => usedPriceIds.Contains(x.Id))
                             .Execute();

            store.AddRange(usedPrices);

            var releaseInfos = query.GetTable <ReleaseInfo>()
                               .Where(x => x.OrganizationUnitId == order.DestOrganizationUnitId)
                               .Where(x => x.IsActive && !x.IsDeleted && !x.IsBeta && x.Status == 2)
                               .Execute();      // можно только последний?

            store.AddRange(releaseInfos);

            var categories = query.GetTable <Category>()
                             .Where(x => categoryIds.Contains(x.Id))
                             .Execute();

            store.AddRange(categories);
            var cat2Ids = categories.Select(x => x.ParentId);

            var categories2 = query.GetTable <Category>()
                              .Where(x => cat2Ids.Contains(x.Id))
                              .Execute();

            store.AddRange(categories2);
            var cat1Ids = categories2.Select(x => x.ParentId);

            var categories1 = query.GetTable <Category>()
                              .Where(x => cat1Ids.Contains(x.Id))
                              .Execute();

            store.AddRange(categories1);

            var categoryOrganizationUnit =
                query.GetTable <CategoryOrganizationUnit>()
                .Where(x => cat1Ids.Union(cat2Ids).Union(categoryIds).Contains(x.CategoryId))
                .Where(x => x.OrganizationUnitId == order.DestOrganizationUnitId)
                .Execute();

            store.AddRange(categoryOrganizationUnit);

            var costPerClickCategoryRestrictions = query.GetTable <CostPerClickCategoryRestriction>()
                                                   .Where(x => x.ProjectId == project.Id)
                                                   .Where(x => categoryIds.Contains(x.CategoryId))
                                                   .Execute();      // Можно ужесточить: рубрики из свзанных заказов нам на самом деле не нужны.

            store.AddRange(costPerClickCategoryRestrictions);

            if (costPerClickCategoryRestrictions.Any())
            {
                var maxDate = costPerClickCategoryRestrictions.Max(x => x.BeginningDate);
                var nextCostPerClickCategoryRestrictions = query.GetTable <CostPerClickCategoryRestriction>()
                                                           .Where(x => x.ProjectId == project.Id)
                                                           .Where(x => x.BeginningDate > maxDate)
                                                           .Take(1)
                                                           .Execute();  // Нужно для того, чтобы понять, что имеющиеся ограчения не являются актуальными
                store.AddRange(nextCostPerClickCategoryRestrictions);
            }

            var salesModelCategoryRestrictions = query.GetTable <SalesModelCategoryRestriction>()
                                                 .Where(x => x.ProjectId == project.Id)
                                                 .Where(x => categoryIds.Contains(x.CategoryId))
                                                 .Execute();      // Можно ужесточить: рубрики из свзанных заказов нам на самом деле не нужны.

            store.AddRange(salesModelCategoryRestrictions);

            var nomenclatureCategories = query.GetTable <NomenclatureCategory>()
                                         .Execute();

            store.AddRange(nomenclatureCategories);

            LoadAmountControlledSales(query, order, usedPriceIds, store);
            LoadFirm(query, order, firmAddressIds, store);
            LoadBuyHere(query, order, store);
            LoadPoi(query, order, store);

            orderSummary = new ResolvedOrderSummary
            {
                BeginDate = order.BeginDistributionDate,
                EndDate   = order.EndDistributionDatePlan,

                ProjectId = project.Id,

                SoldPackagesIds        = soldPackagesIds,
                SoldPackageElementsIds = soldPackageElementsIds
            };
        }
Пример #10
0
            public override void Process(bool isEmpty)
            {
                var data = isEmpty ? Array.Empty <TDataType>() : _accessor.GetSource().Execute();

                _target.AddRange(data);
            }
Пример #11
0
        private static void LoadBuyHere(DataConnection query, Order order, IStore store)
        {
            var categoryCodes =
                Storage.Model.Facts.Position.CategoryCodesPremiumPartnerAdvertising.Concat(
                    Storage.Model.Facts.Position.CategoryCodesFmcgCutout).Concat(
                    new[] { Storage.Model.Facts.Position.CategoryCodePartnerAdvertisingAddress });

            var positions =
                query.GetTable <Position>()
                .Where(x => categoryCodes.Contains(x.CategoryCode))
                .Execute();

            store.AddRange(positions);

            var firmAddresses = (
                from op in query.GetTable <OrderPosition>().Where(x => x.IsActive && !x.IsDeleted).Where(x => x.OrderId == order.Id)
                from opa in query.GetTable <OrderPositionAdvertisement>().Where(x => x.OrderPositionId == op.Id)
                from position in query.GetTable <Position>().Where(x => x.CategoryCode == Storage.Model.Facts.Position.CategoryCodePartnerAdvertisingAddress).Where(x => x.Id == opa.PositionId)
                from address in query.GetTable <FirmAddress>().Where(x => x.Id == opa.FirmAddressId)
                select address
                ).Execute();

            store.AddRange(firmAddresses);
            var firmAddressIds = firmAddresses.Select(x => x.Id).ToList();

            if (!firmAddresses.Any())
            {
                return;
            }

            var firmIds = firmAddresses.Select(x => x.FirmId).ToHashSet();

            // Нужны заказы этих фирм - вдруг фирма является рекламодателем.
            var firmOrders =
                from o in query.GetTable <Order>()
                .Where(x => firmIds.Contains(x.FirmId))
                .Where(x => new[] { 2, 4, 5 }.Contains(x.WorkflowStepId))
                .Where(x => x.AgileDistributionStartDate < order.AgileDistributionEndPlanDate && order.AgileDistributionStartDate < x.AgileDistributionEndPlanDate)
                from op in query.GetTable <OrderPosition>()
                .Where(x => x.IsActive && !x.IsDeleted)
                .Where(x => x.OrderId == o.Id)
                from pp in query.GetTable <PricePosition>()
                .Where(x => x.IsActive && !x.IsDeleted)
                .Where(x => x.Id == op.PricePositionId)
                select new { Order = o, OrderPosition = op, PricePosition = pp };

            store.AddRange(firmOrders.Select(x => x.Order).Execute());
            store.AddRange(firmOrders.Select(x => x.OrderPosition).Execute());
            store.AddRange(firmOrders.Select(x => x.PricePosition).Execute());

            var positionIds = positions.Select(x => x.Id).ToList();

            // Нужны другие ЗМК заказы на те же самые адреса
            var xxxOrders =
                from o in query.GetTable <Order>()
                .Where(x => new[] { 2, 4, 5 }.Contains(x.WorkflowStepId))     // заказы "на оформлении" не нужны - проверяемый их в любом лучае не видит
                .Where(x => x.IsActive && !x.IsDeleted)
                .Where(x => x.AgileDistributionStartDate < order.AgileDistributionEndPlanDate && order.AgileDistributionStartDate < x.AgileDistributionEndPlanDate && x.DestOrganizationUnitId == order.DestOrganizationUnitId)
                from op in query.GetTable <OrderPosition>()
                .Where(x => x.IsActive && !x.IsDeleted)
                .Where(x => x.OrderId == o.Id)
                from opa in query.GetTable <OrderPositionAdvertisement>()
                .Where(x => positionIds.Contains(x.PositionId))
                .Where(x => x.FirmAddressId == null || firmAddressIds.Contains(x.FirmAddressId.Value))
                .Where(x => x.OrderPositionId == op.Id)
                select new { Order = o, OrderPosition = op, OrderPositionAdvertisement = opa };

            store.AddRange(xxxOrders.Select(x => x.Order).Distinct().Execute());
            store.AddRange(xxxOrders.Select(x => x.OrderPosition).Distinct().Execute());
            store.AddRange(xxxOrders.Select(x => x.OrderPositionAdvertisement).Distinct().Execute());
        }
        private static void LoadBuyHere(DataConnection query, Order order, IStore store)
        {
            const long CategoryCodePremiumAdvertising = 809065011136692321; // Реклама в профилях партнеров (приоритетное размещение)
            const long CategoryCodeAdvertisingAddress = 809065011136692326; // Реклама в профилях партнеров (адреса)
            const long CategoryCodeBasicPackage       = 303;                // пакет "Базовый"
            const long CategoryCodeMediaContextBanner = 395122163464046280; // МКБ
            const long CategoryCodeContextBanner      = 809065011136692318; // КБ
            var        categoryCodes = new[] { CategoryCodePremiumAdvertising, CategoryCodeAdvertisingAddress, CategoryCodeBasicPackage, CategoryCodeMediaContextBanner, CategoryCodeContextBanner };

            var positions =
                query.GetTable <Position>()
                .Where(x => categoryCodes.Contains(x.CategoryCode))
                .Execute();

            store.AddRange(positions);

            var firmAddresses = (
                from op in query.GetTable <OrderPosition>().Where(x => x.IsActive && !x.IsDeleted).Where(x => x.OrderId == order.Id)
                from opa in query.GetTable <OrderPositionAdvertisement>().Where(x => x.OrderPositionId == op.Id)
                from position in query.GetTable <Position>().Where(x => x.CategoryCode == CategoryCodeAdvertisingAddress).Where(x => x.Id == opa.PositionId)
                from address in query.GetTable <FirmAddress>().Where(x => x.Id == opa.FirmAddressId)
                select address
                ).Execute();

            store.AddRange(firmAddresses);
            var firmAddressIds = firmAddresses.Select(x => x.Id).ToList();

            if (!firmAddresses.Any())
            {
                return;
            }

            var firmIds = firmAddresses.Select(x => x.FirmId).Distinct().ToList();

            // Нужны заказы этих фирм - вдруг фирма является рекламодателем.
            var firmOrders = query.GetTable <Order>()
                             .Where(x => firmIds.Contains(x.FirmId))
                             .Where(x => new[] { 2, 4, 5 }.Contains(x.WorkflowStepId))
                             .Where(x => x.BeginDistributionDate < order.EndDistributionDatePlan && order.BeginDistributionDate < x.EndDistributionDatePlan)
                             .Execute();

            store.AddRange(firmOrders);

            var positionIds = positions.Select(x => x.Id).ToList();

            // Нужны другие ЗМК заказы на те же самые адреса
            var xxxOrders =
                from opa in query.GetTable <OrderPositionAdvertisement>()
                .Where(x => positionIds.Contains(x.PositionId))
                .Where(x => !x.FirmAddressId.HasValue || firmAddressIds.Contains(x.FirmAddressId.Value))
                from op in query.GetTable <OrderPosition>()
                .Where(x => x.IsActive && !x.IsDeleted)
                .Where(x => x.Id == opa.OrderPositionId)
                from o in query.GetTable <Order>()
                .Where(x => new[] { 2, 4, 5 }.Contains(x.WorkflowStepId))     // заказы "на оформлении" не нужны - проверяемый их в любом лучае не видит
                .Where(x => x.IsActive && !x.IsDeleted)
                .Where(x => x.BeginDistributionDate < order.EndDistributionDatePlan && order.BeginDistributionDate < x.EndDistributionDatePlan && x.DestOrganizationUnitId == order.DestOrganizationUnitId)
                .Where(x => x.Id == op.OrderId)
                select new { Order = o, OrderPosition = op, OrderPositionAdvertisement = opa };

            store.AddRange(xxxOrders.Select(x => x.Order).Distinct().Execute());
            store.AddRange(xxxOrders.Select(x => x.OrderPosition).Distinct().Execute());
            store.AddRange(xxxOrders.Select(x => x.OrderPositionAdvertisement).Distinct().Execute());
        }