protected override decimal?GetDocumentBalance(PXCache cache, object Row)
        {
            ARInvoice row = Document.Cache.GetMain((Document)Row) as ARInvoice;

            decimal?   DocumentBal = 0m;
            ARBalances accumbal    = cache.Current as ARBalances;

            if (accumbal != null && cache.GetStatus(accumbal) == PXEntryStatus.Inserted)
            {
                //get balance only from PXAccumulator
                DocumentBal = accumbal.UnreleasedBal;
            }

            PXCache sender = cache.Graph.Caches[typeof(ARInvoice)];

            if (DocumentBal > 0m && row.ApprovedCredit == true)
            {
                if (row.ApprovedCreditAmt >= row.OrigDocAmt)
                {
                    DocumentBal = 0m;
                }
            }

            return(DocumentBal);
        }
        protected virtual decimal?GetDocumentBalance(PXCache cache, object Row)
        {
            ARBalances accumbal = cache.Current as ARBalances;

            if (accumbal != null && cache.GetStatus(accumbal) == PXEntryStatus.Inserted)
            {
                //get balance only from PXAccumulator
                return(accumbal.CurrentBal + accumbal.UnreleasedBal + accumbal.TotalOpenOrders);
            }

            return(0m);
        }
 public static void UpdateARBalances(PXGraph graph, SOOrder order)
 {
     if (order != null)
     {
         if (order.CustomerID != null && order.CustomerLocationID != null)
         {
             ARBalances arbal = new ARBalances();
             arbal.BranchID           = order.BranchID;
             arbal.CustomerID         = order.CustomerID;
             arbal.CustomerLocationID = order.CustomerLocationID;
             arbal = (ARBalances)graph.Caches[typeof(ARBalances)].Insert(arbal);
             if (arbal.TotalOpenOrders == null)
             {
                 arbal.TotalOpenOrders = 0;
             }
         }
     }
 }
        public virtual void Verify(PXCache sender, object Row, EventArgs e)
        {
            PXCache customercache      = sender.Graph.Caches[typeof(Customer)];
            PXCache customerclasscache = sender.Graph.Caches[typeof(CustomerClass)];
            PXCache arbalancescache    = sender.Graph.Caches[typeof(ARBalances)];

            int?   CustomerID    = (int?)sender.GetValue <Document.customerID>(Row);
            bool?  HoldValue     = GetHoldValue(sender, Row);
            bool?  ReleasedValue = GetReleasedValue(sender, Row);
            string errmsg        = null;

            if (ReleasedValue == true)
            {
                HoldValue = true;
            }

            Customer      customer      = (Customer)customercache.Current;
            CustomerClass customerclass = (CustomerClass)customerclasscache.Current;
            ARBalances    arbalances    = (ARBalances)arbalancescache.Current;

            if (customer != null && object.Equals(customer.BAccountID, CustomerID) == false)
            {
                customercache.Current = null;
                customer = PXSelect <Customer,
                                     Where <Customer.bAccountID, Equal <Required <Customer.bAccountID> > > >
                           .SelectSingleBound(sender.Graph, null, CustomerID);
            }

            if (customer != null && customer.CreditRule != CreditRuleTypes.CS_NO_CHECKING &&
                IsMigrationMode(sender) != true)
            {
                if (arbalances != null && customer.BAccountID != arbalances.CustomerID)
                {
                    arbalancescache.Current = null;
                }

                if (customerclass != null &&
                    object.Equals(customerclass.CustomerClassID, customer.CustomerClassID) == false)
                {
                    customerclasscache.Current = null;
                }

                decimal?DocumentBal = GetDocumentBalance(arbalancescache, Row);

                {
                    decimal? CustomerBal;
                    DateTime?OldInvoiceDate;
                    GetCustomerBalance(arbalancescache, customer, out CustomerBal, out OldInvoiceDate);

                    TimeSpan overdue = (DateTime)sender.Graph.Accessinfo.BusinessDate -
                                       (DateTime)(OldInvoiceDate ?? sender.Graph.Accessinfo.BusinessDate);

                    bool failed  = (ReleasedValue ?? false);
                    bool enforce = false;

                    //On graph load Current for setups can be null
                    if (customer == null || customerclass == null)
                    {
                        return;
                    }
                    if (failed == false && (customer.CreditRule == CreditRuleTypes.CS_BOTH ||
                                            customer.CreditRule == CreditRuleTypes.CS_DAYS_PAST_DUE))
                    {
                        if (overdue.Days > customer.CreditDaysPastDue)
                        {
                            errmsg = PX.Objects.AR.Messages.CreditDaysPastDueWereExceeded;
                        }

                        if (DocumentBal > 0 && overdue.Days > customer.CreditDaysPastDue)
                        {
                            failed = true;
                        }
                    }

                    if (failed == false && (customer.CreditRule == CreditRuleTypes.CS_BOTH ||
                                            customer.CreditRule == CreditRuleTypes.CS_CREDIT_LIMIT))
                    {
                        if (CustomerBal > customer.CreditLimit)
                        {
                            errmsg = PX.Objects.AR.Messages.CreditLimitWasExceeded;
                        }

                        if (DocumentBal > 0 && CustomerBal > customer.CreditLimit + customerclass.OverLimitAmount)
                        {
                            failed = true;
                        }
                    }

                    if (failed == false && customer.Status == BAccount.status.CreditHold)
                    {
                        errmsg = PX.Objects.AR.Messages.CustomerIsOnCreditHold;
                        if (DocumentBal > 0m)
                        {
                            enforce = true;
                            failed  = true;
                        }
                    }

                    if (failed == false && customer.Status == BAccount.status.Hold)
                    {
                        errmsg  = PX.Objects.AR.Messages.CustomerIsOnHold;
                        failed  = true;
                        enforce = true;
                    }

                    if (failed == false && customer.Status == BAccount.status.Inactive)
                    {
                        errmsg  = PX.Objects.AR.Messages.CustomerIsInactive;
                        failed  = true;
                        enforce = true;
                    }

                    if (!string.IsNullOrEmpty(errmsg))
                    {
                        string existingError = PXUIFieldAttribute.GetError <Document.customerID>(sender, Row);
                        if (string.IsNullOrEmpty(existingError))
                        {
                            sender.RaiseExceptionHandling <Document.customerID>(Row, customer.AcctCD,
                                                                                new PXSetPropertyException(errmsg, PXErrorLevel.Warning));
                        }
                    }

                    if (failed && HoldValue == false)
                    {
                        if (e is PXRowUpdatedEventArgs && (enforce || GetCreditCheckError(sender, Row) == true))
                        {
                            object OldRow = sender.CreateCopy(Row);
                            sender.SetValueExt <Document.hold>(Row, true);
                            UpdateARBalances(sender, Row, OldRow);

                            DocumentBal = GetDocumentBalance(arbalancescache, Row);

                            //this is a Credit Memo
                            if (DocumentBal > 0m)
                            {
                                OldRow = sender.CreateCopy(Row);
                                sender.SetValueExt <Document.hold>(Row, false);
                                UpdateARBalances(sender, Row, OldRow);
                            }
                            else
                            {
                                PlaceOnHold(sender, Row, enforce);
                            }
                        }
                        else if (e is PXRowPersistingEventArgs &&
                                 ((((PXRowPersistingEventArgs)e).Operation & PXDBOperation.Command) !=
                                  PXDBOperation.Delete) &&
                                 (enforce || GetCreditCheckError(sender, Row) == true))
                        {
                            if (string.IsNullOrEmpty(errmsg) == false)
                            {
                                object OldRow = sender.CreateCopy(Row);
                                sender.SetValueExt <Document.hold>(Row, true);
                                UpdateARBalances(sender, Row, OldRow);

                                DocumentBal = GetDocumentBalance(arbalancescache, Row);

                                OldRow = sender.CreateCopy(Row);
                                sender.SetValueExt <Document.hold>(Row, false);
                                UpdateARBalances(sender, Row, OldRow);

                                //this is not a Credit Memo
                                if (DocumentBal <= 0m)
                                {
                                    throw new PXException(errmsg);
                                }
                            }
                        }
                    }
                }
            }
        }