예제 #1
0
 public fmCPRRepaymentJurnal(
     Session session,
     fmCPRRepaymentTask repaymentTask,
     fmCDocRCB paymentDocument,
     fmCPRPaymentRequest paymentRequest,
     crmBankAccount bankAccount,
     Decimal sumIn,
     Decimal sumObligationIn,
     Decimal sumOut,
     Decimal sumObligationOut,
     DateTime paymentDate,
     csValuta valutaPayment,
     csValuta valutaObligation,
     CRM.Contract.Analitic.PlaneFact planFact)
     : base(session)
 {
     this.RepaymentTask    = repaymentTask;
     this.PaymentDocument  = paymentDocument;
     this.PaymentRequest   = paymentRequest;
     this.BankAccount      = bankAccount;
     this.SumIn            = sumIn;
     this.SumObligationIn  = sumObligationIn;
     this.SumOut           = sumOut;
     this.SumObligationOut = sumObligationOut;
     this.ValutaPayment    = valutaPayment;
     this.ValutaObligation = valutaObligation;
     this.PaymentDate      = paymentDate;
     this.PlaneFact        = planFact;
 }
 public void ClearFilter()
 {
     this.DateBegin   = System.DateTime.MinValue;
     this.DateEnd     = System.DateTime.MinValue;
     this.Bank        = null;
     this.BankAccount = null;
     //this.ImportResult = null;
 }
예제 #3
0
        private void GetPaymentDocSumByRepaymentJournal(fmCDocRCB PaymentDocument, crmBankAccount bankAccount, out Decimal SumIn, out Decimal SunOut)
        {
            XPQuery <fmCPRRepaymentJurnal> repaymentJournals = new XPQuery <fmCPRRepaymentJurnal>(this.Session, true);
            var queryRepaymentJournals = (from repaymentJournal in repaymentJournals
                                          where repaymentJournal.PaymentDocument == PaymentDocument &&
                                          repaymentJournal.BankAccount == bankAccount
                                          select repaymentJournal).ToList <fmCPRRepaymentJurnal>();

            // В журнале привязок хранятся величины сумм для валют - платежа и обязательства. Суммы берём в валюте платежа.
            SumIn  = queryRepaymentJournals.Sum(x => x.SumIn);
            SunOut = queryRepaymentJournals.Sum(x => x.SumOut);
        }
예제 #4
0
        private void GetPaymentDocSumByOperationJournal(fmCDocRCB PaymentDocument, crmBankAccount bankAccount, out Decimal SumIn, out Decimal SunOut)
        {
            XPQuery <fmCSAOperationJournal> operationJournals = new XPQuery <fmCSAOperationJournal>(this.Session, true);
            var queryOperationJournals = (from operationJournal in operationJournals
                                          where operationJournal.PaymentDocument == PaymentDocument &&
                                          operationJournal.BankAccount == bankAccount
                                          select operationJournal).ToList <fmCSAOperationJournal>();

            // Как я понял, валюта выписки определяется по 3-м знакам счёта выписки, поэтому валюта везде одинаковая и суммирование ниже корректно.
            // В Валюте платежа
            SumIn  = queryOperationJournals.Sum(x => x.SumIn);
            SunOut = queryOperationJournals.Sum(x => x.SumOut);
        }
예제 #5
0
        /// <summary>
        /// Исходящая сумма (относительно "нашей" организации)
        /// </summary>
        /// <returns></returns>
        public Decimal GetSumOut(crmBankAccount bankAccount)
        {
            Decimal Res = 0;

            // Наша организация
            crmCParty OurParty = GetOurParty();

            if (this.PaymentPayerRequisites.INN == OurParty.INN && this.PaymentPayerRequisites.StatementOfAccount.BankAccount == bankAccount)
            {
                Res = this.PaymentCost;
            }

            return(Res);
        }
