Example #1
0
        public void AccountingPriceList_CantAcceptWithZeroArticles()
        {
            try
            {
                var accountingPriceList = new AccountingPriceList("234", DateTime.Today.AddYears(1), DateTime.Today.AddYears(2), new List <Storage>()
                {
                    storage1
                }, user);

                accountingPriceList.Accept(DateTime.Now);
                Assert.Fail("Исключения не было.");
            }
            catch (Exception ex)
            {
                Assert.AreEqual("Невозможно провести реестр цен без товаров.", ex.Message);
            }
        }
Example #2
0
        public void AccountingPriceList_AcceptAndCancellationMustWork()
        {
            var accountingPriceList = new AccountingPriceList("234", DateTime.Today.AddYears(1), DateTime.Today.AddYears(2), storage1, articleAccountingPriceCorrectList1, user);

            var dateBeforeAccept = DateTime.Now;

            accountingPriceList.Accept(DateTime.Now);
            var dateAfterAccept = DateTime.Now;

            Assert.AreEqual(AccountingPriceListState.Accepted, accountingPriceList.State);
            Assert.IsNotNull(accountingPriceList.AcceptanceDate);
            Assert.IsTrue(dateBeforeAccept <= accountingPriceList.AcceptanceDate && accountingPriceList.AcceptanceDate <= dateAfterAccept);

            accountingPriceList.CancelAcceptance();
            Assert.AreEqual(AccountingPriceListState.New, accountingPriceList.State);
            Assert.IsNull(accountingPriceList.AcceptanceDate);
        }
Example #3
0
        public void AccountingPriceList_StartDateTimeMustBeSet()
        {
            bool     changed;
            DateTime startDate;

            // т.к. дата начала действяи РЦ меньше текущей даты, то дата начало должна стать равной текущей
            startDate = DateTime.Now.AddDays(-1);
            changed   = AccountingPriceList.SetTimeForStartDateAndCheck(ref startDate, DateTime.Now);
            Assert.AreEqual(0, (startDate - DateTime.Now).Minutes); // разница должна быть меньше минуты
            Assert.IsTrue(changed);

            // т.к. дата начала действия больше текущей, то она не должна измениться
            startDate = DateTime.Now.AddDays(1);
            var oldStartDate = startDate;

            changed = AccountingPriceList.SetTimeForStartDateAndCheck(ref startDate, DateTime.Now);
            Assert.AreEqual(oldStartDate, startDate);
            Assert.IsFalse(changed);
        }
        /// <summary>
        /// Получение списка необходимых РЦ при отмене проводки РЦ
        /// </summary>
        /// <param name="priceList">Отменяемый РЦ</param>
        public IEnumerable <AccountingPriceList> GetIntersectingPriceLists(AccountingPriceList priceList, DateTime currentDateTime)
        {
            // TODO: не самый оптимальный вариант реализации
            // По идее нужно для каждой пары МХ-товар найти РЦ, у которого StartDate < StartDate данного РЦ, а EndDate > EndDate данного РЦ, взять StartDate этого РЦ.
            // Затем для каждой пары МХ-товар нужно выбрать все РЦ, у которых StartDate больше определенного ранее StartDate.

            var endDate = (priceList.EndDate == null ? currentDateTime : priceList.EndDate.Value);

            var articleSubQuery = GetArticlesSubquery(priceList.Id);
            var storageSubQuery = GetStoragesSubquery(priceList.Id);

            var query = Query <AccountingPriceList>()
                        .Where(x => x.AcceptanceDate != null && x.StartDate < endDate && (x.EndDate > priceList.StartDate || x.EndDate == null))
                        .PropertyIn(x => x.Storages, storageSubQuery);

            return(query.Restriction <ArticleAccountingPrice>(x => x.ArticlePrices)
                   .PropertyIn(x => x.Article, articleSubQuery)
                   .ToList <AccountingPriceList>());
        }
        private bool IsPermissionForTeamDistribution(AccountingPriceList priceList, User user, Permission permission)
        {
            switch (permission)
            {
            case Permission.AccountingPriceList_List_Details:
            case Permission.AccountingPriceList_Storage_Add:
            case Permission.AccountingPriceList_Storage_Remove:
            {
                return(user.Teams.Any(x => x.Storages.Any(y => priceList.Storages.Contains(y))));        //реестр распространяется хотя бы на одно МХ из команд пользователя
            }

            default:
            {
                var userStorages = user.Teams.SelectMany(x => x.Storages);

                return(priceList.Storages.All(x => userStorages.Contains(x)));        //все МХ, на которые распространяется реестр входят в команды пользователя
            }
            }
        }
