}       //	allocateBPartnerAll

        /// <summary>
        ///	Allocate Oldest First using Accounting currency
        /// </summary>
        /// <returns>allocations</returns>
        private int AllocateBPOldestFirst()
        {
            int      _C_Currency_ID = MClient.Get(GetCtx()).GetC_Currency_ID();
            DateTime?_dateAcct      = null;
            //	Payments
            Decimal _totalPayments = Env.ZERO;

            for (int p = 0; p < _payments.Length; p++)
            {
                MPayment _payment = _payments[p];
                if (_payment.IsAllocated())
                {
                    continue;
                }
                if (_payment.GetC_Currency_ID() != _C_Currency_ID)
                {
                    continue;
                }
                Decimal _allocatedAmt = Utility.Util.GetValueOfDecimal(_payment.GetAllocatedAmt());
                log.Info(_payment + ", Allocated=" + _allocatedAmt);
                Decimal _availableAmt = Decimal.Add(Decimal.Add(Decimal.Add(_payment.GetPayAmt(),
                                                                            _payment.GetDiscountAmt()),
                                                                _payment.GetWriteOffAmt()),
                                                    _payment.GetOverUnderAmt());
                if (!_payment.IsReceipt())
                {
                    _availableAmt = Decimal.Negate(_availableAmt);
                }
                log.Fine("Available=" + _availableAmt);
                if (_dateAcct == null || _payment.GetDateAcct() > (_dateAcct))
                {
                    _dateAcct = Utility.Util.GetValueOfDateTime(_payment.GetDateAcct());
                }
                _totalPayments = Decimal.Add(_totalPayments, (_availableAmt));
            }
            //	Invoices
            Decimal _totalInvoices = Env.ZERO;

            for (int i = 0; i < _invoices.Length; i++)
            {
                MInvoice _invoice = _invoices[i];
                if (_invoice.IsPaid())
                {
                    continue;
                }
                if (_invoice.GetC_Currency_ID() != _C_Currency_ID)
                {
                    continue;
                }
                Decimal _openAmt = Utility.Util.GetValueOfDecimal(_invoice.GetOpenAmt(true, null));
                log.Fine("" + _invoice);
                if (!_invoice.IsSOTrx())
                {
                    _openAmt = Decimal.Negate(_openAmt);
                }
                //	Foreign currency
                log.Fine("Open=" + _openAmt);
                if (_dateAcct == null || _invoice.GetDateAcct() > (_dateAcct))
                {
                    _dateAcct = _invoice.GetDateAcct();
                }
                _totalInvoices = Decimal.Add(_totalInvoices, _openAmt);
            }

            //	must be either AP or AR balance
            if (Env.Signum(_totalInvoices) != Env.Signum(_totalPayments))
            {
                log.Fine("Signum - Invoices=" + Env.Signum(_totalInvoices)
                         + " <> Payments=" + Env.Signum(_totalPayments));
                return(0);
            }

            Decimal _difference = Decimal.Subtract(_totalInvoices, _totalPayments);
            //Decimal _maxAmt = _totalInvoices.abs().min(_totalPayments.abs());
            Decimal _maxAmt = Math.Min(Math.Abs(_totalInvoices), Math.Abs(_totalPayments));

            if (Env.Signum(_totalInvoices) < 0)
            {
                _maxAmt = Decimal.Negate(_maxAmt);
            }
            log.Info("= Invoices=" + _totalInvoices
                     + " - Payments=" + _totalPayments
                     + " = Difference=" + _difference + " - Max=" + _maxAmt);


            //	Allocate Payments up to max
            Decimal _allocatedPayments = Env.ZERO;

            for (int p = 0; p < _payments.Length; p++)
            {
                MPayment _payment = _payments[p];
                if (_payment.IsAllocated())
                {
                    continue;
                }
                if (_payment.GetC_Currency_ID() != _C_Currency_ID)
                {
                    continue;
                }
                Decimal _allocatedAmt = Utility.Util.GetValueOfDecimal(_payment.GetAllocatedAmt());
                if (Env.Signum(_allocatedAmt) != 0)
                {
                    continue;
                }
                Decimal _availableAmt = Decimal.Add(Decimal.Add(Decimal.Add(_payment.GetPayAmt(),
                                                                            _payment.GetDiscountAmt()),
                                                                _payment.GetWriteOffAmt()),
                                                    _payment.GetOverUnderAmt());
                if (!_payment.IsReceipt())
                {
                    _availableAmt = Decimal.Negate(_availableAmt);
                }
                _allocatedPayments = Decimal.Add(_allocatedPayments, _availableAmt);
                if ((Env.Signum(_totalInvoices) > 0 && _allocatedPayments.CompareTo(_maxAmt) > 0) ||
                    (Env.Signum(_totalInvoices) < 0 && _allocatedPayments.CompareTo(_maxAmt) < 0))
                {
                    Decimal _diff = Decimal.Subtract(_allocatedPayments, _maxAmt);
                    _availableAmt      = Decimal.Subtract(_availableAmt, _diff);
                    _allocatedPayments = Decimal.Subtract(_allocatedPayments, _diff);
                }
                log.Fine("Payment Allocated=" + _availableAmt);
                if (!CreateAllocation(_C_Currency_ID, "BP Oldest (" + Math.Abs(_difference) + ")",
                                      _dateAcct, _availableAmt, null, null, null,
                                      _payment.GetC_BPartner_ID(), _payment.GetC_Payment_ID(), 0, _payment.GetAD_Org_ID()))
                {
                    throw new Exception("Cannot create Allocation");
                }
                if (_allocatedPayments.CompareTo(_maxAmt) == 0)
                {
                    break;
                }
            }   //	for all payments
            //	Allocated Invoices up to max
            Decimal _allocatedInvoices = Env.ZERO;

            for (int i = 0; i < _invoices.Length; i++)
            {
                MInvoice _invoice = _invoices[i];
                if (_invoice.IsPaid())
                {
                    continue;
                }
                if (_invoice.GetC_Currency_ID() != _C_Currency_ID)
                {
                    continue;
                }
                Decimal _openAmt = Utility.Util.GetValueOfDecimal(_invoice.GetOpenAmt(true, null));
                if (!_invoice.IsSOTrx())
                {
                    _openAmt = Decimal.Negate(_openAmt);
                }
                _allocatedInvoices = Decimal.Add(_allocatedInvoices, _openAmt);
                if ((Env.Signum(_totalInvoices) > 0 && _allocatedInvoices.CompareTo(_maxAmt) > 0) ||
                    (Env.Signum(_totalInvoices) < 0 && _allocatedInvoices.CompareTo(_maxAmt) < 0))
                {
                    Decimal _diff = Decimal.Subtract(_allocatedInvoices, _maxAmt);
                    _openAmt           = Decimal.Subtract(_openAmt, _diff);
                    _allocatedInvoices = Decimal.Subtract(_allocatedInvoices, _diff);
                }
                if (Env.Signum(_openAmt) == 0)
                {
                    break;
                }
                log.Fine("Invoice Allocated=" + _openAmt);
                if (!CreateAllocation(_C_Currency_ID, "BP Oldest (" + Math.Abs(_difference) + ")",
                                      _dateAcct, _openAmt, null, null, null,
                                      _invoice.GetC_BPartner_ID(), 0, _invoice.GetC_Invoice_ID(), _invoice.GetAD_Org_ID()))
                {
                    throw new Exception("Cannot create Allocation");
                }
                if (_allocatedInvoices.CompareTo(_maxAmt) == 0)
                {
                    break;
                }
            }   //	for all invoices

            if (_allocatedPayments.CompareTo(_allocatedInvoices) != 0)
            {
                throw new Exception("Allocated Payments=" + _allocatedPayments
                                    + " <> Invoices=" + _allocatedInvoices);
            }
            ProcessAllocation();
            return(1);
        }       //	allocateOldestFirst
        }         //	allocateOneToOne

        /// <summary>
        ///     Allocate all Payments/Invoices using Accounting currency
        /// </summary>
        /// <returns>allocations</returns>
        private int AllocateBPartnerAll()
        {
            int      _C_Currency_ID = MClient.Get(GetCtx()).GetC_Currency_ID();
            DateTime?_dateAcct      = null;
            //	Payments
            Decimal _totalPayments = Env.ZERO;

            for (int p = 0; p < _payments.Length; p++)
            {
                MPayment _payment = _payments[p];
                if (_payment.IsAllocated())
                {
                    continue;
                }
                Decimal _allocatedAmt = Utility.Util.GetValueOfDecimal(_payment.GetAllocatedAmt());
                //	log.info("allocateBPartnerAll - " + _payment + ", Allocated=" + _allocatedAmt);
                if (Env.Signum(_allocatedAmt) != 0)
                {
                    continue;
                }
                Decimal _availableAmt = Decimal.Add(Decimal.Add(Decimal.Add(_payment.GetPayAmt(),
                                                                            _payment.GetDiscountAmt()),
                                                                _payment.GetWriteOffAmt()),
                                                    _payment.GetOverUnderAmt());
                if (!_payment.IsReceipt())
                {
                    _availableAmt = Decimal.Negate(_availableAmt);
                }
                //	Foreign currency
                if (_payment.GetC_Currency_ID() != _C_Currency_ID)
                {
                    continue;
                }
                //	log.fine("allocateBPartnerAll - Available=" + _availableAmt);
                if (_dateAcct == null || _payment.GetDateAcct() > (_dateAcct))
                {
                    _dateAcct = _payment.GetDateAcct();
                }
                _totalPayments = Decimal.Add(_totalPayments, _availableAmt);
            }
            //	Invoices
            Decimal _totalInvoices = Env.ZERO;

            for (int i = 0; i < _invoices.Length; i++)
            {
                MInvoice _invoice = _invoices[i];
                if (_invoice.IsPaid())
                {
                    continue;
                }
                //	log.info("allocateBPartnerAll - " + _invoice);
                Decimal _openAmt = Utility.Util.GetValueOfDecimal(_invoice.GetOpenAmt(true, null));
                if (!_invoice.IsSOTrx())
                {
                    _openAmt = Decimal.Negate(_openAmt);
                }
                //	Foreign currency
                if (_invoice.GetC_Currency_ID() != _C_Currency_ID)
                {
                    continue;
                }
                //	log.fine("allocateBPartnerAll - Open=" + _openAmt);
                if (_dateAcct == null || _invoice.GetDateAcct() > (_dateAcct))
                {
                    _dateAcct = _invoice.GetDateAcct();
                }
                _totalInvoices = Decimal.Add(_totalInvoices, _openAmt);
            }

            Decimal _difference = Decimal.Subtract(_totalInvoices, _totalPayments);

            log.Info("= Invoices=" + _totalInvoices
                     + " - Payments=" + _totalPayments
                     + " = Difference=" + _difference);

            if (Env.Signum(_difference) == 0)
            {
                for (int p = 0; p < _payments.Length; p++)
                {
                    MPayment _payment = _payments[p];
                    if (_payment.IsAllocated())
                    {
                        continue;
                    }
                    Decimal _allocatedAmt = Utility.Util.GetValueOfDecimal(_payment.GetAllocatedAmt());
                    if (Env.Signum(_allocatedAmt) != 0)
                    {
                        continue;
                    }
                    Decimal _availableAmt = Decimal.Add(Decimal.Add(Decimal.Add(_payment.GetPayAmt(),
                                                                                _payment.GetDiscountAmt()),
                                                                    _payment.GetWriteOffAmt()),
                                                        _payment.GetOverUnderAmt());
                    if (!_payment.IsReceipt())
                    {
                        _availableAmt = Decimal.Negate(_availableAmt);
                    }
                    //	Foreign currency
                    if (_payment.GetC_Currency_ID() != _C_Currency_ID)
                    {
                        continue;
                    }
                    if (!CreateAllocation(_C_Currency_ID, "BP All",
                                          _dateAcct, _availableAmt, null, null, null,
                                          _payment.GetC_BPartner_ID(), _payment.GetC_Payment_ID(), 0, _payment.GetAD_Org_ID()))
                    {
                        throw new Exception("Cannot create Allocation");
                    }
                }       //	for all payments
                //
                for (int i = 0; i < _invoices.Length; i++)
                {
                    MInvoice _invoice = _invoices[i];
                    if (_invoice.IsPaid())
                    {
                        continue;
                    }
                    Decimal _openAmt = Utility.Util.GetValueOfDecimal(_invoice.GetOpenAmt(true, null));
                    if (!_invoice.IsSOTrx())
                    {
                        _openAmt = Decimal.Negate(_openAmt);
                    }
                    //	Foreign currency
                    if (_invoice.GetC_Currency_ID() != _C_Currency_ID)
                    {
                        continue;
                    }
                    if (!CreateAllocation(_C_Currency_ID, "BP All",
                                          _dateAcct, _openAmt, null, null, null,
                                          _invoice.GetC_BPartner_ID(), 0, _invoice.GetC_Invoice_ID(), _invoice.GetAD_Org_ID()))
                    {
                        throw new Exception("Cannot create Allocation");
                    }
                }       //	for all invoices
                ProcessAllocation();
                return(1);
            }   //	Difference OK

            return(0);
        }       //	allocateBPartnerAll
        /// <summary>
        ///     Allocate Individual Payments with _payment references
        /// </summary>
        /// <returns>number of allocations</returns>

        private int allocateBPPaymentWithInfo()
        {
            int _count = 0;

            //****	See if there is a direct link (Invoice or Pay Selection)
            for (int p = 0; p < _payments.Length; p++)
            {
                MPayment _payment = _payments[p];
                if (_payment.IsAllocated())
                {
                    continue;
                }
                Decimal _allocatedAmt = Utility.Util.GetValueOfDecimal(_payment.GetAllocatedAmt());
                log.Info(_payment + ", Allocated=" + _allocatedAmt);
                if (Env.Signum(_allocatedAmt) != 0)
                {
                    continue;
                }
                Decimal _availableAmt = Decimal.Add(Decimal.Add(Decimal.Add(_payment.GetPayAmt(),

                                                                            _payment.GetDiscountAmt()),
                                                                _payment.GetWriteOffAmt()),
                                                    _payment.GetOverUnderAmt());
                if (!_payment.IsReceipt())
                {
                    _availableAmt = Decimal.Negate(_availableAmt);
                }
                log.Fine("Available=" + _availableAmt);
                //
                if (_payment.GetC_Invoice_ID() != 0)
                {
                    for (int i = 0; i < _invoices.Length; i++)
                    {
                        MInvoice _invoice = _invoices[i];
                        if (_invoice.IsPaid())
                        {
                            continue;
                        }
                        //	log.fine("allocateIndividualPayments - " + _invoice);
                        if (_payment.GetC_Invoice_ID() == _invoice.GetC_Invoice_ID())
                        {
                            if (_payment.GetC_Currency_ID() == _invoice.GetC_Currency_ID())
                            {
                                Decimal _openAmt = Utility.Util.GetValueOfDecimal(_invoice.GetOpenAmt(true, null));
                                if (!_invoice.IsSOTrx())
                                {
                                    _openAmt = Decimal.Negate(_openAmt);
                                }
                                log.Fine(_invoice + ", Open=" + _openAmt);
                                //	With Discount, etc.
                                if (_availableAmt.CompareTo(_openAmt) == 0)
                                {
                                    if (_payment.AllocateIt())
                                    {
                                        AddLog(0, _payment.GetDateAcct(), _openAmt, _payment.GetDocumentNo() + " [1]");
                                        _count++;
                                    }
                                    break;
                                }
                            }
                            else        //	Mixed Currency
                            {
                            }
                        } //	_invoice found
                    }     //	for all invoices
                }         //	_payment has _invoice
                else      //	No direct _invoice
                {
                    MPaySelectionCheck psCheck = MPaySelectionCheck.GetOfPayment(GetCtx(), _payment.GetC_Payment_ID(), Get_Trx());
                    if (psCheck == null)
                    {
                        continue;
                    }
                    //
                    Decimal             _totalInvoice = Env.ZERO;
                    MPaySelectionLine[] _psLines      = psCheck.GetPaySelectionLines(false);
                    for (int i = 0; i < _psLines.Length; i++)
                    {
                        MPaySelectionLine _line    = _psLines[i];
                        MInvoice          _invoice = _line.GetInvoice();
                        if (_payment.GetC_Currency_ID() == _invoice.GetC_Currency_ID())
                        {
                            Decimal _invoiceAmt = Utility.Util.GetValueOfDecimal((_invoice.GetOpenAmt(true, null)));
                            Decimal _overUnder  = Decimal.Subtract(Decimal.Subtract(Decimal.Subtract(_line.GetOpenAmt(), _line.GetPayAmt()),
                                                                                    _line.GetDiscountAmt()), _line.GetDifferenceAmt());
                            _invoiceAmt = Decimal.Subtract(Decimal.Subtract(Decimal.Subtract(_invoiceAmt, _line.GetDiscountAmt()),
                                                                            _line.GetDifferenceAmt()), _overUnder);
                            if (!_invoice.IsSOTrx())
                            {
                                _invoiceAmt = Decimal.Negate(_invoiceAmt);
                            }
                            log.Fine(_invoice + ", Invoice=" + _invoiceAmt);
                            _totalInvoice = Decimal.Add(_totalInvoice, _invoiceAmt);
                        }
                        else    //	Multi-Currency
                        {
                        }
                    }
                    if (_availableAmt.CompareTo(_totalInvoice) == 0)
                    {
                        if (_payment.AllocateIt())
                        {
                            AddLog(0, _payment.GetDateAcct(), _availableAmt, _payment.GetDocumentNo() + " [n]");
                            _count++;
                        }
                    }
                }       //	No direct _invoice
            }
            //	See if there is a direct link

            return(_count);
        }       //	allocateIndividualPayments
        }       //	allocateIndividualPayments

        /// <summary>
        ///Allocate Payment:Invoice 1:1
        /// </summary>
        /// <returns>allocations</returns>
        private int AllocateBPOneToOne()
        {
            int _count = 0;

            for (int p = 0; p < _payments.Length; p++)
            {
                MPayment _payment = _payments[p];
                if (_payment.IsAllocated())
                {
                    continue;
                }
                Decimal _allocatedAmt = Utility.Util.GetValueOfDecimal(_payment.GetAllocatedAmt());
                log.Info(_payment + ", Allocated=" + _allocatedAmt);
                if (Env.Signum(_allocatedAmt) != 0)
                {
                    continue;
                }
                Decimal _availableAmt = Decimal.Add(Decimal.Add(Decimal.Add(_payment.GetPayAmt()
                                                                            , _payment.GetDiscountAmt())
                                                                , _payment.GetWriteOffAmt())
                                                    , _payment.GetOverUnderAmt());
                if (!_payment.IsReceipt())
                {
                    _availableAmt = Decimal.Negate(_availableAmt);
                }
                log.Fine("Available=" + _availableAmt);
                for (int i = 0; i < _invoices.Length; i++)
                {
                    MInvoice _invoice = _invoices[i];
                    if (_invoice == null || _invoice.IsPaid())
                    {
                        continue;
                    }
                    if (_payment.GetC_Currency_ID() == _invoice.GetC_Currency_ID())
                    {
                        //	log.fine("allocateBPartnerAll - " + _invoice);
                        Decimal _openAmt = Utility.Util.GetValueOfDecimal(_invoice.GetOpenAmt(true, null));
                        if (!_invoice.IsSOTrx())
                        {
                            _openAmt = Decimal.Negate(_openAmt);
                        }
                        Decimal _difference = Decimal.Subtract(_availableAmt, Math.Abs((_openAmt)));
                        log.Fine(_invoice + ", Open=" + _openAmt + " - Difference=" + _difference);
                        if (Env.Signum(_difference) == 0)
                        {
                            DateTime?_dateAcct = _payment.GetDateAcct();
                            if (_invoice.GetDateAcct() > _dateAcct)
                            {
                                _dateAcct = _invoice.GetDateAcct();
                            }
                            if (!CreateAllocation(_payment.GetC_Currency_ID(), "1:1 (" + _availableAmt + ")",
                                                  _dateAcct, _availableAmt, null, null, null,
                                                  _invoice.GetC_BPartner_ID(), _payment.GetC_Payment_ID(),
                                                  _invoice.GetC_Invoice_ID(), _invoice.GetAD_Org_ID()))
                            {
                                throw new Exception("Cannot create Allocation");
                            }
                            ProcessAllocation();
                            _count++;
                            _invoices[i] = null;                //	remove _invoice
                            _payments[p] = null;
                            _payment     = null;
                            break;
                        }
                    }
                    else        //	Multi-Currency
                    {
                    }
                } //	for all invoices
            }     //	for all payments
            return(_count);
        }         //	allocateOneToOne
        /// <summary>
        /// Get Invoices of BP
        /// </summary>
        /// <param name="_C_BPartner_ID"></param>
        /// <returns>unallocated Invoices</returns>
        private MInvoice[] GetInvoices(int _C_BPartner_ID)
        {
            //ArrayList<MInvoice> list = new ArrayList<MInvoice>();
            List <MInvoice> list = new List <MInvoice>();
            String          sql  = "SELECT * FROM C_Invoice "
                                   + "WHERE IsPaid='N' AND Processed='Y' AND C_BPartner_ID=@param1 ";

            if (_ONLY_AP.Equals(_APAR))
            {
                sql += "AND IsSOTrx='N' ";
            }
            else if (_ONLY_AR.Equals(_APAR))
            {
                sql += "AND IsSOTrx='Y' ";
            }
            sql += "ORDER BY DateInvoiced";
            ;
            SqlParameter[] param = new SqlParameter[1];
            DataTable      dt    = null;
            IDataReader    idr   = null;

            try
            {
                param[0] = new SqlParameter("@param1", _C_BPartner_ID);
                idr      = DataBase.DB.ExecuteReader(sql, param, Get_Trx());
                dt       = new DataTable();
                dt.Load(idr);
                idr.Close();
                foreach (DataRow dr in dt.Rows)
                {
                    MInvoice _invoice = new MInvoice(GetCtx(), dr, Get_Trx());
                    if (Env.Signum(Utility.Util.GetValueOfDecimal(_invoice.GetOpenAmt(false, null))) == 0)
                    {
                        _invoice.SetIsPaid(true);
                        _invoice.Save();
                    }
                    else
                    {
                        list.Add(_invoice);
                    }
                }
            }

            catch (Exception e)
            {
                if (idr != null)
                {
                    idr.Close();
                }
                log.Log(Level.SEVERE, sql, e);
            }
            finally
            {
                dt = null;
                if (idr != null)
                {
                    idr.Close();
                }
            }
            _invoices = new MInvoice[list.Count()];
            _invoices = list.ToArray();
            return(_invoices);
        }