// Computing default value on the basis of the previous values
        protected virtual void ARDunningSetup_DueDays_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
        {
            ARDunningSetup row = e.Row as ARDunningSetup;

            if (row != null)
            {
                int llevel = row.DunningLetterLevel.Value;

                if (llevel == 1)
                {
                    e.NewValue = 30;
                }
                else
                {
                    int PrevValue = 0;
                    foreach (PXResult <ARDunningSetup> ii in PXSelect <ARDunningSetup> .Select(this))
                    {
                        ARDunningSetup v = ii;
                        if (v.DunningLetterLevel.Value == llevel - 1)
                        {
                            PrevValue += v.DueDays.Value;
                        }
                        if (v.DunningLetterLevel.Value == 1 && llevel > 1)
                        {
                            PrevValue += v.DueDays.Value;
                        }
                    }
                    e.NewValue = PrevValue;
                }
            }
        }
        protected virtual void ARDunningSetup_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
        {
            ARDunningSetup row = e.Row as ARDunningSetup;

            if (row != null)
            {
                int            llevel = row.DunningLetterLevel.Value;
                ARDunningSetup nextDL = PXSelect <ARDunningSetup, Where <ARDunningSetup.dunningLetterLevel, Greater <Required <ARDunningSetup.dunningLetterLevel> > > > .Select(this, row.DunningLetterLevel);

                bool clear = true;
                if (nextDL != null && nextDL.DueDays.HasValue)
                {
                    if (row.DueDays.HasValue && row.DaysToSettle.HasValue)
                    {
                        int delay = row.DueDays.Value + row.DaysToSettle.Value;
                        if (delay > nextDL.DueDays)
                        {
                            string dueDaysLabel      = PXUIFieldAttribute.GetDisplayName <ARDunningSetup.dueDays>(sender);
                            string daysToSettleLabel = PXUIFieldAttribute.GetDisplayName <ARDunningSetup.daysToSettle>(sender);
                            sender.RaiseExceptionHandling <ARDunningSetup.daysToSettle>(row, row.DaysToSettle, new PXSetPropertyException(Messages.DateToSettleCrossDunningLetterOfNextLevel, PXErrorLevel.Warning, dueDaysLabel, daysToSettleLabel));
                            //PXUIFieldAttribute.SetWarning<ARDunningSetup.daysToSettle>(sender, row, Messages.DateToSettleCrossDunningLetterOfNextLevel);
                            clear = false;
                        }
                    }
                }
                if (clear)
                {
                    //PXUIFieldAttribute.SetWarning<ARDunningSetup.daysToSettle>(sender, row, null);
                    sender.RaiseExceptionHandling <ARDunningSetup.daysToSettle>(row, row.DaysToSettle, null);
                }
            }
        }
        // Deleting order control. Prevents break of consecutive enumeration.
        protected virtual void ARDunningSetup_RowDeleting(PXCache sender, PXRowDeletingEventArgs e)
        {
            int MaxRN = 0;

            foreach (PXResult <ARDunningSetup> ii in PXSelect <ARDunningSetup> .Select(this))
            {
                ARDunningSetup v    = ii;
                int            MaxR = v.DunningLetterLevel.Value;
                MaxRN = MaxRN < MaxR ? MaxR : MaxRN;
            }

            ARDunningSetup row = e.Row as ARDunningSetup;

            if (row != null)
            {
                if (row.DunningLetterLevel.Value < MaxRN)
                {
                    throw new PXException(Messages.OnlyLastRowCanBeDeleted);
                }
            }
        }
        // Prevents break of monotonically increasing values
        protected virtual void ARDunningSetup_DueDays_FieldVerifying(PXCache sender, PXFieldVerifyingEventArgs e)
        {
            ARDunningSetup row = e.Row as ARDunningSetup;

            if (row != null)
            {
                int llevel = row.DunningLetterLevel.Value;
                int nv     = Convert.ToInt32(e.NewValue);
                if (llevel == 1 && nv <= 0)
                {
                    throw new PXSetPropertyException(Messages.ThisValueMUSTExceed, 0);
                }
                else
                {
                    int NextValue = 0;
                    int PrevValue = 0;
                    foreach (PXResult <ARDunningSetup> ii in PXSelect <ARDunningSetup> .Select(this))
                    {
                        ARDunningSetup v = ii;
                        if (v.DunningLetterLevel.Value == llevel - 1)
                        {
                            PrevValue = v.DueDays.Value;
                        }
                        if (v.DunningLetterLevel.Value == llevel + 1)
                        {
                            NextValue = v.DueDays.Value;
                        }
                    }
                    if (nv <= PrevValue)
                    {
                        throw new PXSetPropertyException(Messages.ThisValueMUSTExceed, PrevValue);
                    }
                    if (nv >= NextValue && NextValue > 0)
                    {
                        throw new PXSetPropertyException(Messages.ThisValueCanNotExceed, NextValue);
                    }
                }
            }
        }
