Exemple #1
0
        private static void VoidProcess(ARDunningLetter doc)
        {
            ARDunningLetterMaint graph = PXGraph.CreateInstance <ARDunningLetterMaint>();

            graph.Document.Current    = doc;
            graph.Details.AllowUpdate = true;
            foreach (ARDunningLetterDetail detail in graph.Details.Select())
            {
                ARDunningLetterProcess.ARInvoiceWithDL invoice = PXSelect <ARDunningLetterProcess.ARInvoiceWithDL, Where <ARDunningLetterProcess.ARInvoiceWithDL.refNbr, Equal <Required <ARInvoice.refNbr> >, And <ARDunningLetterProcess.ARInvoiceWithDL.docType, Equal <Required <ARInvoice.docType> > > > > .Select(graph, detail.RefNbr, detail.DocType);

                if (invoice != null && invoice.DunningLetterLevel > detail.DunningLetterLevel)
                {
                    throw new PXException(Messages.DunningLetterHigherLevelExists);
                }
            }
            ARInvoice feeInvoice = PXSelect <ARInvoice, Where <ARInvoice.refNbr, Equal <Required <ARInvoice.refNbr> >, And <ARInvoice.docType, Equal <Required <ARInvoice.docType> > > > > .Select(graph, doc.FeeRefNbr, doc.FeeDocType);

            if (feeInvoice != null && feeInvoice.Voided == false)
            {
                ARInvoiceEntry invoiceGraph = PXGraph.CreateInstance <ARInvoiceEntry>();
                invoiceGraph.Document.Current = feeInvoice;
                if (feeInvoice.Released == false)
                {
                    invoiceGraph.Delete.Press();
                }
                else if (feeInvoice.Released == true && feeInvoice.OpenDoc == true)
                {
                    if (feeInvoice.CuryOrigDocAmt != feeInvoice.CuryDocBal)
                    {
                        throw new PXException(Messages.DunningLetterHavePaidFee);
                    }
                    invoiceGraph.reverseInvoice.Press();                     // replace by reverse & attach in 2017R2
                    invoiceGraph.Document.Current.Hold = false;
                    invoiceGraph.Document.Update(invoiceGraph.Document.Current);
                    invoiceGraph.release.Press();
                    ARPaymentEntry paymentGraph = PXGraph.CreateInstance <ARPaymentEntry>();
                    paymentGraph.Document.Current = PXSelect <ARPayment, Where <ARPayment.refNbr, Equal <Required <ARPayment.refNbr> >, And <ARPayment.docType, Equal <Required <ARPayment.docType> > > > > .Select(paymentGraph, invoiceGraph.Document.Current.RefNbr, invoiceGraph.Document.Current.DocType);

                    ARAdjust adj = new ARAdjust();
                    paymentGraph.Adjustments.Insert(adj);
                    adj.AdjdRefNbr  = feeInvoice.RefNbr;
                    adj.AdjdDocType = feeInvoice.DocType;
                    paymentGraph.Adjustments.Update(adj);
                    paymentGraph.release.Press();
                }
                else
                {
                    throw new PXException(Messages.DunningLetterHavePaidFee);
                }
            }
            foreach (ARDunningLetterDetail detail in graph.Details.Select())
            {
                detail.Voided = true;
                graph.Details.Update(detail);
            }

            doc.Voided = true;
            graph.Document.Update(doc);
            graph.Save.Press();
        }
Exemple #2
0
        public virtual void EMailDL(int dunningLetterID, bool markOnly, bool showAll)
        {
            ARDunningLetter dunningLetter = DL.Select(dunningLetterID);

            if (dunningLetter.Released == false || dunningLetter.Voided == true)
            {
                throw new PXException(CA.Messages.DocumentStatusInvalid);
            }
            Customer customer = this.Customer.Select(dunningLetter.BAccountID);

            this.Customer.Current = customer;

            if (markOnly)
            {
                dunningLetter.DontEmail = true;
            }
            else
            {
                this.DL.Current = dunningLetter;
                Activity.SendNotification(ARNotificationSource.Customer, notificationCD, dunningLetter.BranchID, new Dictionary <string, string>()
                {
                    { "LetterID", dunningLetterID.ToString() }
                });
                dunningLetter.Emailed = true;
            }
            DL.Cache.Update(dunningLetter);
            this.Save.Press();
        }
