/// <summary> /// Получить отфильтрованный список товаров, которые есть в расширенном наличии для указанных склада и организации. /// В список попадут только те товары, у которых [количество_доступное_для_резерва] > 0. /// </summary> /// <param name="storage">Место хранения.</param> /// <param name="organization">Собственная организация.</param> /// <param name="date">Дата.</param> /// <param name="state">Параметры фильтра и грида, в который будут выводится товары. После работы сюда будет записано новое состояние грида для возвращаемого списка товаров.</param> /// <returns>Отфильтрованный список товаров, имеющихся в расширенном наличии для указанных склада и организации.</returns> public IList <Article> GetExtendedAvailableArticles(Storage storage, AccountOrganization organization, DateTime date, object state) { var articleIdList = articleAvailabilityService.GetExtendedArticleAvailability(storage.Id, organization.Id, date).Where(x => x.Count > 0).Select(x => x.ArticleId).Distinct().ToList(); var articleList = articleRepository.GetList(articleIdList); return(articleRepository.GetFilteredListByCollection(state, articleList)); }
/// <summary> /// Подготовить объект правила расчета учетной цены по умолчанию к работе (заполнить поля нужными списками) /// </summary> /// <returns>Готовое к работе правило расчета учетной цены по умолчанию</returns> public AccountingPriceCalcRule GetReadyAccountingPriceCalcRule(AccountingPriceCalcRule rule, IEnumerable <int> articleIdList, User user) { switch (rule.Type) { case AccountingPriceCalcRuleType.ByPurchaseCost: if (user.HasPermission(Permission.PurchaseCost_View_ForEverywhere)) { rule.CalcByPurchaseCost.AvailabilityList = articleAvailabilityService .GetExactArticleAvailability(storageRepository.GetStorageSubQueryByAllPermission(), articleIdList, DateTime.Now).GroupBy(x => x.ArticleId) .ToDynamicDictionary(x => x.Key, i => i.GroupBy(x => new Tuple <Guid, decimal>(x.BatchId, x.PurchaseCost)) .ToDictionary(x => x.Key, x => x.GroupBy(y => y.StorageId).ToDictionary(y => y.Key, y => y.Sum(z => z.Count)))); if (rule.CalcByPurchaseCost.PurchaseCostDeterminationRuleType == PurchaseCostDeterminationRuleType.ByLastPurchaseCost) { rule.CalcByPurchaseCost.LastPurchaseCostList = articlePriceService.GetLastPurchaseCost(articleIdList); } } break; case AccountingPriceCalcRuleType.ByCurrentAccountingPrice: IEnumerable <Storage> storageList = new List <Storage>(); if (rule.CalcByCurrentAccountingPrice.AccountingPriceDeterminationRule.Type == AccountingPriceDeterminationRuleType.ByAccountingPriceOnStorage) { var storage = rule.CalcByCurrentAccountingPrice.AccountingPriceDeterminationRule.Storage; if (user.HasPermissionToViewStorageAccountingPrices(storage)) { storageList = new List <Storage> { storage }; } } else { switch (rule.CalcByCurrentAccountingPrice.AccountingPriceDeterminationRule.StorageType) { case AccountingPriceListStorageTypeGroup.All: storageList = storageRepository.GetAll(); break; case AccountingPriceListStorageTypeGroup.DistributionCenters: storageList = storageRepository.GetStoragesByType(StorageType.DistributionCenter); break; case AccountingPriceListStorageTypeGroup.ExtraStorages: storageList = storageRepository.GetStoragesByType(StorageType.ExtraStorage); break; case AccountingPriceListStorageTypeGroup.TradePoints: storageList = storageRepository.GetStoragesByType(StorageType.TradePoint); break; } storageList = storageList.Where(s => user.HasPermissionToViewStorageAccountingPrices(s)); } rule.CalcByCurrentAccountingPrice.AccountingPriceDeterminationRule.StorageList = storageList; rule.CalcByCurrentAccountingPrice.AccountingPrices = articlePriceService.GetAccountingPrice(storageList.Select(x => x.Id), articleIdList, DateTime.Now).Transpose(); rule.CalcByCurrentAccountingPrice.AvailabilityList = articleAvailabilityService.GetExtendedArticleAvailability(articleIdList.Distinct(), storageList.Select(x => x.Id).Distinct(), DateTime.Now); break; default: throw new Exception("Неизвестный тип правила определения учетной цены."); } return(rule); }
public AccountingPriceListMainIndicators GetMainIndicators(AccountingPriceList accountingPriceList, User user, bool calculateChangesAndMarkups = false) { var indicators = new AccountingPriceListMainIndicators(); var allowToViewPurchaseCost = user.HasPermission(Permission.PurchaseCost_View_ForEverywhere); decimal purchaseCostSum, oldAccountingPriceSum, newAccountingPriceSum; // Находим актуальную дату (дату, на которую требуется получить наличие и учетные цены) // Если реестр проведен (a) - берем дату начала его действия (она может быть в будущем или в прошлом) // Если реестр не проведен (b), то: // если дата его начала действия еще не наступила - на дату начала действия // иначе - на текущую дату DateTime currentDate = DateTime.Now; // теоретически может измениться, пока идет расчет, так что зафиксируем DateTime newStateDate = accountingPriceList.StartDate > currentDate ? accountingPriceList.StartDate : currentDate; // актуальная дата для случая (b), если реестр не проведен if (accountingPriceList.State == AccountingPriceListState.Accepted && !accountingPriceList.AcceptanceDate.HasValue) { throw new Exception(String.Format("Реестр цен с номером {0} принят, но не имеет даты принятия. Обратитесь к разработчикам.", accountingPriceList.Number)); } DateTime actualDate = accountingPriceList.State == AccountingPriceListState.Accepted ? accountingPriceList.StartDate : newStateDate; purchaseCostSum = 0M; oldAccountingPriceSum = 0M; newAccountingPriceSum = 0M; var oldAccountingPriceListDictionaryList = articlePriceService.GetAccountingPrice(accountingPriceList, actualDate); var quantityListPerBatches = articleAvailabilityService.GetExtendedArticleAvailability(accountingPriceList, actualDate); var accountingPriceListBatches = receiptWaybillService.GetRows(quantityListPerBatches.Select(x => x.BatchId).Distinct()); var batchPurchaseCosts = articlePriceService.GetArticlePurchaseCostsForAccountingPriceList(accountingPriceListBatches.Values.AsEnumerable <ReceiptWaybillRow>(), actualDate); foreach (var articlePrice in accountingPriceListRepository.GetArticleAccountingPrices(accountingPriceList.Id)) { var articleId = articlePrice.Article.Id; var quantityListPerBatch = quantityListPerBatches.Where(x => x.ArticleId == articleId); purchaseCostSum += quantityListPerBatch.Sum(x => x.Count * batchPurchaseCosts.FirstOrDefault(y => y.Key == x.BatchId).Value); foreach (var quantityItem in quantityListPerBatch) { decimal?oldAccountingPrice = oldAccountingPriceListDictionaryList[quantityItem.StorageId][articleId]; if (oldAccountingPrice.HasValue) { oldAccountingPriceSum += quantityItem.Count * oldAccountingPrice.Value; } newAccountingPriceSum += quantityItem.Count * articlePrice.AccountingPrice; } } oldAccountingPriceSum = Math.Round(oldAccountingPriceSum, 2); newAccountingPriceSum = Math.Round(newAccountingPriceSum, 2); purchaseCostSum = Math.Round(purchaseCostSum, 2); indicators.OldAccountingPriceSum = oldAccountingPriceSum; indicators.NewAccountingPriceSum = newAccountingPriceSum; indicators.PurchaseCostSum = allowToViewPurchaseCost ? (decimal?)purchaseCostSum : null; if (calculateChangesAndMarkups) { indicators.AccountingPriceChangePercent = oldAccountingPriceSum != 0M ? (decimal?)Math.Round(((newAccountingPriceSum - oldAccountingPriceSum) / oldAccountingPriceSum) * 100M, 2) : null; indicators.AccountingPriceChangeSum = Math.Round(newAccountingPriceSum - oldAccountingPriceSum, 2); indicators.PurchaseMarkupPercent = allowToViewPurchaseCost && purchaseCostSum != 0M ? (decimal?)Math.Round(((newAccountingPriceSum - purchaseCostSum) / purchaseCostSum) * 100M, 2) : null; indicators.PurchaseMarkupSum = allowToViewPurchaseCost ? (decimal?)Math.Round(newAccountingPriceSum - purchaseCostSum, 2) : null; } return(indicators); }