IDEMPIERE-5119 Make Commission Calculation extensible (#1076)

* IDEMPIERE-5119 - Make variables and methods protected instead of private
* IDEMPIERE-5119 - Code refactor
* IDEMPIERE-5119 - Code refactor. Add submethods to ease readibility and increase extensibility
* IDEMPIERE-5119 - Fix typo
* IDEMPIERE-5119 - Add JavaDoc to the methods
This commit is contained in:
Diego Ruiz 2021-12-21 15:03:46 +01:00 committed by GitHub
parent 56d87ce984
commit 02c79d745c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 251 additions and 176 deletions

View File

@ -46,10 +46,10 @@ import org.compiere.util.Language;
@org.adempiere.base.annotation.Process @org.adempiere.base.annotation.Process
public class CommissionCalc extends SvrProcess public class CommissionCalc extends SvrProcess
{ {
private Timestamp p_StartDate; protected Timestamp p_StartDate;
// //
private Timestamp m_EndDate; protected Timestamp m_EndDate;
private MCommission m_com; protected MCommission m_com;
// //
/** /**
@ -77,37 +77,106 @@ public class CommissionCalc extends SvrProcess
*/ */
protected String doIt() throws Exception protected String doIt() throws Exception
{ {
checkParameters();
setStartEndDate();
MCommissionRun comRun = createCommissionRun();
for (MCommissionLine commissionLine : m_com.getLines())
{
// Amt for Line - Updated By Trigger
MCommissionAmt comAmt = new MCommissionAmt(comRun, commissionLine.getC_CommissionLine_ID());
comAmt.saveEx();
String sql = getCommissionCalculationSQL(commissionLine);
if (log.isLoggable(Level.FINE)) log.fine("Line=" + commissionLine.getLine() + " - " + sql);
createDetail(sql, comAmt);
comAmt.calculateCommission();
comAmt.saveEx();
} // for all commission lines
// Save Last Run
m_com.setDateLastRun (p_StartDate);
m_com.saveEx();
StringBuilder msgreturn = new StringBuilder("@C_CommissionRun_ID@ = ").append(comRun.getDocumentNo())
.append(" - ").append(comRun.getDescription());
return msgreturn.toString();
} // doIt
/**
* Check if the process parameters are valid
* @throws Exception if the commission record is not valid
*/
protected void checkParameters() {
if (log.isLoggable(Level.INFO)) log.info("C_Commission_ID=" + getRecord_ID() + ", StartDate=" + p_StartDate); if (log.isLoggable(Level.INFO)) log.info("C_Commission_ID=" + getRecord_ID() + ", StartDate=" + p_StartDate);
if (p_StartDate == null) if (p_StartDate == null)
p_StartDate = new Timestamp (System.currentTimeMillis()); p_StartDate = new Timestamp (System.currentTimeMillis());
m_com = new MCommission (getCtx(), getRecord_ID(), get_TrxName()); m_com = new MCommission (getCtx(), getRecord_ID(), get_TrxName());
if (m_com.get_ID() == 0) if (m_com.get_ID() == 0)
throw new AdempiereUserError ("No Commission"); throw new AdempiereUserError ("No Commission");
}
// Create Commission /**
MCommissionRun comRun = new MCommissionRun (m_com); * Creates the Commission run with the parameter start date
setStartEndDate(); * and sets the description
* @return MCommissionRun
*/
protected MCommissionRun createCommissionRun() {
MCommissionRun comRun = new MCommissionRun(m_com);
comRun.setStartDate(p_StartDate); comRun.setStartDate(p_StartDate);
comRun.setDescription(getCommissionRunDescription());
comRun.saveEx();
return comRun;
}
/**
* Returns the String that will be used for the description column
* in the Commission Run
* @return Description String
*/
protected String getCommissionRunDescription() {
// 01-Jan-2000 - 31-Jan-2001 - USD // 01-Jan-2000 - 31-Jan-2001 - USD
SimpleDateFormat format = DisplayType.getDateFormat(DisplayType.Date); SimpleDateFormat format = DisplayType.getDateFormat(DisplayType.Date);
StringBuilder description = new StringBuilder().append(format.format(p_StartDate)) StringBuilder description = new StringBuilder().append(format.format(p_StartDate))
.append(" - ").append(format.format(m_EndDate)) .append(" - ").append(format.format(m_EndDate))
.append(" - ").append(MCurrency.getISO_Code(getCtx(), m_com.getC_Currency_ID())); .append(" - ").append(MCurrency.getISO_Code(getCtx(), m_com.getC_Currency_ID()));
comRun.setDescription(description.toString()); return description.toString();
if (!comRun.save()) }
throw new AdempiereSystemError ("Could not save Commission Run");
MCommissionLine[] lines = m_com.getLines(); /**
for (int i = 0; i < lines.length; i++) * Creates the SQL statement string that is used to generate the
{ * Commission detail records
// Amt for Line - Updated By Trigger * @param MCommissionLine commissionLine
MCommissionAmt comAmt = new MCommissionAmt (comRun, lines[i].getC_CommissionLine_ID()); * @return SQL statement
if (!comAmt.save()) */
throw new AdempiereSystemError ("Could not save Commission Amt"); protected String getCommissionCalculationSQL(MCommissionLine commissionLine) {
//
StringBuilder sql = new StringBuilder(); StringBuilder sql = new StringBuilder();
if (MCommission.DOCBASISTYPE_Receipt.equals(m_com.getDocBasisType())) if (MCommission.DOCBASISTYPE_Receipt.equals(m_com.getDocBasisType()))
{ {
sql.append(getPaymentCommissionSQL());
}
else if (MCommission.DOCBASISTYPE_Order.equals(m_com.getDocBasisType()))
{
sql.append(getOrderCommissionSQL());
}
else // Invoice Basis
{
sql.append(getInvoiceCommissionSQL());
}
sql.append(getCommissionLineWhereClause(commissionLine));
// Grouping
if (!m_com.isListDetails())
sql.append(" GROUP BY h.C_Currency_ID");
return sql.toString();
}
/**
* Creates the SQL statement for payments (C_Payment)
* @return SQL statement
*/
protected String getPaymentCommissionSQL() {
StringBuilder sql = new StringBuilder();
if (m_com.isListDetails()) if (m_com.isListDetails())
{ {
sql.append("SELECT h.C_Currency_ID, CASE WHEN h.GrandTotal <> 0 ") sql.append("SELECT h.C_Currency_ID, CASE WHEN h.GrandTotal <> 0 ")
@ -145,9 +214,15 @@ public class CommissionCalc extends SvrProcess
.append(" AND p.AD_Client_ID = ?") .append(" AND p.AD_Client_ID = ?")
.append(" AND p.DateTrx BETWEEN ? AND ?"); .append(" AND p.DateTrx BETWEEN ? AND ?");
} }
return sql.toString();
} }
else if (MCommission.DOCBASISTYPE_Order.equals(m_com.getDocBasisType()))
{ /**
* Creates the SQL statement for orders (C_Order)
* @return SQL statement
*/
protected String getOrderCommissionSQL() {
StringBuilder sql = new StringBuilder();
if (m_com.isListDetails()) if (m_com.isListDetails())
{ {
sql.append("SELECT h.C_Currency_ID, l.LineNetAmt, l.QtyOrdered, ") sql.append("SELECT h.C_Currency_ID, l.LineNetAmt, l.QtyOrdered, ")
@ -173,9 +248,15 @@ public class CommissionCalc extends SvrProcess
.append(" AND h.AD_Client_ID = ?") .append(" AND h.AD_Client_ID = ?")
.append(" AND h.DateOrdered BETWEEN ? AND ?"); .append(" AND h.DateOrdered BETWEEN ? AND ?");
} }
return sql.toString();
} }
else // Invoice Basis
{ /**
* Creates the SQL statement for invoices (C_Invoice)
* @return SQL statement
*/
protected String getInvoiceCommissionSQL() {
StringBuilder sql = new StringBuilder();
if (m_com.isListDetails()) if (m_com.isListDetails())
{ {
sql.append("SELECT h.C_Currency_ID, l.LineNetAmt, l.QtyInvoiced, ") sql.append("SELECT h.C_Currency_ID, l.LineNetAmt, l.QtyInvoiced, ")
@ -201,9 +282,18 @@ public class CommissionCalc extends SvrProcess
.append(" AND h.AD_Client_ID = ?") .append(" AND h.AD_Client_ID = ?")
.append(" AND h.DateInvoiced BETWEEN ? AND ?"); .append(" AND h.DateInvoiced BETWEEN ? AND ?");
} }
return sql.toString();
} }
/**
* Creates the SQL WHERE clause based on the field values
* defined in the Commission Lien record
* @return SQL statement
*/
protected String getCommissionLineWhereClause(MCommissionLine commissionLine) {
StringBuilder sql = new StringBuilder();
// CommissionOrders/Invoices // CommissionOrders/Invoices
if (lines[i].isCommissionOrders()) if (commissionLine.isCommissionOrders())
{ {
MUser[] users = MUser.getOfBPartner(getCtx(), m_com.getC_BPartner_ID(), get_TrxName()); MUser[] users = MUser.getOfBPartner(getCtx(), m_com.getC_BPartner_ID(), get_TrxName());
if (users == null || users.length == 0) if (users == null || users.length == 0)
@ -222,52 +312,37 @@ public class CommissionCalc extends SvrProcess
} }
} }
// Organization // Organization
if (lines[i].getOrg_ID() != 0) if (commissionLine.getOrg_ID() != 0)
sql.append(" AND h.AD_Org_ID=").append(lines[i].getOrg_ID()); sql.append(" AND h.AD_Org_ID=").append(commissionLine.getOrg_ID());
// BPartner // BPartner
if (lines[i].getC_BPartner_ID() != 0) if (commissionLine.getC_BPartner_ID() != 0)
sql.append(" AND h.C_BPartner_ID=").append(lines[i].getC_BPartner_ID()); sql.append(" AND h.C_BPartner_ID=").append(commissionLine.getC_BPartner_ID());
// BPartner Group // BPartner Group
if (lines[i].getC_BP_Group_ID() != 0) if (commissionLine.getC_BP_Group_ID() != 0)
sql.append(" AND h.C_BPartner_ID IN ") sql.append(" AND h.C_BPartner_ID IN ")
.append("(SELECT C_BPartner_ID FROM C_BPartner WHERE C_BP_Group_ID=").append(lines[i].getC_BP_Group_ID()).append(")"); .append("(SELECT C_BPartner_ID FROM C_BPartner WHERE C_BP_Group_ID=").append(commissionLine.getC_BP_Group_ID()).append(")");
// Sales Region // Sales Region
if (lines[i].getC_SalesRegion_ID() != 0) if (commissionLine.getC_SalesRegion_ID() != 0)
sql.append(" AND h.C_BPartner_Location_ID IN ") sql.append(" AND h.C_BPartner_Location_ID IN ")
.append("(SELECT C_BPartner_Location_ID FROM C_BPartner_Location WHERE C_SalesRegion_ID=").append(lines[i].getC_SalesRegion_ID()).append(")"); .append("(SELECT C_BPartner_Location_ID FROM C_BPartner_Location WHERE C_SalesRegion_ID=").append(commissionLine.getC_SalesRegion_ID()).append(")");
// Product // Product
if (lines[i].getM_Product_ID() != 0) if (commissionLine.getM_Product_ID() != 0)
sql.append(" AND l.M_Product_ID=").append(lines[i].getM_Product_ID()); sql.append(" AND l.M_Product_ID=").append(commissionLine.getM_Product_ID());
// Product Category // Product Category
if (lines[i].getM_Product_Category_ID() != 0) if (commissionLine.getM_Product_Category_ID() != 0)
sql.append(" AND l.M_Product_ID IN ") sql.append(" AND l.M_Product_ID IN ")
.append("(SELECT M_Product_ID FROM M_Product WHERE M_Product_Category_ID=").append(lines[i].getM_Product_Category_ID()).append(")"); .append("(SELECT M_Product_ID FROM M_Product WHERE M_Product_Category_ID=").append(commissionLine.getM_Product_Category_ID()).append(")");
// Payment Rule // Payment Rule
if (lines[i].getPaymentRule() != null) if (commissionLine.getPaymentRule() != null)
sql.append(" AND h.PaymentRule='").append(lines[i].getPaymentRule()).append("'"); sql.append(" AND h.PaymentRule='").append(commissionLine.getPaymentRule()).append("'");
// Grouping
if (!m_com.isListDetails())
sql.append(" GROUP BY h.C_Currency_ID");
//
if (log.isLoggable(Level.FINE)) log.fine("Line=" + lines[i].getLine() + " - " + sql);
//
createDetail(sql.toString(), comAmt);
comAmt.calculateCommission();
comAmt.saveEx();
} // for all commission lines
// Save Last Run return sql.toString();
m_com.setDateLastRun (p_StartDate); }
m_com.saveEx();
StringBuilder msgreturn = new StringBuilder("@C_CommissionRun_ID@ = ").append(comRun.getDocumentNo())
.append(" - ").append(comRun.getDescription());
return msgreturn.toString();
} // doIt
/** /**
* Set Start and End Date * Set Start and End Date
*/ */
private void setStartEndDate() protected void setStartEndDate()
{ {
GregorianCalendar cal = new GregorianCalendar(Language.getLoginLanguage().getLocale()); GregorianCalendar cal = new GregorianCalendar(Language.getLoginLanguage().getLocale());
cal.setTimeInMillis(p_StartDate.getTime()); cal.setTimeInMillis(p_StartDate.getTime());
@ -334,7 +409,7 @@ public class CommissionCalc extends SvrProcess
* @param comAmt parent * @param comAmt parent
* @throws Exception * @throws Exception
*/ */
private void createDetail (String sql, MCommissionAmt comAmt) throws Exception protected void createDetail (String sql, MCommissionAmt comAmt) throws Exception
{ {
try (PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());) try (PreparedStatement pstmt = DB.prepareStatement(sql, get_TrxName());)
{ {