private static IEnumerable<Customer> GetCustomersForAutoApplication(PXGraph graph, ARStatementCycle cycle, ARAutoApplyParameters filter) { var result = new List<Customer> { }; if (filter.LoadChildDocuments != LoadChildDocumentsOptions.None) { var childrenOfParentsWithCycle = PXSelectJoin<Customer, InnerJoin<CustomerMaster, On<Customer.parentBAccountID, Equal<CustomerMaster.bAccountID>, And<Customer.consolidateToParent, Equal<True>>>>, Where<CustomerMaster.statementCycleId, Equal<Required<Customer.statementCycleId>>, And<Match<Current<AccessInfo.userName>>>>> .Select(graph, cycle.StatementCycleId); result.AddRange(childrenOfParentsWithCycle.RowCast<Customer>()); } var nonChildrenWithCycle = PXSelectJoin<Customer, LeftJoin<CustomerMaster, On<Customer.parentBAccountID, Equal<CustomerMaster.bAccountID>, And<Customer.consolidateToParent, Equal<True>>>>, Where<Customer.statementCycleId, Equal<Required<Customer.statementCycleId>>, And2<Match<Current<AccessInfo.userName>>, And<Where<CustomerMaster.bAccountID, IsNull, Or<CustomerMaster.statementCycleId, NotEqual<Required<CustomerMaster.statementCycleId>>>>>>>> .Select(graph, cycle.StatementCycleId, cycle.StatementCycleId); var toAdd = nonChildrenWithCycle.RowCast<Customer>() .Where(c => result.FirstOrDefault(alreadyPresent => alreadyPresent.BAccountID == c.BAccountID) == null).ToList(); result.AddRange(toAdd); return result; }
protected static void Accumulate(ARStatement aDest, ARRegister aSrc1, ARStatementCycle aSrc2, bool isNewDoc, bool aAgeCredits) { ARInvoice inv = aSrc1 as ARInvoice; Copy(aDest, aSrc2); if (isNewDoc) { aDest.EndBalance = (aDest.EndBalance ?? Decimal.Zero) + ((aSrc1.Payable ?? false) ? aSrc1.OrigDocAmt : (-aSrc1.OrigDocAmt)); aDest.CuryEndBalance = (aDest.CuryEndBalance ?? Decimal.Zero) + ((aSrc1.Payable ?? false) ? aSrc1.CuryOrigDocAmt : (-aSrc1.CuryOrigDocAmt)); } //ARDocType.SmallCreditWO - is an invoice, but it must be processed as payment int days = 0; if (inv != null && inv.DocType != ARDocType.SmallCreditWO) { TimeSpan diff = (aDest.StatementDate.Value.Subtract(inv.DueDate.Value)); days = diff.Days; } else { TimeSpan diff = (aDest.StatementDate.Value.Subtract(aSrc1.DocDate.Value)); days = diff.Days; } if ((inv != null && inv.DocType != ARDocType.SmallCreditWO) || aAgeCredits) { Decimal docBal = ((bool)aSrc1.Paying) ? -aSrc1.DocBal.Value : aSrc1.DocBal.Value; Decimal curyDocBal = ((bool)aSrc1.Paying) ? -aSrc1.CuryDocBal.Value : aSrc1.CuryDocBal.Value; if (days <= 0) { aDest.AgeBalance00 = (aDest.AgeBalance00 ?? Decimal.Zero) + docBal; aDest.CuryAgeBalance00 = (aDest.CuryAgeBalance00 ?? Decimal.Zero) + curyDocBal; } else if (!aSrc2.AgeDays00.HasValue || days <= aSrc2.AgeDays00) { aDest.AgeBalance01 = (aDest.AgeBalance01 ?? Decimal.Zero) + docBal; aDest.CuryAgeBalance01 = (aDest.CuryAgeBalance01 ?? Decimal.Zero) + curyDocBal; } else if (!aSrc2.AgeDays01.HasValue || days <= aSrc2.AgeDays01) { aDest.AgeBalance02 = (aDest.AgeBalance02 ?? Decimal.Zero) + docBal; aDest.CuryAgeBalance02 = (aDest.CuryAgeBalance02 ?? Decimal.Zero) + curyDocBal; } else if (!aSrc2.AgeDays02.HasValue || days <= aSrc2.AgeDays02) { aDest.AgeBalance03 = (aDest.AgeBalance03 ?? Decimal.Zero) + docBal; aDest.CuryAgeBalance03 = (aDest.CuryAgeBalance03 ?? Decimal.Zero) + curyDocBal; } else { aDest.AgeBalance04 = (aDest.AgeBalance04 ?? Decimal.Zero) + docBal; aDest.CuryAgeBalance04 = (aDest.CuryAgeBalance04 ?? Decimal.Zero) + curyDocBal; } } else { //Payments, when credits are not aged aDest.AgeBalance04 = aDest.AgeBalance04 - aSrc1.DocBal; //After completion we must apply resedual payments to previous buckets aDest.CuryAgeBalance04 = aDest.CuryAgeBalance04 - aSrc1.CuryDocBal; } }
protected virtual void ARStatementCycle_RowSelecting(PXCache sender, PXRowSelectingEventArgs e) { if (e.Row != null) { ARStatementCycle row = e.Row as ARStatementCycle; row.NextStmtDate = ARStatementProcess.CalcStatementDateBefore( sender.Graph, this.Accessinfo.BusinessDate.Value, row.PrepareOn, row.Day00, row.Day01, row.DayOfWeek); if (row.LastStmtDate.HasValue && row.NextStmtDate <= row.LastStmtDate) { row.NextStmtDate = ARStatementProcess.CalcNextStatementDate( sender.Graph, row.LastStmtDate.Value, row.PrepareOn, row.Day00, row.Day01, row.DayOfWeek); } } }
public virtual void CustomerClass_StatementCycleId_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e) { CustomerClass row = (CustomerClass)e.Row; if (row == null) { return; } if ((row.StatementCycleId != null)) { ARSetup setup = (ARSetup)PXSelect <ARSetup> .Select(this); if (setup != null && (setup.DefFinChargeFromCycle == true)) { ARStatementCycle arSC = PXSelect <ARStatementCycle, Where <ARStatementCycle.statementCycleId, Equal <Required <ARStatementCycle.statementCycleId> > > > . Select(this, row.StatementCycleId); if ((arSC != null) && (arSC.FinChargeID != null)) { row.FinChargeID = arSC.FinChargeID; this.CustomerClassRecord.Cache.RaiseFieldUpdated <CustomerClass.finChargeID>(row, null); } } } }
protected virtual void GenerateStatement(ARStatementCycle aCycle, DateTime aStatementDate) { PXSelectBase <Customer> selectCustomer = new PXSelect <Customer, Where <Customer.statementCycleId, Equal <Required <Customer.statementCycleId> > > >(this); PXSelectBase <ARRegister> selectOpenDocs = new PXSelectJoin <ARRegister, LeftJoin <ARInvoice, On <ARInvoice.docType, Equal <ARRegister.docType>, And <ARInvoice.refNbr, Equal <ARRegister.refNbr> > > >, Where <ARRegister.customerID, Equal <Required <ARRegister.customerID> >, And <ARRegister.released, Equal <BQLConstants.BitOn>, And <ARRegister.docDate, LessEqual <Required <ARRegister.docDate> >, And <Where <ARRegister.openDoc, Equal <BQLConstants.BitOn>, Or <ARRegister.statementDate, IsNull> > > > > > >(this); PXSelectBase <ARStatementDetail> selectDocsStmDetail = new PXSelect <ARStatementDetail, Where <ARStatementDetail.customerID, Equal <Required <ARStatementDetail.customerID> >, And <ARStatementDetail.docType, Equal <Required <ARStatementDetail.docType> >, And <ARStatementDetail.refNbr, Equal <Required <ARStatementDetail.refNbr> > > > >, OrderBy <Asc <ARStatementDetail.statementDate> > >(this); PXSelectBase <ARStatement> selectAllPreviousByCustomer = new PXSelect <ARStatement, Where <ARStatement.customerID, Equal <Required <ARStatement.customerID> > >, OrderBy <Asc <ARStatement.curyID, Desc <ARStatement.statementDate> > > >(this); PXSelectBase <ARStatement> selectPreviousStatement = new PXSelect <ARStatement, Where <ARStatement.branchID, Equal <Required <ARStatement.branchID> >, And <ARStatement.customerID, Equal <Required <ARStatement.customerID> >, And <ARStatement.curyID, Equal <Required <ARStatement.curyID> > > > >, OrderBy <Desc <ARStatement.statementDate> > >(this); bool ageCredits = (this.ARSetup.Current.AgeCredits ?? false); foreach (Customer iCst in selectCustomer.Select(aCycle.StatementCycleId)) { GenerateCustomerStatement(aCycle, iCst, aStatementDate, new Dictionary <Tuple <int, string, int, DateTime>, ARStatement>()); } aCycle.LastStmtDate = aStatementDate; }
protected static void Copy(ARStatement aDest, ARStatementCycle aSrc) { aDest.StatementCycleId = aSrc.StatementCycleId; aDest.AgeDays00 = 0; aDest.AgeDays01 = aSrc.AgeDays00; aDest.AgeDays02 = aSrc.AgeDays01; aDest.AgeDays03 = aSrc.AgeDays02; }
public static void ProcessCycles(StatementCycleProcessBO graph, ARStatementCycle aCycle) { graph.Clear(); ARStatementCycle cycle = graph.CyclesList.Select(aCycle.StatementCycleId); DateTime statementDate = aCycle.NextStmtDate ?? graph.Accessinfo.BusinessDate.Value; graph.GenerateStatement(cycle, statementDate, false); }
public static DateTime FindNextStatementDate(DateTime aBusinessDate, ARStatementCycle aCycle) { DateTime?result = CalcStatementDateBefore(aBusinessDate, aCycle.PrepareOn, aCycle.Day00, aCycle.Day01); if (aCycle.LastStmtDate.HasValue && result <= aCycle.LastStmtDate) { result = CalcNextStatementDate(aCycle.LastStmtDate.Value, aCycle.PrepareOn, aCycle.Day00, aCycle.Day01); } return(result.HasValue ? result.Value : aBusinessDate); }
private void SetStatementDateFromCycle(PrintParameters filter) { if (!string.IsNullOrEmpty(filter.StatementCycleId)) { ARStatementCycle cycle = PXSelect <ARStatementCycle, Where <ARStatementCycle.statementCycleId, Equal <Required <ARStatementCycle.statementCycleId> > > > .Select(this, filter.StatementCycleId); filter.StatementDate = cycle.LastStmtDate; } }
public static void RegenerateLastStatement(StatementCycleProcessBO graph, ARStatementCycle aCycle) { graph.Clear(); ARStatementCycle cycle = graph.CyclesList.Select(aCycle.StatementCycleId); if (cycle.LastStmtDate != null) { DateTime stmtDate = (DateTime)cycle.LastStmtDate; graph.GenerateStatement(cycle, stmtDate, true); } }
protected virtual void ARStatementDetailsParameters_StatementCycleId_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e) { ARStatementDetailsParameters row = (ARStatementDetailsParameters)e.Row; if (!string.IsNullOrEmpty(row.StatementCycleId)) { ARStatementCycle cycle = PXSelect <ARStatementCycle, Where <ARStatementCycle.statementCycleId, Equal <Required <ARStatementCycle.statementCycleId> > > > .Select(this, row.StatementCycleId); row.StatementDate = cycle.LastStmtDate; } }
protected static void DeleteStatement(ARStatementCycle aStatementCycle, DateTime aStmtDate) { StatementCreateBO statementBO = PXGraph.CreateInstance <StatementCreateBO>(); foreach (ARStatement iStm in statementBO.Statement.Select(aStatementCycle.StatementCycleId, aStmtDate)) { statementBO.Statement.Delete(iStm); } statementBO.Actions.PressSave(); if (aStatementCycle.LastStmtDate == aStmtDate) { aStatementCycle.LastStmtDate = statementBO.FindLastCycleStatementDate(aStatementCycle.StatementCycleId, aStmtDate); } }
protected virtual void GenerateStatement(ARStatementCycle cycle, DateTime statementDate, bool clearExisting) { PXSelectBase <Customer> selectCustomer = new PXSelectJoin <Customer, InnerJoin <CustomerMaster, On <CustomerMaster.bAccountID, Equal <Customer.statementCustomerID> > >, Where <CustomerMaster.statementCycleId, Equal <Required <Customer.statementCycleId> > >, OrderBy <Asc <Customer.statementCustomerID> > >(this); var statementGraph = CreateInstance <StatementCreateBO>(); var family = new List <Customer> { }; foreach (Customer customer in selectCustomer.Select(cycle.StatementCycleId)) { if (family.Any() == false || family.First().StatementCustomerID == customer.StatementCustomerID) { family.Add(customer); } else { GenerateStatementForCustomerFamily(statementGraph, cycle, family, statementDate, clearExisting); family = new List <Customer> { customer }; } } if (family.Any()) { GenerateStatementForCustomerFamily(statementGraph, cycle, family, statementDate, clearExisting); } Customer leftToProcess = PXSelectReadonly2 <Customer, InnerJoin <CustomerMaster, On <CustomerMaster.bAccountID, Equal <Customer.statementCustomerID> > >, Where <CustomerMaster.statementCycleId, Equal <Required <Customer.statementCycleId> >, And <Where <Customer.statementLastDate, IsNull, Or <Customer.statementLastDate, Less <Required <Customer.statementLastDate> > > > > > > .SelectWindowed(this, 0, 1, cycle.StatementCycleId, statementDate); if (leftToProcess == null) { cycle.LastStmtDate = statementDate; this.CyclesList.Update(cycle); this.Actions.PressSave(); } }
protected static IEnumerable <ARStatement> DeleteStatements(ARStatementCycle aStatementCycle, IEnumerable <Customer> customers, DateTime aStmtDate) { var trace = new List <ARStatement>(); StatementCreateBO statementBO = PXGraph.CreateInstance <StatementCreateBO>(); foreach (var customer in customers) { foreach (ARStatement iStm in statementBO.CustomerStatement.Select(aStatementCycle.StatementCycleId, customer.BAccountID, aStmtDate)) { trace.Add(StatementTrace(iStm)); statementBO.CustomerStatement.Delete(iStm); } } statementBO.Actions.PressSave(); return(trace); }
public static void RegenerateLastStatement(StatementCycleProcessBO graph, ARStatementCycle aCycle) { graph.Clear(); ARStatementCycle cycle = graph.CyclesList.Select(aCycle.StatementCycleId); if (cycle.LastStmtDate != null) { DateTime stmtDate = (DateTime)cycle.LastStmtDate; using (PXTransactionScope ts = new PXTransactionScope()) { DeleteStatement(cycle, stmtDate); graph.GenerateStatement(cycle, stmtDate); PXCache cache = graph.CyclesList.Cache; cache.Update(cycle); cache.Persist(PXDBOperation.Update); ts.Complete(); } } }
public static void RegenerateStatements(StatementCycleProcessBO graph, ARStatementCycle aCycle, IEnumerable <Customer> customers) { graph.Clear(); ARStatementCycle cycle = graph.CyclesList.Select(aCycle.StatementCycleId); if (cycle.LastStmtDate != null) { DateTime stmtDate = (DateTime)cycle.LastStmtDate; var statementGraph = CreateInstance <StatementCreateBO>(); var customerFamilies = GetStatementCustomers(graph, customers).GroupBy(c => c.StatementCustomerID); foreach (var family in customerFamilies) { graph.GenerateStatementForCustomerFamily(statementGraph, aCycle, family, stmtDate, true); } } }
public static DateTime FindNextStatementDateAfter(DateTime aBusinessDate, ARStatementCycle aCycle) { DateTime?result = null; if (aCycle.LastStmtDate.HasValue) { result = CalcNextStatementDate(aCycle.LastStmtDate.Value, aCycle.PrepareOn, aCycle.Day00, aCycle.Day01); if (result >= aBusinessDate) { return(result.Value); } } result = CalcStatementDateBefore(aBusinessDate, aCycle.PrepareOn, aCycle.Day00, aCycle.Day01); do { result = CalcNextStatementDate(result.Value, aCycle.PrepareOn, aCycle.Day00, aCycle.Day01); }while ((result != null) && (result < aBusinessDate)); return(result.Value); }
protected virtual ARStatement AddARStatement(Dictionary <StatementKey, ARStatement> statements, StatementKey key, ARStatementCycle cycle, Customer customer, DateTime statementDate) { ARStatement statement; if (!statements.TryGetValue(key, out statement)) { statement = new ARStatement(); Clear(statement); Copy(statement, customer); Copy(statement, cycle); Copy(statement, key); statement.StatementDate = statementDate; statements[key] = statement; } return(statement); }
protected virtual IEnumerable <ARStatement> DeleteCustomerStatement(ARStatementCycle aCycle, Customer customer, DateTime aStatementDate) { StatementCreateBO statementBO = PXGraph.CreateInstance <StatementCreateBO>(); var trace = new List <ARStatement>(); int deletedCount = 0; foreach (ARStatement iStm in statementBO.CustomerStatement.Select(customer.BAccountID, aStatementDate)) { trace.Add(StatementTrace(iStm)); statementBO.CustomerStatement.Delete(iStm); deletedCount++; } if (deletedCount == 0) { customer.StatementLastDate = statementBO.FindLastCstmStatementDate(customer.BAccountID, aStatementDate); statementBO.Customer.Update(customer); } statementBO.Actions.PressSave(); return(trace); }
public static void ProcessCycles(StatementCycleProcessBO graph, ARStatementCycle aCycle) { graph.Clear(); ARStatementCycle cycle = graph.CyclesList.Select(aCycle.StatementCycleId); DateTime? statementDate = aCycle.NextStmtDate; using (PXTransactionScope ts = new PXTransactionScope()) { if (statementDate.HasValue) { graph.GenerateStatement(cycle, statementDate.Value); } else { graph.GenerateStatement(cycle, graph.Accessinfo.BusinessDate.Value); } graph.CyclesList.Update(cycle); graph.CyclesList.Cache.Persist(PXDBOperation.Update); ts.Complete(); } }
public static void RegenerateStatements(StatementCycleProcessBO graph, ARStatementCycle aCycle, IEnumerable <Customer> customers) { graph.Clear(); ARStatementCycle cycle = graph.CyclesList.Select(aCycle.StatementCycleId); if (cycle.LastStmtDate != null) { DateTime stmtDate = (DateTime)cycle.LastStmtDate; using (PXTransactionScope ts = new PXTransactionScope()) { //why don't we pass the graph to the DeleteStatements? var trace = DeleteStatements(cycle, customers, stmtDate); //don't we want graph.Accessinfo.BusinessDate.Value here??? foreach (var c in customers.GroupBy(cs => cs.BAccountID).Select(g => g.First())) { graph.GenerateCustomerStatement(cycle, c, stmtDate, TraceToDict(trace)); } ts.Complete(); } } }
public virtual void ARStatementCycle_RowSelected(PXCache cache, PXRowSelectedEventArgs e) { if (e.Row == null) { return; } ARStatementCycle row = (ARStatementCycle)e.Row; if (row.NextStmtDate.HasValue == false) { DateTime basisDate = row.LastStmtDate.HasValue? row.LastStmtDate.Value: Accessinfo.BusinessDate.HasValue? Accessinfo.BusinessDate.Value: DateTime.Now; row.NextStmtDate = CalcNextStatementDate(basisDate, row.PrepareOn, row.Day00, row.Day01); } ARSetup setup = this.ARSetup.Select(); PXCache.TryDispose(cache.GetAttributes(e.Row, null)); if (CheckForUnprocessedPPD(this, row.StatementCycleId, row.NextStmtDate, null)) { PXUIFieldAttribute.SetEnabled(cache, row, false); cache.RaiseExceptionHandling <FinPeriod.selected>(row, false, new PXSetPropertyException(Messages.UnprocessedPPDExists, PXErrorLevel.RowError)); return; } bool?hasOverdueInvoices = null; bool hasUnAppliedPayments = false; bool hasChargeableInvoices = false; if (row.RequirePaymentApplication ?? false) { hasOverdueInvoices = CheckForOverdueInvoices(this, row.StatementCycleId, row.NextStmtDate.Value); if (hasOverdueInvoices.Value) { if (CheckForOpenPayments(this, row.StatementCycleId)) { hasUnAppliedPayments = true; } } } // The third condition below conveys the 'hidden' meaning of // DefFinChargeFromCycle, i.e. 'attaching' overdue charges calculation // to statement cycles. // // If DefFinChargeFromCycle is false, it is assumed that the users take // care of overdue charges themselves and need not be warned. // - if ((row.FinChargeApply ?? false) && (row.RequireFinChargeProcessing ?? false) && (setup.DefFinChargeFromCycle ?? false)) { if (!hasOverdueInvoices.HasValue) { hasOverdueInvoices = CheckForOverdueInvoices(this, row.StatementCycleId, row.NextStmtDate.Value); } if (hasOverdueInvoices.Value && (!row.LastFinChrgDate.HasValue || row.LastFinChrgDate.Value < row.NextStmtDate.Value)) { hasChargeableInvoices = true; } } if (hasChargeableInvoices && hasUnAppliedPayments) { this.CyclesList.Cache.RaiseExceptionHandling <ARStatementCycle.statementCycleId>(row, row.StatementCycleId, new PXSetPropertyException(Messages.WRN_ProcessStatementDetectsOverdueInvoicesAndUnappliedPayments, PXErrorLevel.RowWarning)); } else if (hasChargeableInvoices) { this.CyclesList.Cache.RaiseExceptionHandling <ARStatementCycle.statementCycleId>(row, row.StatementCycleId, new PXSetPropertyException(Messages.WRN_ProcessStatementDetectsOverdueInvoices, PXErrorLevel.RowWarning)); } else if (hasUnAppliedPayments) { this.CyclesList.Cache.RaiseExceptionHandling <ARStatementCycle.statementCycleId>(row, row.StatementCycleId, new PXSetPropertyException(Messages.WRN_ProcessStatementDetectsUnappliedPayments, PXErrorLevel.RowWarning)); } }
protected virtual void GenerateStatementForCustomerFamily(StatementCreateBO statementGraph, ARStatementCycle cycle, IEnumerable <Customer> customers, DateTime statementDate, bool clearExisting) { var documentsList = new List <PXResult <ARRegister, ARInvoice> > { }; foreach (var customer in customers.OrderByDescending(c => c.ParentBAccountID)) { using (PXTransactionScope ts = new PXTransactionScope()) { Dictionary <Tuple <int, string, int, DateTime>, ARStatement> trace = new Dictionary <Tuple <int, string, int, DateTime>, ARStatement>(); if (clearExisting || customer.StatementLastDate == statementDate) { //Need to pass Prints and E-mail counts to the regenerated statement - for this reason we need to copy IEnumerable <ARStatement> deleted = this.DeleteCustomerStatement(cycle, customer, statementDate); trace = TraceToDict(deleted); } GenerateCustomerStatement(statementGraph, cycle, customer, statementDate, trace, documentsList); ts.Complete(); } } }
protected virtual void GenerateCustomerStatement(StatementCreateBO statementGraph, ARStatementCycle aCycle, Customer customer, DateTime aStatementDate, Dictionary <Tuple <int, string, int, DateTime>, ARStatement> statementsTrace, IList <PXResult <ARRegister, ARInvoice> > familyDocuments) { PXSelectBase <ARRegister> selectOpenDocs = new PXSelectJoin <ARRegister, LeftJoin <ARInvoice, On <ARInvoice.docType, Equal <ARRegister.docType>, And <ARInvoice.refNbr, Equal <ARRegister.refNbr> > > >, Where <ARRegister.customerID, Equal <Required <ARRegister.customerID> >, And <ARRegister.released, Equal <BQLConstants.BitOn>, And <ARRegister.docDate, LessEqual <Required <ARRegister.docDate> >, And <Where <ARRegister.openDoc, Equal <BQLConstants.BitOn>, Or <ARRegister.statementDate, IsNull> > > > > > >(this); PXSelectBase <ARStatementDetail> selectDocsStmDetail = new PXSelect <ARStatementDetail, Where <ARStatementDetail.customerID, Equal <Required <ARStatementDetail.customerID> >, And <ARStatementDetail.docType, Equal <Required <ARStatementDetail.docType> >, And <ARStatementDetail.refNbr, Equal <Required <ARStatementDetail.refNbr> > > > >, OrderBy <Asc <ARStatementDetail.statementDate> > >(this); PXSelectBase <ARStatement> selectAllPreviousByCustomer = new PXSelect <ARStatement, Where <ARStatement.customerID, Equal <Required <ARStatement.customerID> > >, OrderBy <Asc <ARStatement.curyID, Desc <ARStatement.statementDate> > > >(this); PXSelectBase <ARStatement> selectPreviousStatement = new PXSelect <ARStatement, Where <ARStatement.branchID, Equal <Required <ARStatement.branchID> >, And <ARStatement.customerID, Equal <Required <ARStatement.customerID> >, And <ARStatement.curyID, Equal <Required <ARStatement.curyID> > > > >, OrderBy <Desc <ARStatement.statementDate> > >(this); bool ageCredits = (this.ARSetup.Current.AgeCredits ?? false); bool isParent = customer.StatementCustomerID == customer.BAccountID; Dictionary <StatementKey, ARStatement> statements = new Dictionary <StatementKey, ARStatement>(); if (isParent) { foreach (PXResult <ARRegister, ARInvoice> res in familyDocuments) { ARRegister doc = res; StatementKey key = new StatementKey(doc.BranchID.Value, doc.CuryID); AddARStatement(statements, key, aCycle, customer, aStatementDate); } } List <ARStatementDetail> details = new List <ARStatementDetail>(); foreach (PXResult <ARRegister, ARInvoice> iDoc in selectOpenDocs.Select(customer.BAccountID, aStatementDate)) { ARRegister doc = iDoc; ARInvoice inv = iDoc; ARStatementDetail statementDetail = selectDocsStmDetail.Select(doc.CustomerID, doc.DocType, doc.RefNbr); bool isNewDoc = statementDetail == null; StatementKey key = new StatementKey(doc.BranchID.Value, doc.CuryID); familyDocuments.Add(iDoc); if (IsMultipleInstallmentMaster(inv)) { continue; //Skip invoice, which is the first in multiple installments sequence (master) } ARStatement header = AddARStatement(statements, key, aCycle, customer, aStatementDate); if (header.Processed != true) { ARStatement prevStatement = selectPreviousStatement.Select(header.BranchID, header.CustomerID, header.CuryID); if (prevStatement != null) { header.PrevStatementDate = prevStatement.StatementDate; } ARStatement trace; if (statementsTrace.TryGetValue(new Tuple <int, string, int, DateTime>(header.BranchID.Value, header.CuryID, header.CustomerID.Value, header.StatementDate.Value), out trace)) { header.PrevPrintedCnt = trace.PrevPrintedCnt; header.PrevEmailedCnt = trace.PrevEmailedCnt; } header.Processed = true; } ARStatementDetail det = new ARStatementDetail(); Copy(det, header); Copy(det, doc); if (doc.DocType != AR.ARDocType.CashSale && doc.DocType != AR.ARDocType.CashReturn) { var document = (doc.Payable == true ? inv : doc); if (header.StatementType == StatementTypes.CS_BALANCE_BROUGHT_FORWARD && isNewDoc) { header.EndBalance = (header.EndBalance ?? 0m) + document.SignBalance * document.OrigDocAmt; header.CuryEndBalance = (header.CuryEndBalance ?? 0m) + document.SignBalance * document.CuryOrigDocAmt; } else if (header.StatementType == StatementTypes.CS_OPEN_ITEM) { header.EndBalance = (header.EndBalance ?? 0m) + document.SignBalance * document.DocBal; header.CuryEndBalance = (header.CuryEndBalance ?? 0m) + document.SignBalance * document.CuryDocBal; } } details.Add(det); } if (isParent) { AccumulateAgeBalancesIntoStatements(familyDocuments, statements, ageCredits); } //Merge with previous statements - is needed for Balance Brought Forward Dictionary <StatementKey, DateTime> lastCuryStatement = new Dictionary <StatementKey, DateTime>(); foreach (ARStatement iPrev in selectAllPreviousByCustomer.Select(customer.BAccountID)) { StatementKey key = new StatementKey(iPrev.BranchID.Value, iPrev.CuryID); if (lastCuryStatement.ContainsKey(key) && lastCuryStatement[key] > iPrev.StatementDate) { continue; } ARStatement header = AddARStatement(statements, key, aCycle, customer, aStatementDate); header.BegBalance = iPrev.EndBalance; header.CuryBegBalance = iPrev.CuryEndBalance; Recalculate(header); lastCuryStatement[key] = iPrev.StatementDate.Value; } foreach (ARStatement iH in statements.Values) { ARStatement prev = selectPreviousStatement.Select(iH.CustomerID, iH.BranchID, iH.CuryID); if (prev != null) { iH.BegBalance = prev.EndBalance; iH.CuryBegBalance = prev.CuryEndBalance; } ApplyFIFORule(iH, ageCredits); } PersistStatement(statementGraph, customer.BAccountID, aStatementDate, statements.Values, details); }
protected virtual IEnumerable history() { this.History.Cache.Clear(); ARStatementHistoryParameters header = Filter.Current; if (header == null) { yield break; } int? prevCustomerID = null; string prevCuryID = null; HistoryResult prevRec = null; PXResultset <ARStatement> res; List <object> stored = new List <object>(); PXSelectBase <ARStatement> select = new PXSelectJoin <ARStatement, LeftJoin <ARStatementCycle, On <ARStatementCycle.statementCycleId, Equal <ARStatement.statementCycleId> >, LeftJoin <Customer, On <Customer.bAccountID, Equal <ARStatement.statementCustomerID> > > >, Where <ARStatement.statementCustomerID, Equal <ARStatement.customerID>, And <ARStatement.statementDate, GreaterEqual <Required <ARStatement.statementDate> >, And <ARStatement.statementDate, LessEqual <Required <ARStatement.statementDate> >, And <Where <ARStatement.statementCycleId, Equal <Required <ARStatement.statementCycleId> >, Or <Required <ARStatement.statementCycleId>, IsNull> > > > > >, OrderBy <Asc <ARStatement.statementCycleId, Asc <ARStatement.statementDate, Asc <ARStatement.customerID, Asc <ARStatement.curyID> > > > > >(this); using (new PXFieldScope(select.View, typeof(ARStatement.branchID), typeof(ARStatement.statementCycleId), typeof(ARStatement.statementDate), typeof(ARStatement.customerID), typeof(ARStatement.statementCustomerID), typeof(ARStatement.curyID), typeof(ARStatement.dontPrint), typeof(ARStatement.dontEmail), typeof(ARStatement.printed), typeof(ARStatement.emailed), typeof(ARStatementCycle.descr), typeof(Customer.printCuryStatements))) { res = select.Select(header.StartDate, header.EndDate, header.StatementCycleId, header.StatementCycleId); } foreach (PXResult <ARStatement, ARStatementCycle, Customer> item in res) { stored.Add(item); ARStatement st = item; ARStatementCycle cycle = item; Customer cust = item; HistoryResult rec = new HistoryResult { StatementCycleId = st.StatementCycleId, StatementDate = st.StatementDate, Descr = cycle.Descr, DontPrintCount = 0, DontEmailCount = 0, PrintedCount = 0, EmailedCount = 0, NoActionCount = 0 }; rec = (HistoryResult)this.History.Cache.Locate(rec) ?? this.History.Insert(rec); if (rec != null) { if (prevRec != rec) { prevCustomerID = null; prevCuryID = null; } if (prevCustomerID != st.CustomerID || (cust.PrintCuryStatements == true && prevCuryID != st.CuryID)) { rec.NumberOfDocuments += 1; rec.DontPrintCount += st.DontPrint == true ? 1 : 0; rec.DontEmailCount += st.DontEmail == true ? 1 : 0; rec.NoActionCount += st.DontEmail == true && st.DontPrint == true ? 1 : 0; rec.PrintedCount += st.Printed == true ? 1 : 0; rec.EmailedCount += st.Emailed == true ? 1 : 0; } prevRec = rec; prevCustomerID = st.CustomerID; prevCuryID = st.CuryID; } } select.StoreCached(new PXCommandKey(new object[] { header.StartDate, header.EndDate, header.StatementCycleId, header.StatementCycleId }), stored); this.History.Cache.IsDirty = false; foreach (HistoryResult ret in this.History.Cache.Inserted) { yield return(ret); } }
public static void ProcessDoc(ARPaymentEntry graph, ARStatementCycle cycle, ARAutoApplyParameters filter) { List <ARRegister> toRelease = new List <ARRegister>(); // Build Invoices List foreach (Customer customer in PXSelect <Customer, Where <Customer.statementCycleId, Equal <Required <Customer.statementCycleId> >, And <Match <Required <AccessInfo.userName> > > > > .Select(graph, cycle.StatementCycleId, graph.Accessinfo.UserName)) { List <ARInvoice> arInvoiceList = new List <ARInvoice>(); foreach (ARInvoice invoice in PXSelect <ARInvoice, Where <ARInvoice.customerID, Equal <Required <ARInvoice.customerID> >, And <ARInvoice.released, Equal <boolTrue>, And <ARInvoice.openDoc, Equal <boolTrue>, And <Where <ARInvoice.docType, Equal <Required <ARInvoice.docType> >, Or <ARInvoice.docType, Equal <Required <ARInvoice.docType> >, Or <ARInvoice.docType, Equal <Required <ARInvoice.docType> > > > > > > > >, OrderBy <Asc <ARInvoice.dueDate> > > .Select(graph, customer.BAccountID, ARDocType.Invoice, ARDocType.FinCharge, filter.ApplyCreditMemos == true ? ARDocType.DebitMemo : ARDocType.Invoice)) { arInvoiceList.Add(invoice); } arInvoiceList.Sort(new Comparison <ARInvoice>(delegate(ARInvoice a, ARInvoice b) { if ((bool)graph.arsetup.Current.FinChargeFirst) { int aSortOrder = (a.DocType == ARDocType.FinCharge ? 0 : 1); int bSortOrder = (b.DocType == ARDocType.FinCharge ? 0 : 1); int ret = ((IComparable)aSortOrder).CompareTo(bSortOrder); if (ret != 0) { return(ret); } } { object aDueDate = a.DueDate; object bDueDate = b.DueDate; int ret = ((IComparable)aDueDate).CompareTo(bDueDate); return(ret); } } )); if (arInvoiceList.Count > 0) { int invoiceIndex = 0; // this foreach gets all payments [and CreditMemos if applyCreditMemos = true] sorted by docDate foreach (ARPayment payment in PXSelect <ARPayment, Where <ARPayment.customerID, Equal <Required <ARPayment.customerID> >, And <ARPayment.released, Equal <boolTrue>, And <ARPayment.openDoc, Equal <boolTrue>, And <Where <ARPayment.docType, Equal <Required <ARPayment.docType> >, Or <ARPayment.docType, Equal <Required <ARPayment.docType> > > > > > > >, OrderBy <Asc <ARPayment.docDate> > > .Select(graph, customer.BAccountID, ARDocType.Payment, filter.ApplyCreditMemos == true ? ARDocType.CreditMemo : ARDocType.Payment)) { graph.Clear(); graph.Document.Current = payment; if (graph.Adjustments.Select().Count == 0) { bool adjustmentAdded = false; while (graph.Document.Current.CuryUnappliedBal > 0) { if (graph.Document.Current.CuryApplAmt == null) { object curyapplamt = graph.Document.Cache.GetValueExt <ARPayment.curyApplAmt>(graph.Document.Current); if (curyapplamt is PXFieldState) { curyapplamt = ((PXFieldState)curyapplamt).Value; } graph.Document.Current.CuryApplAmt = (decimal?)curyapplamt; } graph.Document.Current.AdjDate = filter.ApplicationDate; graph.Document.Current.AdjFinPeriodID = filter.FinPeriodID; graph.Document.Cache.Update(graph.Document.Current); ARInvoice invoice = arInvoiceList[invoiceIndex]; ARAdjust adj = new ARAdjust(); adj.AdjdDocType = invoice.DocType; adj.AdjdRefNbr = invoice.RefNbr; graph.AutoPaymentApp = true; adj = graph.Adjustments.Insert(adj); if (adj == null) { throw new PXException(PXMessages.LocalizeFormat(Messages.ErrorAutoApply, invoice.DocType, invoice.RefNbr, payment.DocType, payment.RefNbr)); } adjustmentAdded = true; if (adj.CuryDocBal <= 0m) { invoiceIndex++; } if (invoiceIndex >= arInvoiceList.Count) { break; } } if (adjustmentAdded) { graph.Save.Press(); if (filter.ReleaseBatchWhenFinished == true) { toRelease.Add(graph.Document.Current); } } } if (invoiceIndex >= arInvoiceList.Count) { break; } } } } if (toRelease.Count > 0) { ARDocumentRelease.ReleaseDoc(toRelease, false); } }
protected virtual void GenerateCustomerStatement(ARStatementCycle aCycle, Customer customer, DateTime aStatementDate, Dictionary <Tuple <int, string, int, DateTime>, ARStatement> statementsTrace) { PXSelectBase <Customer> selectCustomer = new PXSelect <Customer, Where <Customer.statementCycleId, Equal <Required <Customer.statementCycleId> > > >(this); PXSelectBase <ARRegister> selectOpenDocs = new PXSelectJoin <ARRegister, LeftJoin <ARInvoice, On <ARInvoice.docType, Equal <ARRegister.docType>, And <ARInvoice.refNbr, Equal <ARRegister.refNbr> > > >, Where <ARRegister.customerID, Equal <Required <ARRegister.customerID> >, And <ARRegister.released, Equal <BQLConstants.BitOn>, And <ARRegister.docDate, LessEqual <Required <ARRegister.docDate> >, And <Where <ARRegister.openDoc, Equal <BQLConstants.BitOn>, Or <ARRegister.statementDate, IsNull> > > > > > >(this); PXSelectBase <ARStatementDetail> selectDocsStmDetail = new PXSelect <ARStatementDetail, Where <ARStatementDetail.customerID, Equal <Required <ARStatementDetail.customerID> >, And <ARStatementDetail.docType, Equal <Required <ARStatementDetail.docType> >, And <ARStatementDetail.refNbr, Equal <Required <ARStatementDetail.refNbr> > > > >, OrderBy <Asc <ARStatementDetail.statementDate> > >(this); PXSelectBase <ARStatement> selectAllPreviousByCustomer = new PXSelect <ARStatement, Where <ARStatement.customerID, Equal <Required <ARStatement.customerID> > >, OrderBy <Asc <ARStatement.curyID, Desc <ARStatement.statementDate> > > >(this); PXSelectBase <ARStatement> selectPreviousStatement = new PXSelect <ARStatement, Where <ARStatement.branchID, Equal <Required <ARStatement.branchID> >, And <ARStatement.customerID, Equal <Required <ARStatement.customerID> >, And <ARStatement.curyID, Equal <Required <ARStatement.curyID> > > > >, OrderBy <Desc <ARStatement.statementDate> > >(this); bool ageCredits = (this.ARSetup.Current.AgeCredits ?? false); Dictionary <StatementKey, ARStatement> statements = new Dictionary <StatementKey, ARStatement>(); List <ARStatementDetail> details = new List <ARStatementDetail>(); foreach (PXResult <ARRegister, ARInvoice> iDoc in selectOpenDocs.Select(customer.BAccountID, aStatementDate)) { ARStatement header = null; ARRegister doc = (ARRegister)iDoc; ARInvoice inv = (ARInvoice)iDoc; ARStatementDetail statementDetail = (ARStatementDetail)selectDocsStmDetail.Select(doc.CustomerID, doc.DocType, doc.RefNbr); bool isNewDoc = (statementDetail == null); StatementKey key = new StatementKey(doc.BranchID.Value, doc.CuryID); if (IsMultipleInstallmentMaster(inv)) { continue; //Skip invoice, which is the first in multiple installments sequence (master) } if (!statements.ContainsKey(key)) { header = new ARStatement(); Clear(header); Copy(header, customer); Copy(header, aCycle); Copy(header, doc); header.StatementDate = aStatementDate; ARStatement trace = null; bool gotTrace = statementsTrace.TryGetValue(new Tuple <int, string, int, DateTime>(header.BranchID.Value, header.CuryID, header.CustomerID.Value, header.StatementDate.Value), out trace); if (gotTrace) { header.PrevPrintedCnt = trace.PrevPrintedCnt; header.PrevEmailedCnt = trace.PrevEmailedCnt; } statements[key] = header; } else { header = statements[key]; } ARStatementDetail det = new ARStatementDetail(); Copy(det, header); Copy(det, doc); if (doc.DocType != AR.ARDocType.CashSale && doc.DocType != AR.ARDocType.CashReturn) { Accumulate(header, (doc.Payable == true ? inv : doc), aCycle, isNewDoc, ageCredits); } details.Add(det); } //Merge with previous statements - is needed for Balance Brought Forward Dictionary <StatementKey, DateTime> lastCuryStatement = new Dictionary <StatementKey, DateTime>(); foreach (ARStatement iPrev in selectAllPreviousByCustomer.Select(customer.BAccountID)) { ARStatement header = null; StatementKey key = new StatementKey(iPrev.BranchID.Value, iPrev.CuryID); if (lastCuryStatement.ContainsKey(key) && lastCuryStatement[key] > iPrev.StatementDate) { continue; } if (!statements.ContainsKey(key)) { header = new ARStatement(); Clear(header); header.BranchID = iPrev.BranchID; header.CuryID = iPrev.CuryID; header.CustomerID = iPrev.CustomerID; header.StatementDate = aStatementDate; Copy(header, customer); Copy(header, aCycle); statements[key] = header; } else { header = statements[key]; } header.BegBalance = iPrev.EndBalance; header.CuryBegBalance = iPrev.CuryEndBalance; Recalculate(header); lastCuryStatement[key] = iPrev.StatementDate.Value; } foreach (ARStatement iH in statements.Values) { ARStatement prev = selectPreviousStatement.Select(iH.CustomerID, iH.BranchID, iH.CuryID); if (prev != null) { iH.BegBalance = prev.EndBalance; iH.CuryBegBalance = prev.CuryEndBalance; } ApplyFIFORule(iH, ageCredits); } PersistStatement(customer.BAccountID, aStatementDate, statements.Values, details); }
public static void ProcessDoc(ARPaymentEntry graph, ARStatementCycle cycle, ARAutoApplyParameters filter) { List<ARRegister> toRelease = new List<ARRegister>(); HashSet<string> trace = new HashSet<string>(); string warningRefNbr = String.Empty; int?[] branches = PXAccess.GetBranchIDs().Select(i => (int?)i).ToArray<int?>(); foreach (Customer customer in GetCustomersForAutoApplication(graph, cycle, filter)) { List<ARInvoice> arInvoiceList = new List<ARInvoice>(); var invoiceQuery = new PXSelectJoin<ARInvoice, InnerJoin<Customer, On<ARInvoice.customerID, Equal<Customer.bAccountID>>>, Where<ARInvoice.released, Equal<True>, And<ARInvoice.openDoc, Equal<True>, And<ARInvoice.pendingPPD, NotEqual<True>, And<Where<ARInvoice.docType, Equal<ARDocType.invoice>, Or<ARInvoice.docType, Equal<ARDocType.finCharge>, Or<ARInvoice.docType, Equal<ARDocType.debitMemo>>>>>>>>, OrderBy<Asc<ARInvoice.dueDate>>>(graph); if(filter.LoadChildDocuments == LoadChildDocumentsOptions.None || customer.ParentBAccountID != null) { invoiceQuery.WhereAnd<Where<Customer.bAccountID, Equal<Required<ARInvoice.customerID>>>>(); } else { invoiceQuery.WhereAnd<Where<Customer.consolidatingBAccountID, Equal<Required<ARInvoice.customerID>>>>(); } PXResultset<ARInvoice> invoices; using (new PXReadBranchRestrictedScope(null, branches, true, false)) { invoices = invoiceQuery.Select(customer.BAccountID); } foreach (ARInvoice invoice in invoices) { arInvoiceList.Add(invoice); } arInvoiceList.Sort(new Comparison<ARInvoice>(delegate(ARInvoice a, ARInvoice b) { if ((bool)graph.arsetup.Current.FinChargeFirst) { int aSortOrder = (a.DocType == ARDocType.FinCharge ? 0 : 1); int bSortOrder = (b.DocType == ARDocType.FinCharge ? 0 : 1); int ret = ((IComparable)aSortOrder).CompareTo(bSortOrder); if (ret != 0) { return ret; } } { object aDueDate = a.DueDate; object bDueDate = b.DueDate; int ret = ((IComparable)aDueDate).CompareTo(bDueDate); return ret; } } )); if (arInvoiceList.Count > 0) { PXSelectBase<ARPayment> getPaymentsQuery = new PXSelectJoin<ARPayment, InnerJoin<Branch, On<ARPayment.branchID, Equal<Branch.branchID>>, InnerJoin<OrganizationFinPeriod, On<Branch.organizationID, Equal<OrganizationFinPeriod.organizationID>, And<OrganizationFinPeriod.finPeriodID, Equal<Required<OrganizationFinPeriod.finPeriodID>>>>>>, Where< OrganizationFinPeriod.status, NotEqual<FinPeriod.status.locked>, And<OrganizationFinPeriod.status, NotEqual<FinPeriod.status.inactive>, And<ARPayment.released, Equal<True>, And<ARPayment.openDoc, Equal<True>, And<ARPayment.customerID, Equal<Required<ARPayment.customerID>>, And2<Not<HasUnreleasedVoidPayment<ARPayment.docType, ARPayment.refNbr>>, And<Where< ARPayment.docType, Equal<ARDocType.payment>, Or<ARPayment.docType, Equal<ARDocType.prepayment>, Or<ARPayment.docType, Equal<Required<ARPayment.docType>>>>>>>>>>>>, OrderBy< Asc<ARPayment.docDate>>>(graph); if (!graph.FinPeriodUtils.CanPostToClosedPeriod()) { getPaymentsQuery.WhereAnd<Where<OrganizationFinPeriod.status, NotEqual<FinPeriod.status.closed>>>(); } foreach (ARPayment payment in getPaymentsQuery.Select(filter.FinPeriodID, customer.BAccountID, filter.ApplyCreditMemos == true ? ARDocType.CreditMemo : ARDocType.Payment)) { ApplyPayment(graph, filter, payment, arInvoiceList, toRelease, out warningRefNbr); trace.Add(warningRefNbr); } } var remainingParentInvoices = arInvoiceList.Where(inv => inv.CustomerID == customer.BAccountID).ToList(); if (remainingParentInvoices.Count > 0 && filter.ApplyCreditMemos == true && filter.LoadChildDocuments == LoadChildDocumentsOptions.IncludeCRM) { PXSelectBase<ARPayment> getCreditMemosQuery = new PXSelectJoin<ARPayment, InnerJoin<Customer, On<ARPayment.customerID, Equal<Customer.bAccountID>>, InnerJoin<Branch, On<ARPayment.branchID, Equal<Branch.branchID>>, InnerJoin<OrganizationFinPeriod, On<Branch.organizationID, Equal<OrganizationFinPeriod.organizationID>, And<OrganizationFinPeriod.finPeriodID, Equal<Required<OrganizationFinPeriod.finPeriodID>>>>>>>, Where< OrganizationFinPeriod.status, NotEqual<FinPeriod.status.locked>, And<OrganizationFinPeriod.status, NotEqual<FinPeriod.status.inactive>, And<ARPayment.released, Equal<True>, And<ARPayment.openDoc, Equal<True>, And<Customer.consolidatingBAccountID, Equal<Required<Customer.consolidatingBAccountID>>, And<ARPayment.docType, Equal<ARDocType.creditMemo>, And<Not<HasUnreleasedVoidPayment<ARPayment.docType, ARPayment.refNbr>>>>>>>>>, OrderBy< Asc<ARPayment.docDate>>>(graph); if (!graph.FinPeriodUtils.CanPostToClosedPeriod()) { getCreditMemosQuery.WhereAnd<Where<OrganizationFinPeriod.status, NotEqual<FinPeriod.status.closed>>>(); } foreach (ARPayment payment in getCreditMemosQuery.Select(filter.FinPeriodID, customer.BAccountID)) { ApplyPayment(graph, filter, payment, remainingParentInvoices, toRelease, out warningRefNbr); trace.Add(warningRefNbr); } } } if (trace != null && trace.Count != 0) { PXTrace.WriteWarning(String.Format(Messages.FuturePayments, trace.Where(x => !x.IsNullOrEmpty()).JoinToString("; "))); trace.Clear(); } if (toRelease.Count > 0) { ARDocumentRelease.ReleaseDoc(toRelease, false); } }
public virtual void ARStatementCycle_RowSelected(PXCache cache, PXRowSelectedEventArgs e) { if (e.Row == null) { return; } ARStatementCycle row = (ARStatementCycle)e.Row; if (row.NextStmtDate.HasValue == false) { DateTime basisDate = row.LastStmtDate.HasValue? row.LastStmtDate.Value: Accessinfo.BusinessDate.HasValue? Accessinfo.BusinessDate.Value: DateTime.Now; row.NextStmtDate = CalcNextStatementDate(basisDate, row.PrepareOn, row.Day00, row.Day01); } ARSetup setup = this.ARSetup.Select(); cache.GetAttributes(e.Row, null); if (setup.DefFinChargeFromCycle ?? false) { bool?hasOverdueInvoices = null; bool hasUnAppliedPayments = false; bool hasChargeableInvoices = false; if (row.RequirePaymentApplication ?? false) { hasOverdueInvoices = CheckForOverdueInvoices(this, row.StatementCycleId, row.NextStmtDate.Value); if (hasOverdueInvoices.Value) { if (CheckForOpenPayments(this, row.StatementCycleId)) { hasUnAppliedPayments = true; } } } if ((row.FinChargeApply ?? false) && (row.RequireFinChargeProcessing ?? false)) { if (!hasOverdueInvoices.HasValue) { hasOverdueInvoices = CheckForOverdueInvoices(this, row.StatementCycleId, row.NextStmtDate.Value); } if (hasOverdueInvoices.Value && (!row.LastFinChrgDate.HasValue || row.LastFinChrgDate.Value < row.NextStmtDate.Value)) { hasChargeableInvoices = true; } } if (hasChargeableInvoices && hasUnAppliedPayments) { this.CyclesList.Cache.RaiseExceptionHandling <ARStatementCycle.statementCycleId>(row, row.StatementCycleId, new PXSetPropertyException(Messages.WRN_ProcessStatementDetectsOverdueInvoicesAndUnappliedPayments, PXErrorLevel.RowWarning)); } else { if (hasChargeableInvoices) { this.CyclesList.Cache.RaiseExceptionHandling <ARStatementCycle.statementCycleId>(row, row.StatementCycleId, new PXSetPropertyException(Messages.WRN_ProcessStatementDetectsOverdueInvoices, PXErrorLevel.RowWarning)); } if (hasUnAppliedPayments) { this.CyclesList.Cache.RaiseExceptionHandling <ARStatementCycle.statementCycleId>(row, row.StatementCycleId, new PXSetPropertyException(Messages.WRN_ProcessStatementDetectsUnappliedPayments, PXErrorLevel.RowWarning)); } } } }
public static void ProcessDoc(ARPaymentEntry graph, ARStatementCycle cycle, ARAutoApplyParameters filter) { List <ARRegister> toRelease = new List <ARRegister>(); foreach (Customer customer in GetCustomersForAutoApplication(graph, cycle, filter)) { List <ARInvoice> arInvoiceList = new List <ARInvoice>(); var invoiceQuery = new PXSelectJoin <ARInvoice, InnerJoin <Customer, On <ARInvoice.customerID, Equal <Customer.bAccountID> > >, Where <ARInvoice.released, Equal <True>, And <ARInvoice.openDoc, Equal <True>, And <ARInvoice.pendingPPD, NotEqual <True>, And <Where <ARInvoice.docType, Equal <ARDocType.invoice>, Or <ARInvoice.docType, Equal <ARDocType.finCharge>, Or <ARInvoice.docType, Equal <ARDocType.debitMemo> > > > > > > >, OrderBy <Asc <ARInvoice.dueDate> > >(graph); if (filter.LoadChildDocuments == LoadChildDocumentsOptions.None || customer.ParentBAccountID != null) { invoiceQuery.WhereAnd <Where <Customer.bAccountID, Equal <Required <ARInvoice.customerID> > > >(); } else { invoiceQuery.WhereAnd <Where <Customer.consolidatingBAccountID, Equal <Required <ARInvoice.customerID> > > >(); } foreach (ARInvoice invoice in invoiceQuery.Select( customer.BAccountID)) { arInvoiceList.Add(invoice); } arInvoiceList.Sort(new Comparison <ARInvoice>(delegate(ARInvoice a, ARInvoice b) { if ((bool)graph.arsetup.Current.FinChargeFirst) { int aSortOrder = (a.DocType == ARDocType.FinCharge ? 0 : 1); int bSortOrder = (b.DocType == ARDocType.FinCharge ? 0 : 1); int ret = ((IComparable)aSortOrder).CompareTo(bSortOrder); if (ret != 0) { return(ret); } } { object aDueDate = a.DueDate; object bDueDate = b.DueDate; int ret = ((IComparable)aDueDate).CompareTo(bDueDate); return(ret); } } )); if (arInvoiceList.Count > 0) { foreach (ARPayment payment in PXSelect <ARPayment, Where <ARPayment.released, Equal <True>, And <ARPayment.openDoc, Equal <True>, And <ARPayment.customerID, Equal <Required <ARPayment.customerID> >, And <Where <ARPayment.docType, Equal <ARDocType.payment>, Or <ARPayment.docType, Equal <ARDocType.prepayment>, Or <ARPayment.docType, Equal <Required <ARPayment.docType> > > > > > > > >, OrderBy <Asc <ARPayment.docDate> > > .Select(graph, customer.BAccountID, filter.ApplyCreditMemos == true ? ARDocType.CreditMemo : ARDocType.Payment)) { ApplyPayment(graph, filter, payment, arInvoiceList, toRelease); } } var remainingParentInvoices = arInvoiceList.Where(inv => inv.CustomerID == customer.BAccountID).ToList(); if (remainingParentInvoices.Count > 0 && filter.ApplyCreditMemos == true && filter.LoadChildDocuments == LoadChildDocumentsOptions.IncludeCRM) { foreach (ARPayment payment in PXSelectJoin <ARPayment, InnerJoin <Customer, On <ARPayment.customerID, Equal <Customer.bAccountID> > >, Where <ARPayment.released, Equal <True>, And <ARPayment.openDoc, Equal <True>, And <Customer.consolidatingBAccountID, Equal <Required <Customer.consolidatingBAccountID> >, And <ARPayment.docType, Equal <ARDocType.creditMemo> > > > >, OrderBy <Asc <ARPayment.docDate> > > .Select(graph, customer.BAccountID)) { ApplyPayment(graph, filter, payment, remainingParentInvoices, toRelease); } } } if (toRelease.Count > 0) { ARDocumentRelease.ReleaseDoc(toRelease, false); } }