Пример #5
0
        public static void ReleaseProcess(ARDunningLetterMaint graph, ARDunningLetter doc)
        {
            if (doc != null && doc.Released != true && doc.Voided != true)
            {
                graph.Document.Current = doc;
                doc.DunningLetterLevel = 0;
                foreach (ARDunningLetterDetail detail in graph.Details.Select())
                {
                    doc.DunningLetterLevel = Math.Max(doc.DunningLetterLevel ?? 0, detail.DunningLetterLevel ?? 0);
                }

                if (doc.DunningLetterLevel == 0)
                {
                    throw new PXException(Messages.DunningLetterZeroLevel);
                }

                ARDunningSetup dunningSetup = PXSelect <ARDunningSetup,
                                                        Where <ARDunningSetup.dunningLetterLevel, Equal <Required <ARDunningLetter.dunningLetterLevel> > > > .Select(graph, doc.DunningLetterLevel);

                if (dunningSetup.DunningFee.HasValue && dunningSetup.DunningFee != 0m)
                {
                    ARInvoice feeInvoice = InsertFeeInvoice(doc, dunningSetup.DunningFee ?? 0m);

                    doc.FeeRefNbr  = feeInvoice.RefNbr;
                    doc.FeeDocType = feeInvoice.DocType;
                }

                foreach (ARDunningLetterDetail detail in graph.Details.Select())
                {
                    detail.Released = true;
                    graph.Details.Update(detail);
                }

                doc.Released = true;
                graph.Document.Update(doc);
                graph.Save.Press();
            }
        }
        public static void ReleaseProcess(ARDunningLetterMaint graph, ARDunningLetter doc)
        {
            if (doc != null && doc.Released != true && doc.Voided != true)
            {
                graph.Document.Current = doc;
                doc.DunningLetterLevel = 0;
                foreach (ARDunningLetterDetail detail in graph.Details.Select())
                {
                    doc.DunningLetterLevel = Math.Max(doc.DunningLetterLevel ?? 0, detail.DunningLetterLevel ?? 0);
                }

                if (doc.DunningLetterLevel == 0)
                {
                    throw new PXException(Messages.DunningLetterZeroLevel);
                }

                ARSetup setup = PXSelect <ARSetup> .Select(graph);

                ARDunningSetup dunningSetup = PXSelect <ARDunningSetup, Where <ARDunningSetup.dunningLetterLevel, Equal <Required <ARDunningLetter.dunningLetterLevel> > > > .Select(graph, doc.DunningLetterLevel);

                ARInvoiceEntry invGraph = PXGraph.CreateInstance <ARInvoiceEntry>();
                if (dunningSetup.DunningFee.HasValue && dunningSetup.DunningFee != 0m)
                {
                    if (setup.DunningFeeInventoryID == null)
                    {
                        throw new PXException(Messages.DunningLetterEmptyInventory);
                    }

                    Customer  customer   = graph.CurrentCustomer.Select();
                    ARInvoice feeInvoice = new ARInvoice
                    {
                        Released   = false,
                        Hold       = false,
                        Voided     = false,
                        BranchID   = doc.BranchID,
                        DocDate    = doc.DunningLetterDate,
                        CustomerID = doc.BAccountID
                    };

                    invGraph.Document.Current     = feeInvoice;
                    feeInvoice.CustomerLocationID = customer.DefLocationID;
                    invGraph.Document.Update(feeInvoice);

                    feeInvoice.CuryID = customer.AllowOverrideCury == false && customer.CuryID != null
                                                ? customer.CuryID
                                                : ((GL.Company)PXSelect <GL.Company> .Select(invGraph)).BaseCuryID;
                    invGraph.Document.SetValueExt <ARInvoice.curyID>(invGraph.Document.Current, feeInvoice.CuryID);
                    invGraph.Document.Update(feeInvoice);

                    feeInvoice.DocDesc = Messages.DunningLetterFee;
                    feeInvoice.Hold    = false;
                    invGraph.Document.Update(feeInvoice);

                    decimal curyVal;
                    var     curyInfo = invGraph.currencyinfo.Select();
                    PXCurrencyAttribute.PXCurrencyHelper.CuryConvCury(invGraph.Caches[typeof(CurrencyInfo)], curyInfo, dunningSetup.DunningFee ?? 0m, out curyVal);

                    IN.InventoryItem item = PXSelect <IN.InventoryItem,
                                                      Where <IN.InventoryItem.inventoryID, Equal <Required <ARSetup.dunningFeeInventoryID> > > > .Select(graph, setup.DunningFeeInventoryID);

                    if (item == null)
                    {
                        throw new PXException(Messages.DunningLetterEmptyInventory);
                    }

                    if (item.SalesAcctID == null)
                    {
                        throw new PXException(Messages.DunningProcessFeeEmptySalesAccount);
                    }

                    ARTran detail = new ARTran
                    {
                        BranchID      = doc.BranchID,
                        Qty           = 1,
                        CuryUnitPrice = curyVal,
                        InventoryID   = setup.DunningFeeInventoryID,
                        AccountID     = item.SalesAcctID,
                        SubID         = item.SalesSubID
                    };
                    invGraph.Transactions.Insert(detail);

                    feeInvoice = PXCache <ARInvoice> .CreateCopy(invGraph.Document.Current);

                    feeInvoice.OrigDocAmt     = feeInvoice.DocBal;
                    feeInvoice.CuryOrigDocAmt = feeInvoice.CuryDocBal;
                    invGraph.Document.Update(feeInvoice);
                    invGraph.Save.Press();

                    if (setup.AutoReleaseDunningFee == true)
                    {
                        invGraph.release.Press();
                    }
                    doc.FeeRefNbr  = invGraph.Document.Current.RefNbr;
                    doc.FeeDocType = invGraph.Document.Current.DocType;
                }

                graph.Details.AllowUpdate = true;
                foreach (ARDunningLetterDetail detail in graph.Details.Select())
                {
                    detail.Released = true;
                    graph.Details.Update(detail);
                }

                doc.Released = true;
                graph.Document.Update(doc);
                graph.Save.Press();
            }
        }