Example #6
0
        public void AccountingPriceList_ReceiptWaybill_Initial_Parameters_Must_Be_Set()
        {
            DateTime date1 = DateTime.Today.AddYears(1), date2 = DateTime.Today.AddYears(2).SetHoursMinutesAndSeconds(23, 59, 59);
            var      accountingPriceList = new AccountingPriceList("234", date1, date2, receiptWaybill, storageList1, articleAccountingPriceCorrectList1, user, priceRule, digitRule);

            Assert.AreEqual(Guid.Empty, accountingPriceList.Id);

            Assert.AreEqual("234", accountingPriceList.Number);
            Assert.AreEqual(date1, accountingPriceList.StartDate);
            Assert.AreEqual(date2, accountingPriceList.EndDate);

            Assert.AreEqual(AccountingPriceListState.New, accountingPriceList.State);

            Assert.AreEqual(AccountingPriceListReason.ReceiptWaybill, accountingPriceList.Reason);
            Assert.AreEqual("Приход №123АБВ от " + DateTime.Today.ToShortDateString(), accountingPriceList.ReasonDescription);

            Assert.AreEqual(3, accountingPriceList.Storages.Count());

            Assert.AreEqual(articleAccountingPriceWrongListOnlyA.Count(), accountingPriceList.ArticlePrices.Count());
        }
Example #7
0
        public void AccountingPriceList_Autogeneration_Initial_Parameters_Must_Be_Set()
        {
            DateTime date1 = DateTime.Today.AddYears(1), date2 = DateTime.Today.AddYears(2).SetHoursMinutesAndSeconds(23, 59, 59);
            var      accountingPriceList = new AccountingPriceList("234", date1, date2, storage1, articleAccountingPriceCorrectList1, user, priceRule, digitRule);

            Assert.AreEqual(Guid.Empty, accountingPriceList.Id);

            Assert.AreEqual("234", accountingPriceList.Number);
            Assert.AreEqual(date1.SetHoursMinutesAndSeconds(0, 0, 0), accountingPriceList.StartDate);
            Assert.AreEqual(date2.SetHoursMinutesAndSeconds(23, 59, 59), accountingPriceList.EndDate);

            Assert.AreEqual(AccountingPriceListState.New, accountingPriceList.State);

            Assert.AreEqual(AccountingPriceListReason.Storage, accountingPriceList.Reason);
            Assert.AreEqual("По месту хранения", accountingPriceList.ReasonDescription);

            Assert.AreEqual(1, accountingPriceList.Storages.Count());

            Assert.AreEqual(articleAccountingPriceWrongListOnlyA.Count(), accountingPriceList.ArticlePrices.Count());
        }
