IDEMPIERE-2108 add an option for a minimum amount to create invoices process

This commit is contained in:
Carlos Ruiz 2014-07-30 23:20:09 +02:00
parent bbd6556f45
commit 6b391f688e
6 changed files with 114 additions and 22 deletions

View File

@ -0,0 +1,11 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Jul 30, 2014 10:11:38 AM CEST
-- IDEMPIERE-2108 add an option for a minimum amount to create invoices process
INSERT INTO AD_Process_Para (IsRange,AD_Process_Para_ID,AD_Process_Para_UU,AD_Process_ID,IsMandatory,EntityType,Name,ColumnName,Description,FieldLength,IsCentrallyMaintained,SeqNo,IsActive,UpdatedBy,Updated,CreatedBy,AD_Org_ID,IsEncrypted,AD_Client_ID,AD_Element_ID,AD_Reference_ID,Created) VALUES ('N',200107,'5dd9e63d-e70d-41c4-97ea-e6bb37015368',119,'N','D','Minimum Amt','MinimumAmt','Minimum Amount in Document Currency',22,'Y',60,'Y',100,TO_DATE('2014-07-30 10:11:37','YYYY-MM-DD HH24:MI:SS'),100,0,'N',0,2177,12,TO_DATE('2014-07-30 10:11:37','YYYY-MM-DD HH24:MI:SS'))
;
SELECT register_migration_script('201407301015_IDEMPIERE-2108.sql') FROM dual
;

View File

@ -0,0 +1,8 @@
-- Jul 30, 2014 10:11:38 AM CEST
-- IDEMPIERE-2108 add an option for a minimum amount to create invoices process
INSERT INTO AD_Process_Para (IsRange,AD_Process_Para_ID,AD_Process_Para_UU,AD_Process_ID,IsMandatory,EntityType,Name,ColumnName,Description,FieldLength,IsCentrallyMaintained,SeqNo,IsActive,UpdatedBy,Updated,CreatedBy,AD_Org_ID,IsEncrypted,AD_Client_ID,AD_Element_ID,AD_Reference_ID,Created) VALUES ('N',200107,'5dd9e63d-e70d-41c4-97ea-e6bb37015368',119,'N','D','Minimum Amt','MinimumAmt','Minimum Amount in Document Currency',22,'Y',60,'Y',100,TO_TIMESTAMP('2014-07-30 10:11:37','YYYY-MM-DD HH24:MI:SS'),100,0,'N',0,2177,12,TO_TIMESTAMP('2014-07-30 10:11:37','YYYY-MM-DD HH24:MI:SS'))
;
SELECT register_migration_script('201407301015_IDEMPIERE-2108.sql') FROM dual
;

View File

