hg merge release-6.2 (merge release6.2 into default)

This commit is contained in:
Carlos Ruiz 2019-09-21 12:57:50 +02:00
commit 6133471c1b
17 changed files with 687 additions and 196 deletions

View File

@ -0,0 +1,42 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-4006 Wrong matched PO quanity for vendor credit memo
-- Sep 3, 2019, 5:51:11 PM SGT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203363,0,0,'Y',TO_DATE('2019-09-03 17:51:10','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-09-03 17:51:10','YYYY-MM-DD HH24:MI:SS'),100,'Ref_MatchPO_ID','Referenced Match PO','Referenced Match PO','D','880834ea-81fe-4813-95de-7390350cee95')
;
-- Sep 3, 2019, 5:51:15 PM SGT
UPDATE AD_Element SET EntityType='D',Updated=TO_DATE('2019-09-03 17:51:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203363
;
-- Sep 3, 2019, 5:52:04 PM SGT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (214044,0,'Referenced Match PO',473,'Ref_MatchPO_ID',10,'N','N','N','N','N',0,'N',30,200017,0,0,'Y',TO_DATE('2019-09-03 17:52:03','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-09-03 17:52:03','YYYY-MM-DD HH24:MI:SS'),100,203363,'Y','N','D','N','N','N','Y','50fc1a1d-5bb0-4631-94c3-92c2fa9ec13a','Y',0,'N','N','N','N')
;
-- Sep 3, 2019, 5:52:16 PM SGT
UPDATE AD_Column SET EntityType='D',Updated=TO_DATE('2019-09-03 17:52:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214044
;
-- Sep 3, 2019, 5:52:21 PM SGT
UPDATE AD_Column SET FKConstraintName='RefMatchPO_MMatchPO', FKConstraintType='N',Updated=TO_DATE('2019-09-03 17:52:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214044
;
-- Sep 3, 2019, 5:52:21 PM SGT
ALTER TABLE M_MatchPO ADD Ref_MatchPO_ID NUMBER(10) DEFAULT NULL
;
-- Sep 3, 2019, 5:52:22 PM SGT
ALTER TABLE M_MatchPO ADD CONSTRAINT RefMatchPO_MMatchPO FOREIGN KEY (Ref_MatchPO_ID) REFERENCES m_matchpo(m_matchpo_id) DEFERRABLE INITIALLY DEFERRED
;
-- Sep 4, 2019, 5:39:23 PM SGT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (206171,'Referenced Match PO',409,214044,'Y',10,180,'N','N','N','N',0,0,'Y',TO_DATE('2019-09-04 17:39:22','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-09-04 17:39:22','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','e69ff166-dfc2-4b3d-b432-744b10440827','Y',180,2)
;
-- Sep 4, 2019, 5:41:04 PM SGT
UPDATE AD_Field SET SeqNo=65, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, SeqNoGrid=65, XPosition=4, IsToolbarButton=NULL,Updated=TO_DATE('2019-09-04 17:41:04','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206171
;
SELECT register_migration_script('201909061600_IDEMPIERE-4006.sql') FROM dual
;

View File

@ -0,0 +1,10 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-2134 - Issues found on Payment Selection process : PayAmt is null
-- 2019-09-16 09:28:03
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Could not find Payment Amount for some invoices, maybe currency rate is not configured',0,0,'Y',TO_DATE('2019-09-16 09:28:02','YYYY-MM-DD HH24:MI:SS'),0,TO_DATE('2019-09-16 09:28:02','YYYY-MM-DD HH24:MI:SS'),0,200563,'PaySelectionPayAmtIsNull','D','6a5563d2-ddcc-4244-a6e8-3a85d93e08b1')
;
SELECT register_migration_script('201909160930_IDEMPIERE-2134_FixPayAmtIsNull.sql') FROM dual
;

View File

@ -0,0 +1,39 @@
-- IDEMPIERE-4006 Wrong matched PO quanity for vendor credit memo
-- Sep 3, 2019, 5:51:11 PM SGT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203363,0,0,'Y',TO_TIMESTAMP('2019-09-03 17:51:10','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-09-03 17:51:10','YYYY-MM-DD HH24:MI:SS'),100,'Ref_MatchPO_ID','Referenced Match PO','Referenced Match PO','D','880834ea-81fe-4813-95de-7390350cee95')
;
-- Sep 3, 2019, 5:51:15 PM SGT
UPDATE AD_Element SET EntityType='D',Updated=TO_TIMESTAMP('2019-09-03 17:51:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203363
;
-- Sep 3, 2019, 5:52:04 PM SGT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (214044,0,'Referenced Match PO',473,'Ref_MatchPO_ID',10,'N','N','N','N','N',0,'N',30,200017,0,0,'Y',TO_TIMESTAMP('2019-09-03 17:52:03','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-09-03 17:52:03','YYYY-MM-DD HH24:MI:SS'),100,203363,'Y','N','D','N','N','N','Y','50fc1a1d-5bb0-4631-94c3-92c2fa9ec13a','Y',0,'N','N','N','N')
;
-- Sep 3, 2019, 5:52:16 PM SGT
UPDATE AD_Column SET EntityType='D',Updated=TO_TIMESTAMP('2019-09-03 17:52:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214044
;
-- Sep 3, 2019, 5:52:21 PM SGT
UPDATE AD_Column SET FKConstraintName='RefMatchPO_MMatchPO', FKConstraintType='N',Updated=TO_TIMESTAMP('2019-09-03 17:52:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214044
;
-- Sep 3, 2019, 5:52:21 PM SGT
ALTER TABLE M_MatchPO ADD COLUMN Ref_MatchPO_ID NUMERIC(10) DEFAULT NULL
;
-- Sep 3, 2019, 5:52:22 PM SGT
ALTER TABLE M_MatchPO ADD CONSTRAINT RefMatchPO_MMatchPO FOREIGN KEY (Ref_MatchPO_ID) REFERENCES m_matchpo(m_matchpo_id) DEFERRABLE INITIALLY DEFERRED
;
-- Sep 4, 2019, 5:39:23 PM SGT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (206171,'Referenced Match PO',409,214044,'Y',10,180,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2019-09-04 17:39:22','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-09-04 17:39:22','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','e69ff166-dfc2-4b3d-b432-744b10440827','Y',180,2)
;
-- Sep 4, 2019, 5:41:04 PM SGT
UPDATE AD_Field SET SeqNo=65, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, SeqNoGrid=65, XPosition=4, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2019-09-04 17:41:04','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206171
;
SELECT register_migration_script('201909061600_IDEMPIERE-4006.sql') FROM dual
;

View File

@ -0,0 +1,7 @@
-- IDEMPIERE-2134 - Issues found on Payment Selection process : PayAmt is null
-- 2019-09-16 09:28:03
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Could not find Payment Amount for some invoices, maybe currency rate is not configured',0,0,'Y',TO_TIMESTAMP('2019-09-16 09:28:02','YYYY-MM-DD HH24:MI:SS'),0,TO_TIMESTAMP('2019-09-16 09:28:02','YYYY-MM-DD HH24:MI:SS'),0,200563,'PaySelectionPayAmtIsNull','D','6a5563d2-ddcc-4244-a6e8-3a85d93e08b1')
;
SELECT register_migration_script('201909160930_IDEMPIERE-2134_FixPayAmtIsNull.sql') FROM dual
;

View File

@ -19,6 +19,7 @@ package org.compiere.process;
import java.util.logging.Level;
import org.compiere.model.MMatchInv;
import org.compiere.model.MMatchPO;
import org.compiere.util.AdempiereUserError;
import org.compiere.util.CLogger;
import org.compiere.util.ValueNamePair;
@ -51,19 +52,28 @@ public class MatchInvDelete extends SvrProcess
protected String doIt() throws Exception
{
if (log.isLoggable(Level.INFO)) log.info ("M_MatchInv_ID=" + p_M_MatchInv_ID);
String msg = "";
MMatchInv inv = new MMatchInv (getCtx(), p_M_MatchInv_ID, get_TrxName());
if (inv.get_ID() == 0)
throw new AdempiereUserError("@NotFound@ @M_MatchInv_ID@ " + p_M_MatchInv_ID);
if (inv.delete(true))
return "@OK@";
String msg = null;
ValueNamePair err = CLogger.retrieveError();
if (err != null)
msg = err.getName();
if (msg == null || msg.length() == 0)
msg = " - Check log";
return "@Error@: " + msg;
int reversalId = inv.getReversal_ID();
if (!inv.delete(true))
return "@Error@";
msg += "@Deleted@";
if (reversalId > 0) {
MMatchInv invrev = new MMatchInv (getCtx(), reversalId, get_TrxName());
if (invrev.get_ID() == 0)
throw new AdempiereUserError("@NotFound@ @M_MatchInv_ID@ " + reversalId);
if (!invrev.delete(true)) {
return "@Error@ @Reversal_ID@";
}
msg += " + @Deleted@ @Reversal_ID@";
}
return msg;
} // doIt
} // MatchInvDelete

View File

@ -25,6 +25,7 @@ import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.compiere.model.MInvoice;
import org.compiere.model.MPaySelection;
import org.compiere.model.MPaySelectionLine;
import org.compiere.model.X_C_Order;
@ -271,6 +272,10 @@ public class PaySelectionCreateFrom extends SvrProcess
{
int C_Invoice_ID = rs.getInt(1);
BigDecimal PayAmt = rs.getBigDecimal(2);
if (PayAmt == null)
return "@Error@ @PaySelectionPayAmtIsNull@ (" + new MInvoice(getCtx(), C_Invoice_ID, get_TrxName()).getDocumentInfo() + ")";
if (C_Invoice_ID == 0 || Env.ZERO.compareTo(PayAmt) == 0)
continue;
BigDecimal DiscountAmt = rs.getBigDecimal(3);

View File

@ -41,6 +41,7 @@ import org.compiere.model.MOrderLandedCostAllocation;
import org.compiere.model.MOrderLine;
import org.compiere.model.MProduct;
import org.compiere.model.MTax;
import org.compiere.model.MatchPOAutoMatch;
import org.compiere.model.ProductCost;
import org.compiere.model.X_M_InOut;
import org.compiere.process.DocAction;
@ -114,7 +115,7 @@ public class Doc_MatchPO extends Doc
List<MMatchPO> noInvoiceLines = new ArrayList<MMatchPO>();
Map<Integer, BigDecimal[]> noShipmentLines = new HashMap<>();
Map<Integer, BigDecimal[]> postedNoShipmentLines = new HashMap<>();
MMatchPO[] matchPOs = MMatchPO.getOrderLine(getCtx(), m_oLine.getC_OrderLine_ID(), getTrxName());
List<MMatchPO> matchPOs = MatchPOAutoMatch.getNotMatchedMatchPOList(getCtx(), m_oLine.getC_OrderLine_ID(), getTrxName());
for (MMatchPO matchPO : matchPOs)
{
if (matchPO.getM_InOutLine_ID() > 0 && matchPO.getC_InvoiceLine_ID() == 0 && matchPO.getReversal_ID()==0)
@ -188,7 +189,8 @@ public class Doc_MatchPO extends Doc
if (m_M_InOutLine_ID == 0) // Defer posting if not matched to Shipment
{
m_deferPosting = true;
if (m_matchPO.getRef_MatchPO_ID() == 0)
m_deferPosting = true;
}
else
{
@ -264,6 +266,9 @@ public class Doc_MatchPO extends Doc
if (m_M_InOutLine_ID == 0) // No posting if not matched to Shipment
{
if (m_matchPO.getRef_MatchPO_ID() > 0)
return facts;
p_Error = "No posting if not matched to Shipment";
return null;
}

View File

@ -327,6 +327,17 @@ public interface I_M_MatchPO
*/
public BigDecimal getQty();
/** Column name Ref_MatchPO_ID */
public static final String COLUMNNAME_Ref_MatchPO_ID = "Ref_MatchPO_ID";
/** Set Referenced Match PO */
public void setRef_MatchPO_ID (int Ref_MatchPO_ID);
/** Get Referenced Match PO */
public int getRef_MatchPO_ID();
public org.compiere.model.I_M_MatchPO getRef_MatchPO() throws RuntimeException;
/** Column name Reversal_ID */
public static final String COLUMNNAME_Reversal_ID = "Reversal_ID";

View File

@ -642,10 +642,20 @@ public class MInOutLine extends X_M_InOutLine
*/
protected boolean beforeDelete ()
{
if (getParent().getDocStatus().equals(MInOut.DOCSTATUS_Drafted))
return true;
log.saveError("Error", Msg.getMsg(getCtx(), "CannotDelete"));
return false;
if (! getParent().getDocStatus().equals(MInOut.DOCSTATUS_Drafted)) {
log.saveError("Error", Msg.getMsg(getCtx(), "CannotDelete"));
return false;
}
// IDEMPIERE-3391 Not possible to delete a line in the Material Receipt window
List<MInvoiceLine> ils = new Query(getCtx(), MInvoiceLine.Table_Name, "M_InOutLine_ID=?", get_TrxName())
.setParameters(getM_InOutLine_ID())
.list();
ils.forEach(il -> {
il.setM_InOutLine_ID(-1);
il.saveEx();
});
//
return true;
} // beforeDelete
/**

View File

@ -1144,6 +1144,7 @@ public class MInvoice extends X_C_Invoice implements DocAction
int no = DB.executeUpdate(sql.toString(), get_TrxName());
if (log.isLoggable(Level.FINE)) log.fine("Lines -> #" + no);
}
return true;
} // afterSave
@ -1831,10 +1832,11 @@ public class MInvoice extends X_C_Invoice implements DocAction
&& !isReversal())
{
MInOutLine receiptLine = new MInOutLine (getCtx(),line.getM_InOutLine_ID(), get_TrxName());
BigDecimal matchQty = line.getQtyInvoiced();
BigDecimal movementQty = receiptLine.getM_InOut().getMovementType().charAt(1) == '-' ? receiptLine.getMovementQty().negate() : receiptLine.getMovementQty();
BigDecimal matchQty = isCreditMemo() ? line.getQtyInvoiced().negate() : line.getQtyInvoiced();
if (receiptLine.getMovementQty().compareTo(matchQty) < 0)
matchQty = receiptLine.getMovementQty();
if (movementQty.compareTo(matchQty) < 0)
matchQty = movementQty;
MMatchInv inv = new MMatchInv(line, getDateInvoiced(), matchQty);
if (!inv.save(get_TrxName()))
@ -1869,7 +1871,7 @@ public class MInvoice extends X_C_Invoice implements DocAction
&& !isReversal())
{
// MatchPO is created also from MInOut when Invoice exists before Shipment
BigDecimal matchQty = line.getQtyInvoiced();
BigDecimal matchQty = isCreditMemo() ? line.getQtyInvoiced().negate() : line.getQtyInvoiced();
MMatchPO po = MMatchPO.create (line, null,
getDateInvoiced(), matchQty);
if (po != null)
@ -1897,7 +1899,7 @@ public class MInvoice extends X_C_Invoice implements DocAction
}
}
}
//Update QtyInvoiced RMA Line
if (line.getM_RMALine_ID() != 0)
{
@ -2425,6 +2427,9 @@ public class MInvoice extends X_C_Invoice implements DocAction
}
addDocsPostProcess(new MMatchInv(Env.getCtx(), mInv[i].getReversal_ID(), get_TrxName()));
}
MatchPOAutoMatch.unmatch(getCtx(), getC_Invoice_ID(), get_TrxName());
MMatchPO[] mPO = MMatchPO.getInvoice(getCtx(), getC_Invoice_ID(), get_TrxName());
for (int i = 0; i < mPO.length; i++)
{

View File

@ -352,17 +352,11 @@ public class MMatchPO extends X_M_MatchPO
MInOutLine sLine, int C_OrderLine_ID, Timestamp dateTrx,
BigDecimal qty, String trxName) {
MMatchPO retValue = null;
String sql = "SELECT * FROM M_MatchPO WHERE C_OrderLine_ID=? and Reversal_ID IS NULL ORDER BY M_MatchPO_ID";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
List<MMatchPO> matchPOList = MatchPOAutoMatch.getNotMatchedMatchPOList(ctx, C_OrderLine_ID, trxName);
if (!matchPOList.isEmpty())
{
pstmt = DB.prepareStatement (sql, trxName);
pstmt.setInt (1, C_OrderLine_ID);
rs = pstmt.executeQuery ();
while (rs.next ())
for (MMatchPO mpo : matchPOList)
{
MMatchPO mpo = new MMatchPO (ctx, rs, trxName);
if (qty.compareTo(mpo.getQty()) >= 0)
{
BigDecimal toMatch = qty;
@ -408,7 +402,7 @@ public class MMatchPO extends X_M_MatchPO
{
//verify m_matchinv not created for other invoice
int cnt = DB.getSQLValue(iLine.get_TrxName(), "SELECT Count(*) FROM M_MatchInv WHERE M_InOutLine_ID="+mpo.getM_InOutLine_ID()
+" AND C_InvoiceLine_ID != "+iLine.getC_InvoiceLine_ID());
+" AND C_InvoiceLine_ID != "+iLine.getC_InvoiceLine_ID() + " AND Reversal_ID=0");
if (cnt > 0)
continue;
}
@ -429,46 +423,10 @@ public class MMatchPO extends X_M_MatchPO
+" AND C_InvoiceLine_ID="+C_InvoiceLine_ID);
if (cnt <= 0)
{
Trx trx = trxName != null ? Trx.get(trxName, false) : null;
Savepoint savepoint = trx != null ? trx.getConnection().setSavepoint() : null;
MMatchInv matchInv = new MMatchInv(mpo.getCtx(), 0, mpo.get_TrxName());
matchInv.setC_InvoiceLine_ID(C_InvoiceLine_ID);
matchInv.setM_Product_ID(mpo.getM_Product_ID());
matchInv.setM_InOutLine_ID(M_InOutLine_ID);
matchInv.setAD_Client_ID(mpo.getAD_Client_ID());
matchInv.setAD_Org_ID(mpo.getAD_Org_ID());
matchInv.setM_AttributeSetInstance_ID(mpo.getM_AttributeSetInstance_ID());
matchInv.setQty(mpo.getQty());
matchInv.setDateTrx(dateTrx);
matchInv.setProcessed(true);
if (!matchInv.save())
{
if (savepoint != null)
{
trx.getConnection().rollback(savepoint);
savepoint = null;
}
else
{
matchInv.delete(true);
}
String msg = "Failed to auto match invoice.";
ValueNamePair error = CLogger.retrieveError();
if (error != null)
{
msg = msg + " " + error.getName();
}
//log as debug message and continue
s_log.fine(msg);
MMatchInv matchInv = createMatchInv(mpo, C_InvoiceLine_ID, M_InOutLine_ID, mpo.getQty(), dateTrx, trxName);
if (matchInv == null)
continue;
}
mpo.setMatchInvCreated(matchInv);
if (savepoint != null)
{
try {
trx.getConnection().releaseSavepoint(savepoint);
} catch (Exception e) {}
}
}
}
if (iLine != null)
@ -499,22 +457,6 @@ public class MMatchPO extends X_M_MatchPO
}
}
}
catch (Exception e)
{
s_log.log(Level.SEVERE, sql, e);
if (e instanceof RuntimeException)
{
throw (RuntimeException)e;
}
else
{
throw new IllegalStateException(e);
}
}
finally
{
DB.close(rs, pstmt);
}
// Create New
if (retValue == null)
@ -528,7 +470,7 @@ public class MMatchPO extends X_M_MatchPO
if (sLine != null && (sLine.getC_OrderLine_ID() == C_OrderLine_ID || iLine == null)
&& (sLineMatchedQty == null || sLineMatchedQty.signum() <= 0))
{
if (qty.signum() > 0)
if (qty.signum() != 0)
{
retValue = new MMatchPO (sLine, dateTrx, qty);
retValue.setC_OrderLine_ID(C_OrderLine_ID);
@ -562,52 +504,8 @@ public class MMatchPO extends X_M_MatchPO
//auto create matchinv
if (otherMatchPO != null)
{
Savepoint savepoint = null;
Trx trx = null;
try
{
trx = trxName != null ? Trx.get(trxName, false) : null;
savepoint = trx != null ? trx.getConnection().setSavepoint() : null;
MMatchInv matchInv = new MMatchInv(retValue.getCtx(), 0, retValue.get_TrxName());
matchInv.setC_InvoiceLine_ID(otherMatchPO.getC_InvoiceLine_ID());
matchInv.setM_Product_ID(retValue.getM_Product_ID());
matchInv.setM_InOutLine_ID(retValue.getM_InOutLine_ID());
matchInv.setAD_Client_ID(retValue.getAD_Client_ID());
matchInv.setAD_Org_ID(retValue.getAD_Org_ID());
matchInv.setM_AttributeSetInstance_ID(retValue.getM_AttributeSetInstance_ID());
matchInv.setQty(retValue.getQty());
matchInv.setDateTrx(dateTrx);
matchInv.setProcessed(true);
if (!matchInv.save())
{
if (savepoint != null)
{
trx.getConnection().rollback(savepoint);
savepoint = null;
}
else
{
matchInv.delete(true);
}
String msg = "Failed to auto match invoice.";
ValueNamePair error = CLogger.retrieveError();
if (error != null)
{
msg = msg + " " + error.getName();
}
s_log.severe(msg);
}
retValue.setMatchInvCreated(matchInv);
} catch (Exception e) {
s_log.log(Level.SEVERE, "Failed to auto match Invoice.", e);
} finally {
if (savepoint != null)
{
try {
trx.getConnection().releaseSavepoint(savepoint);
} catch (Exception e) {}
}
}
MMatchInv matchInv = createMatchInv(retValue, otherMatchPO.getC_InvoiceLine_ID(), retValue.getM_InOutLine_ID(), retValue.getQty(), dateTrx, trxName);
retValue.setMatchInvCreated(matchInv);
if (otherMatchPO.getQty().signum() == 0 )
otherMatchPO.deleteEx(true);
}
@ -626,7 +524,7 @@ public class MMatchPO extends X_M_MatchPO
}
else if (iLine != null)
{
if (qty.signum() > 0)
if (qty.signum() != 0)
{
retValue = new MMatchPO (iLine, dateTrx, qty);
retValue.setC_OrderLine_ID(C_OrderLine_ID);
@ -652,7 +550,7 @@ public class MMatchPO extends X_M_MatchPO
if (matchPO.getM_MatchPO_ID() == retValue.getM_MatchPO_ID())
continue;
if (matchPO.getM_InOutLine_ID() > 0 && matchPO.getReversal_ID() == 0)
if (matchPO.getM_InOutLine_ID() > 0 && matchPO.getReversal_ID() == 0 && matchPO.getRef_MatchPO_ID() == 0)
{
if (matchPO.getC_InvoiceLine_ID() == 0)
{
@ -738,54 +636,8 @@ public class MMatchPO extends X_M_MatchPO
}
if (autoMatchQty != null && autoMatchQty.signum() > 0)
{
Savepoint savepoint = null;
Trx trx = null;
MMatchInv matchInv = null;
try
{
trx = trxName != null ? Trx.get(trxName, false) : null;
savepoint = trx != null ? trx.getConnection().setSavepoint() : null;
matchInv = new MMatchInv(retValue.getCtx(), 0, retValue.get_TrxName());
matchInv.setC_InvoiceLine_ID(retValue.getC_InvoiceLine_ID());
matchInv.setM_Product_ID(retValue.getM_Product_ID());
matchInv.setM_InOutLine_ID(matchPO.getM_InOutLine_ID());
matchInv.setAD_Client_ID(retValue.getAD_Client_ID());
matchInv.setAD_Org_ID(retValue.getAD_Org_ID());
matchInv.setM_AttributeSetInstance_ID(retValue.getM_AttributeSetInstance_ID());
matchInv.setQty(autoMatchQty);
matchInv.setDateTrx(dateTrx);
matchInv.setProcessed(true);
if (!matchInv.save())
{
if (savepoint != null)
{
trx.getConnection().rollback(savepoint);
savepoint = null;
}
else
{
matchInv.delete(true);
}
String msg = "Failed to auto match invoice.";
ValueNamePair error = CLogger.retrieveError();
if (error != null)
{
msg = msg + " " + error.getName();
}
s_log.severe(msg);
matchInv = null;
}
} catch (Exception e) {
s_log.log(Level.SEVERE, "Failed to auto match Invoice.", e);
matchInv = null;
} finally {
if (savepoint != null)
{
try {
trx.getConnection().releaseSavepoint(savepoint);
} catch (Exception e) {}
}
}
MMatchInv matchInv = createMatchInv(retValue, retValue.getC_InvoiceLine_ID(), matchPO.getM_InOutLine_ID(), autoMatchQty, dateTrx, trxName);
retValue.setMatchInvCreated(matchInv);
if (matchInv == null)
break;
}
@ -797,9 +649,65 @@ public class MMatchPO extends X_M_MatchPO
}
}
if (C_OrderLine_ID > 0 && retValue != null)
MatchPOAutoMatch.match(ctx, C_OrderLine_ID, retValue, trxName);
return retValue;
} // create
private static MMatchInv createMatchInv(MMatchPO mpo, int C_InvoiceLine_ID, int M_InOutLine_ID, BigDecimal qty, Timestamp dateTrx, String trxName)
{
Savepoint savepoint = null;
Trx trx = null;
MMatchInv matchInv = null;
try
{
trx = trxName != null ? Trx.get(trxName, false) : null;
savepoint = trx != null ? trx.getConnection().setSavepoint() : null;
matchInv = new MMatchInv(mpo.getCtx(), 0, mpo.get_TrxName());
matchInv.setC_InvoiceLine_ID(C_InvoiceLine_ID);
matchInv.setM_Product_ID(mpo.getM_Product_ID());
matchInv.setM_InOutLine_ID(M_InOutLine_ID);
matchInv.setAD_Client_ID(mpo.getAD_Client_ID());
matchInv.setAD_Org_ID(mpo.getAD_Org_ID());
matchInv.setM_AttributeSetInstance_ID(mpo.getM_AttributeSetInstance_ID());
matchInv.setQty(qty);
matchInv.setDateTrx(dateTrx);
matchInv.setProcessed(true);
if (!matchInv.save())
{
if (savepoint != null)
{
trx.getConnection().rollback(savepoint);
savepoint = null;
}
else
{
matchInv.delete(true);
}
String msg = "Failed to auto match invoice.";
ValueNamePair error = CLogger.retrieveError();
if (error != null)
{
msg = msg + " " + error.getName();
}
s_log.severe(msg);
matchInv = null;
}
} catch (Exception e) {
s_log.log(Level.SEVERE, "Failed to auto match Invoice.", e);
matchInv = null;
} finally {
if (savepoint != null)
{
try {
trx.getConnection().releaseSavepoint(savepoint);
} catch (Exception e) {}
}
}
return matchInv;
}
protected MMatchInv m_matchInv;
@ -1450,6 +1358,7 @@ public class MMatchPO extends X_M_MatchPO
reversal.set_ValueNoCheck ("DocumentNo", null);
reversal.setPosted (false);
reversal.setProcessed(true);
reversal.setRef_MatchPO_ID(getRef_MatchPO_ID());
reversal.setReversal_ID(getM_MatchPO_ID());
reversal.saveEx();

View File

@ -0,0 +1,385 @@
/******************************************************************************
* Product: iDempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2019 Elaine Tan *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.compiere.model;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Properties;
import org.compiere.process.DocAction;
import org.compiere.util.Env;
/**
*
* @author hengsin
*
*/
public class MatchPOAutoMatch {
/**
*
* @param ctx
* @param C_OrderLine_ID
* @param trxName
* @return not fully matched matchpo records
*/
public static List<MMatchPO> getNotMatchedMatchPOList(Properties ctx, int C_OrderLine_ID, String trxName)
{
List<MMatchPO> notMatchedMatchPOList = new ArrayList<MMatchPO>();
List<MMatchPO> creditMemoMatchPOList = new ArrayList<MMatchPO>();
List<MMatchPO> notMatchedCreditMemoMatchPOList = new ArrayList<MMatchPO>();
MMatchPO[] mpos = MMatchPO.getOrderLine(ctx, C_OrderLine_ID, trxName);
for (MMatchPO mpo : mpos)
{
if (mpo.getReversal_ID() == 0 && mpo.getRef_MatchPO_ID() == 0)
{
if (mpo.getQty().signum() < 0)
{
if (mpo.getC_InvoiceLine_ID() > 0 && mpo.getM_InOutLine_ID() == 0)
{
String docStatus = mpo.getC_InvoiceLine().getC_Invoice().getDocStatus();
if (docStatus.equals(DocAction.STATUS_Completed) || docStatus.equals(DocAction.STATUS_Closed)) {
creditMemoMatchPOList.add(mpo);
}
}
continue;
}
notMatchedMatchPOList.add(mpo);
}
}
if (!notMatchedMatchPOList.isEmpty())
{
Collections.sort(notMatchedMatchPOList, new Comparator<MMatchPO>() {
@Override
public int compare(MMatchPO arg0, MMatchPO arg1) {
return arg0.getM_MatchPO_ID() > arg1.getM_MatchPO_ID()
? 1
: (arg0.getM_MatchPO_ID()==arg1.getM_MatchPO_ID() ? 0 : -1);
}
});
}
if (!creditMemoMatchPOList.isEmpty())
{
BigDecimal totalNotMatchingCreditMemoQty = Env.ZERO;
for (MMatchPO matchPOCreditMemo : creditMemoMatchPOList)
{
boolean found = false;
int Ref_InvoiceLine_ID = matchPOCreditMemo.getC_InvoiceLine().getRef_InvoiceLine_ID();
if (Ref_InvoiceLine_ID > 0)
{
for (MMatchPO matchPO : notMatchedMatchPOList)
{
if (!matchPO.isPosted() && matchPO.getC_InvoiceLine_ID() == Ref_InvoiceLine_ID && matchPO.getM_InOutLine_ID() == 0)
{
if (matchPO.getQty().compareTo(matchPOCreditMemo.getQty().negate()) == 0)
{
notMatchedMatchPOList.remove(matchPO);
found = true;
break;
}
}
}
}
if (found)
continue;
for (MMatchPO matchPO : notMatchedMatchPOList)
{
if (!matchPO.isPosted() && matchPO.getC_InvoiceLine_ID() > 0 && matchPO.getM_InOutLine_ID() == 0)
{
if (matchPO.getQty().compareTo(matchPOCreditMemo.getQty().negate()) == 0)
{
notMatchedMatchPOList.remove(matchPO);
found = true;
break;
}
}
}
if (!found)
{
totalNotMatchingCreditMemoQty = totalNotMatchingCreditMemoQty.add(matchPOCreditMemo.getQty().negate());
notMatchedCreditMemoMatchPOList.add(matchPOCreditMemo);
}
}
if (totalNotMatchingCreditMemoQty.signum() != 0)
{
BigDecimal totalInvoiceQty = Env.ZERO;
for (MMatchPO matchPO : notMatchedMatchPOList)
{
if (!matchPO.isPosted() && matchPO.getC_InvoiceLine_ID() > 0 && matchPO.getM_InOutLine_ID() == 0)
totalInvoiceQty = totalInvoiceQty.add(matchPO.getQty());
}
if (totalNotMatchingCreditMemoQty.compareTo(totalInvoiceQty) == 0)
notMatchedMatchPOList.clear();
}
}
return notMatchedMatchPOList;
}
/**
* auto match matchpo
* @param ctx
* @param C_OrderLine_ID
* @param currentPO
* @param trxName
*/
public static void match(Properties ctx, int C_OrderLine_ID, MMatchPO currentPO, String trxName)
{
List<MMatchPO> notMatchedMatchPOList = new ArrayList<MMatchPO>();
List<MMatchPO> creditMemoMatchPOList = new ArrayList<MMatchPO>();
List<MMatchPO> matchedMatchPOList = new ArrayList<MMatchPO>();
MMatchPO[] mpos = MMatchPO.getOrderLine(ctx, C_OrderLine_ID, trxName);
for (MMatchPO mpo : mpos)
{
if (mpo.getReversal_ID() == 0 && mpo.getRef_MatchPO_ID() == 0)
{
if (mpo.getQty().signum() < 0)
{
if (mpo.getC_InvoiceLine_ID() > 0 && mpo.getM_InOutLine_ID() == 0)
{
String docStatus = mpo.getC_InvoiceLine().getC_Invoice().getDocStatus();
if ((currentPO != null && mpo.getM_MatchPO_ID() == currentPO.getM_MatchPO_ID())
|| docStatus.equals(DocAction.STATUS_Completed)
|| docStatus.equals(DocAction.STATUS_Closed)) {
creditMemoMatchPOList.add(mpo);
}
}
continue;
}
notMatchedMatchPOList.add(mpo);
}
}
if (!notMatchedMatchPOList.isEmpty())
{
Collections.sort(notMatchedMatchPOList, new Comparator<MMatchPO>() {
@Override
public int compare(MMatchPO arg0, MMatchPO arg1) {
return arg0.getM_MatchPO_ID() > arg1.getM_MatchPO_ID()
? 1
: (arg0.getM_MatchPO_ID()==arg1.getM_MatchPO_ID() ? 0 : -1);
}
});
}
if (!creditMemoMatchPOList.isEmpty())
{
for (MMatchPO matchPOCreditMemo : creditMemoMatchPOList)
{
BigDecimal creditMemoQty = matchPOCreditMemo.getQty().negate();
int Ref_InvoiceLine_ID = matchPOCreditMemo.getC_InvoiceLine().getRef_InvoiceLine_ID();
if (Ref_InvoiceLine_ID > 0)
{
for (MMatchPO matchPO : notMatchedMatchPOList)
{
if (!matchPO.isPosted() && matchPO.getC_InvoiceLine_ID() == Ref_InvoiceLine_ID && matchPO.getM_InOutLine_ID() == 0)
{
if (matchPO.getQty().compareTo(creditMemoQty) > 0)
{
matchPO.setQty(matchPO.getQty().subtract(creditMemoQty));
matchPO.saveEx(trxName);
MInvoiceLine iLine = new MInvoiceLine(ctx, matchPO.getC_InvoiceLine_ID(), trxName);
MMatchPO po = new MMatchPO(iLine, iLine.getC_Invoice().getDateInvoiced(), creditMemoQty);
po.setC_OrderLine_ID(C_OrderLine_ID);
po.setRef_MatchPO_ID(matchPOCreditMemo.getM_MatchPO_ID());
po.setPosted(true);
po.saveEx(trxName);
matchPOCreditMemo.setRef_MatchPO_ID(po.getM_MatchPO_ID());
matchPOCreditMemo.setPosted(true);
matchPOCreditMemo.saveEx(trxName);
matchedMatchPOList.add(po);
creditMemoQty = creditMemoQty.subtract(po.getQty());
}
else if (matchPO.getQty().compareTo(creditMemoQty) == 0)
{
matchPO.setRef_MatchPO_ID(matchPOCreditMemo.getM_MatchPO_ID());
matchPO.setPosted(true);
matchPO.saveEx(trxName);
matchPOCreditMemo.setRef_MatchPO_ID(matchPO.getM_MatchPO_ID());
matchPOCreditMemo.setPosted(true);
matchPOCreditMemo.saveEx(trxName);
matchedMatchPOList.add(matchPO);
creditMemoQty = creditMemoQty.subtract(matchPO.getQty());
}
else if (matchPO.getQty().compareTo(creditMemoQty) < 0)
{
matchPOCreditMemo.setQty(matchPOCreditMemo.getQty().add(matchPO.getQty()));
matchPOCreditMemo.saveEx(trxName);
MInvoiceLine iLine = new MInvoiceLine(ctx, matchPOCreditMemo.getC_InvoiceLine_ID(), trxName);
MMatchPO po = new MMatchPO(iLine, iLine.getC_Invoice().getDateInvoiced(), matchPO.getQty().negate());
po.setC_OrderLine_ID(C_OrderLine_ID);
po.setRef_MatchPO_ID(matchPO.getM_MatchPO_ID());
po.setPosted(true);
po.saveEx(trxName);
matchPO.setRef_MatchPO_ID(po.getM_MatchPO_ID());
matchPO.setPosted(true);
matchPO.saveEx(trxName);
matchedMatchPOList.add(matchPO);
creditMemoQty = creditMemoQty.subtract(matchPO.getQty());
}
if (creditMemoQty.signum() == 0)
break;
}
}
for (MMatchPO matchedMatchPO : matchedMatchPOList)
notMatchedMatchPOList.remove(matchedMatchPO);
}
if (creditMemoQty.signum() == 0)
continue;
for (MMatchPO matchPO : notMatchedMatchPOList)
{
if (!matchPO.isPosted() && matchPO.getC_InvoiceLine_ID() > 0 && matchPO.getM_InOutLine_ID() == 0)
{
if (matchPO.getQty().compareTo(creditMemoQty) > 0)
{
matchPO.setQty(matchPO.getQty().subtract(creditMemoQty));
matchPO.saveEx(trxName);
MInvoiceLine iLine = new MInvoiceLine(ctx, matchPO.getC_InvoiceLine_ID(), trxName);
MMatchPO po = new MMatchPO(iLine, iLine.getC_Invoice().getDateInvoiced(), creditMemoQty);
po.setC_OrderLine_ID(C_OrderLine_ID);
po.setRef_MatchPO_ID(matchPOCreditMemo.getM_MatchPO_ID());
po.setPosted(true);
po.saveEx(trxName);
matchPOCreditMemo.setRef_MatchPO_ID(po.getM_MatchPO_ID());
matchPOCreditMemo.setPosted(true);
matchPOCreditMemo.saveEx(trxName);
matchedMatchPOList.add(po);
creditMemoQty = creditMemoQty.subtract(po.getQty());
}
else if (matchPO.getQty().compareTo(creditMemoQty) == 0)
{
matchPO.setRef_MatchPO_ID(matchPOCreditMemo.getM_MatchPO_ID());
matchPO.setPosted(true);
matchPO.saveEx(trxName);
matchPOCreditMemo.setRef_MatchPO_ID(matchPO.getM_MatchPO_ID());
matchPOCreditMemo.setPosted(true);
matchPOCreditMemo.saveEx(trxName);
matchedMatchPOList.add(matchPO);
creditMemoQty = creditMemoQty.subtract(matchPO.getQty());
}
else if (matchPO.getQty().compareTo(creditMemoQty) < 0)
{
matchPOCreditMemo.setQty(matchPOCreditMemo.getQty().add(matchPO.getQty()));
matchPOCreditMemo.saveEx(trxName);
MInvoiceLine iLine = new MInvoiceLine(ctx, matchPOCreditMemo.getC_InvoiceLine_ID(), trxName);
MMatchPO po = new MMatchPO(iLine, iLine.getC_Invoice().getDateInvoiced(), matchPO.getQty().negate());
po.setC_OrderLine_ID(C_OrderLine_ID);
po.setRef_MatchPO_ID(matchPO.getM_MatchPO_ID());
po.setPosted(true);
po.saveEx(trxName);
matchPO.setRef_MatchPO_ID(po.getM_MatchPO_ID());
matchPO.setPosted(true);
matchPO.saveEx(trxName);
matchedMatchPOList.add(matchPO);
creditMemoQty = creditMemoQty.subtract(matchPO.getQty());
}
if (creditMemoQty.signum() == 0)
break;
}
}
for (MMatchPO matchedMatchPO : matchedMatchPOList)
notMatchedMatchPOList.remove(matchedMatchPO);
}
}
if (currentPO != null)
{
for (MMatchPO matchPOCreditMemo : creditMemoMatchPOList)
{
if (matchPOCreditMemo.getM_MatchPO_ID() == currentPO.getM_MatchPO_ID())
{
if (matchPOCreditMemo.getReversal_ID() == 0 && matchPOCreditMemo.getRef_MatchPO_ID() == 0)
throw new RuntimeException("Failed to find the corresponding invoice matched po");
}
}
}
}
/**
* remove match between vendor invoice and vendor cm
* @param ctx
* @param C_Invoice_ID
* @param trxName
*/
public static void unmatch(Properties ctx, int C_Invoice_ID, String trxName)
{
List<Integer> unmatchedOrderLineID = new ArrayList<Integer>();
MMatchPO[] mpos = MMatchPO.getInvoice(ctx, C_Invoice_ID, trxName);
for (MMatchPO mpo : mpos)
{
if (mpo.getReversal_ID() > 0 || mpo.getRef_MatchPO_ID() == 0)
continue;
int C_OrderLine_ID = mpo.getC_OrderLine_ID();
if (!unmatchedOrderLineID.contains(C_OrderLine_ID))
{
unmatchedOrderLineID.add(C_OrderLine_ID);
MMatchPO[] pos = MMatchPO.getOrderLine(ctx, C_OrderLine_ID, trxName);
for (MMatchPO po : pos)
{
if (po.getReversal_ID() == 0 && po.getC_InvoiceLine_ID() > 0 && po.getRef_MatchPO_ID() > 0)
{
if (po.getC_InvoiceLine().getC_Invoice_ID() == C_Invoice_ID)
{
po.setRef_MatchPO_ID(0);
po.setPosted(false);
po.saveEx(trxName);
}
else if (po.getRef_MatchPO().getC_InvoiceLine().getC_Invoice_ID() == C_Invoice_ID)
{
po.setRef_MatchPO_ID(0);
po.setPosted(false);
po.saveEx(trxName);
}
}
}
}
}
}
}

View File

@ -33,7 +33,7 @@ public class X_M_MatchPO extends PO implements I_M_MatchPO, I_Persistent
/**
*
*/
private static final long serialVersionUID = 20190106L;
private static final long serialVersionUID = 20190903L;
/** Standard Constructor */
public X_M_MatchPO (Properties ctx, int M_MatchPO_ID, String trxName)
@ -488,6 +488,31 @@ public class X_M_MatchPO extends PO implements I_M_MatchPO, I_Persistent
return bd;
}
public org.compiere.model.I_M_MatchPO getRef_MatchPO() throws RuntimeException
{
return (org.compiere.model.I_M_MatchPO)MTable.get(getCtx(), org.compiere.model.I_M_MatchPO.Table_Name)
.getPO(getRef_MatchPO_ID(), get_TrxName()); }
/** Set Referenced Match PO.
@param Ref_MatchPO_ID Referenced Match PO */
public void setRef_MatchPO_ID (int Ref_MatchPO_ID)
{
if (Ref_MatchPO_ID < 1)
set_Value (COLUMNNAME_Ref_MatchPO_ID, null);
else
set_Value (COLUMNNAME_Ref_MatchPO_ID, Integer.valueOf(Ref_MatchPO_ID));
}
/** Get Referenced Match PO.
@return Referenced Match PO */
public int getRef_MatchPO_ID ()
{
Integer ii = (Integer)get_Value(COLUMNNAME_Ref_MatchPO_ID);
if (ii == null)
return 0;
return ii.intValue();
}
public org.compiere.model.I_M_MatchPO getReversal() throws RuntimeException
{
return (org.compiere.model.I_M_MatchPO)MTable.get(getCtx(), org.compiere.model.I_M_MatchPO.Table_Name)

View File

@ -21,6 +21,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.VetoableChangeListener;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Vector;
import java.util.logging.Level;
@ -94,6 +95,8 @@ public class VCreateFromInvoiceUI extends CreateFromInvoice implements ActionLis
/** Combo box for selecting RMA document */
private JComboBox<Object> rmaField = new JComboBox<Object>();
private boolean isCreditMemo = false;
/**
* Dynamic Init
* @throws Exception if Lookups cannot be initialized
@ -116,6 +119,9 @@ public class VCreateFromInvoiceUI extends CreateFromInvoice implements ActionLis
rmaField.setVisible(false);
}
isCreditMemo = MDocType.DOCBASETYPE_APCreditMemo.equals(docType.getDocBaseType())
|| MDocType.DOCBASETYPE_ARCreditMemo.equals(docType.getDocBaseType());
initBPartner(true);
bPartnerField.addVetoableChangeListener(this);
@ -276,7 +282,7 @@ public class VCreateFromInvoiceUI extends CreateFromInvoice implements ActionLis
orderField.removeAllItems();
orderField.addItem(pp);
ArrayList<KeyNamePair> list = loadOrderData(C_BPartner_ID, forInvoice, false);
ArrayList<KeyNamePair> list = loadOrderData(C_BPartner_ID, forInvoice, false, isCreditMemo);
for(KeyNamePair knp : list)
orderField.addItem(knp);
@ -343,7 +349,7 @@ public class VCreateFromInvoiceUI extends CreateFromInvoice implements ActionLis
*/
protected void loadOrder (int C_Order_ID, boolean forInvoice)
{
loadTableOIS(getOrderData(C_Order_ID, forInvoice));
loadTableOIS(getOrderData(C_Order_ID, forInvoice, isCreditMemo));
} // LoadOrder
protected void loadRMA (int M_RMA_ID)

View File

@ -13,6 +13,7 @@
*****************************************************************************/
package org.adempiere.webui.apps.form;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Vector;
import java.util.logging.Level;
@ -105,6 +106,8 @@ public class WCreateFromInvoiceUI extends CreateFromInvoice implements EventList
private Grid parameterStdLayout;
private boolean isCreditMemo = false;
/**
* Dynamic Init
* @throws Exception if Lookups cannot be initialized
@ -127,6 +130,9 @@ public class WCreateFromInvoiceUI extends CreateFromInvoice implements EventList
rmaField.setVisible(false);
}
isCreditMemo = MDocType.DOCBASETYPE_APCreditMemo.equals(docType.getDocBaseType())
|| MDocType.DOCBASETYPE_ARCreditMemo.equals(docType.getDocBaseType());
initBPartner(true);
bPartnerField.addValueChangeListener(this);
@ -315,7 +321,7 @@ public class WCreateFromInvoiceUI extends CreateFromInvoice implements EventList
orderField.removeAllItems();
orderField.addItem(pp);
ArrayList<KeyNamePair> list = loadOrderData(C_BPartner_ID, forInvoice, false);
ArrayList<KeyNamePair> list = loadOrderData(C_BPartner_ID, forInvoice, false, isCreditMemo);
for(KeyNamePair knp : list)
orderField.addItem(knp);
@ -381,7 +387,7 @@ public class WCreateFromInvoiceUI extends CreateFromInvoice implements EventList
*/
protected void loadOrder (int C_Order_ID, boolean forInvoice)
{
loadTableOIS(getOrderData(C_Order_ID, forInvoice));
loadTableOIS(getOrderData(C_Order_ID, forInvoice, isCreditMemo));
} // LoadOrder
protected void loadRMA (int M_RMA_ID)

View File

@ -88,6 +88,11 @@ public abstract class CreateFrom implements ICreateFrom
* @param forInvoice for invoice
*/
protected ArrayList<KeyNamePair> loadOrderData (int C_BPartner_ID, boolean forInvoice, boolean sameWarehouseOnly)
{
return loadOrderData(C_BPartner_ID, forInvoice, sameWarehouseOnly, false);
}
protected ArrayList<KeyNamePair> loadOrderData (int C_BPartner_ID, boolean forInvoice, boolean sameWarehouseOnly, boolean forCreditMemo)
{
ArrayList<KeyNamePair> list = new ArrayList<KeyNamePair>();
@ -109,14 +114,20 @@ public abstract class CreateFrom implements ICreateFrom
.append(display)
.append(" FROM C_Order o WHERE ")
.append(colBP)
.append("=? AND o.IsSOTrx=? AND o.DocStatus IN ('CL','CO') AND o.C_Order_ID IN (SELECT ol.C_Order_ID FROM C_OrderLine ol WHERE ol.QtyOrdered-")
.append(column)
.append("!=0) ");
.append("=? AND o.IsSOTrx=? AND o.DocStatus IN ('CL','CO') AND o.C_Order_ID IN (SELECT ol.C_Order_ID FROM C_OrderLine ol WHERE ");
if (forCreditMemo)
sql.append(column).append(">0 AND (CASE WHEN ol.QtyDelivered>=ol.QtyOrdered THEN ol.QtyDelivered-ol.QtyInvoiced!=0 ELSE 1=1 END)) ");
else
sql.append("ol.QtyOrdered-").append(column).append("!=0) ");
if(sameWarehouseOnly)
{
sql = sql.append(" AND o.M_Warehouse_ID=? ");
}
sql = sql.append("ORDER BY o.DateOrdered,o.DocumentNo");
if (forCreditMemo)
sql = sql.append("ORDER BY o.DateOrdered DESC,o.DocumentNo DESC");
else
sql = sql.append("ORDER BY o.DateOrdered,o.DocumentNo");
//
PreparedStatement pstmt = null;
ResultSet rs = null;
@ -155,6 +166,11 @@ public abstract class CreateFrom implements ICreateFrom
* @param forInvoice true if for invoice vs. delivery qty
*/
protected Vector<Vector<Object>> getOrderData (int C_Order_ID, boolean forInvoice)
{
return getOrderData (C_Order_ID, forInvoice, false);
}
protected Vector<Vector<Object>> getOrderData (int C_Order_ID, boolean forInvoice, boolean forCreditMemo)
{
/**
* Selected - 0
@ -170,9 +186,9 @@ public abstract class CreateFrom implements ICreateFrom
p_order = new MOrder (Env.getCtx(), C_Order_ID, null);
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
StringBuilder sql = new StringBuilder("SELECT "
+ "l.QtyOrdered-SUM(COALESCE(m.Qty,0))," // 1
+ "CASE WHEN l.QtyOrdered=0 THEN 0 ELSE l.QtyEntered/l.QtyOrdered END," // 2
StringBuilder sql = new StringBuilder("SELECT ");
sql.append(forCreditMemo ? "SUM(COALESCE(m.Qty,0))," : "l.QtyOrdered-SUM(COALESCE(m.Qty,0)),"); // 1
sql.append("CASE WHEN l.QtyOrdered=0 THEN 0 ELSE l.QtyEntered/l.QtyOrdered END," // 2
+ " l.C_UOM_ID,COALESCE(uom.UOMSymbol,uom.Name)," // 3..4
+ " COALESCE(l.M_Product_ID,0),COALESCE(p.Name,c.Name),po.VendorProductNo," // 5..7
+ " l.C_OrderLine_ID,l.Line " // 8..9
@ -180,7 +196,7 @@ public abstract class CreateFrom implements ICreateFrom
+ " LEFT OUTER JOIN M_Product_PO po ON (l.M_Product_ID = po.M_Product_ID AND l.C_BPartner_ID = po.C_BPartner_ID) "
+ " LEFT OUTER JOIN M_MatchPO m ON (l.C_OrderLine_ID=m.C_OrderLine_ID AND ");
sql.append(forInvoice ? "m.C_InvoiceLine_ID" : "m.M_InOutLine_ID");
sql.append(" IS NOT NULL)")
sql.append(" IS NOT NULL AND COALESCE(m.Reversal_ID,0)=0)")
.append(" LEFT OUTER JOIN M_Product p ON (l.M_Product_ID=p.M_Product_ID)"
+ " LEFT OUTER JOIN C_Charge c ON (l.C_Charge_ID=c.C_Charge_ID)");
if (Env.isBaseLanguage(Env.getCtx(), "C_UOM"))

View File

@ -365,7 +365,7 @@ public abstract class CreateFromInvoice extends CreateFrom
protected void configureMiniTable (IMiniTable miniTable)
{
miniTable.setColumnClass(0, Boolean.class, false); // 0-Selection
miniTable.setColumnClass(1, BigDecimal.class, true); // 1-Qty
miniTable.setColumnClass(1, BigDecimal.class, false); // 1-Qty
miniTable.setColumnClass(2, String.class, true); // 2-UOM
miniTable.setColumnClass(3, String.class, true); // 3-Product
miniTable.setColumnClass(4, String.class, true); // 4-VendorProductNo