/// <summary> /// Рассчитать учетную цену /// </summary> /// <param name="rule">Правило расчета учетной цены</param> /// <param name="digitRule">Правило расчета последней цифры</param> /// <param name="article">Товар, для которого рассчитывать</param> /// <param name="accPriceCalcError">true, если не удалось использовать заданное правило расчета учетной цены </param> /// <param name="lastDigitError">true, если не удалось использовать заданное правило расчета последней цифры</param> public decimal CalculateAccountingPrice(AccountingPriceCalcRule rule, LastDigitCalcRule digitRule, Article article, out bool accPriceCalcError, out bool lastDigitError) { accPriceCalcError = false; lastDigitError = false; decimal?accountingPrice = rule.CalculateAccountingPriceValue(article); if (accountingPrice == null) { accPriceCalcError = true; return(0); } if (accountingPrice <= 0) { return(0); } var finalAccountingPrice = digitRule.CalculateLastDigit(article, accountingPrice.Value); if (finalAccountingPrice == null) { lastDigitError = true; return(0); } return(finalAccountingPrice.Value); }
/// <summary> /// Рассчитать учетную цену /// </summary> /// <param name="rule">Правило расчета учетной цены </param> /// <param name="digitRule">Правило расчета последней цифры</param> /// <param name="article">Товар, для которого рассчитывать</param> /// <param name="error">Признак того, что не удалось применить одно из правил</param> /// <returns>Рассчитанная учетная цена</returns> public decimal CalculateAccountingPrice(AccountingPriceCalcRule rule, LastDigitCalcRule digitRule, Article article, out bool error) { bool accPriceCalcError = false, lastDigitError = false; var accPrice = CalculateAccountingPrice(rule, digitRule, article, out accPriceCalcError, out lastDigitError); error = accPriceCalcError & lastDigitError; return(accPrice); }
public void AccountingPriceCalcRule_When_Init_By_AccountingPriceCalcByCurrentAccountingPrice_Type_Must_Equal_ByCurrentAccountingPrice() { var apdRule = new AccountingPriceDeterminationRule(AccountingPriceDeterminationRuleType.ByAverageAccountingPrice, AccountingPriceListStorageTypeGroup.DistributionCenters, new List <Storage>()); var apCalc = new AccountingPriceCalcByCurrentAccountingPrice(apdRule, 18); var apRule = new AccountingPriceCalcRule(apCalc); Assert.AreEqual(apCalc, apRule.CalcByCurrentAccountingPrice); Assert.IsNull(apRule.CalcByPurchaseCost); Assert.AreEqual(AccountingPriceCalcRuleType.ByCurrentAccountingPrice, apRule.Type); }
public void AccountingPriceCalcRule_When_Init_By_AccountingPriceCalcByPurchaseCost_Type_Must_Equal_ByPurchaseCost() { var mpdRule = new MarkupPercentDeterminationRule(28); var apCalc = new AccountingPriceCalcByPurchaseCost(PurchaseCostDeterminationRuleType.ByMaximalPurchaseCost, mpdRule); var apRule = new AccountingPriceCalcRule(apCalc); Assert.IsNull(apRule.CalcByCurrentAccountingPrice); Assert.AreEqual(apCalc, apRule.CalcByPurchaseCost); Assert.AreEqual(AccountingPriceCalcRuleType.ByPurchaseCost, apRule.Type); }
/// <summary> /// Рассчитать учетную цену /// </summary> /// <param name="rule">Правило расчета учетной цены </param> /// <param name="digitRule">Правило расчета последней цифры</param> /// <param name="articleList">Список товаров, для которых нужно рассчитывать</param> /// <param name="accPriceCalcError">Словарь по товарам: true, если не удалось использовать заданное правило расчета учетной цены</param> /// <param name="lastDigitError">Словарь по товарам: true, если не удалось использовать заданное правило расчета для последней цифры</param> /// <returns>Рассчитанная учетная цена</returns> public Dictionary <int, decimal> CalculateAccountingPrice(AccountingPriceCalcRule rule, LastDigitCalcRule digitRule, IEnumerable <Article> articleList, out Dictionary <int, bool> accPriceCalcError, out Dictionary <int, bool> lastDigitError) { var result = new Dictionary <int, decimal>(); bool accPriceCalcErrorForArticle = false, lastDigitErrorForArticle = false; accPriceCalcError = new Dictionary <int, bool>(); lastDigitError = new Dictionary <int, bool>(); foreach (var article in articleList) { result.Add(article.Id, CalculateAccountingPrice(rule, digitRule, article, out accPriceCalcErrorForArticle, out lastDigitErrorForArticle)); // сохраняем информацию о том, что не удалось использовать заданное правило accPriceCalcError.Add(article.Id, accPriceCalcErrorForArticle); lastDigitError.Add(article.Id, lastDigitErrorForArticle); } return(result); }
/// <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); }
/// <summary> /// Подготовить объект правила расчета учетной цены по умолчанию к работе (заполнить поля нужными списками) /// </summary> /// <returns>Готовое к работе правило расчета учетной цены по умолчанию</returns> public AccountingPriceCalcRule GetReadyAccountingPriceCalcRule(AccountingPriceCalcRule rule, int articleId, User user) { return(GetReadyAccountingPriceCalcRule(rule, new List <int> { articleId }, user)); }
/// <summary> /// Подготовка дефолтных правил к работе. Метод должен быть вызван перед подсчетом цен, иначе, в случае если по указанному правилу цену подсчитать не получится, будет выброшен эксепшн. /// </summary> public void InitializeDefaultRules(AccountingPriceCalcRule accountingPriceCalcRule, LastDigitCalcRule lastDigitCalcRule, IEnumerable <int> articleIdList, User user) { accountingPriceCalcRule.DefaultRule = GetReadyAccountingPriceCalcRule(AccountingPriceCalcRule.GetDefault(), articleIdList, user); lastDigitCalcRule.DefaultRule = GetReadyLastDigitCalcRule(LastDigitCalcRule.GetDefault(), articleIdList, user); }
/// <summary> /// Рассчитать учетную цену /// </summary> /// <param name="rule">Правило расчета учетной цены </param> /// <param name="digitRule">Правило расчета последней цифры</param> /// <param name="article">Товар, для которого рассчитывать</param> /// <returns>Рассчитанная учетная цена</returns> public decimal CalculateAccountingPrice(AccountingPriceCalcRule rule, LastDigitCalcRule digitRule, Article article) { bool accPriceCalcError = false, lastDigitError = false; return(CalculateAccountingPrice(rule, digitRule, article, out accPriceCalcError, out lastDigitError)); }
public void Init() { articleGroup = new ArticleGroup("Бытовая техника", "Бытовая техника"); articleGroup.SalaryPercent = 15; articleGroup.Id = 8; measureUnit = new MeasureUnit("шт.", "Штука", "123", 0); measureUnit.Id = 17; articleA = new Article("Пылесос", articleGroup, measureUnit, true) { Id = 29, Number = "ПЫЛ" }; articleB = new Article("Холодильник", articleGroup, measureUnit, true) { Id = 38, Number = "ХО-1" }; articleC = new Article("Плита газовая", articleGroup, measureUnit, true) { Id = 48, Number = "ПГ1" }; articleAccountingPriceA1 = new ArticleAccountingPrice(articleA, 1M); articleAccountingPriceA2 = new ArticleAccountingPrice(articleA, 1001M); articleAccountingPriceA3 = new ArticleAccountingPrice(articleA, 1192.45M); articleAccountingPriceB = new ArticleAccountingPrice(articleB, 150M); articleAccountingPriceC = new ArticleAccountingPrice(articleC, 180M); articleAccountingPriceWrongListOnlyA = new List <ArticleAccountingPrice>(); articleAccountingPriceWrongListOnlyA.Add(articleAccountingPriceA1); articleAccountingPriceWrongListOnlyA.Add(articleAccountingPriceA2); articleAccountingPriceWrongListOnlyA.Add(articleAccountingPriceA3); articleAccountingPriceCorrectList1 = new List <ArticleAccountingPrice>(); articleAccountingPriceCorrectList1.Add(articleAccountingPriceA2); articleAccountingPriceCorrectList1.Add(articleAccountingPriceB); articleAccountingPriceCorrectList1.Add(articleAccountingPriceC); storage1 = new Storage("Торговая точка номер 1", StorageType.TradePoint); storage2 = new Storage("Доп. склад северный", StorageType.ExtraStorage); storage3 = new Storage("Торговая точка номер 2", StorageType.TradePoint); storageList1 = new List <Storage>(); storageList1.Add(storage1); storageList1.Add(storage2); storageList1.Add(storage3); var juridicalLegalForm = new LegalForm("ООО", EconomicAgentType.JuridicalPerson); var physicalLegalForm = new LegalForm("ИП", EconomicAgentType.PhysicalPerson); juridicalPerson = new JuridicalPerson(juridicalLegalForm) { Id = 1 }; physicalPerson = new PhysicalPerson(physicalLegalForm) { Id = 2 }; accountOrganization = new AccountOrganization("Тестовое юридическое лицо", "Тестовое юридическое лицо", juridicalPerson) { Id = 1 }; providerOrganization = new ProviderOrganization("Тестовое физическое лицо", "Тестовое физическое лицо", physicalPerson) { Id = 2 }; provider = new Provider("Тестовый поставщик", new ProviderType("Тестовый тип поставщика"), ProviderReliability.Medium, 5); provider.AddContractorOrganization(providerOrganization); providerContract = new ProviderContract(accountOrganization, providerOrganization, "ABC", "123", DateTime.Now, DateTime.Today); provider.AddProviderContract(providerContract); user = new User(new Employee("Иван", "Иванов", "Иванович", new EmployeePost("Менеджер"), null), "Иванов Иван", "ivanov", "pa$$w0rd", new Team("Тестовая команда", null), null); var customDeclarationNumber = new String('0', 25); receiptWaybill = new ReceiptWaybill("123АБВ", DateTime.Today, storage1, accountOrganization, provider, 100.05M, 0M, new ValueAddedTax("18%", 18), providerContract, customDeclarationNumber, user, user, DateTime.Now); priceRule = new AccountingPriceCalcRule( new AccountingPriceCalcByPurchaseCost(PurchaseCostDeterminationRuleType.ByMinimalPurchaseCost, new MarkupPercentDeterminationRule(10))); digitRule = new LastDigitCalcRule(LastDigitCalcRuleType.SetCustom); user = new User(new Employee("Иван", "Иванов", "Иванович", new EmployeePost("Менеджер"), null), "Иванов Иван", "ivanov", "pa$$w0rd", new Team("Тестовая команда", null), null); }