@ -19,7 +19,10 @@ package org.compiere.process;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException; import org.adempiere.exceptions.AdempiereException;
@ -43,6 +46,7 @@ import org.compiere.util.DisplayType;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Language; import org.compiere.util.Language;
import org.compiere.util.Msg; import org.compiere.util.Msg;
import org.compiere.util.Trx;
/** /**
* Generate Invoices * Generate Invoices
@ -77,6 +81,12 @@ public class InvoiceGenerate extends SvrProcess
private int m_line = 0; private int m_line = 0;
/** Business Partner */ /** Business Partner */
private MBPartner m_bp = null; private MBPartner m_bp = null;
/** Minimum Amount to Invoice */
private BigDecimal p_MinimumAmt = null;
/** Minimum Amount to Invoice according to Invoice Schedule */
private BigDecimal p_MinimumAmtInvSched = null;
/** Per Invoice Savepoint */
private Savepoint m_savepoint = null;
/** /**
* Prepare - e.g., get Parameters. * Prepare - e.g., get Parameters.
@ -103,6 +113,8 @@ public class InvoiceGenerate extends SvrProcess
p_ConsolidateDocument = "Y".equals(para[i].getParameter()); p_ConsolidateDocument = "Y".equals(para[i].getParameter());
else if (name.equals("DocAction")) else if (name.equals("DocAction"))
p_docAction = (String)para[i].getParameter(); p_docAction = (String)para[i].getParameter();
else if (name.equals("MinimumAmt"))
p_MinimumAmt = para[i].getParameterAsBigDecimal();
else else
log.log(Level.SEVERE, "Unknown Parameter: " + name); log.log(Level.SEVERE, "Unknown Parameter: " + name);
} }
@ -198,6 +210,7 @@ public class InvoiceGenerate extends SvrProcess
rs = pstmt.executeQuery (); rs = pstmt.executeQuery ();
while (rs.next ()) while (rs.next ())
{ {
p_MinimumAmtInvSched = null;
MOrder order = new MOrder (getCtx(), rs, get_TrxName()); MOrder order = new MOrder (getCtx(), rs, get_TrxName());
StringBuilder msgsup = new StringBuilder(Msg.getMsg(getCtx(), "Processing")).append(" ").append(order.getDocumentInfo()); StringBuilder msgsup = new StringBuilder(Msg.getMsg(getCtx(), "Processing")).append(" ").append(order.getDocumentInfo());
statusUpdate(msgsup.toString()); statusUpdate(msgsup.toString());
@ -223,11 +236,14 @@ public class InvoiceGenerate extends SvrProcess
else else
{ {
MInvoiceSchedule is = MInvoiceSchedule.get(getCtx(), m_bp.getC_InvoiceSchedule_ID(), get_TrxName()); MInvoiceSchedule is = MInvoiceSchedule.get(getCtx(), m_bp.getC_InvoiceSchedule_ID(), get_TrxName());
if (is.canInvoice(order.getDateOrdered(), order.getGrandTotal())) if (is.canInvoice(order.getDateOrdered())) {
if (is.isAmount() && is.getAmt() != null)
p_MinimumAmtInvSched = is.getAmt();
doInvoice = true; doInvoice = true;
else } else {
continue; continue;
} }
}
} // Schedule } // Schedule
// After Delivery // After Delivery
@ -352,6 +368,13 @@ public class InvoiceGenerate extends SvrProcess
{ {
if (m_invoice == null) if (m_invoice == null)
{ {
try {
if (m_savepoint != null)
Trx.get(get_TrxName(), false).releaseSavepoint(m_savepoint);
m_savepoint = Trx.get(get_TrxName(), false).setSavepoint(null);
} catch (SQLException e) {
throw new AdempiereException(e);
}
m_invoice = new MInvoice (order, 0, p_DateInvoiced); m_invoice = new MInvoice (order, 0, p_DateInvoiced);
if (!m_invoice.save()) if (!m_invoice.save())
throw new IllegalStateException("Could not create Invoice (o)"); throw new IllegalStateException("Could not create Invoice (o)");
@ -377,6 +400,13 @@ public class InvoiceGenerate extends SvrProcess
{ {
if (m_invoice == null) if (m_invoice == null)
{ {
try {
if (m_savepoint != null)
Trx.get(get_TrxName(), false).releaseSavepoint(m_savepoint);
m_savepoint = Trx.get(get_TrxName(), false).setSavepoint(null);
} catch (SQLException e) {
throw new AdempiereException(e);
}
m_invoice = new MInvoice (order, 0, p_DateInvoiced); m_invoice = new MInvoice (order, 0, p_DateInvoiced);
if (!m_invoice.save()) if (!m_invoice.save())
throw new IllegalStateException("Could not create Invoice (s)"); throw new IllegalStateException("Could not create Invoice (s)");
@ -486,6 +516,28 @@ public class InvoiceGenerate extends SvrProcess
} }
} }
if ( (p_MinimumAmt != null && p_MinimumAmt.signum() != 0
&& m_invoice.getGrandTotal().compareTo(p_MinimumAmt) < 0)
|| (p_MinimumAmtInvSched != null
&& m_invoice.getGrandTotal().compareTo(p_MinimumAmtInvSched) < 0)) {
// minimum amount not reached
DecimalFormat format = DisplayType.getNumberFormat(DisplayType.Amount);
String amt = format.format(m_invoice.getGrandTotal().doubleValue());
String message = Msg.parseTranslation(getCtx(), "@NotInvoicedAmt@ " + amt + " - " + m_invoice.getC_BPartner().getName());
addLog(message);
if (m_savepoint != null) {
try {
Trx.get(get_TrxName(), false).rollback(m_savepoint);
} catch (SQLException e) {
throw new AdempiereException(e);
}
} else {
throw new AdempiereException("No savepoint");
}
} else {
if (!m_invoice.processIt(p_docAction)) if (!m_invoice.processIt(p_docAction))
{ {
log.warning("completeInvoice - failed: " + m_invoice); log.warning("completeInvoice - failed: " + m_invoice);
@ -499,6 +551,7 @@ public class InvoiceGenerate extends SvrProcess
addBufferLog(m_invoice.getC_Invoice_ID(), m_invoice.getDateInvoiced(), null, message, m_invoice.get_Table_ID(), m_invoice.getC_Invoice_ID()); addBufferLog(m_invoice.getC_Invoice_ID(), m_invoice.getDateInvoiced(), null, message, m_invoice.get_Table_ID(), m_invoice.getC_Invoice_ID());
m_created++; m_created++;
} }
}
m_invoice = null; m_invoice = null;
m_ship = null; m_ship = null;
m_line = 0; m_line = 0;

View File

@ -1046,11 +1046,13 @@ public class MInvoice extends X_C_Invoice implements DocAction
// reset shipment line invoiced flag // reset shipment line invoiced flag
MInvoiceLine[] lines = getLines(false); MInvoiceLine[] lines = getLines(false);
for (int i = 0; i < lines.length; i++) { for (int i = 0; i < lines.length; i++) {
if (lines[i].getM_InOutLine_ID() > 0) {
MInOutLine sLine = new MInOutLine(getCtx(), lines[i].getM_InOutLine_ID(), get_TrxName()); MInOutLine sLine = new MInOutLine(getCtx(), lines[i].getM_InOutLine_ID(), get_TrxName());
sLine.setIsInvoiced(false); sLine.setIsInvoiced(false);
sLine.saveEx(); sLine.saveEx();
} }
} }
}
return true; return true;
} //afterDelete } //afterDelete

View File

@ -91,6 +91,9 @@ public class MInvoiceSchedule extends X_C_InvoiceSchedule
* @param orderAmt order amount * @param orderAmt order amount
* @return true if I can send Invoice * @return true if I can send Invoice
*/ */
@Deprecated
// Deprecation note: consider using just canInvoice(Timestamp)
// validating the order amount doesn't make sense as the total must be calculated based on shipments
public boolean canInvoice (Timestamp xDate, BigDecimal orderAmt) public boolean canInvoice (Timestamp xDate, BigDecimal orderAmt)
{ {
// Amount // Amount
@ -98,6 +101,16 @@ public class MInvoiceSchedule extends X_C_InvoiceSchedule
&& orderAmt.compareTo(getAmt()) >= 0) && orderAmt.compareTo(getAmt()) >= 0)
return true; return true;
return canInvoice(xDate);
} // canInvoice
/**
* Can I send Invoice
* @param xDate date
* @return true if I can send Invoice
*/
public boolean canInvoice (Timestamp xDate)
{
// Daily // Daily
if (INVOICEFREQUENCY_Daily.equals(getInvoiceFrequency())) if (INVOICEFREQUENCY_Daily.equals(getInvoiceFrequency()))
return true; return true;

View File

@ -608,9 +608,14 @@ public class ProcessInfo implements Serializable
{ {
if (m_logs == null) if (m_logs == null)
return null; return null;
int[] ids = new int[m_logs.size()]; ArrayList<Integer> idsarray = new ArrayList<Integer>();
for (int i = 0; i < m_logs.size(); i++) for (int i = 0; i < m_logs.size(); i++) {
ids[i] = m_logs.get(i).getP_ID(); if (m_logs.get(i).getP_ID() > 0)
idsarray.add(m_logs.get(i).getP_ID());
}
int[] ids = new int[idsarray.size()];
for (int i = 0; i < idsarray.size(); i++)
ids[i] = idsarray.get(i);
return ids; return ids;
} // getIDs } // getIDs