Пример #7
0
        protected virtual IEnumerable dunningLetterList()
        {
            this.DunningLetterList.Cache.Clear();

            ARDunningLetterRecordsParameters header = Filter.Current;

            if (header == null || header.DocDate == null)
            {
                yield break;
            }


            bool Cons              = false;
            int? DBranch           = null;
            bool canAccessToBranch = false;

            try
            {
                ARSetup SetupV = PXSelect <ARSetup, Where <MatchWithBranch <ARSetup.dunningLetterBranchID> > > .Select(this);

                if (SetupV != null)
                {
                    Cons              = SetupV.ConsolidatedDunningLetter ?? false;
                    DBranch           = SetupV.DunningLetterBranchID;
                    canAccessToBranch = true;
                }
            }
            catch {}

            if (!canAccessToBranch)
            {
                yield break;
            }

            //Select due customers. (ARInvoice.dueDate < "current date")
            int?OldBAccount = null;
            int?OldBranch   = null;

            foreach (PXResult <Customer, ARInvoice> item in
                     PXSelectJoinGroupBy <Customer,
                                          InnerJoin <ARInvoice, On <ARInvoice.customerID, Equal <Customer.bAccountID> > >,
                                          Where <ARInvoice.released, Equal <boolTrue>,
                                                 And <ARInvoice.openDoc, Equal <boolTrue>,
                                                      And <ARInvoice.voided, Equal <boolFalse>,
                                                           And <Where <ARInvoice.docType, Equal <ARDocType.invoice>, Or <ARInvoice.docType, Equal <ARDocType.finCharge>,
                                                                                                                         And <ARInvoice.dueDate, Less <Required <ARDunningLetterRecordsParameters.docDate> > > >
                                                                       > > > > >, Aggregate <GroupBy <Customer.bAccountID, GroupBy <ARInvoice.branchID> > > >
                     .Select(this, header.DocDate))
            {
                Customer  cust = item;
                ARInvoice br   = item;

                if (header.CustomerClassID != null)
                {
                    if (cust.CustomerClassID != header.CustomerClassID)
                    {
                        continue;                                                   // CustomerClassID filter
                    }
                }
                int?BranchID = (Cons ? DBranch : br.BranchID);

                if ((BranchID == OldBranch) && (OldBAccount == cust.BAccountID))
                {
                    continue;                                                               // Group by BranchID
                }
                if (OldBAccount != cust.BAccountID)
                {
                    OldBranch   = null;
                    OldBAccount = cust.BAccountID;
                }

                OldBranch = BranchID;

                ARDunningLetterList rec = new ARDunningLetterList();
                rec.CustomerClassID = cust.CustomerClassID;
                rec.BAccountID      = cust.BAccountID;
                rec.BranchID        = BranchID;
                rec.DocDate         = header.DocDate;

                bool Show      = true;
                DateTime maxRD = DateTime.MinValue;
                int rlevel     = 0;

                //Find last active (not closed) Dunning Letter for each Customer
                foreach (PXResult <ARDunningLetter> ii in
                         PXSelectJoinGroupBy <ARDunningLetter,
                                              InnerJoin <ARDunningLetterDetail, On <ARDunningLetterDetail.dunningLetterID, Equal <ARDunningLetter.dunningLetterID>,
                                                                                    And <ARDunningLetterDetail.overdue, Equal <boolTrue> > >,
                                                         InnerJoin <ARInvoice, On <ARInvoice.docType, Equal <ARDunningLetterDetail.docType>,
                                                                                   And <ARInvoice.refNbr, Equal <ARDunningLetterDetail.refNbr>,
                                                                                        And <ARInvoice.released, Equal <boolTrue>,
                                                                                             And <ARInvoice.openDoc, Equal <boolTrue>,
                                                                                                  And <ARInvoice.voided, Equal <boolFalse> > > > > > > >,
                                              Where <ARDunningLetter.bAccountID, Equal <Required <ARDunningLetter.bAccountID> >,
                                                     And <ARDunningLetter.branchID, Equal <Required <ARDunningLetter.branchID> > >
                                                     >,
                                              Aggregate <GroupBy <ARDunningLetter.dunningLetterLevel, GroupBy <ARDunningLetter.dunningLetterDate> >
                                                         > > .Select(this, cust.BAccountID, BranchID))
                {
                    ARDunningLetter RR = ii;
                    if (maxRD < RR.DunningLetterDate.Value)
                    {
                        maxRD  = RR.DunningLetterDate.Value;
                        rlevel = RR.DunningLetterLevel.Value;
                    }
                }
                if (rlevel >= D_MaxLevel)
                {
                    Show = false;    // Dunning Letter max level is exceeded
                }
                else if (rlevel > 0) // has active Dunning Letter
                {
                    if (maxRD.AddDays(D_DueDays[rlevel]) > header.DocDate.Value)
                    {
                        Show = false;   //Letter is not overdue, not process
                    }
                }
                if (Show)   // need to process
                {
                    rec.NumberOfDocuments        = 0;
                    rec.NumberOfOverdueDocuments = 0;
                    rec.OrigDocAmt = 0;
                    rec.DocBal     = 0;
                    DateTime minD = DateTime.Today;

                    // Selecl all invoices
                    foreach (PXResult <ARInvoice> ix in
                             PXSelect <ARInvoice,
                                       Where <ARInvoice.customerID, Equal <Required <ARInvoice.customerID> >,
                                              And <ARInvoice.released, Equal <boolTrue>,
                                                   And <ARInvoice.openDoc, Equal <boolTrue>,
                                                        And <ARInvoice.voided, Equal <boolFalse>,
                                                             And <Where <ARInvoice.docType, Equal <ARDocType.invoice>, Or <ARInvoice.docType, Equal <ARDocType.finCharge>,
                                                                                                                           And <ARInvoice.docDate, Less <Required <ARInvoice.docDate> > > > > > > > > >
                                       > .Select(this, cust.BAccountID, header.DocDate))
                    {
                        ARInvoice dl = ix;

                        if (!Cons && dl.BranchID != BranchID)
                        {
                            continue;                                   // alien branch
                        }
                        minD = minD < dl.DueDate.Value ? minD : dl.DueDate.Value;
                        rec.NumberOfDocuments++;
                        rec.NumberOfOverdueDocuments += (dl.DueDate > header.DocDate ? 0 : 1);
                        rec.OrigDocAmt += dl.DocBal;
                        rec.DocBal     += (dl.DueDate > header.DocDate ? 0 : dl.DocBal);
                    }
                    rec.DunningLetterLevel = rlevel + 1;
                    rec.DueDate            = minD;
                    ARDunningSetup settings = this.DunningSetupList[rlevel];
                    rec.DueDays = (settings.DaysToSettle ?? 0);
                    //rec.DueDays = D_DueDays[rlevel];

                    if (rlevel > 0)
                    {
                        rec.LastDunningLetterDate = maxRD;
                    }
                    else
                    {
                        rec.LastDunningLetterDate = null;
                    }

                    if (minD.AddDays(D_DueDays[rlevel]) < header.DocDate) //Has at least one overdue invoice
                    {
                        try
                        {
                            this.DunningLetterList.Insert(rec);
                        }
                        catch {}
                    }
                }
            }

            this.DunningLetterList.Cache.IsDirty = false;
            foreach (ARDunningLetterList ret in this.DunningLetterList.Cache.Inserted)
            {
                yield return(ret);
            }
        }