Exemple #3
0
        public static void Release(PrintParameters filter, List <DetailsResult> list)
        {
            if (list.Count > 0)
            {
                bool failed = false;
                ARDunningLetterMaint graph = PXGraph.CreateInstance <ARDunningLetterMaint>();

                int i = 0;
                foreach (DetailsResult res in list)
                {
                    try
                    {
                        ARDunningLetter doc = PXSelect <ARDunningLetter,
                                                        Where <ARDunningLetter.dunningLetterID, Equal <Required <DetailsResult.dunningLetterID> > > > .Select(graph, res.DunningLetterID);

                        ARDunningLetterMaint.ReleaseProcess(graph, doc);
                        PXFilteredProcessing <DetailsResult, PrintParameters> .SetProcessed();
                    }
                    catch (Exception e)
                    {
                        failed = true;
                        PXFilteredProcessing <DetailsResult, PrintParameters> .SetError(i, e);
                    }

                    i++;
                }

                if (failed)
                {
                    throw new PXException(Messages.OneOrMoreItemsAreNotReleased);
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Generates a list of documents that meet the filter criteria.
        /// This list is used for display in the processing screen
        /// </summary>
        /// <returns>List of Dunning Letters</returns>
        protected virtual IEnumerable details()
        {
            PrintParameters      header = Filter.Current;
            List <DetailsResult> result = new List <DetailsResult>();

            if (header == null)
            {
                yield break;
            }

            GL.Company company = PXSelect <GL.Company> .Select(this);

            foreach (PXResult <ARDunningLetter, Customer> it in PXSelectJoin <ARDunningLetter, InnerJoin <Customer, On <Customer.bAccountID, Equal <ARDunningLetter.bAccountID> > >,
                                                                              Where <ARDunningLetter.dunningLetterDate,
                                                                                     Between <Required <ARDunningLetter.dunningLetterDate>, Required <ARDunningLetter.dunningLetterDate> >,
                                                                                     And <ARDunningLetter.consolidated, Equal <Required <ARDunningLetter.consolidated> > > >,
                                                                              OrderBy <Asc <ARDunningLetter.bAccountID> > >
                     .Select(this, header.BeginDate, header.EndDate, this.Consolidated))
            {
                DetailsResult   res  = new DetailsResult();
                ARDunningLetter dl   = it;
                Customer        cust = it;
                res.Copy(this, dl, cust);

                if (this.Filter.Current.Action == 0)
                {
                    if (header.ShowAll == false && (dl.DontPrint == true || dl.Printed == true))
                    {
                        continue;
                    }
                }

                if (this.Filter.Current.Action == 1)
                {
                    if (header.ShowAll == false && (dl.DontEmail == true || dl.Emailed == true))
                    {
                        continue;
                    }
                }

                if (this.Filter.Current.Action == 2)
                {
                    if (header.ShowAll == false && (dl.DontEmail == true || dl.Emailed == true))
                    {
                        continue;
                    }
                }

                result.Add(res);
            }
            foreach (var item in result)
            {
                Details.Cache.SetStatus(item, PXEntryStatus.Held);
                yield return(item);
            }
            Details.Cache.IsDirty = false;
        }
        public static void Print(PrintParameters filter, List <DetailsResult> list, bool markOnly)
        {
            bool failed = false;
            ARDunningLetterUpdate     graph = PXGraph.CreateInstance <ARDunningLetterUpdate>();
            PXReportRequiredException ex    = null;

            foreach (DetailsResult t in list)
            {
                int?            L   = t.DunningLetterID;
                ARDunningLetter doc = graph.DL.Select(L.Value);
                PXFilteredProcessing <DetailsResult, PrintParameters> .SetCurrentItem(t);

                if (doc.Released == false || doc.Voided == true)
                {
                    PXFilteredProcessing <DetailsResult, PrintParameters> .SetError(CA.Messages.DocumentStatusInvalid);

                    failed = true;
                    continue;
                }
                if (markOnly)
                {
                    if (filter.ShowAll != true)
                    {
                        doc.DontPrint = true;
                        graph.docs.Cache.Update(doc);
                        PXFilteredProcessing <DetailsResult, PrintParameters> .SetProcessed();
                    }
                }
                else
                {
                    Dictionary <string, string> d = new Dictionary <string, string>();
                    d["ARDunningLetter.DunningLetterID"] = L.ToString();

                    if (doc.Printed != true)
                    {
                        doc.Printed = true;
                        graph.docs.Cache.Update(doc);
                        PXFilteredProcessing <DetailsResult, PrintParameters> .SetProcessed();
                    }
                    ex = PXReportRequiredException.CombineReport(ex, GetCustomerReportID(graph, "AR661000", t), d);
                }
            }


            graph.Save.Press();

            if (ex != null)
            {
                throw ex;
            }

            if (failed)
            {
                throw new PXException(Messages.OneOrMoreItemsAreNotProcessed);
            }
        }
Exemple #6
0
        public ARDunningLetter DunningLetterDoc(int Letter)
        {
            PXResult <ARDunningLetter> RD = PXSelect <ARDunningLetter,
                                                      Where <ARDunningLetter.dunningLetterID, Equal <Required <ARDunningLetter.dunningLetterID> > > >
                                            .Select(this, Letter);

            ARDunningLetter doc = RD;

            return(doc);
        }
Exemple #7
0
        private static void VoidProcess(ARDunningLetter doc)
        {
            ARDunningLetterMaint graph = PXGraph.CreateInstance <ARDunningLetterMaint>();

            graph.Document.Current    = doc;
            graph.Details.AllowUpdate = true;
            foreach (ARDunningLetterDetail detail in graph.Details.Select())
            {
                ARDunningLetterProcess.ARInvoiceWithDL invoice = PXSelect <ARDunningLetterProcess.ARInvoiceWithDL, Where <ARDunningLetterProcess.ARInvoiceWithDL.refNbr, Equal <Required <ARInvoice.refNbr> >, And <ARDunningLetterProcess.ARInvoiceWithDL.docType, Equal <Required <ARInvoice.docType> > > > > .Select(graph, detail.RefNbr, detail.DocType);

                if (invoice != null && invoice.DunningLetterLevel > detail.DunningLetterLevel)
                {
                    throw new PXException(Messages.DunningLetterHigherLevelExists);
                }
            }
            ARInvoice feeInvoice = PXSelect <ARInvoice, Where <ARInvoice.refNbr, Equal <Required <ARInvoice.refNbr> >, And <ARInvoice.docType, Equal <Required <ARInvoice.docType> > > > > .Select(graph, doc.FeeRefNbr, doc.FeeDocType);

            if (feeInvoice != null && feeInvoice.Voided == false)
            {
                ARInvoiceEntry invoiceGraph = PXGraph.CreateInstance <ARInvoiceEntry>();
                invoiceGraph.Document.Current = feeInvoice;
                if (feeInvoice.Released == false)
                {
                    invoiceGraph.Delete.Press();
                    doc.FeeRefNbr  = null;
                    doc.FeeDocType = null;
                }
                else if (feeInvoice.Released == true && feeInvoice.OpenDoc == true)
                {
                    if (feeInvoice.CuryOrigDocAmt != feeInvoice.CuryDocBal)
                    {
                        throw new PXException(Messages.DunningLetterHavePaidFee);
                    }
                    invoiceGraph.reverseInvoiceAndApplyToMemo.Press();
                    invoiceGraph.Document.Current.Hold = false;
                    invoiceGraph.Document.Update(invoiceGraph.Document.Current);
                    invoiceGraph.release.Press();
                }
                else
                {
                    throw new PXException(Messages.DunningLetterHavePaidFee);
                }
            }
            foreach (ARDunningLetterDetail detail in graph.Details.Select())
            {
                detail.Voided = true;
                graph.Details.Update(detail);
            }

            doc.Voided = true;
            graph.Document.Update(doc);
            graph.Save.Press();
        }
        protected virtual void ARDunningLetter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
        {
            ARDunningLetter row      = (ARDunningLetter)e.Row;
            bool            released = row.Released == true;
            bool            voided   = row.Voided == true;

            sender.AllowDelete  = !released;
            Details.AllowDelete = !released;
            VoidLetter.SetEnabled(released && !voided);
            PrintLetter.SetEnabled(released && !voided);
            Revoke.SetEnabled(!released);
            Release.SetEnabled(!released);
        }
Exemple #9
0
        /// <summary>
        /// Process selected rows
        /// </summary>
        /// <param name="aDoc">Row of selection</param>
        public virtual void DunningLetterProc(PX.Objects.AR.ARDunningLetterProcess.ARDunningLetterList aDoc)
        {
            this.Clear();
            ARDunningLetter doc = new ARDunningLetter();

            doc.BAccountID         = aDoc.BAccountID;
            doc.BranchID           = aDoc.BranchID;
            doc.DunningLetterDate  = aDoc.DocDate;
            doc.Deadline           = aDoc.DocDate.Value.AddDays(aDoc.DueDays.Value);
            doc.DunningLetterLevel = aDoc.DunningLetterLevel;
            doc.Consolidated       = Cons;
            doc.Printed            = false;
            doc.Emailed            = false;
            doc.DontPrint          = false;
            doc.DontEmail          = false;
            doc.LastLevel          = aDoc.DunningLetterLevel >= D_MaxLevel;
            doc = docs.Insert(doc);
            int?R_ID = doc.DunningLetterID;

            foreach (PXResult <ARInvoice> ii in
                     PXSelect <ARInvoice,
                               Where <ARInvoice.customerID, Equal <Required <ARInvoice.customerID> >,
                                      And <ARInvoice.branchID, Equal <Required <ARInvoice.branchID> >,
                                           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, aDoc.BAccountID, aDoc.BranchID, aDoc.DocDate))
            {
                ARInvoice             dl     = ii;
                ARDunningLetterDetail docDet = new ARDunningLetterDetail();

                docDet.DunningLetterID = R_ID;
                docDet.CuryOrigDocAmt  = dl.CuryOrigDocAmt;
                docDet.CuryDocBal      = dl.CuryDocBal;
                docDet.CuryID          = dl.CuryID;
                docDet.OrigDocAmt      = dl.OrigDocAmt;
                docDet.DocBal          = dl.DocBal;
                docDet.DueDate         = dl.DueDate;
                docDet.DocType         = dl.DocType;
                docDet.RefNbr          = dl.RefNbr;
                docDet.DocDate         = dl.DocDate;
                docDet.Overdue         = dl.DueDate < aDoc.DocDate;
                docDet = docsDet.Insert(docDet);
            }

            this.Actions.PressSave();
        }
Exemple #10
0
 public virtual IEnumerable enqResults()
 {
     foreach (var result in PXSelectJoinGroupBy <ARDunningLetter,
                                                 LeftJoin <Customer, On <Customer.bAccountID, Equal <ARDunningLetter.bAccountID> >,
                                                           LeftJoin <ARDunningLetterDetail, On <ARDunningLetterDetail.dunningLetterID, Equal <ARDunningLetter.dunningLetterID> > > >,
                                                 Where2 <Where <ARDunningLetter.bAccountID, Equal <Current <DLByCustomerFilter.bAccountID> >, Or <Current <DLByCustomerFilter.bAccountID>, IsNull> >,
                                                         And <ARDunningLetter.dunningLetterDate, GreaterEqual <Current <DLByCustomerFilter.beginDate> >,
                                                              And <ARDunningLetter.dunningLetterDate, LessEqual <Current <DLByCustomerFilter.endDate> > > > >,
                                                 Aggregate <GroupBy <ARDunningLetter.dunningLetterID, GroupBy <ARDunningLetter.released, GroupBy <ARDunningLetter.voided, Sum <ARDunningLetterDetail.overdueBal, Count <ARDunningLetterDetail.refNbr> > > > > >,
                                                 OrderBy <Asc <ARDunningLetter.dunningLetterDate> > > .Select(this))
     {
         ARDunningLetter letter = (ARDunningLetter)result;
         letter.DetailsCount = result.RowCount;
         yield return(result);
     }
 }
Exemple #11
0
        public virtual IEnumerable viewDocument(PXAdapter adapter)
        {
            if (Details.Current != null)
            {
                ARDunningLetter doc = PXSelect <ARDunningLetter,
                                                Where <ARDunningLetter.dunningLetterID, Equal <Required <DetailsResult.dunningLetterID> > > > .Select(this, Details.Current.DunningLetterID);

                if (doc != null)
                {
                    ARDunningLetterMaint graph = PXGraph.CreateInstance <ARDunningLetterMaint>();
                    graph.Document.Current = doc;
                    PXRedirectHelper.TryRedirect(graph, PXRedirectHelper.WindowMode.NewWindow);
                }
            }
            return(adapter.Get());
        }
        /// <summary>
        /// Generates a list of documents that meet the filter criteria.
        /// This list is used for display in the processing screen
        /// </summary>
        /// <returns>List of Customers with Dunning Letters</returns>
        protected virtual IEnumerable details()
        {
            CreditHoldParameters header = Filter.Current;
            List <DetailsResult> result = new List <DetailsResult>();

            if (header == null)
            {
                yield break;
            }

            foreach (PXResult <Customer, ARDunningLetter> record in GetCustomersToProcess(header))
            {
                ARDunningLetter dunningLetter = record;
                Customer        customer      = record;
                if (header.ShowAll == false && customer.Status != header.IncludedCustomerStatus)
                {
                    continue;
                }

                DetailsResult res = new DetailsResult();
                res.Copy(this, dunningLetter, customer);

                IEnumerable <Override.ExtendedCustomer> customerFamily =
                    CustomerMaint.GetChildAccountsAndSelfStripped <Override.Customer.sharedCreditCustomerID>(this, customer.BAccountID);

                int?[] customerFamilyIDs = customerFamily
                                           .Select(row => row.BusinessAccount.BAccountID)
                                           .Where(id => id != null)
                                           .ToArray();

                var balances = CustomerMaint.GetCustomerBalances(this, customerFamilyIDs);
                if (balances != null)
                {
                    res.InvBal = balances.CurrentBal ?? 0.0m;
                }
                result.Add(res);
            }

            foreach (var item in result)
            {
                Details.Cache.SetStatus(item, PXEntryStatus.Held);
                yield return(item);
            }
            Details.Cache.IsDirty = false;
        }
Exemple #13
0
            /// <summary>
            /// Copy field values from selection and aggregate details
            /// </summary>
            /// <param name="G">Graph</param>
            /// <param name="aSrc">Selected DunningLetter</param>
            /// <param name="cust">Selected Customer</param>
            public virtual void Copy(PXGraph G, ARDunningLetter aSrc, Customer cust)
            {
                this.CustomerId        = cust.BAccountID;
                this.DunningLetterID   = aSrc.DunningLetterID;
                this.DunningLetterDate = aSrc.DunningLetterDate;
                this.DocBal            = 0;
                this.InvBal            = 0;
                this.Status            = cust.Status;

                foreach (PXResult <ARDunningLetterDetail> it in PXSelect <ARDunningLetterDetail,
                                                                          Where <ARDunningLetterDetail.dunningLetterID,
                                                                                 Equal <Required <ARDunningLetterDetail.dunningLetterID> > > >
                         .Select(G, aSrc.DunningLetterID))
                {
                    ARDunningLetterDetail d = it;
                    this.DocBal += d.DocBal;
                }
            }
Exemple #14
0
        public static void Print(PrintParameters filter, List <DetailsResult> list, bool markOnly)
        {
            ARDunningLetterUpdate     graph = PXGraph.CreateInstance <ARDunningLetterUpdate>();
            PXReportRequiredException ex    = null;

            foreach (DetailsResult t in list)
            {
                int?            L   = t.DunningLetterID;
                ARDunningLetter doc = graph.DL.Select(L.Value);
                if (markOnly)
                {
                    if (filter.ShowAll != true)
                    {
                        doc.DontPrint = true;
                        graph.docs.Cache.Update(doc);
                    }
                }
                else
                {
                    Dictionary <string, string> d = new Dictionary <string, string>();
                    d["ARDunningLetter.DunningLetterID"] = L.ToString();

                    if (doc.Printed != true)
                    {
                        doc.Printed = true;
                        graph.docs.Cache.Update(doc);
                    }
                    ex = PXReportRequiredException.CombineReport(ex, GetCustomerReportID(graph, "AR661000", t), d);
                }
            }


            graph.Save.Press();

            if (ex != null)
            {
                throw ex;
            }
        }
Exemple #15
0
            public virtual void Copy(PXGraph graph, ARDunningLetter source, Customer customer)
            {
                BranchID           = source.BranchID;
                CustomerId         = source.BAccountID;
                DunningLetterID    = source.DunningLetterID;
                DunningLetterDate  = source.DunningLetterDate;
                DunningLetterLevel = source.DunningLetterLevel;
                LastLevel          = source.LastLevel;
                DontEmail          = source.DontEmail;
                DontPrint          = source.DontPrint;
                Emailed            = source.Emailed;
                Printed            = source.Printed;
                DocBal             = 0;

                foreach (PXResult <ARDunningLetterDetail> it in PXSelect <ARDunningLetterDetail,
                                                                          Where <ARDunningLetterDetail.dunningLetterID, Equal <Required <ARDunningLetterDetail.dunningLetterID> > > >
                         .Select(graph, source.DunningLetterID))
                {
                    ARDunningLetterDetail detail = it;
                    DocBal += detail.OverdueBal;
                }
            }
            /// <summary>
            /// Copy field values from selection and aggregate details
            /// </summary>
            /// <param name="G">Graph</param>
            /// <param name="aSrc">Selected DunningLetter</param>
            /// <param name="cust">Selected Customer</param>
            public virtual void Copy(PXGraph G, ARDunningLetter aSrc, Customer cust)
            {
                this.BranchID           = aSrc.BranchID;
                this.CustomerId         = aSrc.BAccountID;
                this.DunningLetterID    = aSrc.DunningLetterID;
                this.DunningLetterDate  = aSrc.DunningLetterDate;
                this.DunningLetterLevel = aSrc.DunningLetterLevel;
                this.LastLevel          = aSrc.LastLevel;
                this.DontEmail          = aSrc.DontEmail;
                this.DontPrint          = aSrc.DontPrint;
                this.Emailed            = aSrc.Emailed;
                this.Printed            = aSrc.Printed;
                this.DocBal             = 0;

                foreach (PXResult <ARDunningLetterDetail> it in PXSelect <ARDunningLetterDetail,
                                                                          Where <ARDunningLetterDetail.dunningLetterID, Equal <Required <ARDunningLetterDetail.dunningLetterID> > > >
                         .Select(G, aSrc.DunningLetterID))
                {
                    ARDunningLetterDetail d = it;
                    this.DocBal += d.OverdueBal;
                }
            }
Exemple #17
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();
            }
        }
