public void DealPaymentDocumentDistributionTest_DealPaymentDocumentDistributionToSaleWaybill_InitialParameters_Must_Be_Set()
        {
            // Создаем оплату от клиента
            var currentDate           = DateTime.Now;
            var distributionDate      = DateTime.Now.AddDays(1);
            var dealPaymentFromClient = new DealPaymentFromClient(team.Object, user, "001", new DateTime(2012, 2, 18), 500M, DealPaymentForm.Cash, currentDate);

            var dealPaymentDocumentDistributionToSaleWaybill = new DealPaymentDocumentDistributionToSaleWaybill(dealPaymentFromClient, expenditureWaybill, 500M, distributionDate, currentDate);

            Assert.AreEqual(distributionDate, dealPaymentDocumentDistributionToSaleWaybill.DistributionDate);
            Assert.AreEqual(currentDate, dealPaymentDocumentDistributionToSaleWaybill.CreationDate);
            Assert.AreEqual(dealPaymentFromClient, dealPaymentDocumentDistributionToSaleWaybill.SourceDealPaymentDocument);
            Assert.AreEqual(expenditureWaybill, dealPaymentDocumentDistributionToSaleWaybill.SaleWaybill);
            Assert.AreEqual(500M, dealPaymentDocumentDistributionToSaleWaybill.Sum);
        }
        public void DealPaymentDocumentDistributionTest_AddDealPaymentDocumentDistribution_Must_Set_IsFullyDistributed_Flag_If_Fully_Distributed()
        {
            // Создаем оплату от клиента
            var currentDate           = DateTime.Now;
            var distributionDate      = DateTime.Now.AddDays(1);
            var dealPaymentFromClient = new DealPaymentFromClient(team.Object, user, "001", new DateTime(2012, 2, 18), 500M, DealPaymentForm.Cash, currentDate);

            // Создаем разнесение
            var dealPaymentDocumentDistributionToSaleWaybill = new DealPaymentDocumentDistributionToSaleWaybill(dealPaymentFromClient, expenditureWaybill, 500M, distributionDate, currentDate);

            Assert.IsFalse(dealPaymentFromClient.IsFullyDistributed);

            // Act
            dealPaymentFromClient.AddDealPaymentDocumentDistribution(dealPaymentDocumentDistributionToSaleWaybill);

            Assert.IsTrue(dealPaymentFromClient.IsFullyDistributed);
        }
Exemple #3
0
        /// <summary>
        /// Разнести неразнесенные части платежных документов на накладную реализации.
        /// После разнесения у накладной реализации может оставаться неоплаченный остаток.
        /// Если до разнесения накладная реализации не имеет положительного неоплаченного остатка, разнесение платежного документа не будет создано.
        /// При полной оплате накладной реализации происходит установка признака того, что накладная реализации полностью оплачена.
        /// </summary>
        /// <param name="dealPaymentUndistributedPartsInfo">Список неразнесенных частей платежных документов</param>
        /// <param name="saleWaybill">Накладная реализации (единственная), на которую выполняется разнесение платежных документов</param>
        /// <param name="debtRemainder">Текущий неоплаченный остаток по накладной</param>
        /// <param name="sumToDistribute">Сумма к разнесению</param>
        /// <param name="currentDate">Дата операции</param>
        private void PaySaleWaybill(List <DealPaymentUndistributedPartInfo> dealPaymentUndistributedPartsInfo, SaleWaybill saleWaybill, decimal debtRemainder, decimal sumToDistribute, DateTime currentDate)
        {
            // разносим неразнесенные части оплат
            foreach (var distributionPartInfo in dealPaymentUndistributedPartsInfo.OrderBy(x => x.AppearenceDate))
            {
                var dealPaymentDocument = distributionPartInfo.DealPaymentDocument;

                // cумма создаваемого разнесения платежного документа
                decimal sum = Math.Min(distributionPartInfo.Sum, sumToDistribute);
                // вычитаем разносимую сумму
                distributionPartInfo.Sum -= sum;
                sumToDistribute          -= sum;

                // дата создаваемого разнесения
                var distributionDate = DateTimeUtils.GetMaxDate(distributionPartInfo.AppearenceDate, saleWaybill.AcceptanceDate.Value);

                ValidationUtils.Assert(dealPaymentDocument.Is <DealPaymentFromClient>() || dealPaymentDocument.Is <DealCreditInitialBalanceCorrection>(),
                                       "Платежный документ имеет недопустимый тип.");

                ValidationUtils.Assert(sum > 0, "Сумма для разнесения должна быть положительной.");

                if (saleWaybill.Is <ExpenditureWaybill>()) // Если появятся еще типы накладных реализации, вместо "накладная реализации товаров" выводить их названия
                {
                    ExpenditureWaybill expenditureWaybill = saleWaybill.As <ExpenditureWaybill>();

                    ValidationUtils.Assert(expenditureWaybill.IsAccepted, String.Format("Невозможно разнести платежный документ на накладную реализации товаров {0} со статусом «{1}».",
                                                                                        expenditureWaybill.Name, expenditureWaybill.State.GetDisplayName()));

                    ValidationUtils.Assert(sum <= debtRemainder, String.Format("Сумма для разнесения ({0} р.) превышает неоплаченный остаток накладной реализации товаров {1} ({2} р.)",
                                                                               sum.ForDisplay(ValueDisplayType.Money), expenditureWaybill.Name, debtRemainder.ForDisplay(ValueDisplayType.Money)));

                    ValidationUtils.Assert(dealPaymentDocument.Team == saleWaybill.Team,
                                           String.Format("Невозможно оплатить накладную реализации «{0}», т.к. она относится к другой команде.", saleWaybill.Name));

                    // формируем разнесение
                    var dealPaymentDocumentDistributionToSaleWaybill = new DealPaymentDocumentDistributionToSaleWaybill(dealPaymentDocument, expenditureWaybill, sum,
                                                                                                                        distributionDate, currentDate)
                    {
                        SourceDistributionToReturnFromClientWaybill = distributionPartInfo.DealPaymentDocumentDistributionToReturnFromClientWaybill
                    };

                    dealPaymentDocument.AddDealPaymentDocumentDistribution(dealPaymentDocumentDistributionToSaleWaybill);

                    debtRemainder -= sum;

                    // Если накладная реализации товаров полностью оплачена, ставим ей признак полной оплаты
                    expenditureWaybill.IsFullyPaid = debtRemainder <= 0M;
                }

                // и выходим
                if (saleWaybill.IsFullyPaid)
                {
                    break;
                }
            }

            // удаляем полностью разнесенные части
            var undistributedPartsToDelete = dealPaymentUndistributedPartsInfo.Where(x => x.Sum == 0).ToList();

            foreach (var item in undistributedPartsToDelete)
            {
                dealPaymentUndistributedPartsInfo.Remove(item);
            }
        }