Example #8
0
        public void AccountingPriceList_Revaluation_Initial_Parameters_Must_Be_Set()
        {
            DateTime date1 = DateTime.Today.AddYears(1), date2 = DateTime.Today.AddYears(2).SetHoursMinutesAndSeconds(23, 59, 59);
            var      accountingPriceList = new AccountingPriceList("123", date1, date2, storageList1, user, priceRule, digitRule);

            Assert.AreEqual(Guid.Empty, accountingPriceList.Id);

            Assert.AreEqual("123", accountingPriceList.Number);
            Assert.AreEqual(date1, accountingPriceList.StartDate);
            Assert.AreEqual(date2, accountingPriceList.EndDate);

            Assert.AreEqual(AccountingPriceListState.New, accountingPriceList.State);

            Assert.AreEqual(AccountingPriceListReason.Revaluation, accountingPriceList.Reason);
            Assert.AreEqual("Переоценка", accountingPriceList.ReasonDescription);

            Assert.AreEqual(3, accountingPriceList.Storages.Count());

            Assert.AreEqual(0, accountingPriceList.ArticlePrices.Count());
        }
        public AccountingPriceListServiceTest()
        {
            articleGroup = new ArticleGroup("Бытовая техника", "Бытовая техника");
            articleGroup.SalaryPercent = 15;
            articleGroup.Id            = 8;

            measureUnit    = new MeasureUnit("шт.", "Штука", "123", 0);
            measureUnit.Id = 17;

            article1    = new Article("Пылесос", articleGroup, measureUnit, true);
            article1.Id = 9;
            article2    = new Article("Фен", articleGroup, measureUnit, true);
            article2.Id = 29;
            article3    = new Article("Утюг", articleGroup, measureUnit, true);
            article3.Id = 421;

            storage1 = new Storage("Склад 1", StorageType.DistributionCenter);
            storage2 = new Storage("Склад 2", StorageType.DistributionCenter);

            articleAccountingPrice1_1 = new ArticleAccountingPrice(article1, 1M);
            articleAccountingPrice1_2 = new ArticleAccountingPrice(article2, 1001M);
            articleAccountingPrice1_3 = new ArticleAccountingPrice(article3, 1192.45M);

            user = new User(new Employee("Иван", "Иванов", "Иванович", new EmployeePost("Менеджер"), null), "Иванов Иван", "ivanov", "pa$$w0rd", new Team("Тестовая команда", null), null);

            accountingPriceList1 = new AccountingPriceList("27", DateTime.Now, null, new List <Storage> {
                storage1
            }, user);
            accountingPriceList1.AddArticleAccountingPrice(articleAccountingPrice1_1);
            accountingPriceList1.AddArticleAccountingPrice(articleAccountingPrice1_2);
            accountingPriceList1.AddArticleAccountingPrice(articleAccountingPrice1_3);

            articleAccountingPrice2_1 = new ArticleAccountingPrice(article1, 34M);
            articleAccountingPrice2_2 = new ArticleAccountingPrice(article3, 56M);

            accountingPriceList2 = new AccountingPriceList("39", DateTime.Now, null, new List <Storage> {
                storage1, storage2
            }, user);
            accountingPriceList2.AddArticleAccountingPrice(articleAccountingPrice2_1);
            accountingPriceList2.AddArticleAccountingPrice(articleAccountingPrice2_2);
        }
Example #10
0
        public void AccountingPriceList_ReDeletion_Must_Not_Work()
        {
            var accountingPriceList = new AccountingPriceList("123", DateTime.Today.AddYears(1), DateTime.Today.AddYears(2), new List <Storage>()
            {
                storage1
            }, user);

            var curDate  = DateTime.Now;
            var nextDate = curDate + new TimeSpan(1, 0, 0, 0);

            Assert.IsNull(accountingPriceList.DeletionDate);

            accountingPriceList.DeletionDate = curDate;

            Assert.AreEqual(curDate, accountingPriceList.DeletionDate);

            accountingPriceList.DeletionDate = nextDate;

            Assert.AreEqual(curDate, accountingPriceList.DeletionDate);
            Assert.AreNotEqual(nextDate, accountingPriceList.DeletionDate);
        }
Example #11
0
        public void AccountingPriceList_Revaluation_Must_Throw_Exception_On_NonUnique_Storages()
        {
            var storage = new Storage("Склад", StorageType.DistributionCenter)
            {
                Id = 1
            };

            try
            {
                var list = new AccountingPriceList("123", DateTime.Now, null, new List <Storage>()
                {
                    storage, storage
                }, user, priceRule, digitRule);

                Assert.Fail("Исключения не было.");
            }
            catch (Exception ex)
            {
                Assert.AreEqual("Список мест хранения содержит повторяющиеся элементы.", ex.Message);
            }
        }
 public void DeleteArticleAccountingPrice(AccountingPriceList accountingPriceList, ArticleAccountingPrice articleAccountingPrice)
 {
     accountingPriceList.DeleteArticleAccountingPrice(articleAccountingPrice);
 }
