use of org.compiere.model.MDunningLevel in project adempiere by adempiere.
the class DunningPrint method doIt.
// prepare
/**
* Process
* @return info
* @throws Exception
*/
protected String doIt() throws Exception {
log.info("C_DunningRun_ID=" + p_C_DunningRun_ID + ",R_MailText_ID=" + p_R_MailText_ID + ", EmailPDF=" + p_EMailPDF + ",IsOnlyIfBPBalance=" + p_IsOnlyIfBPBalance + ",PrintUnprocessedOnly=" + p_PrintUnprocessedOnly);
// Need to have Template
if (p_EMailPDF && p_R_MailText_ID == 0)
throw new AdempiereUserError("@NotFound@: @R_MailText_ID@");
// String subject = "";
MMailText mText = null;
if (p_EMailPDF) {
mText = new MMailText(getCtx(), p_R_MailText_ID, get_TrxName());
if (p_EMailPDF && mText.get_ID() == 0)
throw new AdempiereUserError("@NotFound@: @R_MailText_ID@ - " + p_R_MailText_ID);
// subject = mText.getMailHeader();
}
//
MDunningRun run = new MDunningRun(getCtx(), p_C_DunningRun_ID, get_TrxName());
if (run.get_ID() == 0)
throw new AdempiereUserError("@NotFound@: @C_DunningRun_ID@ - " + p_C_DunningRun_ID);
MClient client = MClient.get(getCtx());
int count = 0;
int errors = 0;
MDunningRunEntry[] entries = run.getEntries(false);
for (int i = 0; i < entries.length; i++) {
MDunningRunEntry entry = entries[i];
// Print Format on Dunning Level
MDunningLevel level = new MDunningLevel(getCtx(), entry.getC_DunningLevel_ID(), get_TrxName());
MPrintFormat format = null;
if (level.getDunning_PrintFormat_ID() > 0)
format = MPrintFormat.get(getCtx(), level.getDunning_PrintFormat_ID(), false);
if (p_IsOnlyIfBPBalance && entry.getAmt().signum() <= 0)
continue;
if (p_PrintUnprocessedOnly && entry.isProcessed())
continue;
// To BPartner
MBPartner bp = new MBPartner(getCtx(), entry.getC_BPartner_ID(), get_TrxName());
if (bp.get_ID() == 0) {
addLog(entry.get_ID(), null, null, "@NotFound@: @C_BPartner_ID@ " + entry.getC_BPartner_ID());
errors++;
continue;
}
// To User
MUser to = new MUser(getCtx(), entry.getAD_User_ID(), get_TrxName());
if (p_EMailPDF) {
if (to.get_ID() == 0) {
addLog(entry.get_ID(), null, null, "@NotFound@: @AD_User_ID@ - " + bp.getName());
errors++;
continue;
} else if (to.getEMail() == null || to.getEMail().length() == 0) {
addLog(entry.get_ID(), null, null, "@NotFound@: @EMail@ - " + to.getName());
errors++;
continue;
}
}
// query
MQuery query = new MQuery("C_Dunning_Header_v");
query.addRestriction("C_DunningRunEntry_ID", MQuery.EQUAL, new Integer(entry.getC_DunningRunEntry_ID()));
// Engine
PrintInfo info = new PrintInfo(bp.getName(), MDunningRunEntry.Table_ID, entry.getC_DunningRunEntry_ID(), entry.getC_BPartner_ID());
info.setDescription(bp.getName() + ", Amt=" + entry.getAmt());
ReportEngine re = null;
if (format != null)
re = new ReportEngine(getCtx(), format, query, info);
boolean printed = false;
if (p_EMailPDF) {
EMail email = client.createEMail(to.getEMail(), null, null);
if (!email.isValid()) {
addLog(entry.get_ID(), null, null, "@RequestActionEMailError@ Invalid EMail: " + to);
errors++;
continue;
}
// variable context
mText.setUser(to);
mText.setBPartner(bp);
mText.setPO(entry);
String message = mText.getMailText(true);
if (mText.isHtml())
email.setMessageHTML(mText.getMailHeader(), message);
else {
email.setSubject(mText.getMailHeader());
email.setMessageText(message);
}
//
if (re != null) {
File attachment = re.getPDF(File.createTempFile("Dunning", ".pdf"));
log.fine(to + " - " + attachment);
email.addAttachment(attachment);
}
//
String msg = email.send();
MUserMail um = new MUserMail(mText, entry.getAD_User_ID(), email);
um.saveEx();
if (msg.equals(EMail.SENT_OK)) {
addLog(entry.get_ID(), null, null, bp.getName() + " @RequestActionEMailOK@");
count++;
printed = true;
} else {
addLog(entry.get_ID(), null, null, bp.getName() + " @RequestActionEMailError@ " + msg);
errors++;
}
} else {
if (re != null) {
re.print();
count++;
printed = true;
}
}
if (printed) {
entry.setProcessed(true);
entry.save();
}
}
// for all dunning letters
if (errors == 0) {
run.setProcessed(true);
run.saveEx();
}
if (p_EMailPDF)
return "@Sent@=" + count + " - @Errors@=" + errors;
return "@Printed@=" + count;
}
use of org.compiere.model.MDunningLevel in project adempiere by adempiere.
the class DunningRunCreate method doIt.
// prepare
/**
* Process
* @return message
* @throws Exception
*/
protected String doIt() throws Exception {
log.info("C_DunningRun_ID=" + p_C_DunningRun_ID + ", Dispute=" + p_IncludeInDispute + ", C_BP_Group_ID=" + p_C_BP_Group_ID + ", C_BPartner_ID=" + p_C_BPartner_ID);
m_run = new MDunningRun(getCtx(), p_C_DunningRun_ID, get_TrxName());
if (m_run.get_ID() == 0)
throw new IllegalArgumentException("Not found MDunningRun");
if (!m_run.deleteEntries(true))
throw new IllegalArgumentException("Cannot delete existing entries");
if (p_SalesRep_ID == 0)
throw new IllegalArgumentException("No SalesRep");
if (p_C_Currency_ID == 0)
throw new IllegalArgumentException("No Currency");
//
for (MDunningLevel l_level : m_run.getLevels()) {
addInvoices(l_level);
addPayments(l_level);
if (l_level.isChargeFee())
addFees(l_level);
// we need to check whether this is a statement or not and some other rules
checkDunningEntry(l_level);
}
int entries = DB.getSQLValue(get_TrxName(), "SELECT COUNT(*) FROM C_DunningRunEntry WHERE C_DunningRun_ID=?", m_run.get_ID());
return "@C_DunningRunEntry_ID@ #" + entries;
}
use of org.compiere.model.MDunningLevel in project adempiere by adempiere.
the class DunningRunCreate method addInvoices.
// doIt
/**************************************************************************
* Add Invoices to Run
* @param level the Dunning level
* @return no of invoices
*/
private int addInvoices(MDunningLevel level) {
int count = 0;
String sql = "SELECT i.C_Invoice_ID, i.C_Currency_ID," + " i.GrandTotal*i.MultiplierAP," + " invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID)*MultiplierAP," + // ##1/2
" COALESCE(daysBetween(?,ips.DueDate),paymentTermDueDays(i.C_PaymentTerm_ID,i.DateInvoiced,?))," + " i.IsInDispute, i.C_BPartner_ID, i.C_InvoicePaySchedule_ID " + "FROM C_Invoice_v i " + " LEFT OUTER JOIN C_InvoicePaySchedule ips ON (i.C_InvoicePaySchedule_ID=ips.C_InvoicePaySchedule_ID) " + // ##3
"WHERE i.IsPaid='N' AND i.AD_Client_ID=?" + " AND i.DocStatus IN ('CO','CL')" + " AND (i.DunningGrace IS NULL OR i.DunningGrace<?) " + // Only BP(Group) with Dunning defined
" AND EXISTS (SELECT * FROM C_DunningLevel dl " + // // ##4
"WHERE dl.C_DunningLevel_ID=?" + " AND dl.C_Dunning_ID IN " + "(SELECT COALESCE(bp.C_Dunning_ID, bpg.C_Dunning_ID) " + "FROM C_BPartner bp" + " INNER JOIN C_BP_Group bpg ON (bp.C_BP_Group_ID=bpg.C_BP_Group_ID) " + "WHERE i.C_BPartner_ID=bp.C_BPartner_ID" + " AND (bp.DunningGrace IS NULL OR bp.DunningGrace<?)))";
if (p_C_BPartner_ID != 0)
// ##5
sql += " AND i.C_BPartner_ID=?";
else if (p_C_BP_Group_ID != 0)
sql += " AND EXISTS (SELECT * FROM C_BPartner bp " + // ##5
"WHERE i.C_BPartner_ID=bp.C_BPartner_ID AND bp.C_BP_Group_ID=?)";
if (p_OnlySOTrx)
sql += " AND i.IsSOTrx='Y'";
if (!p_IsAllCurrencies)
sql += " AND i.C_Currency_ID=" + p_C_Currency_ID;
if (p_AD_Org_ID != 0)
sql += " AND i.AD_Org_ID=" + p_AD_Org_ID;
// log.info(sql);
String sql2 = null;
// which this invoice is not yet included!
if (level.getParent().isCreateLevelsSequentially()) {
// Build a list of all topmost Dunning Levels
MDunningLevel[] previousLevels = level.getPreviousLevels();
if (previousLevels != null && previousLevels.length > 0) {
String sqlAppend = "";
for (MDunningLevel element : previousLevels) {
sqlAppend += " AND i.C_Invoice_ID IN (SELECT C_Invoice_ID FROM C_DunningRunLine WHERE " + "C_DunningRunEntry_ID IN (SELECT C_DunningRunEntry_ID FROM C_DunningRunEntry WHERE " + "C_DunningRun_ID IN (SELECT C_DunningRun_ID FROM C_DunningRunEntry WHERE " + "C_DunningLevel_ID=" + element.get_ID() + ")) AND Processed<>'N')";
}
sql += sqlAppend;
}
}
// ensure that we do only dunn what's not yet dunned, so we lookup the max of last Dunn Date which was processed
sql2 = "SELECT COUNT(*), COALESCE(DAYSBETWEEN(MAX(dr2.DunningDate), MAX(dr.DunningDate)),0)" + "FROM C_DunningRun dr2, C_DunningRun dr" + " INNER JOIN C_DunningRunEntry dre ON (dr.C_DunningRun_ID=dre.C_DunningRun_ID)" + " INNER JOIN C_DunningRunLine drl ON (dre.C_DunningRunEntry_ID=drl.C_DunningRunEntry_ID) " + // ##1 ##2
"WHERE dr2.C_DunningRun_ID=? AND drl.C_Invoice_ID=?";
BigDecimal DaysAfterDue = level.getDaysAfterDue();
int DaysBetweenDunning = level.getDaysBetweenDunning();
PreparedStatement pstmt = null;
PreparedStatement pstmt2 = null;
ResultSet rs = null;
try {
pstmt = DB.prepareStatement(sql, get_TrxName());
pstmt.setTimestamp(1, m_run.getDunningDate());
pstmt.setTimestamp(2, m_run.getDunningDate());
pstmt.setInt(3, m_run.getAD_Client_ID());
pstmt.setTimestamp(4, m_run.getDunningDate());
pstmt.setInt(5, level.getC_DunningLevel_ID());
pstmt.setTimestamp(6, m_run.getDunningDate());
if (p_C_BPartner_ID != 0)
pstmt.setInt(7, p_C_BPartner_ID);
else if (p_C_BP_Group_ID != 0)
pstmt.setInt(7, p_C_BP_Group_ID);
//
pstmt2 = DB.prepareStatement(sql2, get_TrxName());
//
rs = pstmt.executeQuery();
while (rs.next()) {
int C_Invoice_ID = rs.getInt(1);
int C_Currency_ID = rs.getInt(2);
BigDecimal GrandTotal = rs.getBigDecimal(3);
BigDecimal Open = rs.getBigDecimal(4);
int DaysDue = rs.getInt(5);
boolean IsInDispute = "Y".equals(rs.getString(6));
int C_BPartner_ID = rs.getInt(7);
int C_InvoicePaySchedule_ID = rs.getInt(8);
log.fine("DaysAfterDue: " + DaysAfterDue.intValue() + " isShowAllDue: " + level.isShowAllDue());
log.fine("C_Invoice_ID - DaysDue - GrandTotal: " + C_Invoice_ID + " - " + DaysDue + " - " + GrandTotal);
log.fine("C_InvoicePaySchedule_ID: " + C_InvoicePaySchedule_ID);
// Check for Dispute
if (!p_IncludeInDispute && IsInDispute)
continue;
// Check the day again based on rulesets
if (DaysDue > 0 && DaysDue < DaysAfterDue.intValue() && !level.isShowAllDue())
continue;
// Check for an open amount
if (Env.ZERO.compareTo(Open) == 0)
continue;
//
int TimesDunned = 0;
int DaysAfterLast = 0;
// SubQuery
pstmt2.setInt(1, m_run.get_ID());
pstmt2.setInt(2, C_Invoice_ID);
ResultSet rs2 = pstmt2.executeQuery();
if (rs2.next()) {
TimesDunned = rs2.getInt(1);
DaysAfterLast = rs2.getInt(2);
}
rs2.close();
// there is something which we really must Dunn.
if (DaysBetweenDunning != 0 && TimesDunned > 0 && DaysAfterLast < DaysBetweenDunning && !level.isShowAllDue() && !level.isShowNotDue())
continue;
// We don't want to show non due documents
if (DaysDue < 0 && !level.isShowNotDue())
continue;
// See also checkDunningEntry()
if (DaysAfterLast < DaysBetweenDunning)
TimesDunned = TimesDunned * -1;
//
if (createInvoiceLine(C_Invoice_ID, C_InvoicePaySchedule_ID, C_Currency_ID, GrandTotal, Open, DaysDue, IsInDispute, C_BPartner_ID, TimesDunned, DaysAfterLast, level.getC_DunningLevel_ID())) {
count++;
}
}
} catch (Exception e) {
log.log(Level.SEVERE, "addInvoices", e);
getProcessInfo().addLog(getProcessInfo().getAD_PInstance_ID(), null, null, e.getLocalizedMessage());
} finally {
DB.close(rs, pstmt);
rs = null;
pstmt = null;
pstmt2 = null;
}
return count;
}
Aggregations