Exemple #18
0
        public virtual void EMailDL(int DocID, bool aMarkOnly, bool ShowAll)
        {
            ARDunningLetter iDoc     = DL.Select(DocID);
            Customer        customer = this.Customer.Select(iDoc.BAccountID);

            this.Customer.Current = customer;

            if (aMarkOnly)
            {
                iDoc.DontEmail = true;
            }
            else
            {
                this.DL.Current = iDoc;
                Activity.SendNotification(ARNotificationSource.Customer, notificationCD, iDoc.BranchID, new Dictionary <string, string>()
                {
                    { "LetterID", DocID.ToString() }
                });
                iDoc.Emailed = true;
            }
            DL.Cache.Update(iDoc);
            this.Save.Press();
        }
Exemple #19
0
        /// <summary>
        /// Generates a list of documents that meet the filter criteria.
        /// This list is used for display in the processing screen
        /// </summary>
        /// <returns>List of Customers with Dunning Letters</returns>
        protected virtual IEnumerable details()
        {
            CreditHoldParameters header = Filter.Current;
            List <DetailsResult> result = new List <DetailsResult>();

            if (header == null)
            {
                yield break;
            }

            foreach (PXResult <Customer, ARDunningLetter> record in GetCustomersToProcess(header))
            {
                ARDunningLetter dunningLetter = record;
                Customer        customer      = record;
                if (header.ShowAll == false && customer.Status != header.IncludedCustomerStatus)
                {
                    continue;
                }

                DetailsResult res = new DetailsResult();
                res.Copy(this, dunningLetter, customer);

                ARBalances balances = CustomerMaint.GetCustomerBalances <Override.Customer.sharedCreditCustomerID>(this, customer.BAccountID);
                if (balances != null)
                {
                    res.InvBal = balances.CurrentBal ?? 0.0m;
                }
                result.Add(res);
            }

            foreach (var item in result)
            {
                Details.Cache.SetStatus(item, PXEntryStatus.Held);
                yield return(item);
            }
            Details.Cache.IsDirty = false;
        }