Example #13
0
        /// <summary>
        /// Создание связей между позициями РЦ и позициями входящих принятых с расхождениями накладных
        /// </summary>
        /// <param name="incomingRows">Список позиций входящих принятых с расхождениями накладных</param>
        /// <param name="priceList">РЦ</param>
        /// <param name="isOnAccountingPriceListStart">Признак: создается ли связь на начало периода действия РЦ</param>
        /// <param name="takingDate">Дата и время связи</param>
        public void CreateTakingFromIncomingDivergenceArticleAvailability(IEnumerable <IncomingWaybillRow> incomingRows, AccountingPriceList priceList, bool isOnAccountingPriceListStart, DateTime takingDate)
        {
            // если создаем связь на конец периода действия РЦ, но дата завершения действия РЦ не установлена - ошибка
            ValidationUtils.Assert(priceList.EndDate != null || isOnAccountingPriceListStart, "Не установлена дата окончания действия реестра цен.");

            foreach (var incomingRow in incomingRows)
            {
                var articleId = incomingRow.Batch.Article.Id;
                var articleAccountingPrice = priceList.ArticlePrices.Where(x => x.Article.Id == articleId).FirstOrDefault();

                if (articleAccountingPrice != null)
                {
                    var taking = new AccountingPriceListWaybillTaking(takingDate, true,
                                                                      articleAccountingPrice.Id, incomingRow.Type, incomingRow.Id, articleId, incomingRow.RecipientStorage.Id, incomingRow.Recipient.Id,
                                                                      articleAccountingPrice.AccountingPrice, isOnAccountingPriceListStart, 0); // для позиций, принятых с расхождениями, в связи указываем 0

                    accountingPriceListWaybillTakingRepository.Save(taking);
                }
            }
        }
Example #14
0
        /// <summary>
        /// Создание связей между позициями РЦ и позициями входящих принятых накладных по точному наличию (Дельта 0)
        /// </summary>
        /// <param name="incomingRows">Список позиций входящих принятых накладных</param>
        /// <param name="priceList">РЦ</param>
        /// <param name="isOnAccountingPriceListStart">Признак: создается ли связь на начало периода действия РЦ</param>
        /// <param name="takingDate">Дата и время связи</param>
        public void CreateTakingFromExactArticleAvailability(IEnumerable <IncomingWaybillRow> incomingRows, AccountingPriceList priceList, bool isOnAccountingPriceListStart, DateTime takingDate)
        {
            // если создаем связь на конец периода действия РЦ, но дата завершения действия РЦ не установлена - ошибка
            ValidationUtils.Assert(priceList.EndDate != null || isOnAccountingPriceListStart, "Не установлена дата окончания действия реестра цен.");

            foreach (var incomingRow in incomingRows)
            {
                var articleId = incomingRow.Batch.Article.Id;
                var articleAccountingPrice = priceList.ArticlePrices.Where(x => x.Article.Id == articleId).FirstOrDefault();

                if (articleAccountingPrice != null)
                {
                    var taking = new AccountingPriceListWaybillTaking(takingDate, true,
                                                                      articleAccountingPrice.Id, incomingRow.Type, incomingRow.Id, articleId, incomingRow.RecipientStorage.Id, incomingRow.Recipient.Id,
                                                                      articleAccountingPrice.AccountingPrice, isOnAccountingPriceListStart, incomingRow.AvailableInStorageCount);

                    // для связи типа Дельта_0 можно сразу установить дату осуществления переоценки
                    taking.RevaluationDate = isOnAccountingPriceListStart ? priceList.StartDate : priceList.EndDate.Value;

                    accountingPriceListWaybillTakingRepository.Save(taking);
                }
            }
        }