예제 #6
0
 protected crmBankAccount BankAccountGet(IObjectSpace os, crmBank bank, String number, crmCPerson pers)
 {
     if (_accounts.ContainsKey(bank.Oid) && _accounts[bank.Oid].ContainsKey(number))
     {
         return(os.GetObject <crmBankAccount>(_accounts[bank.Oid][number]));
     }
     else
     {
         crmBankAccount acc = os.CreateObject <crmBankAccount>();
         acc.Bank   = bank;
         acc.Number = number;
         acc.Person = pers;
         if (!_accounts.ContainsKey(bank.Oid))
         {
             _accounts[bank.Oid] = new Dictionary <string, crmBankAccount>();
         }
         _accounts[bank.Oid][number] = acc;
         return(acc);
     }
 }
예제 #7
0
        public virtual void AutoBinding(crmBankAccount BankAccount, fmCPRPaymentRequest PaymentRequest, fmCPRRepaymentTask RepaymentTask)
        {
            // Привязка с распределением счетов

            // Проверка на уже связанность заявки
            XPQuery <fmCPRRepaymentJurnal> repaymentJurnalExists = new XPQuery <fmCPRRepaymentJurnal>(this.Session);
            var queryRepaymentJurnalExists = from repaymentJurnal in repaymentJurnalExists
                                             where repaymentJurnal.PaymentDocument == this
                                             select repaymentJurnal;

            if (queryRepaymentJurnalExists.Count() > 0)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("Заявка уже привязана");
                return;
            }

            // Проверка на превышение сумм
            if (RepaymentTask.RepaymentRegisterSum + PaymentRequest.Summ > RepaymentTask.OperationRegisterSum)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("Сумма связанных заявок превысит сумму по документам выписки. Привязка невозможна.");
                return;
            }


            // Наша организация
            crmCParty OurParty = GetOurParty();

            // Привязка в принципе возможна, т.е. выбранная заявка добавляется в fmCPRRepaymentJurnal
            fmCPRRepaymentJurnal newRepaymentJournalRecord = new fmCPRRepaymentJurnal(Session);

            newRepaymentJournalRecord.BankAccount = BankAccount;
            //newRepaymentJournalRecord.PaymentDate =
            newRepaymentJournalRecord.PaymentDocument = this;
            newRepaymentJournalRecord.PaymentRequest  = PaymentRequest;
            newRepaymentJournalRecord.PlaneFact       = CRM.Contract.Analitic.PlaneFact.FACT;

            if (OurParty.INN == PaymentRequest.PartyPayReceiver.INN)
            {
                newRepaymentJournalRecord.SumIn = PaymentRequest.Summ;
            }
            if (OurParty.INN == PaymentRequest.PartyPaySender.INN)
            {
                newRepaymentJournalRecord.SumOut = PaymentRequest.Summ;
            }

            newRepaymentJournalRecord.ValutaObligation = PaymentRequest.Valuta;        // Валюта обязательств
            newRepaymentJournalRecord.ValutaPayment    = PaymentRequest.PaymentValuta; // Валюта платежа


            // Обновление таблицы RepaymentTaskLines

            // Удаление всех записей из fmCPRRepaymentTaskLine
            Session.Delete(RepaymentTask.RepaymentTaskLines);
            //Session.PurgeDeletedObjects();

            // Журнал привязок
            XPQuery <fmCPRRepaymentJurnal> repaymentJurnals = new XPQuery <fmCPRRepaymentJurnal>(this.Session);
            var queryRepaymentJurnals = from repaymentJurnal in repaymentJurnals
                                        where repaymentJurnal.PaymentDocument == this
                                        select repaymentJurnal;
            var queryGroupRepaymentJurnals = from repaymentJurnal in queryRepaymentJurnals
                                             group repaymentJurnal by new { repaymentJurnal.PaymentRequest }
            into grj
                select new {
                PaymentRequest = grj.Key.PaymentRequest,
                GroupSumIn     = grj.Sum(row => row.SumIn),
                GroupSumOut    = grj.Sum(row => row.SumOut)
            };

            foreach (var grj in queryGroupRepaymentJurnals)
            {
                // Добавляем запись в fmCPRRepaymentTaskLine
                fmCPRRepaymentTaskLine newLine = new fmCPRRepaymentTaskLine(Session);
                newLine.RepaymentTask = RepaymentTask;
                RepaymentTask.RepaymentTaskLines.Add(newLine);
                newLine.PaymentRequest = PaymentRequest;
                newLine.RequestSum     = grj.GroupSumIn + grj.GroupSumOut; // Одна из них равна 0
            }
        }