Exemple #20
0
        /// <summary>
        /// Generates a list of documents that meet the filter criteria.
        /// This list is used for display in the processing screen
        /// </summary>
        /// <returns>List of Dunning Letters</returns>
        protected virtual IEnumerable details()
        {
            Details.Cache.Clear();
            PrintParameters header = Filter.Current;

            if (header == null)
            {
                yield break;
            }
            List <DetailsResult> results = new List <DetailsResult>();

            PXSelectBase <ARDunningLetter> cmd = new PXSelectJoinGroupBy <ARDunningLetter,
                                                                          InnerJoin <ARDunningLetterDetail,
                                                                                     On <ARDunningLetterDetail.dunningLetterID, Equal <ARDunningLetter.dunningLetterID> > >,
                                                                          Where <ARDunningLetter.dunningLetterDate,
                                                                                 Between <Required <ARDunningLetter.dunningLetterDate>, Required <ARDunningLetter.dunningLetterDate> >,
                                                                                 And <ARDunningLetter.consolidated, Equal <Required <ARDunningLetter.consolidated> > > >,
                                                                          Aggregate <GroupBy <ARDunningLetter.dunningLetterID, Sum <ARDunningLetterDetail.overdueBal> > >,
                                                                          OrderBy <Asc <ARDunningLetter.bAccountID> > >(this);

            if (Filter.Current.Action == ActionTypes.Release)
            {
                cmd.WhereAnd <Where <ARDunningLetter.released, Equal <False>, And <ARDunningLetter.voided, Equal <False> > > >();
            }
            else
            {
                cmd.WhereAnd <Where <ARDunningLetter.released, Equal <True>, And <ARDunningLetter.voided, Equal <False> > > >();
            }
            foreach (PXResult <ARDunningLetter, ARDunningLetterDetail> res in cmd.Select(header.BeginDate, header.EndDate, this.Consolidated))
            {
                ARDunningLetter       dunningLetter = res;
                ARDunningLetterDetail detailSum     = res;

                if (Filter.Current.Action == ActionTypes.Print &&
                    header.ShowAll == false &&
                    (dunningLetter.DontPrint == true || dunningLetter.Printed == true))
                {
                    continue;
                }

                if (Filter.Current.Action == ActionTypes.Email &&
                    header.ShowAll == false &&
                    (dunningLetter.DontEmail == true || dunningLetter.Emailed == true))
                {
                    continue;
                }

                if (Filter.Current.Action == ActionTypes.MarkDontEmail &&
                    header.ShowAll == false &&
                    (dunningLetter.DontEmail == true || dunningLetter.Emailed == true))
                {
                    continue;
                }

                DetailsResult row = new DetailsResult();
                row.BranchID           = dunningLetter.BranchID;
                row.CustomerId         = dunningLetter.BAccountID;
                row.DunningLetterID    = dunningLetter.DunningLetterID;
                row.DunningLetterDate  = dunningLetter.DunningLetterDate;
                row.DunningLetterLevel = dunningLetter.DunningLetterLevel;
                row.LastLevel          = dunningLetter.LastLevel;
                row.DontEmail          = dunningLetter.DontEmail;
                row.DontPrint          = dunningLetter.DontPrint;
                row.Emailed            = dunningLetter.Emailed;
                row.Printed            = dunningLetter.Printed;
                row.DocBal             = detailSum.OverdueBal;
                results.Add(row);
            }
            foreach (DetailsResult item in results)
            {
                Details.Cache.SetStatus(item, PXEntryStatus.Held);
                yield return(item);
            }
            Details.Cache.IsDirty = false;
        }