Example #15
0
        /// <summary>
        /// Создание связей между позициями РЦ и позициями исходящих проведенных, но не отгруженных/не принятых получателем накладных (Дельта 1-)
        /// </summary>
        /// <param name="outgoingRows">Список позиций исходящих проведенных, но не отгруженных/не принятых получателем накладных</param>
        /// <param name="priceList">РЦ</param>
        /// <param name="isOnAccountingPriceListStart">Признак: создается ли связь на начало периода действия РЦ</param>
        /// <param name="takingDate">Дата и время связи</param>
        public void CreateTakingFromOutgoingAcceptedArticleAvailability(IEnumerable <OutgoingWaybillRow> outgoingRows, AccountingPriceList priceList, bool isOnAccountingPriceListStart, DateTime takingDate)
        {
            // если создаем связь на конец периода действия РЦ, но дата завершения действия РЦ не установлена - ошибка
            ValidationUtils.Assert(priceList.EndDate != null || isOnAccountingPriceListStart, "Не установлена дата окончания действия реестра цен.");

            foreach (var outgoingRow in outgoingRows)
            {
                var articleId = outgoingRow.Batch.Article.Id;
                var articleAccountingPrice = priceList.ArticlePrices.Where(x => x.Article.Id == articleId).FirstOrDefault();

                if (articleAccountingPrice != null)
                {
                    var taking = new AccountingPriceListWaybillTaking(takingDate, false,
                                                                      articleAccountingPrice.Id, outgoingRow.Type, outgoingRow.Id, articleId, outgoingRow.SenderStorage.Id, outgoingRow.Sender.Id,
                                                                      articleAccountingPrice.AccountingPrice, isOnAccountingPriceListStart, outgoingRow.Count);

                    accountingPriceListWaybillTakingRepository.Save(taking);
                }
            }
        }
 public void Delete(AccountingPriceList entity)
 {
     entity.DeletionDate = DateTime.Now;
     CurrentSession.SaveOrUpdate(entity);
 }
 public void Save(AccountingPriceList entity)
 {
     CurrentSession.SaveOrUpdate(entity);
     CurrentSession.Flush();
 }
Example #18
0
        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);
        }
Example #19
0
        /// <summary>
        /// Получить учетные цены по списку товаров и списку мест хранения из РЦ, действующие за 1 секунду перед наступлением указанного момента времени
        /// </summary>
        /// <remarks>Возвращает двумерный динамический массив "код МХ - код товара"</remarks>
        public DynamicDictionary <short, DynamicDictionary <int, decimal?> > GetAccountingPrice(AccountingPriceList accountingPriceList, DateTime?date)
        {
            date = date ?? DateTime.Now;

            date = date.Value.AddSeconds(-1);

            var indicators = articleAccountingPriceIndicatorService.GetList(accountingPriceList, date.Value);

            var result = new DynamicDictionary <short, DynamicDictionary <int, decimal?> >();

            foreach (var item in indicators)
            {
                result[item.StorageId][item.ArticleId] = item.AccountingPrice;
            }

            return(result);
        }
 public void CheckPossibilityToViewDetails(AccountingPriceList priceList, User user)
 {
     CheckPermissionToPerformOperation(priceList, user, Permission.AccountingPriceList_List_Details);
 }
        public void AddStorage(AccountingPriceList accPriceList, Storage storage, IEnumerable <Storage> storageList, User user)
        {
            CheckPossibilityToAddStorage(accPriceList, user);

            accPriceList.AddStorage(storage);
        }
        public void Delete(AccountingPriceList accountingPriceList, User user)
        {
            CheckPossibilityToDelete(accountingPriceList, user);

            accountingPriceListRepository.Delete(accountingPriceList);
        }
 public void Save(AccountingPriceList accountingPriceList)
 {
     accountingPriceListRepository.Save(accountingPriceList);
 }
        public void DeleteStorage(AccountingPriceList accPriceList, Storage storage, IEnumerable <Storage> storageList, User user)
        {
            CheckPossibilityToRemoveStorage(accPriceList, user);

            accPriceList.RemoveStorage(storage);
        }