예제 #1
0
        /// <summary>
        /// Расчет стоимости накладной в учетных ценах
        /// </summary>
        /// <param name="waybill">Приходная накладная</param>
        /// <param name="user">Пользователь</param>
        /// <param name="excludeDivergences">Исключить ли суммы по позициям с расхождениями</param>
        /// <returns>Сумма в учетных ценах. Если не удалось рассчитать, то null</returns>
        public decimal?CalcAccountingPriceSum(ReceiptWaybill waybill, User user, bool excludeDivergences)
        {
            decimal?result = 0;

            // если накладная не проведена - считаем по текущим УЦ
            if (!waybill.IsAccepted)
            {
                result = CalcCurrentAccountingPriceSum(waybill.Rows, waybill.Id, waybill.ReceiptStorage, user);
            }
            // если накладная принята с расхождениями (т.е. принята, но не согласована)
            else if (waybill.ReceiptDate != null && !waybill.IsApproved)
            {
                // считаем сумму в УЦ для позиций без расхождений
                result = waybill.Rows.Where(x => !x.AreDivergencesAfterReceipt).Sum(x => Math.Round(x.CurrentCount * x.RecipientArticleAccountingPrice.AccountingPrice, 2));

                // если включаем позиции с расхождениями
                if (!excludeDivergences)
                {
                    // для позиций, добавленных при приемке, берем 0
                    result += waybill.Rows.Where(x => x.AreDivergencesAfterReceipt)
                              .Sum(x => Math.Round(x.CurrentCount * (x.RecipientArticleAccountingPrice != null ? x.RecipientArticleAccountingPrice.AccountingPrice : 0), 2));
                }
            }
            // если накладная проведена, но не принята; принята без расхождений; согласована после расхождений
            else
            {
                result = waybill.Rows.Sum(x => Math.Round(x.CurrentCount * x.RecipientArticleAccountingPrice.AccountingPrice, 2));
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Пересчет финансовых показателей после отмены окончательного согласования приходной накладной
        /// </summary>
        /// <param name="waybill">Приходная накладная</param>
        public void ReceiptWaybillApprovementCancelled(ReceiptWaybill waybill)
        {
            //для расчета учетных сумм
            decimal currentAccountingSum = 0M, currentPurchaseCostSum = 0M;

            // если есть позиции с расхождениями после приемки
            if (waybill.AreDivergencesAfterReceipt)
            {
                // позиции с расхождениями при приемке
                var rows = waybill.Rows.Where(x => x.AreDivergencesAfterReceipt == true || x.PendingCount == 0);

                // расчет суммы в учетных ценах
                currentAccountingSum = CalculateReceiptWaybillAccountingPriceSumByRows(rows);
                // расчет суммы в закупочных ценах
                currentPurchaseCostSum = CalculateReceiptWaybillPurchaseCostSumByRows(rows);
            }
            else
            {
                // берем все позиции накладной
                var rows = waybill.Rows;

                // расчет суммы в учетных ценах
                currentAccountingSum = CalculateReceiptWaybillAccountingPriceSumByRows(rows);
                // расчет суммы в закупочных ценах
                currentPurchaseCostSum = CalculateReceiptWaybillPurchaseCostSumByRows(rows);
            }

            articleMovementFactualFinancialIndicatorService.Update(waybill.ApprovementDate.Value, null, null, waybill.AccountOrganization.Id,
                                                                   waybill.ReceiptStorage.Id, ArticleMovementOperationType.Receipt, waybill.Id, -currentPurchaseCostSum, -currentAccountingSum, 0);
        }
예제 #3
0
        public void Init()
        {
            storage = new Storage("Тестовое место хранения", StorageType.DistributionCenter)
            {
                Id = 1
            };
            writeoffReason = new WriteoffReason("Тестовая причина списания")
            {
                Id = 2
            };

            var juridicalLegalForm = new LegalForm("ООО", EconomicAgentType.JuridicalPerson)
            {
                Id = 3
            };
            var juridicalPerson = new JuridicalPerson(juridicalLegalForm)
            {
                Id = 4
            };
            var juridicalPerson2 = new JuridicalPerson(juridicalLegalForm)
            {
                Id = 15
            };

            accountOrganization = new AccountOrganization("Тестовое юридическое лицо", "Тестовое юридическое лицо", juridicalPerson)
            {
                Id = 5
            };

            var provider = new Provider("Тестовый поставщик", new ProviderType("Тестовый тип поставщика"), ProviderReliability.Medium, 5)
            {
                Id = 6
            };
            var providerOrganization = new ProviderOrganization("Организация поставщика", "Организация поставщика", juridicalPerson2);
            var articleGroup         = new ArticleGroup("Тестовая группа", "Тестовая группа");
            var measureUnit          = new MeasureUnit("шт.", "Штука", "123", 0)
            {
                Id = 1
            };
            var customDeclarationNumber = new String('0', 25);

            article          = new Article("Тестовый товар А", articleGroup, measureUnit, true);
            providerContract = new ProviderContract(accountOrganization, providerOrganization, "Договор", "4645", DateTime.Now, DateTime.Now);
            provider.AddProviderContract(providerContract);

            user              = new User(new Employee("Иван", "Иванов", "Иванович", new EmployeePost("Менеджер"), null), "Иванов Иван", "ivanov", "pa$$w0rd", new Team("Тестовая команда", null), null);
            receiptWaybill    = new ReceiptWaybill("123АБВ", DateTime.Today.AddDays(1), storage, accountOrganization, provider, 1234.5M, 0M, new ValueAddedTax("18%", 18), providerContract, customDeclarationNumber, user, user, DateTime.Now);
            receiptWaybillRow = new ReceiptWaybillRow(article, 100, 1234.5M, receiptWaybill.PendingValueAddedTax);
            receiptWaybill.AddRow(receiptWaybillRow);

            writeoffWaybill = new WriteoffWaybill("123", DateTime.Today, storage, accountOrganization, writeoffReason, user, user, DateTime.Now);

            priceLists = new List <ArticleAccountingPrice>()
            {
                new ArticleAccountingPrice(article, 10M)
            };
        }
예제 #4
0
        /// <summary>
        /// Пересчет показателей закупок при отмене согласования накладной прихода.
        /// </summary>
        /// <param name="waybill">Накладная прихода. На момент вызова метода должна быть в состоянии "Согласована".</param>
        public void ReceiptWaybillApprovementCancelled(ReceiptWaybill waybill)
        {
            UpdateAcceptedIndicators(waybill, waybill.ApprovementDate.Value, -1, x => x.AreDivergencesAfterReceipt);
            UpdateApprovedIndicators(waybill, waybill.ApprovementDate.Value, -1, x => x.AreDivergencesAfterReceipt);

            if (!waybill.Rows.Any(x => x.AreDivergencesAfterReceipt))
            {
                UpdateApprovedIndicators(waybill, waybill.ReceiptDate.Value, -1, x => !x.AreDivergencesAfterReceipt);
            }
        }
예제 #5
0
        /// <summary>
        /// Установка закупочных цен в индикаторах по заданной приходной накладной из 0 в заданные значения (значения берутся из позиций приходной накладной)
        /// </summary>
        /// <param name="receiptWaybill">Приходная накладная</param>
        public void SetPurchaseCosts(ReceiptWaybill receiptWaybill)
        {
            var indicatorList = GetList(receiptWaybill.Id);

            var purchaseCostDictionary = receiptWaybill.Rows.ToDictionary(x => x.Id, x => x.PurchaseCost);

            foreach (var indicator in indicatorList)
            {
                indicator.PurchaseCostSum = Math.Round(purchaseCostDictionary[indicator.BatchId] * indicator.ReturnedCount, 6);
            }
        }
예제 #6
0
        /// <summary>
        /// Установка закупочных цен по заданной приходной накладной из 0 в заданные значения (из позиций приходной накладной)
        /// </summary>
        /// <param name="receiptWaybill">Приходная накладная</param>
        public void SetPurchaseCosts(ReceiptWaybill receiptWaybill)
        {
            var indicatorList = GetList(receiptWaybill.Id);

            var purchaseCostDictionary = receiptWaybill.Rows.ToDictionary(x => x.Id, x => x.PurchaseCost);

            foreach (var indicator in indicatorList)
            {
                indicator.PurchaseCost = purchaseCostDictionary[indicator.BatchId];
            }
        }
예제 #7
0
        /// <summary>
        /// Пересчет финансовых показателей после окончательного согласования приходной накладной
        /// </summary>
        /// <param name="waybill">Приходная накладная</param>
        public void ReceiptWaybillApproved(ReceiptWaybill waybill)
        {
            // позиции с расхождениями при приемке
            var rows = waybill.Rows.Where(x => x.AreDivergencesAfterReceipt == true || x.PendingCount == 0);

            // расчет суммы в учетных ценах
            var currentAccountingSum = CalculateReceiptWaybillAccountingPriceSumByRows(rows);
            // расчет суммы в закупочных ценах
            var currentPurchaseCostSum = CalculateReceiptWaybillPurchaseCostSumByRows(rows);

            articleMovementFactualFinancialIndicatorService.Update(waybill.ApprovementDate.Value, null, null, waybill.AccountOrganization.Id,
                                                                   waybill.ReceiptStorage.Id, ArticleMovementOperationType.Receipt, waybill.Id, currentPurchaseCostSum, currentAccountingSum, 0);
        }
        /// <summary>
        /// Измеение закупочных цен в индикаторах.
        /// </summary>
        /// <param name="receiptWaybill">Приходная накладная.</param>
        /// <param name="startDate">Дата, начиная с которой должны быть изменены индикаторы.</param>
        /// <param name="sign">Коэффициент, определяющий направление изменения индикатора. Принимает значение 1, или -1. При значении 1 индикатор будет увеличен, -1 — уменьшен.</param>
        private void UpdatePurchaseCosts(ReceiptWaybill receiptWaybill, DateTime startDate, short sign)
        {
            var indicatorList = purchaseIndicatorRepository.GetFrom(startDate.RoundToSeconds(), receiptWaybill.Curator.Id, receiptWaybill.ReceiptStorage.Id, receiptWaybill.Contract.Id,
                                                                    receiptWaybill.Contractor.Id, receiptWaybill.AccountOrganization.Id, receiptWaybill.ContractorOrganization.Id, receiptWaybillRepository.GetArticlesSubquery(receiptWaybill.Id));

            var purchaseCostDictionary = receiptWaybill.Rows.ToDictionary(x => x.Article.Id, x => x.PurchaseCost);

            foreach (var row in receiptWaybill.Rows)
            {
                foreach (var indicator in indicatorList.Where(x => x.ArticleId == row.Article.Id))
                {
                    indicator.PurchaseCostSum += sign * Math.Round(purchaseCostDictionary[indicator.ArticleId] * row.CurrentCount, 6);
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Обновление показателя "отгруженных закупок".
        /// </summary>
        /// <param name="waybill">Накладная прихода.</param>
        /// <param name="date">Дата начала действия индикатора.</param>
        /// <param name="sign">Коэффициент, определяющий направление изменения индикатора. Принимает значение 1, или -1. При значении 1 индикатор будет увеличен, -1 — уменьшен.</param>
        /// <param name="rowsFilter">Фильтр позиций накладной. Должен возвращать true, если по этой позиции создавать индикатор и false в противном случае.</param>
        private void UpdateApprovedIndicators(ReceiptWaybill waybill, DateTime date, short sign, Func <ReceiptWaybillRow, bool> rowsFilter = null)
        {
            var approvedIndicators = new List <ApprovedPurchaseIndicator>();

            ValidationUtils.Assert(sign == 1 || sign == -1, "Значение множителя может быть только 1 или -1.");

            var rows = rowsFilter != null?waybill.Rows.Where(x => rowsFilter(x)) : waybill.Rows;

            foreach (var item in rows)
            {
                approvedIndicators.Add(CreateApprovedPurchaseIndicator(date, item, sign));
            }

            approvedPurchaseIndicatorService.Update(date, waybill.Curator.Id, waybill.ReceiptStorage.Id, waybill.Contract.Id,
                                                    waybill.Contractor.Id, waybill.AccountOrganization.Id, waybill.ContractorOrganization.Id, approvedIndicators);
        }
예제 #10
0
        /// <summary>
        /// Расчет стоимости накладной в закупочных ценах
        /// </summary>
        /// <param name="waybill">Приходная накладная</param>
        /// <param name="user">Пользователь</param>
        /// <param name="excludeDivergences">Исключить ли суммы по позициям с расхождениями</param>
        /// <returns>Сумма в учетных ценах. Если не удалось рассчитать, то null</returns>
        public decimal?CalcPurchaseCostSum(ReceiptWaybill waybill, User user, bool excludeDivergences)
        {
            decimal?result = 0;

            // если накладная принята с расхождениями (т.е. принята, но не согласована)
            if (waybill.ReceiptDate != null && !waybill.IsApproved)
            {
                // считаем сумму в УЦ для позиций без расхождений
                result = waybill.Rows.Where(x => !x.AreDivergencesAfterReceipt).Sum(x => Math.Round(x.CurrentCount * x.PurchaseCost, 2));

                // если включаем позиции с расхождениями
                if (!excludeDivergences)
                {
                    result += waybill.Rows.Where(x => x.AreDivergencesAfterReceipt).Sum(x => Math.Round(x.CurrentCount * x.PurchaseCost, 2));
                }
            }
            else
            {
                result = waybill.Rows.Sum(x => Math.Round(x.CurrentCount * x.PurchaseCost, 2));
            }

            return(result);
        }
예제 #11
0
 /// <summary>
 /// Пересчет показателей закупок при отмене проводки накладной прихода.
 /// </summary>
 /// <param name="waybill">Накладная прихода. На момент вызова метода долна быть еще в состоянии "Проведена".</param>
 public void ReceiptWaybillAcceptanceCancelled(ReceiptWaybill waybill)
 {
     UpdateAcceptedIndicators(waybill, waybill.AcceptanceDate.Value, -1);
 }
 /// <summary>
 /// Пересчитать суммы в закупочных ценах во всех затронутых индикаторах. Вызывается при установке цен в позициях данной приходной накладной (были нулевые)
 /// </summary>
 /// <param name="receiptWaybill">Приходная накладная (цены должны быть уже вычислены и записаны в нее)</param>
 public void SetPurchaseCosts(ReceiptWaybill receiptWaybill)
 {
     ChangePurchaseCosts(receiptWaybill, Decimal.One);
 }
예제 #13
0
 /// <summary>
 /// Пересчет показателей закупок при согласовании накладной прихода.
 /// </summary>
 /// <param name="waybill">Накладная прихода. На момент вызова метода должна быть в состоянии "Согласована".</param>
 public void ReceiptWaybillApproved(ReceiptWaybill waybill)
 {
     UpdateAcceptedIndicators(waybill, waybill.ApprovementDate.Value, 1, x => x.AreDivergencesAfterReceipt);
     UpdateApprovedIndicators(waybill, waybill.ApprovementDate.Value, 1, x => x.AreDivergencesAfterReceipt);
 }
예제 #14
0
 /// <summary>
 /// Пересчет показателей закупок при отмене приемки накладной прихода.
 /// </summary>
 /// <param name="waybill">Накладная прихода. На момент вызова метода должна быть в состоянии "Принята".</param>
 public void ReceiptWaybillReceiptCancelled(ReceiptWaybill waybill)
 {
     UpdateAcceptedIndicators(waybill, waybill.ReceiptDate.Value, 1, x => x.AreDivergencesAfterReceipt);
     UpdateApprovedIndicators(waybill, waybill.ReceiptDate.Value, -1, x => !x.AreDivergencesAfterReceipt);
 }
예제 #15
0
        public void Init()
        {
            // инициализация IoC
            IoCInitializer.Init();

            receiptWaybillRepository = Mock.Get(IoCContainer.Resolve <IReceiptWaybillRepository>());

            receiptWaybillService = new ReceiptWaybillService(IoCContainer.Resolve <IArticleRepository>(),
                                                              receiptWaybillRepository.Object,
                                                              IoCContainer.Resolve <IMovementWaybillRepository>(), IoCContainer.Resolve <IExpenditureWaybillRepository>(),
                                                              IoCContainer.Resolve <IStorageRepository>(), IoCContainer.Resolve <IUserRepository>(),
                                                              IoCContainer.Resolve <IChangeOwnerWaybillRepository>(), IoCContainer.Resolve <IWriteoffWaybillRepository>(),
                                                              IoCContainer.Resolve <IStorageService>(),
                                                              IoCContainer.Resolve <IAccountOrganizationService>(),
                                                              IoCContainer.Resolve <IProviderService>(),
                                                              IoCContainer.Resolve <IProviderContractService>(),
                                                              IoCContainer.Resolve <IValueAddedTaxService>(),
                                                              IoCContainer.Resolve <IArticleMovementService>(),
                                                              IoCContainer.Resolve <IArticlePriceService>(),
                                                              IoCContainer.Resolve <IExactArticleAvailabilityIndicatorService>(),
                                                              IoCContainer.Resolve <IIncomingAcceptedArticleAvailabilityIndicatorService>(),
                                                              IoCContainer.Resolve <IArticleAccountingPriceIndicatorService>(),
                                                              IoCContainer.Resolve <IArticleMovementOperationCountService>(),
                                                              IoCContainer.Resolve <IOutgoingAcceptedFromExactArticleAvailabilityIndicatorService>(),
                                                              IoCContainer.Resolve <IOutgoingAcceptedFromIncomingAcceptedArticleAvailabilityIndicatorService>(),
                                                              IoCContainer.Resolve <IArticleMovementFactualFinancialIndicatorService>(),
                                                              IoCContainer.Resolve <IFactualFinancialArticleMovementService>(),
                                                              IoCContainer.Resolve <IAcceptedSaleIndicatorService>(),
                                                              IoCContainer.Resolve <IShippedSaleIndicatorService>(),
                                                              IoCContainer.Resolve <IReceiptedReturnFromClientIndicatorService>(),
                                                              IoCContainer.Resolve <IAcceptedReturnFromClientIndicatorService>(),
                                                              IoCContainer.Resolve <IReturnFromClientBySaleAcceptanceDateIndicatorService>(),
                                                              IoCContainer.Resolve <IReturnFromClientBySaleShippingDateIndicatorService>(),
                                                              IoCContainer.Resolve <IArticleRevaluationService>(),
                                                              IoCContainer.Resolve <IArticlePurchaseService>(),
                                                              IoCContainer.Resolve <IAcceptedPurchaseIndicatorService>(),
                                                              IoCContainer.Resolve <IApprovedPurchaseIndicatorService>(),
                                                              IoCContainer.Resolve <IArticleAvailabilityService>()
                                                              );

            var juridicalLegalForm = new LegalForm("ООО", EconomicAgentType.JuridicalPerson);
            var providerType       = new ProviderType("Тестовый тип поставщика");
            var articleGroup       = new ArticleGroup("Бытовая техника", "Бытовая техника");
            var measureUnit        = new MeasureUnit("шт", "штука", "123", 0);
            var article            = new Article("Пылесос", articleGroup, measureUnit, true)
            {
                Id = 1
            };

            priceLists = new List <ArticleAccountingPrice>()
            {
                new ArticleAccountingPrice(article, 100M)
            };

            var provider = new Provider("Нейтральная организация", providerType, ProviderReliability.Medium, 5);

            var providerOrganization = new ProviderOrganization("Тестовое физическое лицо", "Тестовое физическое лицо", new JuridicalPerson(juridicalLegalForm))
            {
                Id = 1
            };
            var accountOrganization = new AccountOrganization(@"ООО ""Юридическое лицо""", @"ООО ""Юридическое лицо""", new JuridicalPerson(juridicalLegalForm))
            {
                Id = 2
            };

            provider.AddContractorOrganization(providerOrganization);

            var providerContract = new ProviderContract(accountOrganization, providerOrganization, "ABC", "123", DateTime.Now, DateTime.Today);

            provider.AddProviderContract(providerContract);

            role = new Role("Администратор");
            role.AddPermissionDistribution(new PermissionDistribution(Permission.ReceiptWaybill_Delete_Row_Delete, PermissionDistributionType.All));
            user = new User(new Employee("Иван", "Иванов", "Иванович", new EmployeePost("Менеджер"), null), "Иванов Иван", "ivanov", "pa$$w0rd", new Team("Тестовая команда", null), null);
            user.AddRole(role);
            createdBy = new User(new Employee("Олег", "Олегов", "Олегович", new EmployeePost("Менеджер"), null), "Олегов Олег", "olegov", "pa$$w0rd", new Team("Тестовая команда", null), null);
            createdBy.AddRole(role);
            acceptedBy = new User(new Employee("Петр", "Петров", "Петрович", new EmployeePost("Менеджер"), null), "Петров Петр", "petrov", "pa$$w0rd", new Team("Тестовая команда", null), null);
            acceptedBy.AddRole(role);
            receiptedBy = new User(new Employee("Николай", "Николаев", "Николаевия", new EmployeePost("Менеджер"), null), "Николаев Николай", "nikolaev", "pa$$w0rd", new Team("Тестовая команда", null), null);
            receiptedBy.AddRole(role);

            var customDeclarationNumber = new String('0', 25);

            receiptWaybill    = new ReceiptWaybill("999999", DateTime.Today, new Storage("Третий склад", StorageType.DistributionCenter), accountOrganization, provider, 50, 0M, new ValueAddedTax("10%", 10), providerContract, customDeclarationNumber, user, createdBy, DateTime.Now);
            receiptWaybillRow = new ReceiptWaybillRow(article, 5, 50M, receiptWaybill.PendingValueAddedTax);

            receiptWaybill.AddRow(receiptWaybillRow);

            receiptWaybillList = new List <ReceiptWaybill> {
                receiptWaybill
            };

            receiptWaybillRepository.Setup(x => x.Delete(It.IsAny <ReceiptWaybill>())).Callback <ReceiptWaybill>(waybill => receiptWaybillList.Remove(waybill));
        }
        public void Init()
        {
            receiptWaybillRepository              = Mock.Get(IoCContainer.Resolve <IReceiptWaybillRepository>());
            productionOrderRepository             = Mock.Get(IoCContainer.Resolve <IProductionOrderRepository>());
            productionOrderBatchRepository        = Mock.Get(IoCContainer.Resolve <IProductionOrderBatchRepository>());
            defaultProductionOrderStageRepository = Mock.Get(IoCContainer.Resolve <IDefaultProductionOrderStageRepository>());
            taskRepository = Mock.Get(IoCContainer.Resolve <ITaskRepository>());

            articleAccountingPriceIndicatorService = Mock.Get(IoCContainer.Resolve <IArticleAccountingPriceIndicatorService>());

            productionOrderService_accessor = new Mock <ProductionOrderService_Accessor>(productionOrderRepository.Object, productionOrderBatchRepository.Object,
                                                                                         receiptWaybillRepository.Object, taskRepository.Object, defaultProductionOrderStageRepository.Object);
            productionOrderService = new Mock <ProductionOrderService>(productionOrderRepository.Object, productionOrderBatchRepository.Object,
                                                                       receiptWaybillRepository.Object, taskRepository.Object, defaultProductionOrderStageRepository.Object);

            var juridicalLegalForm = new LegalForm("ООО", EconomicAgentType.JuridicalPerson);
            var providerType       = new ProviderType("Тестовый тип поставщика");
            var articleGroup       = new ArticleGroup("Бытовая техника", "Бытовая техника");
            var measureUnit        = new MeasureUnit("шт", "штука", "123", 0);

            article1 = new Article("Пылесос", articleGroup, measureUnit, true)
            {
                Id = 1
            };
            article2 = new Article("Пылесос2", articleGroup, measureUnit, true)
            {
                Id = 2
            };
            article3 = new Article("Пылесос3", articleGroup, measureUnit, true)
            {
                Id = 3
            };

            priceLists = new List <ArticleAccountingPrice>()
            {
                new ArticleAccountingPrice(article1, 100M),
                new ArticleAccountingPrice(article2, 150M),
                new ArticleAccountingPrice(article3, 200M)
            };

            var provider = new Provider("Нейтральная организация", providerType, ProviderReliability.Medium, 5);

            var providerOrganization = new ProviderOrganization("Тестовое физическое лицо", "Тестовое физическое лицо", new JuridicalPerson(juridicalLegalForm))
            {
                Id = 1
            };
            var accountOrganization = new AccountOrganization(@"ООО ""Юридическое лицо""", @"ООО ""Юридическое лицо""", new JuridicalPerson(juridicalLegalForm))
            {
                Id = 2
            };

            provider.AddContractorOrganization(providerOrganization);

            var providerContract = new ProviderContract(accountOrganization, providerOrganization, "ABC", "123", DateTime.Now, DateTime.Today);

            provider.AddProviderContract(providerContract);

            role = new Role("Администратор");
            role.AddPermissionDistribution(new PermissionDistribution(Permission.ReceiptWaybill_Delete_Row_Delete, PermissionDistributionType.All));
            user = new User(new Employee("Иван", "Иванов", "Иванович", new EmployeePost("Менеджер"), null), "Иванов Иван", "ivanov", "pa$$w0rd", new Team("Тестовая команда", null), null);
            user.AddRole(role);

            storage = new Storage("МХ", StorageType.TradePoint);
            storage.AddAccountOrganization(accountOrganization);

            producer = new Producer("producer", "organization", 5, user, false);
            var producerContract = new ProducerContract(accountOrganization, producer.Organization, "ABC", "123", DateTime.Now, DateTime.Today);

            currency = new Currency("755", "EUR", "Евро");

            var stage1 = new ProductionOrderBatchStage_Accessor("1", ProductionOrderBatchStageType.Calculation, 1, false)
            {
                IsDefault = true
            };
            var stage2 = new ProductionOrderBatchStage_Accessor("2", ProductionOrderBatchStageType.Closed, 0, false)
            {
                IsDefault = true
            };
            var stage3 = new ProductionOrderBatchStage_Accessor("3", ProductionOrderBatchStageType.Closed, 0, false)
            {
                IsDefault = true
            };
            var currentDateTime = DateTimeUtils.GetCurrentDateTime();

            productionOrder = new ProductionOrder("ЗАКАЗ", producer, currency,
                                                  (ProductionOrderBatchStage)stage1.Target,
                                                  (ProductionOrderBatchStage)stage2.Target,
                                                  (ProductionOrderBatchStage)stage3.Target,
                                                  ProductionOrderArticleTransportingPrimeCostCalculationType.Weight,
                                                  true, true, true, true, true, false, false,
                                                  user, currentDateTime)
            {
                Storage = storage
            };

            productionOrder.AddContract(producerContract);
            productionOrderBatch = productionOrder.Batches.FirstOrDefault();
            manufacturer         = new Manufacturer("Изготовитель");
            producer.AddManufacturer(manufacturer);
            productionOrderBatchRow1 = new ProductionOrderBatchRow(article1, currency, 5M, 10M, 1.0M, new Country("Страна1", "686"), manufacturer)
            {
                Id = Guid.NewGuid()
            };
            productionOrderBatchRow2 = new ProductionOrderBatchRow(article2, currency, 25M, 5M, 2.0M, new Country("Страна2", "686"), manufacturer)
            {
                Id = Guid.NewGuid()
            };
            productionOrderBatchRow3 = new ProductionOrderBatchRow(article3, currency, 100M, 2M, 1.5M, new Country("Страна3", "686"), manufacturer)
            {
                Id = Guid.NewGuid()
            };
            productionOrderBatch.AddRow(productionOrderBatchRow1);
            productionOrderBatch.AddRow(productionOrderBatchRow2);
            productionOrderBatch.AddRow(productionOrderBatchRow3);

            var customDeclarationNumber = new String('0', 25);

            receiptWaybill_accessor = new ReceiptWaybill_Accessor(productionOrderBatch, "999999", DateTime.Today, new ValueAddedTax("10%", 10), customDeclarationNumber, user, user, DateTime.Now);
            receiptWaybill          = (ReceiptWaybill)receiptWaybill_accessor.Target;

            receiptWaybillRow1 = new ReceiptWaybillRow(article1, 10M, 0M, receiptWaybill.PendingValueAddedTax)
            {
                Id = Guid.NewGuid()
            };
            receiptWaybill.AddRow(receiptWaybillRow1);
            productionOrderBatch.Rows.Where(x => x.Article == article1).FirstOrDefault().ReceiptWaybillRow = receiptWaybillRow1;

            receiptWaybillRow2 = new ReceiptWaybillRow(article2, 5M, 0M, receiptWaybill.PendingValueAddedTax)
            {
                Id = Guid.NewGuid()
            };
            receiptWaybill.AddRow(receiptWaybillRow2);
            productionOrderBatch.Rows.Where(x => x.Article == article2).FirstOrDefault().ReceiptWaybillRow = receiptWaybillRow2;

            receiptWaybillRow3 = new ReceiptWaybillRow(article3, 2M, 0M, receiptWaybill.PendingValueAddedTax)
            {
                Id = Guid.NewGuid()
            };
            receiptWaybill.AddRow(receiptWaybillRow3);
            productionOrderBatch.Rows.Where(x => x.Article == article3).FirstOrDefault().ReceiptWaybillRow = receiptWaybillRow3;

            receiptWaybillList = new List <ReceiptWaybill> {
                receiptWaybill
            };

            receiptWaybillRepository.Setup(x => x.Delete(It.IsAny <ReceiptWaybill>())).Callback <ReceiptWaybill>(waybill => receiptWaybillList.Remove(waybill));

            receiptWaybill.Accept(priceLists, user, DateTime.Now);

            receiptWaybillRow1.ReceiptedCount = receiptWaybillRow1.PendingCount;
            receiptWaybillRow1.ProviderCount  = receiptWaybillRow1.PendingCount;
            receiptWaybillRow1.ProviderSum    = 0M;

            receiptWaybillRow2.ReceiptedCount = receiptWaybillRow2.PendingCount;
            receiptWaybillRow2.ProviderCount  = receiptWaybillRow2.PendingCount;
            receiptWaybillRow2.ProviderSum    = 0M;

            receiptWaybillRow3.ReceiptedCount = receiptWaybillRow3.PendingCount;
            receiptWaybillRow3.ProviderCount  = receiptWaybillRow3.PendingCount;
            receiptWaybillRow3.ProviderSum    = 0M;
        }
 /// <summary>
 /// Уменьшение закупочных цен в индикаторах по заданной приходной накладной на заданные значения(значения берутся из позиций приходной накладной).
 /// </summary>
 /// <param name="receiptWaybill">Приходная накладная.</param>
 /// <param name="startDate">Дата, начиная с которой должны быть изменены индикаторы.</param>
 public void ResetPurchaseCosts(ReceiptWaybill receiptWaybill, DateTime startDate)
 {
     UpdatePurchaseCosts(receiptWaybill, startDate, -1);
 }
 public void WaybillFinalizationCancelled(ReceiptWaybill waybill)
 {
     articleMovementOperationCountIndicatorService.DecrementIndicator(waybill.ReceiptDate.Value, ArticleMovementOperationType.Receipt, waybill.ReceiptStorage.Id);
 }
 /// <summary>
 /// Пересчитать суммы в закупочных ценах во всех затронутых индикаторах. Вызывается при обнулении цен в позициях данной приходной накладной
 /// </summary>
 /// <param name="receiptWaybill">Приходная накладная</param>
 public void ResetPurchaseCosts(ReceiptWaybill receiptWaybill)
 {
     ChangePurchaseCosts(receiptWaybill, Decimal.MinusOne);
 }
        /// <summary>
        /// Пересчитать суммы в закупочных ценах во всех затронутых индикаторах.
        /// </summary>
        /// <param name="receiptWaybill">Приходная накладная, содержащая закупочные цены</param>
        /// <param name="sign">Знак (+1 или -1), с которым применяются данные закупочные цены (они возникают или обнуляются)</param>
        private void ChangePurchaseCosts(ReceiptWaybill receiptWaybill, decimal sign)
        {
            IEnumerable <Guid> movementWaybillIdList, writeoffWaybillIdList, expenditureWaybillIdList, returnFromClientWaybillIdList;
            IEnumerable <MovementWaybillRow>         movementWaybillRowList;
            IEnumerable <WriteoffWaybillRow>         writeoffWaybillRowList;
            IEnumerable <ExpenditureWaybillRow>      expenditureWaybillRowList;
            IEnumerable <ReturnFromClientWaybillRow> returnFromClientWaybillRowList;
            DateTime startDate;

            // Получаем список индикаторов, непосредственно отражающих действия с накладными, имеющими позиции по заданному приходу
            var actionIndicatorList = articleMovementFactualFinancialIndicatorRepository.GetIndicatorListForReceiptWaybill(receiptWaybill.Id,
                                                                                                                           out movementWaybillIdList, out movementWaybillRowList, out writeoffWaybillIdList, out writeoffWaybillRowList,
                                                                                                                           out expenditureWaybillIdList, out expenditureWaybillRowList, out returnFromClientWaybillIdList, out returnFromClientWaybillRowList,
                                                                                                                           out startDate);

            // Создаем словарь старых закупочных цен (ключ - код показателя, значение - старая ЗЦ, если нет такого элемента, ЗЦ не менялась)
            var oldPurchaseCostSumList = new Dictionary <Guid, decimal>();

            // 321 Так как проверяется только наличие показателя в данном списке (по id), можно бы сделать возвращаемое значение списком id - и облегчить запрос?
            // Если это не будет противоречить рефакторингу, о котором написано ниже (отобрать индикаторы во 2 список по одним ключам из 5-ти значений из списка actionIndicatorList)

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

            // Приход всегда один. И операция по нему одна - приемка без расхождений. И первая по времени
            var receiptWaybillRowDictionary = receiptWaybill.Rows.ToDictionary(x => x.Id);

            // Вычисляем суммы в ЗЦ, на которые изменились суммы затронутых накладных, и помещаем в Dictionary
            var purchaseCostChangeSumList = new DynamicDictionary <Guid, decimal>();

            purchaseCostChangeSumList[receiptWaybill.Id] = receiptWaybillRowDictionary.Sum(x => Math.Round(x.Value.PendingCount * x.Value.PurchaseCost, 6));

            foreach (var movementWaybillRow in movementWaybillRowList)
            {
                purchaseCostChangeSumList[movementWaybillRow.MovementWaybill.Id] +=
                    Math.Round(movementWaybillRow.MovingCount * receiptWaybillRowDictionary[movementWaybillRow.ReceiptWaybillRow.Id].PurchaseCost, 6);
            }

            foreach (var writeoffWaybillRow in writeoffWaybillRowList)
            {
                purchaseCostChangeSumList[writeoffWaybillRow.WriteoffWaybill.Id] +=
                    Math.Round(writeoffWaybillRow.WritingoffCount * receiptWaybillRowDictionary[writeoffWaybillRow.ReceiptWaybillRow.Id].PurchaseCost, 6);
            }

            foreach (var expenditureWaybillRow in expenditureWaybillRowList)
            {
                purchaseCostChangeSumList[expenditureWaybillRow.SaleWaybill.Id] +=
                    Math.Round(expenditureWaybillRow.SellingCount * receiptWaybillRowDictionary[expenditureWaybillRow.ReceiptWaybillRow.Id].PurchaseCost, 6);
            }

            foreach (var returnFromClientWaybillRow in returnFromClientWaybillRowList)
            {
                purchaseCostChangeSumList[returnFromClientWaybillRow.ReturnFromClientWaybill.Id] +=
                    Math.Round(returnFromClientWaybillRow.ReturnCount *
                               receiptWaybillRowDictionary[returnFromClientWaybillRow.ReceiptWaybillRow.Id].PurchaseCost, 6);
            }

            // Сделана проверка только на получателя! (Ведь пересчитывать сумму в ЗЦ на конкретном месте хранения следует только с момента,
            // когда данное МХ появляется в получателе (RecipientStorageId) - т.е. когда на данное МХ приходит товар, приходом, перемещением или возвратом)
            var storageList = actionIndicatorList.Select(x => x.Value.RecipientStorageId).Distinct().Where(x => x != null).Select(x => x.Value);

            // Словарь дельт (изменений суммы) в ЗЦ по всем ключам по отношению к ситуации до пересчета
            // Ключ (см. сущность показателя) есть код организации-отправителя, код МХ-отправителя, код организации-получателя, код МХ-получателя, тип операции товародвижения
            var storagePurchaseCostChangeSumDictionary = new DynamicDictionary <int, DynamicDictionary <short, DynamicDictionary <int, DynamicDictionary <short,
                                                                                                                                                          DynamicDictionary <ArticleMovementOperationType, decimal> > > > >();

            // Возможно, можно отбирать индикаторы во 2-й список по одним ключам из 5-ти значений из списка actionIndicatorList,
            // а не тянуть все для данного МХ. Но этот вопрос требует дополнительных исследований

            // Получаем список всех индикаторов, затронутых данными действиями (туда войдут и все из первого списка)
            var indicatorList = articleMovementFactualFinancialIndicatorRepository.GetIndicatorsListAfterDate(storageList, startDate);

            var indicatorDictionary = indicatorList.ToDictionary <ArticleMovementFactualFinancialIndicator, Guid>(x => x.Id);

            // Перебираем индикаторы по времени начала действия
            foreach (var indicator in indicatorList.OrderBy(x => x.StartDate))
            {
                // Из-за текущей системы проектирования показателей в БД остается строка даже для отмененной операции. При этом нет никакого признака, что операция отменена.
                // Поэтому можно брать разницу между данным показателем и предыдущим, и если она равна 0 - то игнорировать его.
                // Надо отметить, что при 0-х УЦ и ЗЦ может статься, что показатель не приращивает ни одно из значений, но не "отменен".
                // Этого тоже надо в будущем при перепроектировании избежать.
                decimal purchaseCostChangeSum, accountingPriceChangeSum, salePriceChangeSum;

                // Если показатель имеет предыдущий, вычисляем разность между ними во всех видах цен.
                if (indicator.PreviousId.HasValue)
                {
                    ArticleMovementFactualFinancialIndicator previousIndicator;

                    // Предыдущий может не попасть в выборку indicatorDictionary (если он был создан давно).
                    // Если же попадает, в indicatorDictionary быстро находим по ключу показатель с заданным Id.
                    if (indicatorDictionary.ContainsKey(indicator.PreviousId.Value))
                    {
                        previousIndicator = indicatorDictionary[indicator.PreviousId.Value];
                    }
                    else
                    {
                        previousIndicator = articleMovementFactualFinancialIndicatorRepository.GetById(indicator.PreviousId.Value);
                        ValidationUtils.NotNull(previousIndicator, "Индикатор не найден по своему идентификатору.");
                    }

                    decimal previousIndicatorOldPurchaseCostSum = oldPurchaseCostSumList.ContainsKey(previousIndicator.Id) ?
                                                                  oldPurchaseCostSumList[previousIndicator.Id] : previousIndicator.PurchaseCostSum;
                    purchaseCostChangeSum    = indicator.PurchaseCostSum - previousIndicatorOldPurchaseCostSum;
                    accountingPriceChangeSum = indicator.AccountingPriceSum - previousIndicator.AccountingPriceSum;
                    salePriceChangeSum       = indicator.SalePriceSum - previousIndicator.SalePriceSum;
                }
                else
                {
                    purchaseCostChangeSum    = indicator.PurchaseCostSum;
                    accountingPriceChangeSum = indicator.AccountingPriceSum;
                    salePriceChangeSum       = indicator.SalePriceSum;
                }

                // Если показатель дает нулевое приращение - например, он остался на месте показателя по принятию накладной после отмены принятия - игнорируем его:
                // не изменяем из-за него дельту по его ключу (но, как и для всех, пересчитываем его сумму в ЗЦ по существующей дельте)
                if (purchaseCostChangeSum != 0M || accountingPriceChangeSum != 0M || salePriceChangeSum != 0M)
                {
                    // При нахождении данного показателя в списке непосредственно отражающих действия с накладными - изменяем дельту по данному ключу
                    if (actionIndicatorList.ContainsKey(indicator.Id))
                    {
                        decimal waybillPurchaseCostChangeSum = purchaseCostChangeSumList[indicator.WaybillId] * sign;

                        storagePurchaseCostChangeSumDictionary
                        [indicator.SenderId ?? 0]
                        [indicator.SenderStorageId ?? (short)0]
                        [indicator.RecipientId ?? 0]
                        [indicator.RecipientStorageId ?? (short)0]
                        [indicator.ArticleMovementOperationType] += waybillPurchaseCostChangeSum;
                    }
                }

                // Если дельта по данному ключу не равна 0, меняем значение индикатора
                decimal indicatorPurchaseCostChangeSum = storagePurchaseCostChangeSumDictionary[indicator.SenderId ?? 0]
                                                         [indicator.SenderStorageId ?? (short)0]
                                                         [indicator.RecipientId ?? 0]
                                                         [indicator.RecipientStorageId ?? (short)0]
                                                         [indicator.ArticleMovementOperationType];

                if (indicatorPurchaseCostChangeSum != 0M)
                {
                    oldPurchaseCostSumList[indicator.Id] = indicator.PurchaseCostSum;
                    indicator.PurchaseCostSum           += indicatorPurchaseCostChangeSum;
                }
            }
        }
예제 #21
0
 /// <summary>
 /// Сброс закупочных цен в индикаторах по заданной приходной накладной в 0
 /// </summary>
 /// <param name="receiptWaybill">Приходная накладная</param>
 public void ResetPurchaseCosts(ReceiptWaybill receiptWaybill)
 {
     GetList(receiptWaybill.Id).ToList().ForEach(x => x.PurchaseCostSum = 0M);
 }
예제 #22
0
        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);
        }