예제 #8
0
        private void GetPaymentRequestSumByRepaymentJournal(fmCPRPaymentRequest PaymentRequest, crmBankAccount bankAccount, out Decimal SumIn, out Decimal SunOut, out Decimal SumObligationIn, out Decimal SunObligationOut)
        {
            XPQuery <fmCPRRepaymentJurnal> repaymentJournals = new XPQuery <fmCPRRepaymentJurnal>(this.Session, true);
            var queryRepaymentJournals = (from repaymentJournal in repaymentJournals
                                          where repaymentJournal.PaymentRequest == PaymentRequest &&
                                          repaymentJournal.BankAccount == bankAccount
                                          select repaymentJournal).ToList <fmCPRRepaymentJurnal>();

            SumIn  = queryRepaymentJournals.Sum(x => x.SumIn);
            SunOut = queryRepaymentJournals.Sum(x => x.SumOut);

            SumObligationIn  = queryRepaymentJournals.Sum(x => x.SumObligationIn);
            SunObligationOut = queryRepaymentJournals.Sum(x => x.SumObligationOut);
        }
예제 #9
0
        public virtual void AutoBinding(crmBankAccount BankAccount, fmCPRRepaymentTask RepaymentTask)
        {
            // Несколько замечаний.
            // Сопоставление ведётся только с уже существующими заявками в статусе IN_PAY.
            // Для данного платёжного документа выбираются только такие заявки, в которых Плательщик и Получатель
            // соответствуют таковым в платёжном документе.
            // Часть суммы платёжного документа, не покрытая заявками, должна равняться части суммы Заявки, не истраченной
            // на Платёжные документы.
            // Распределение средств Заявки из предыдущего пункта происходит по дням в операционном журнале.

            // Список счетов "нашей" организации
            XPQuery <crmBankAccount> ourBankAccounts = new XPQuery <crmBankAccount>(Session);
            var OurBankAccounts = (from bankAccount in ourBankAccounts
                                   where bankAccount.PrefferedParty.Code == GetOurParty().Code   //"2518"
                                   select bankAccount).ToList <crmBankAccount>();

            DateTime DateAccountChanged = (this.ReceivedByPayerBankDate != DateTime.MinValue) ? this.ReceivedByPayerBankDate : ((this.DeductedFromPayerAccount != DateTime.MinValue) ? this.DeductedFromPayerAccount : DateTime.MinValue);
            csValuta paymentValuta      = crmBankAccount.GetValutaByBankAccount(Session, BankAccount);

            // Сумма Платёжного документа по OperationJournal (в валюте платежа)
            Decimal operationPaymentDocSumIn = 0, operationPaymentDocSumOut = 0;

            GetPaymentDocSumByOperationJournal(this, BankAccount, out operationPaymentDocSumIn, out operationPaymentDocSumOut);     // @@@@@@@@@@@ Добавить проверку по BankAccount
            // Одна из сумм operationPaymentDocSumIn или operationPaymentDocSumOut обязательно равна 0

            // Сумма Платёжного документа по RepaymentJournal (в валюте платежа - это величины SumIn и SumOut)
            Decimal repaymentDocSumIn = 0, repaymentDocSumOut = 0;

            GetPaymentDocSumByRepaymentJournal(this, BankAccount, out repaymentDocSumIn, out repaymentDocSumOut);   // @@@@@@@@@@@ Добавить проверку по BankAccount
            // Одна из сумм repaymentDocSumIn или repaymentDocSumOut также обязательно равна 0

            // Величина непокрытия Платёжного документа Заявками (все суммы в валюте платежа)
            Decimal deltaDocSumIn  = operationPaymentDocSumIn - repaymentDocSumIn;
            Decimal deltaDocSumOut = operationPaymentDocSumOut - repaymentDocSumOut;

            if (Decimal.Compare(Math.Abs(deltaDocSumIn) + Math.Abs(deltaDocSumOut), _Accuracy) <= 0)
            {
                return; // Всё сопоставлено уже с точностью до _Accuracy - так условились!
            }
            // Одна (или обе) из сумм deltaDocSumIn или deltaDocSumOut также равна (равны) 0
            Decimal deltaDocSum = deltaDocSumIn + deltaDocSumOut;   // !!!!!!! ПЕРЕСМОТРЕТЬ ?????????

            // Поиск подходящей заявки (Статус, Плательщик, Получатель, остаточные суммы)
            XPQuery <fmCPRPaymentRequest> paymentRequests = new XPQuery <fmCPRPaymentRequest>(Session, true);
            var queryPaymentRequests = from paymentRequest in paymentRequests
                                       where (paymentRequest.State == PaymentRequestStates.IN_PAYMENT || paymentRequest.State == PaymentRequestStates.IN_BANK) &&
                                       paymentRequest.PartyPayReceiver == this.PaymentReceiverRequisites.Party &&
                                       paymentRequest.PartyPaySender == this.PaymentPayerRequisites.Party &&
                                       OurBankAccounts.Contains <crmBankAccount>(this.PaymentPayerRequisites.BankAccount) && // Означает РАСХОД
                                       DateAccountChanged.Date >= paymentRequest.Date.Date                                   //&& DateAccountChanged.Date < paymentRequest.Date.AddDays(3).Date
                                       select paymentRequest;

            foreach (var paymentRequest in queryPaymentRequests)
            {
                // Отбраковка:
                // (1) сумма заявки не должна быть исчерпана полностью,
                // (2) остаточная сумма должна равняться величине непокрытия Платёжного документа

                Decimal paymentRequestSumIn = 0, paymentRequestSumOut = 0;                     // Эти суммы в валюте платежа
                Decimal paymentRequestSumObligationIn = 0, paymentRequestSumObligationOut = 0; // Эти суммы в валюте обязательств
                GetPaymentRequestSumByRepaymentJournal(
                    paymentRequest,
                    BankAccount,
                    out paymentRequestSumIn,
                    out paymentRequestSumOut,
                    out paymentRequestSumObligationIn,
                    out paymentRequestSumObligationOut
                    );

                // Величина неиспользованности Заявки   !!!!!!!! ПЕРЕСМОТРЕТЬ !!!!!!!!!!!
                // Поясение о вычислении неиспользованности. Сумма в заявке - это в валюте обязательств, чтобы её сравнить
                // с суммой платежа, надо перевести по кросс-курсу к валюте платежа и уже полученную сумму сравнить. Вопрос: на
                // какой день брать курс? Предлагается брать DateAccountChanged
                //Decimal deltaRequestSum = GetRequestSumByCourse(paymentRequest, paymentRequest.Valuta);   // В валюте платежа
                Decimal deltaRequestSum = GetRequestSumByCourse(paymentRequest, paymentValuta);   // В валюте платежа
                if (this.PaymentPayerRequisites.BankAccount == BankAccount)
                {
                    deltaRequestSum -= paymentRequestSumOut;
                }
                else if (this.PaymentReceiverRequisites.BankAccount == BankAccount)
                {
                    deltaRequestSum -= paymentRequestSumIn;
                }

                if (Decimal.Compare(Math.Abs(deltaRequestSum), _Accuracy) <= 0)
                {
                    continue;   // Переход к следующей заявке (тогда у заявки должен был бы быть статус PAYED и она не должна была попасть в рассмотрение - это предусловие контракта)
                }
                // Сравнение с точностью до 1 копейки
                if (Decimal.Compare(Math.Abs(deltaDocSum - deltaRequestSum), _Accuracy) <= 0)
                {
                    // Создаём задачу привязки
                    Session uow = this.Session;
                    //using (UnitOfWork uow = new UnitOfWork(Session.ObjectLayer)) {
                    fmCPRRepaymentTask task = new fmCPRRepaymentTask(uow);
                    task.BankAccount     = BankAccount;
                    task.PaymentDocument = this;
                    task.FillRepaymentTaskLines();
                    task.FillRequestList();
                    task.DoBindingRequest(paymentRequest, true, 0);
                    //uow.CommitChanges();
                    //}
                    // Поскольку заявка исчерпана, то меняем ей статус
                    paymentRequest.State = PaymentRequestStates.PAYED;
                    this.State           = PaymentDocProcessingStates.PROCESSED;

                    // Заявка и документ выписки полностью взаимопокрылись, поэтому
                    break;
                }
            }
        }