Exemple #21
0
        /// <summary>
        /// Generates a list of documents that meet the filter criteria.
        /// This list is used for display in the processing screen
        /// </summary>
        /// <returns>List of Customers with Dunning Letters</returns>
        protected virtual IEnumerable details()
        {
            CreditHoldParameters header = Filter.Current;
            List <DetailsResult> result = new List <DetailsResult>();

            if (header == null)
            {
                yield break;
            }

            bool AllShow = header.ShowAll ?? false;

            if (this.Filter.Current.Action == 0)
            {
                foreach (PXResult <Customer, ARDunningLetter> it in PXSelectJoin <Customer,
                                                                                  InnerJoin <ARDunningLetter, On <Customer.bAccountID, Equal <ARDunningLetter.bAccountID>,
                                                                                                                  And <ARDunningLetter.lastLevel, Equal <boolTrue> > > >,
                                                                                  Where <ARDunningLetter.dunningLetterDate,
                                                                                         Between <Required <ARDunningLetter.dunningLetterDate>, Required <ARDunningLetter.dunningLetterDate> > >,
                                                                                  OrderBy <Asc <ARDunningLetter.bAccountID> > >
                         .Select(this, header.BeginDate, header.EndDate))
                {
                    ARDunningLetter dl   = it;
                    Customer        cust = it;
                    if (!AllShow && cust.Status != BAccount.status.Active)
                    {
                        continue;
                    }

                    DetailsResult res = new DetailsResult();
                    res.Copy(this, dl, cust);

                    //==============================================================================
                    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 <ARInvoice.docType, Equal <AP.APDocType.invoice>,
                                                                  And <ARInvoice.docDate, Between <Required <ARInvoice.docDate>, Required <ARInvoice.docDate> > > > > > > >
                                       > .Select(this, cust.BAccountID, header.BeginDate, header.EndDate))
                    {
                        ARInvoice inv = ix;

                        if (inv.BranchID != dl.BranchID)
                        {
                            continue;                              // alien branch
                        }
                        res.InvBal += inv.DocBal;
                    }
                    result.Add(res);
                }
            }
            else if (this.Filter.Current.Action == 1)
            {
                foreach (PXResult <Customer, ARDunningLetter> it in PXSelectJoin <Customer,
                                                                                  LeftJoin <ARDunningLetter, On <Customer.bAccountID, Equal <ARDunningLetter.bAccountID>,
                                                                                                                 And <ARDunningLetter.lastLevel, Equal <boolTrue> > > > >
                         .Select(this))
                {
                    ARDunningLetter dl   = it;
                    Customer        cust = it;
                    if (!AllShow && cust.Status != BAccount.status.CreditHold)
                    {
                        continue;
                    }

                    DetailsResult res = new DetailsResult();
                    res.Copy(this, dl, cust);

                    //==============================================================================
                    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 <ARInvoice.docType, Equal <AP.APDocType.invoice>,
                                                                  And <ARInvoice.docDate, Less <Required <ARInvoice.docDate> > > > > > > >
                                       > .Select(this, cust.BAccountID, header.EndDate))
                    {
                        ARInvoice inv = ix;

                        //if (inv.BranchID != dl.BranchID) continue; // alien branch

                        res.InvBal += inv.DocBal;
                    }
                    result.Add(res);
                }
            }
            else
            {
                yield break;
            }
            foreach (var item in result)
            {
                Details.Cache.SetStatus(item, PXEntryStatus.Held);
                yield return(item);
            }
            Details.Cache.IsDirty = false;
        }
        public static void Print(PrintParameters filter, List <DetailsResult> list, bool markOnly)
        {
            bool failed = false;
            ARDunningLetterUpdate     graph = PXGraph.CreateInstance <ARDunningLetterUpdate>();
            PXReportRequiredException reportRedirectException             = null;
            Dictionary <string, PXReportRequiredException> reportsToPrint = new Dictionary <string, PXReportRequiredException>();

            foreach (DetailsResult res in list)
            {
                int?            letterID = res.DunningLetterID;
                ARDunningLetter doc      = graph.DL.Select(letterID.Value);
                PXFilteredProcessing <DetailsResult, PrintParameters> .SetCurrentItem(res);

                if (doc.Released == false || doc.Voided == true)
                {
                    PXFilteredProcessing <DetailsResult, PrintParameters> .SetError(CA.Messages.DocumentStatusInvalid);

                    failed = true;
                    continue;
                }
                if (markOnly)
                {
                    if (filter.ShowAll != true)
                    {
                        doc.DontPrint = true;
                        graph.docs.Cache.Update(doc);
                        PXFilteredProcessing <DetailsResult, PrintParameters> .SetProcessed();
                    }
                }
                else
                {
                    Dictionary <string, string> reportParameters = new Dictionary <string, string>();
                    reportParameters["ARDunningLetter.DunningLetterID"] = letterID.ToString();

                    if (doc.Printed != true)
                    {
                        doc.Printed = true;
                        graph.docs.Cache.Update(doc);
                        PXFilteredProcessing <DetailsResult, PrintParameters> .SetProcessed();
                    }

                    string actualReportID = GetCustomerReportID(graph, ARReports.DunningLetterReportID, res);

                    reportRedirectException = PXReportRequiredException.CombineReport(reportRedirectException, actualReportID, reportParameters);

                    reportsToPrint = PX.SM.SMPrintJobMaint.AssignPrintJobToPrinter(reportsToPrint, reportParameters, filter, new NotificationUtility(graph).SearchPrinter, ARNotificationSource.Customer, ARReports.DunningLetterReportID, actualReportID, doc.BranchID);
                }
            }

            graph.Save.Press();

            if (reportRedirectException != null)
            {
                PX.SM.SMPrintJobMaint.CreatePrintJobGroups(reportsToPrint);

                throw reportRedirectException;
            }

            if (failed)
            {
                throw new PXException(Messages.OneOrMoreItemsAreNotProcessed);
            }
        }
        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();
            }
        }
        public static void ReleaseProcess(ARDunningLetter doc)
        {
            ARDunningLetterMaint graph = PXGraph.CreateInstance <ARDunningLetterMaint>();

            ReleaseProcess(graph, doc);
        }
Exemple #25
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);
            }
        }
Exemple #26
0
        private static ARInvoice InsertFeeInvoice(ARDunningLetter doc, decimal dunningFee)
        {
            ARInvoiceEntry invGraph = PXGraph.CreateInstance <ARInvoiceEntry>();

            int?   organizationID = PXAccess.GetParentOrganizationID(doc.BranchID);
            string finPeriodID    = invGraph.GetService <IFinPeriodRepository>().GetPeriodIDFromDate(doc.DunningLetterDate, organizationID);

            invGraph.GetService <IFinPeriodUtils>().ValidateFinPeriod(doc.SingleToArray(), m => finPeriodID, m => m.BranchID.SingleToArray());

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

            Customer customer = PXSelect <Customer, Where <Customer.bAccountID, Equal <Required <ARDunningLetter.bAccountID> > > > .Select(invGraph, doc.BAccountID);

            CS.Numbering numbering = PXSelect <CS.Numbering,
                                               Where <CS.Numbering.numberingID, Equal <Required <ARSetup.dunningFeeNumberingID> > > > .Select(invGraph, setup.DunningFeeNumberingID);

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

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

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


            ARInvoice feeInvoice = new ARInvoice
            {
                DocType = ARDocType.Invoice
            };

            if (numbering != null)
            {
                CS.AutoNumberAttribute.SetNumberingId <ARInvoice.refNbr>(invGraph.Document.Cache, feeInvoice.DocType, numbering.NumberingID);
            }
            feeInvoice = (ARInvoice)invGraph.Document.Cache.CreateCopy(invGraph.Document.Insert(feeInvoice));

            feeInvoice.Released           = false;
            feeInvoice.Hold               = false;
            feeInvoice.Voided             = false;
            feeInvoice.BranchID           = doc.BranchID;
            feeInvoice.DocDate            = doc.DunningLetterDate;
            feeInvoice.CustomerID         = customer.BAccountID;
            feeInvoice.DocDesc            = Messages.DunningLetterFee;
            feeInvoice.CustomerLocationID = customer.DefLocationID;
            feeInvoice.CuryID             = customer.AllowOverrideCury == false && customer.CuryID != null
                        ? customer.CuryID
                        : ((GL.Company)PXSelect <GL.Company> .Select(invGraph)).BaseCuryID;

            invGraph.Document.Update(feeInvoice);


            decimal      curyVal;
            CurrencyInfo curyInfo = invGraph.currencyinfo.Select();

            PXCurrencyAttribute.PXCurrencyHelper.CuryConvCury(invGraph.Caches[typeof(CurrencyInfo)], curyInfo, dunningFee, out curyVal);

            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();
            }
            return(invGraph.Document.Current);
        }