hg merge release-4.1 (merge release4.1 into development)

This commit is contained in:
Carlos Ruiz 2017-10-13 16:41:48 +02:00
commit ea5192578b
35 changed files with 1243 additions and 656 deletions

View File

@ -0,0 +1,11 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-3488 Improvement to Error Message for Negative Inventory Disallow exception
-- Sep 14, 2017 6:28:55 PM GMT+08:00
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 ('E','The {0} warehouse does not allow negative inventory for Product = {1}, ASI = {2}, Locator = {3} (Shortage of {4})',0,0,'Y',TO_DATE('2017-09-14 18:28:54','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-09-14 18:28:54','YYYY-MM-DD HH24:MI:SS'),100,200431,'NegativeInventoryDisallowedInfo','D','1a686715-09f5-4437-9885-882719423bd1')
;
SELECT register_migration_script('201709151000_IDEMPIERE-3488.sql') FROM dual
;

View File

@ -0,0 +1,23 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-3517 Report Cube - OrgTrx Dimension is not displayed
-- Oct 13, 2017 2:04:42 PM CEST
UPDATE AD_Field SET DisplayLogic='@$Element_OT@=Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-13 14:04:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=2344
;
-- Oct 13, 2017 2:05:12 PM CEST
UPDATE AD_Field SET DisplayLogic='@$Element_AY@=Y ', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-13 14:05:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=3886
;
-- Oct 13, 2017 2:05:54 PM CEST
UPDATE AD_Field SET DisplayLogic='@$Element_OT@=Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-13 14:05:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=57023
;
-- Oct 13, 2017 2:06:02 PM CEST
UPDATE AD_Field SET DisplayLogic='@$Element_AY@=Y ', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-10-13 14:06:02','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=57013
;
SELECT register_migration_script('201710131406_IDEMPIERE-3517.sql') FROM dual
;

View File

@ -0,0 +1,14 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-3519:column updated, created of c_salesregion_trl isn't yet sync so miss default value
-- Oct 13, 2017 12:41:29 PM ICT
ALTER TABLE C_SalesRegion_Trl MODIFY Created DATE DEFAULT SYSDATE
;
-- Oct 13, 2017 12:41:53 PM ICT
ALTER TABLE C_SalesRegion_Trl MODIFY Updated DATE DEFAULT SYSDATE
;
SELECT register_migration_script('201710131604-IDEMPIERE-3519.sql') FROM dual
;

View File

@ -0,0 +1,8 @@
-- IDEMPIERE-3488 Improvement to Error Message for Negative Inventory Disallow exception
-- Sep 14, 2017 6:28:55 PM GMT+08:00
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 ('E','The {0} warehouse does not allow negative inventory for Product = {1}, ASI = {2}, Locator = {3} (Shortage of {4})',0,0,'Y',TO_TIMESTAMP('2017-09-14 18:28:54','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-09-14 18:28:54','YYYY-MM-DD HH24:MI:SS'),100,200431,'NegativeInventoryDisallowedInfo','D','1a686715-09f5-4437-9885-882719423bd1')
;
SELECT register_migration_script('201709151000_IDEMPIERE-3488.sql') FROM dual
;

View File

@ -0,0 +1,20 @@
-- IDEMPIERE-3517 Report Cube - OrgTrx Dimension is not displayed
-- Oct 13, 2017 2:04:42 PM CEST
UPDATE AD_Field SET DisplayLogic='@$Element_OT@=Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-13 14:04:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=2344
;
-- Oct 13, 2017 2:05:12 PM CEST
UPDATE AD_Field SET DisplayLogic='@$Element_AY@=Y ', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-13 14:05:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=3886
;
-- Oct 13, 2017 2:05:54 PM CEST
UPDATE AD_Field SET DisplayLogic='@$Element_OT@=Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-13 14:05:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=57023
;
-- Oct 13, 2017 2:06:02 PM CEST
UPDATE AD_Field SET DisplayLogic='@$Element_AY@=Y ', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-10-13 14:06:02','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=57013
;
SELECT register_migration_script('201710131406_IDEMPIERE-3517.sql') FROM dual
;

View File

@ -0,0 +1,11 @@
-- IDEMPIERE-3519:column updated, created of c_salesregion_trl isn't yet sync so miss default value
-- Oct 13, 2017 12:41:29 PM ICT
INSERT INTO t_alter_column values('c_salesregion_trl','Created','TIMESTAMP',null,'statement_timestamp()')
;
-- Oct 13, 2017 12:41:53 PM ICT
INSERT INTO t_alter_column values('c_salesregion_trl','Updated','TIMESTAMP',null,'statement_timestamp()')
;
SELECT register_migration_script('201710131604-IDEMPIERE-3519.sql') FROM dual
;

View File

@ -72,7 +72,7 @@ public class EventManager implements IEventManager {
*/
public static IEventManager getInstance() {
synchronized (mutex) {
if (instance == null) {
while (instance == null) {
try {
mutex.wait(10000);
} catch (InterruptedException e) {

View File

@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (C) 2017 Trek Global Inc. *
* Copyright (C) 2017 Low Heng Sin *
* 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.adempiere.exceptions;
import java.math.BigDecimal;
import java.util.Properties;
import org.compiere.model.MAttributeSetInstance;
import org.compiere.model.MLocator;
import org.compiere.model.MProduct;
import org.compiere.model.MSysConfig;
import org.compiere.model.MWarehouse;
import org.compiere.util.Env;
import org.compiere.util.Msg;
/**
*
* @author hengsin
*
*/
public class NegativeInventoryDisallowedException extends AdempiereException
{
/**
*
*/
private static final long serialVersionUID = 253224414462489886L;
private int M_Warehouse_ID;
private int M_Product_ID;
private int M_AttributeSetInstance_ID;
private int M_Locator_ID;
private BigDecimal QtyOnHand;
private BigDecimal MovementQty;
public NegativeInventoryDisallowedException(Properties ctx, int M_Warehouse_ID, int M_Product_ID, int M_AttributeSetInstance_ID, int M_Locator_ID,
BigDecimal QtyOnHand, BigDecimal MovementQty)
{
super(Msg.getMsg(ctx, "NegativeInventoryDisallowedInfo", new Object[] {
MWarehouse.get(ctx, M_Warehouse_ID).getName(),
MProduct.get(ctx, M_Product_ID).getValue() + MSysConfig.getValue(MSysConfig.IDENTIFIER_SEPARATOR, "_", Env.getAD_Client_ID(ctx)) + MProduct.get(ctx, M_Product_ID).getName(),
M_AttributeSetInstance_ID > 0 ? MAttributeSetInstance.get(ctx, M_AttributeSetInstance_ID, M_Product_ID).getDescription() : "0",
M_Locator_ID > 0 ? MLocator.get(ctx, M_Locator_ID).getValue() : "0", MovementQty.subtract(QtyOnHand)
}));
this.M_Warehouse_ID = M_Warehouse_ID;
this.M_Product_ID = M_Product_ID;
this.M_AttributeSetInstance_ID = M_AttributeSetInstance_ID;
this.M_Locator_ID = M_Locator_ID;
this.QtyOnHand = QtyOnHand;
this.MovementQty = MovementQty;
}
public int getM_Warehouse_ID() {
return M_Warehouse_ID;
}
public int getM_Product_ID() {
return M_Product_ID;
}
public int getM_AttributeSetInstance_ID() {
return M_AttributeSetInstance_ID;
}
public int getM_Locator_ID() {
return M_Locator_ID;
}
public BigDecimal getQtyOnHand() {
return QtyOnHand;
}
public BigDecimal getMovementQty() {
return MovementQty;
}
}

View File

@ -1326,6 +1326,8 @@ public class GridTabCSVImporter implements IGridTabImporter
return (new Optional(new ParseBigDecimal(new DecimalFormatSymbols(Language.getLoginLanguage().getLocale()))));
} else if (DisplayType.YesNo == field.getDisplayType()) {
return (new Optional(new ParseBool("y", "n")));
} else if (DisplayType.TextLong == field.getDisplayType()) {
return (new Optional(new StrMinMax(1, Long.MAX_VALUE)));
} else if (DisplayType.isText(field.getDisplayType())) {
return (new Optional(new StrMinMax(1, field.getFieldLength())));
} else { // optional lookups and text

View File

@ -555,6 +555,12 @@ public abstract class Doc
p_Error = loadDocumentDetails();
if (p_Error != null)
return p_Error;
if (isDeferPosting())
{
unlock();
p_Status = STATUS_NotPosted;
return null;
}
Trx trx = Trx.get(getTrxName(), true);
// Delete existing Accounting
@ -2304,4 +2310,11 @@ public abstract class Doc
public ArrayList<Fact> getFacts() {
return m_fact;
}
/**
* Return document whether need to defer posting or not
*/
public boolean isDeferPosting() {
return false;
}
} // Doc

View File

@ -77,6 +77,7 @@ public class Doc_MatchPO extends Doc
private ProductCost m_pc;
private int m_M_AttributeSetInstance_ID = 0;
private MMatchPO m_matchPO;
private boolean m_deferPosting = false;
/**
* Load Specific Document Details
@ -102,7 +103,25 @@ public class Doc_MatchPO extends Doc
//
m_pc = new ProductCost (Env.getCtx(),
getM_Product_ID(), m_M_AttributeSetInstance_ID, getTrxName());
m_pc.setQty(getQty());
m_pc.setQty(getQty());
if (m_M_InOutLine_ID == 0)
{
MMatchPO[] matchPOs = MMatchPO.getOrderLine(getCtx(), m_oLine.getC_OrderLine_ID(), getTrxName());
for (MMatchPO matchPO : matchPOs)
{
if (matchPO.getM_InOutLine_ID() > 0 && matchPO.getC_InvoiceLine_ID() == 0)
{
m_M_InOutLine_ID = matchPO.getM_InOutLine_ID();
break;
}
}
}
if (m_M_InOutLine_ID == 0) // Defer posting if not matched to Shipment
{
m_deferPosting = true;
}
return null;
} // loadDocumentDetails
@ -487,4 +506,11 @@ public class Doc_MatchPO extends Doc
return null;
}
@Override
public boolean isDeferPosting() {
return m_deferPosting;
}
} // Doc_MatchPO

View File

@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.logging.Level;
import org.compiere.model.MAcctSchema;
import org.compiere.model.MCostDetail;
import org.compiere.model.MProduct;
import org.compiere.model.MProject;
import org.compiere.model.MProjectIssue;
@ -157,6 +158,20 @@ public class Doc_ProjectIssue extends Doc
cr.setM_Locator_ID(m_line.getM_Locator_ID());
cr.setLocationFromLocator(m_line.getM_Locator_ID(), true); // from Loc
//
if (product != null && product.get_ID() > 0 && !product.isService() && product.isStocked()) {
BigDecimal costDetailQty = m_line.getQty();
BigDecimal costDetailAmt = cost;
if (!MCostDetail.createProjectIssue(as, m_line.getAD_Org_ID(),
m_line.getM_Product_ID(), m_line.getM_AttributeSetInstance_ID(),
m_line.get_ID(), 0,
costDetailAmt, costDetailQty,
m_line.getDescription(), getTrxName()))
{
p_Error = "Failed to create cost detail record";
return null;
}
}
//
ArrayList<Fact> facts = new ArrayList<Fact>();
facts.add(fact);
return facts;
@ -203,6 +218,8 @@ public class Doc_ProjectIssue extends Doc
DB.close(rs, pstmt);
pstmt = null; rs = null;
}
if (retValue != null)
retValue = retValue.multiply(m_line.getQty());
return retValue;
} // getPOCost();

View File

@ -529,6 +529,70 @@ public class MCostDetail extends X_M_CostDetail
return ok;
} // createMatchInvoice
/**
* Create Cost Detail for Project Issue.
* Called from Doc_ProjectIssue
* @param as accounting schema
* @param AD_Org_ID org
* @param M_Product_ID product
* @param M_AttributeSetInstance_ID asi
* @param C_ProjectIssue_ID project issue line
* @param M_CostElement_ID optional cost element
* @param Amt amt total amount
* @param Qty qty
* @param Description optional description
* @param trxName transaction
* @return true if no error
*/
public static boolean createProjectIssue(MAcctSchema as, int AD_Org_ID,
int M_Product_ID, int M_AttributeSetInstance_ID,
int C_ProjectIssue_ID, int M_CostElement_ID,
BigDecimal Amt, BigDecimal Qty,
String Description, String trxName)
{
MCostDetail cd = get (as.getCtx(), "C_ProjectIssue_ID=? AND Coalesce(M_CostElement_ID,0)="+M_CostElement_ID,
C_ProjectIssue_ID, M_AttributeSetInstance_ID, as.getC_AcctSchema_ID(), trxName);
//
if (cd == null) // createNew
{
cd = new MCostDetail (as, AD_Org_ID,
M_Product_ID, M_AttributeSetInstance_ID,
M_CostElement_ID,
Amt, Qty, Description, trxName);
cd.setC_ProjectIssue_ID(C_ProjectIssue_ID);
}
else
{
if (cd.isProcessed())
{
cd.setDeltaAmt(Amt.subtract(cd.getAmt()));
cd.setDeltaQty(Qty.subtract(cd.getQty()));
}
else
{
cd.setDeltaAmt(BigDecimal.ZERO);
cd.setDeltaQty(BigDecimal.ZERO);
cd.setAmt(Amt);
cd.setQty(Qty);
}
if (cd.isDelta())
{
cd.setProcessed(false);
cd.setAmt(Amt);
cd.setQty(Qty);
}
else if (cd.isProcessed())
return true; // nothing to do
}
boolean ok = cd.save();
if (ok && !cd.isProcessed())
{
ok = cd.process();
}
if (s_log.isLoggable(Level.CONFIG)) s_log.config("(" + ok + ") " + cd);
return ok;
} // createProjectIssue
/**************************************************************************
* Get Cost Detail
* @param ctx context
@ -1319,10 +1383,14 @@ public class MCostDetail extends X_M_CostDetail
log.warning("Unknown Type: " + toString());
return false;
}
setCurrentCostPrice(cost.getCurrentCostPrice());
setCurrentQty(cost.getCurrentQty());
setCumulatedAmt(cost.getCumulatedAmt());
setCumulatedQty(cost.getCumulatedQty());
//Should only update cost detail with value from as costing method
if(as.getCostingMethod().equals(ce.getCostingMethod())) {
setCurrentCostPrice(cost.getCurrentCostPrice());
setCurrentQty(cost.getCurrentQty());
setCumulatedAmt(cost.getCumulatedAmt());
setCumulatedQty(cost.getCumulatedQty());
}
//update history
history.setNewQty(cost.getCurrentQty());

View File

@ -26,6 +26,7 @@ import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
import org.adempiere.exceptions.PeriodClosedException;
import org.compiere.print.MPrintFormat;
import org.compiere.print.ReportEngine;
@ -1286,6 +1287,7 @@ public class MInOut extends X_M_InOut implements DocAction
if (log.isLoggable(Level.INFO)) log.info(toString());
StringBuilder info = new StringBuilder();
StringBuilder errors = new StringBuilder();
// For all lines
MInOutLine[] lines = getLines(false);
for (int lineIndex = 0; lineIndex < lines.length; lineIndex++)
@ -1293,353 +1295,326 @@ public class MInOut extends X_M_InOut implements DocAction
MInOutLine sLine = lines[lineIndex];
MProduct product = sLine.getProduct();
// Qty & Type
String MovementType = getMovementType();
BigDecimal Qty = sLine.getMovementQty();
if (MovementType.charAt(1) == '-') // C- Customer Shipment - V- Vendor Return
Qty = Qty.negate();
// Update Order Line
MOrderLine oLine = null;
if (sLine.getC_OrderLine_ID() != 0)
try
{
oLine = new MOrderLine (getCtx(), sLine.getC_OrderLine_ID(), get_TrxName());
if (log.isLoggable(Level.FINE)) log.fine("OrderLine - Reserved=" + oLine.getQtyReserved()
+ ", Delivered=" + oLine.getQtyDelivered());
}
// Load RMA Line
MRMALine rmaLine = null;
if (sLine.getM_RMALine_ID() != 0)
{
rmaLine = new MRMALine(getCtx(), sLine.getM_RMALine_ID(), get_TrxName());
}
if (log.isLoggable(Level.INFO)) log.info("Line=" + sLine.getLine() + " - Qty=" + sLine.getMovementQty());
// Stock Movement - Counterpart MOrder.reserveStock
if (product != null
&& product.isStocked() )
{
//Ignore the Material Policy when is Reverse Correction
if(!isReversal())
// Qty & Type
String MovementType = getMovementType();
BigDecimal Qty = sLine.getMovementQty();
if (MovementType.charAt(1) == '-') // C- Customer Shipment - V- Vendor Return
Qty = Qty.negate();
// Update Order Line
MOrderLine oLine = null;
if (sLine.getC_OrderLine_ID() != 0)
{
BigDecimal movementQty = sLine.getMovementQty();
BigDecimal qtyOnLineMA = MInOutLineMA.getManualQty(sLine.getM_InOutLine_ID(), get_TrxName());
if ( (movementQty.signum() != 0 && qtyOnLineMA.signum() != 0 && movementQty.signum() != qtyOnLineMA.signum()) // must have same sign
|| (qtyOnLineMA.abs().compareTo(movementQty.abs())>0)) { // compare absolute values
// More then line qty on attribute tab for line 10
m_processMsg = "@Over_Qty_On_Attribute_Tab@ " + sLine.getLine();
return DOCSTATUS_Invalid;
}
checkMaterialPolicy(sLine,movementQty.subtract(qtyOnLineMA));
oLine = new MOrderLine (getCtx(), sLine.getC_OrderLine_ID(), get_TrxName());
if (log.isLoggable(Level.FINE)) log.fine("OrderLine - Reserved=" + oLine.getQtyReserved()
+ ", Delivered=" + oLine.getQtyDelivered());
}
log.fine("Material Transaction");
MTransaction mtrx = null;
//
BigDecimal overReceipt = BigDecimal.ZERO;
if (!isReversal())
// Load RMA Line
MRMALine rmaLine = null;
if (sLine.getM_RMALine_ID() != 0)
{
rmaLine = new MRMALine(getCtx(), sLine.getM_RMALine_ID(), get_TrxName());
}
if (log.isLoggable(Level.INFO)) log.info("Line=" + sLine.getLine() + " - Qty=" + sLine.getMovementQty());
// Stock Movement - Counterpart MOrder.reserveStock
if (product != null
&& product.isStocked() )
{
if (oLine != null)
//Ignore the Material Policy when is Reverse Correction
if(!isReversal())
{
BigDecimal toDelivered = oLine.getQtyOrdered()
.subtract(oLine.getQtyDelivered());
if (toDelivered.signum() < 0) // IDEMPIERE-2889
toDelivered = Env.ZERO;
if (sLine.getMovementQty().compareTo(toDelivered) > 0)
overReceipt = sLine.getMovementQty().subtract(
toDelivered);
if (overReceipt.signum() != 0)
{
sLine.setQtyOverReceipt(overReceipt);
sLine.saveEx();
BigDecimal movementQty = sLine.getMovementQty();
BigDecimal qtyOnLineMA = MInOutLineMA.getManualQty(sLine.getM_InOutLine_ID(), get_TrxName());
if ( (movementQty.signum() != 0 && qtyOnLineMA.signum() != 0 && movementQty.signum() != qtyOnLineMA.signum()) // must have same sign
|| (qtyOnLineMA.abs().compareTo(movementQty.abs())>0)) { // compare absolute values
// More then line qty on attribute tab for line 10
m_processMsg = "@Over_Qty_On_Attribute_Tab@ " + sLine.getLine();
return DOCSTATUS_Invalid;
}
checkMaterialPolicy(sLine,movementQty.subtract(qtyOnLineMA));
}
}
else
{
overReceipt = sLine.getQtyOverReceipt();
}
BigDecimal orderedQtyToUpdate = sLine.getMovementQty().subtract(overReceipt);
//
if (sLine.getM_AttributeSetInstance_ID() == 0)
{
MInOutLineMA mas[] = MInOutLineMA.get(getCtx(),
sLine.getM_InOutLine_ID(), get_TrxName());
for (int j = 0; j < mas.length; j++)
log.fine("Material Transaction");
MTransaction mtrx = null;
//
BigDecimal overReceipt = BigDecimal.ZERO;
if (!isReversal())
{
MInOutLineMA ma = mas[j];
BigDecimal QtyMA = ma.getMovementQty();
if (MovementType.charAt(1) == '-') // C- Customer Shipment - V- Vendor Return
QtyMA = QtyMA.negate();
// Update Storage - see also VMatch.createMatchRecord
if (oLine != null)
{
BigDecimal toDelivered = oLine.getQtyOrdered()
.subtract(oLine.getQtyDelivered());
if (toDelivered.signum() < 0) // IDEMPIERE-2889
toDelivered = Env.ZERO;
if (sLine.getMovementQty().compareTo(toDelivered) > 0)
overReceipt = sLine.getMovementQty().subtract(
toDelivered);
if (overReceipt.signum() != 0)
{
sLine.setQtyOverReceipt(overReceipt);
sLine.saveEx();
}
}
}
else
{
overReceipt = sLine.getQtyOverReceipt();
}
BigDecimal orderedQtyToUpdate = sLine.getMovementQty().subtract(overReceipt);
//
if (sLine.getM_AttributeSetInstance_ID() == 0)
{
MInOutLineMA mas[] = MInOutLineMA.get(getCtx(),
sLine.getM_InOutLine_ID(), get_TrxName());
for (int j = 0; j < mas.length; j++)
{
MInOutLineMA ma = mas[j];
BigDecimal QtyMA = ma.getMovementQty();
if (MovementType.charAt(1) == '-') // C- Customer Shipment - V- Vendor Return
QtyMA = QtyMA.negate();
// Update Storage - see also VMatch.createMatchRecord
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
sLine.getM_Locator_ID(),
sLine.getM_Product_ID(),
ma.getM_AttributeSetInstance_ID(),
QtyMA,ma.getDateMaterialPolicy(),
get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory OnHand (MA) [" + product.getValue() + "] - " + lastError;
return DocAction.STATUS_Invalid;
}
// Create Transaction
mtrx = new MTransaction (getCtx(), sLine.getAD_Org_ID(),
MovementType, sLine.getM_Locator_ID(),
sLine.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),
QtyMA, getMovementDate(), get_TrxName());
mtrx.setM_InOutLine_ID(sLine.getM_InOutLine_ID());
if (!mtrx.save())
{
m_processMsg = "Could not create Material Transaction (MA) [" + product.getValue() + "]";
return DocAction.STATUS_Invalid;
}
}
if (oLine!=null && mtrx!=null && oLine.getQtyOrdered().signum() > 0)
{
if (sLine.getC_OrderLine_ID() != 0)
{
if (!MStorageReservation.add(getCtx(), oLine.getM_Warehouse_ID(),
sLine.getM_Product_ID(),
oLine.getM_AttributeSetInstance_ID(),
orderedQtyToUpdate.negate(),
isSOTrx(),
get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory " + (isSOTrx()? "Reserved" : "Ordered") + " (MA) - [" + product.getValue() + "] - " + lastError;
return DocAction.STATUS_Invalid;
}
}
}
}
// sLine.getM_AttributeSetInstance_ID() != 0
if (mtrx == null)
{
Timestamp dateMPolicy= null;
MStorageOnHand[] storages = MStorageOnHand.getWarehouse(getCtx(), 0,
sLine.getM_Product_ID(), sLine.getM_AttributeSetInstance_ID(), null,
MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), false,
sLine.getM_Locator_ID(), get_TrxName());
for (MStorageOnHand storage : storages) {
if (storage.getQtyOnHand().compareTo(sLine.getMovementQty()) >= 0) {
dateMPolicy = storage.getDateMaterialPolicy();
break;
}
}
if (dateMPolicy == null && storages.length > 0)
dateMPolicy = storages[0].getDateMaterialPolicy();
if(dateMPolicy==null)
dateMPolicy = getMovementDate();
// Fallback: Update Storage - see also VMatch.createMatchRecord
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
sLine.getM_Locator_ID(),
sLine.getM_Product_ID(),
ma.getM_AttributeSetInstance_ID(),
QtyMA,ma.getDateMaterialPolicy(),
get_TrxName()))
sLine.getM_AttributeSetInstance_ID(),
Qty,dateMPolicy,get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory OnHand (MA) [" + product.getValue() + "] - " + lastError;
return DocAction.STATUS_Invalid;
}
// Create Transaction
mtrx = new MTransaction (getCtx(), sLine.getAD_Org_ID(),
MovementType, sLine.getM_Locator_ID(),
sLine.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),
QtyMA, getMovementDate(), get_TrxName());
mtrx.setM_InOutLine_ID(sLine.getM_InOutLine_ID());
if (!mtrx.save())
{
m_processMsg = "Could not create Material Transaction (MA) [" + product.getValue() + "]";
m_processMsg = "Cannot correct Inventory OnHand [" + product.getValue() + "] - " + lastError;
return DocAction.STATUS_Invalid;
}
}
if (oLine!=null && mtrx!=null && oLine.getQtyOrdered().signum() > 0)
{
if (sLine.getC_OrderLine_ID() != 0)
if (oLine!=null && oLine.getQtyOrdered().signum() > 0)
{
if (!MStorageReservation.add(getCtx(), oLine.getM_Warehouse_ID(),
sLine.getM_Product_ID(),
oLine.getM_AttributeSetInstance_ID(),
orderedQtyToUpdate.negate(),
isSOTrx(),
get_TrxName()))
orderedQtyToUpdate.negate(), isSOTrx(), get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory " + (isSOTrx()? "Reserved" : "Ordered") + " (MA) - [" + product.getValue() + "] - " + lastError;
m_processMsg = "Cannot correct Inventory Reserved " + (isSOTrx()? "Reserved [" :"Ordered [") + product.getValue() + "]";
return DocAction.STATUS_Invalid;
}
}
}
}
// sLine.getM_AttributeSetInstance_ID() != 0
if (mtrx == null)
{
Timestamp dateMPolicy= null;
MStorageOnHand[] storages = MStorageOnHand.getWarehouse(getCtx(), 0,
sLine.getM_Product_ID(), sLine.getM_AttributeSetInstance_ID(), null,
MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), false,
sLine.getM_Locator_ID(), get_TrxName());
for (MStorageOnHand storage : storages) {
if (storage.getQtyOnHand().compareTo(sLine.getMovementQty()) >= 0) {
dateMPolicy = storage.getDateMaterialPolicy();
break;
}
}
if (dateMPolicy == null && storages.length > 0)
dateMPolicy = storages[0].getDateMaterialPolicy();
if(dateMPolicy==null)
dateMPolicy = getMovementDate();
// Fallback: Update Storage - see also VMatch.createMatchRecord
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
sLine.getM_Locator_ID(),
sLine.getM_Product_ID(),
sLine.getM_AttributeSetInstance_ID(),
Qty,dateMPolicy,get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory OnHand [" + product.getValue() + "] - " + lastError;
return DocAction.STATUS_Invalid;
}
if (oLine!=null && oLine.getQtyOrdered().signum() > 0)
{
if (!MStorageReservation.add(getCtx(), oLine.getM_Warehouse_ID(),
sLine.getM_Product_ID(),
oLine.getM_AttributeSetInstance_ID(),
orderedQtyToUpdate.negate(), isSOTrx(), get_TrxName()))
// FallBack: Create Transaction
mtrx = new MTransaction (getCtx(), sLine.getAD_Org_ID(),
MovementType, sLine.getM_Locator_ID(),
sLine.getM_Product_ID(), sLine.getM_AttributeSetInstance_ID(),
Qty, getMovementDate(), get_TrxName());
mtrx.setM_InOutLine_ID(sLine.getM_InOutLine_ID());
if (!mtrx.save())
{
m_processMsg = "Cannot correct Inventory Reserved " + (isSOTrx()? "Reserved [" :"Ordered [") + product.getValue() + "]";
m_processMsg = CLogger.retrieveErrorString("Could not create Material Transaction [" + product.getValue() + "]");
return DocAction.STATUS_Invalid;
}
}
// FallBack: Create Transaction
mtrx = new MTransaction (getCtx(), sLine.getAD_Org_ID(),
MovementType, sLine.getM_Locator_ID(),
sLine.getM_Product_ID(), sLine.getM_AttributeSetInstance_ID(),
Qty, getMovementDate(), get_TrxName());
mtrx.setM_InOutLine_ID(sLine.getM_InOutLine_ID());
if (!mtrx.save())
} // stock movement
// Correct Order Line
if (product != null && oLine != null) // other in VMatch.createMatchRecord
{
oLine.setQtyReserved(oLine.getQtyReserved().subtract(sLine.getMovementQty().subtract(sLine.getQtyOverReceipt())));
}
// Update Sales Order Line
if (oLine != null)
{
if (isSOTrx() // PO is done by Matching
|| sLine.getM_Product_ID() == 0) // PO Charges, empty lines
{
m_processMsg = CLogger.retrieveErrorString("Could not create Material Transaction [" + product.getValue() + "]");
if (isSOTrx())
oLine.setQtyDelivered(oLine.getQtyDelivered().subtract(Qty));
else
oLine.setQtyDelivered(oLine.getQtyDelivered().add(Qty));
oLine.setDateDelivered(getMovementDate()); // overwrite=last
}
if (!oLine.save())
{
m_processMsg = "Could not update Order Line";
return DocAction.STATUS_Invalid;
}
}
} // stock movement
// Correct Order Line
if (product != null && oLine != null) // other in VMatch.createMatchRecord
{
oLine.setQtyReserved(oLine.getQtyReserved().subtract(sLine.getMovementQty().subtract(sLine.getQtyOverReceipt())));
}
// Update Sales Order Line
if (oLine != null)
{
if (isSOTrx() // PO is done by Matching
|| sLine.getM_Product_ID() == 0) // PO Charges, empty lines
{
if (isSOTrx())
oLine.setQtyDelivered(oLine.getQtyDelivered().subtract(Qty));
else
oLine.setQtyDelivered(oLine.getQtyDelivered().add(Qty));
oLine.setDateDelivered(getMovementDate()); // overwrite=last
if (log.isLoggable(Level.FINE)) log.fine("OrderLine -> Reserved=" + oLine.getQtyReserved()
+ ", Delivered=" + oLine.getQtyReserved());
}
if (!oLine.save())
// Update RMA Line Qty Delivered
else if (rmaLine != null)
{
if (isSOTrx())
{
rmaLine.setQtyDelivered(rmaLine.getQtyDelivered().add(Qty));
}
else
{
rmaLine.setQtyDelivered(rmaLine.getQtyDelivered().subtract(Qty));
}
if (!rmaLine.save())
{
m_processMsg = "Could not update RMA Line";
return DocAction.STATUS_Invalid;
}
}
// Create Asset for SO
if (product != null
&& isSOTrx()
&& product.isCreateAsset()
&& !product.getM_Product_Category().getA_Asset_Group().isFixedAsset()
&& sLine.getMovementQty().signum() > 0
&& !isReversal())
{
m_processMsg = "Could not update Order Line";
return DocAction.STATUS_Invalid;
}
else
if (log.isLoggable(Level.FINE)) log.fine("OrderLine -> Reserved=" + oLine.getQtyReserved()
+ ", Delivered=" + oLine.getQtyReserved());
}
// Update RMA Line Qty Delivered
else if (rmaLine != null)
{
if (isSOTrx())
{
rmaLine.setQtyDelivered(rmaLine.getQtyDelivered().add(Qty));
}
else
{
rmaLine.setQtyDelivered(rmaLine.getQtyDelivered().subtract(Qty));
}
if (!rmaLine.save())
{
m_processMsg = "Could not update RMA Line";
return DocAction.STATUS_Invalid;
}
}
// Create Asset for SO
if (product != null
&& isSOTrx()
&& product.isCreateAsset()
&& !product.getM_Product_Category().getA_Asset_Group().isFixedAsset()
&& sLine.getMovementQty().signum() > 0
&& !isReversal())
{
log.fine("Asset");
info.append("@A_Asset_ID@: ");
int noAssets = sLine.getMovementQty().intValue();
if (!product.isOneAssetPerUOM())
noAssets = 1;
for (int i = 0; i < noAssets; i++)
{
if (i > 0)
info.append(" - ");
int deliveryCount = i+1;
log.fine("Asset");
info.append("@A_Asset_ID@: ");
int noAssets = sLine.getMovementQty().intValue();
if (!product.isOneAssetPerUOM())
deliveryCount = 0;
MAsset asset = new MAsset (this, sLine, deliveryCount);
if (!asset.save(get_TrxName()))
noAssets = 1;
for (int i = 0; i < noAssets; i++)
{
m_processMsg = "Could not create Asset";
return DocAction.STATUS_Invalid;
}
info.append(asset.getValue());
}
} // Asset
// Matching
if (!isSOTrx()
&& sLine.getM_Product_ID() != 0
&& !isReversal())
{
BigDecimal matchQty = sLine.getMovementQty();
// Invoice - Receipt Match (requires Product)
MInvoiceLine iLine = MInvoiceLine.getOfInOutLine (sLine);
if (iLine != null && iLine.getM_Product_ID() != 0)
{
if (matchQty.compareTo(iLine.getQtyInvoiced())>0)
matchQty = iLine.getQtyInvoiced();
MMatchInv[] matches = MMatchInv.get(getCtx(),
sLine.getM_InOutLine_ID(), iLine.getC_InvoiceLine_ID(), get_TrxName());
if (matches == null || matches.length == 0)
{
MMatchInv inv = new MMatchInv (iLine, getMovementDate(), matchQty);
if (sLine.getM_AttributeSetInstance_ID() != iLine.getM_AttributeSetInstance_ID())
if (i > 0)
info.append(" - ");
int deliveryCount = i+1;
if (!product.isOneAssetPerUOM())
deliveryCount = 0;
MAsset asset = new MAsset (this, sLine, deliveryCount);
if (!asset.save(get_TrxName()))
{
iLine.setM_AttributeSetInstance_ID(sLine.getM_AttributeSetInstance_ID());
iLine.saveEx(); // update matched invoice with ASI
inv.setM_AttributeSetInstance_ID(sLine.getM_AttributeSetInstance_ID());
}
if (!inv.save(get_TrxName()))
{
m_processMsg = CLogger.retrieveErrorString("Could not create Inv Matching");
m_processMsg = "Could not create Asset";
return DocAction.STATUS_Invalid;
}
addDocsPostProcess(inv);
info.append(asset.getValue());
}
}
// Link to Order
if (sLine.getC_OrderLine_ID() != 0)
} // Asset
// Matching
if (!isSOTrx()
&& sLine.getM_Product_ID() != 0
&& !isReversal())
{
log.fine("PO Matching");
// Ship - PO
MMatchPO po = MMatchPO.create (null, sLine, getMovementDate(), matchQty);
if (po != null) {
if (!po.save(get_TrxName()))
BigDecimal matchQty = sLine.getMovementQty();
// Invoice - Receipt Match (requires Product)
MInvoiceLine iLine = MInvoiceLine.getOfInOutLine (sLine);
if (iLine != null && iLine.getM_Product_ID() != 0)
{
if (matchQty.compareTo(iLine.getQtyInvoiced())>0)
matchQty = iLine.getQtyInvoiced();
MMatchInv[] matches = MMatchInv.get(getCtx(),
sLine.getM_InOutLine_ID(), iLine.getC_InvoiceLine_ID(), get_TrxName());
if (matches == null || matches.length == 0)
{
m_processMsg = "Could not create PO Matching";
return DocAction.STATUS_Invalid;
}
if (!po.isPosted())
addDocsPostProcess(po);
MMatchInv matchInvCreated = po.getMatchInvCreated();
if (matchInvCreated != null) {
addDocsPostProcess(matchInvCreated);
MMatchInv inv = new MMatchInv (iLine, getMovementDate(), matchQty);
if (sLine.getM_AttributeSetInstance_ID() != iLine.getM_AttributeSetInstance_ID())
{
iLine.setM_AttributeSetInstance_ID(sLine.getM_AttributeSetInstance_ID());
iLine.saveEx(); // update matched invoice with ASI
inv.setM_AttributeSetInstance_ID(sLine.getM_AttributeSetInstance_ID());
}
if (!inv.save(get_TrxName()))
{
m_processMsg = CLogger.retrieveErrorString("Could not create Inv Matching");
return DocAction.STATUS_Invalid;
}
addDocsPostProcess(inv);
}
}
// Update PO with ASI
if ( oLine != null && oLine.getM_AttributeSetInstance_ID() == 0
&& sLine.getMovementQty().compareTo(oLine.getQtyOrdered()) == 0) // just if full match [ 1876965 ]
// Link to Order
if (sLine.getC_OrderLine_ID() != 0)
{
oLine.setM_AttributeSetInstance_ID(sLine.getM_AttributeSetInstance_ID());
oLine.saveEx(get_TrxName());
}
}
else // No Order - Try finding links via Invoice
{
// Invoice has an Order Link
if (iLine != null && iLine.getC_OrderLine_ID() != 0)
{
// Invoice is created before Shipment
log.fine("PO(Inv) Matching");
// Ship - Invoice
MMatchPO po = MMatchPO.create (iLine, sLine,
getMovementDate(), matchQty);
log.fine("PO Matching");
// Ship - PO
MMatchPO po = MMatchPO.create (null, sLine, getMovementDate(), matchQty);
if (po != null) {
if (!po.save(get_TrxName()))
{
m_processMsg = "Could not create PO(Inv) Matching";
m_processMsg = "Could not create PO Matching";
return DocAction.STATUS_Invalid;
}
if (!po.isPosted())
addDocsPostProcess(po);
MMatchInv matchInvCreated = po.getMatchInvCreated();
if (matchInvCreated != null) {
addDocsPostProcess(matchInvCreated);
}
}
// Update PO with ASI
oLine = new MOrderLine (getCtx(), iLine.getC_OrderLine_ID(), get_TrxName());
if ( oLine != null && oLine.getM_AttributeSetInstance_ID() == 0
&& sLine.getMovementQty().compareTo(oLine.getQtyOrdered()) == 0) // just if full match [ 1876965 ]
{
@ -1647,11 +1622,52 @@ public class MInOut extends X_M_InOut implements DocAction
oLine.saveEx(get_TrxName());
}
}
} // No Order
} // PO Matching
else // No Order - Try finding links via Invoice
{
// Invoice has an Order Link
if (iLine != null && iLine.getC_OrderLine_ID() != 0)
{
// Invoice is created before Shipment
log.fine("PO(Inv) Matching");
// Ship - Invoice
MMatchPO po = MMatchPO.create (iLine, sLine,
getMovementDate(), matchQty);
if (po != null) {
if (!po.save(get_TrxName()))
{
m_processMsg = "Could not create PO(Inv) Matching";
return DocAction.STATUS_Invalid;
}
if (!po.isPosted())
addDocsPostProcess(po);
}
// Update PO with ASI
oLine = new MOrderLine (getCtx(), iLine.getC_OrderLine_ID(), get_TrxName());
if ( oLine != null && oLine.getM_AttributeSetInstance_ID() == 0
&& sLine.getMovementQty().compareTo(oLine.getQtyOrdered()) == 0) // just if full match [ 1876965 ]
{
oLine.setM_AttributeSetInstance_ID(sLine.getM_AttributeSetInstance_ID());
oLine.saveEx(get_TrxName());
}
}
} // No Order
} // PO Matching
}
catch (NegativeInventoryDisallowedException e)
{
log.severe(e.getMessage());
errors.append(Msg.getElement(getCtx(), "Line")).append(" ").append(sLine.getLine()).append(": ");
errors.append(e.getMessage()).append("\n");
}
} // for all lines
if (errors.toString().length() > 0)
{
m_processMsg = errors.toString();
return DocAction.STATUS_Invalid;
}
// Counter Documents
MInOut counter = createCounterDoc();
if (counter != null)

View File

@ -24,6 +24,7 @@ import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
import org.adempiere.exceptions.PeriodClosedException;
import org.compiere.process.DocAction;
import org.compiere.process.DocumentEngine;
@ -435,6 +436,7 @@ public class MInventory extends X_M_Inventory implements DocAction
approveIt();
if (log.isLoggable(Level.INFO)) log.info(toString());
StringBuilder errors = new StringBuilder();
MInventoryLine[] lines = getLines(false);
for (MInventoryLine line : lines)
{
@ -442,98 +444,159 @@ public class MInventory extends X_M_Inventory implements DocAction
continue;
MProduct product = line.getProduct();
BigDecimal qtyDiff = Env.ZERO;
if (MDocType.DOCSUBTYPEINV_InternalUseInventory.equals(docSubTypeInv))
qtyDiff = line.getQtyInternalUse().negate();
else if (MDocType.DOCSUBTYPEINV_PhysicalInventory.equals(docSubTypeInv))
qtyDiff = line.getQtyCount().subtract(line.getQtyBook());
else if (MDocType.DOCSUBTYPEINV_CostAdjustment.equals(docSubTypeInv))
try
{
if (!isReversal())
BigDecimal qtyDiff = Env.ZERO;
if (MDocType.DOCSUBTYPEINV_InternalUseInventory.equals(docSubTypeInv))
qtyDiff = line.getQtyInternalUse().negate();
else if (MDocType.DOCSUBTYPEINV_PhysicalInventory.equals(docSubTypeInv))
qtyDiff = line.getQtyCount().subtract(line.getQtyBook());
else if (MDocType.DOCSUBTYPEINV_CostAdjustment.equals(docSubTypeInv))
{
BigDecimal currentCost = line.getCurrentCostPrice();
MClient client = MClient.get(getCtx(), getAD_Client_ID());
MAcctSchema as = client.getAcctSchema();
MAcctSchema[] ass = MAcctSchema.getClientAcctSchema(getCtx(), client.get_ID());
if (as.getC_Currency_ID() != getC_Currency_ID())
if (!isReversal())
{
for (int i = 0; i < ass.length ; i ++)
BigDecimal currentCost = line.getCurrentCostPrice();
MClient client = MClient.get(getCtx(), getAD_Client_ID());
MAcctSchema as = client.getAcctSchema();
MAcctSchema[] ass = MAcctSchema.getClientAcctSchema(getCtx(), client.get_ID());
if (as.getC_Currency_ID() != getC_Currency_ID())
{
MAcctSchema a = ass[i];
if (a.getC_Currency_ID() == getC_Currency_ID())
as = a ;
for (int i = 0; i < ass.length ; i ++)
{
MAcctSchema a = ass[i];
if (a.getC_Currency_ID() == getC_Currency_ID())
as = a ;
}
}
MCost cost = product.getCostingRecord(as, getAD_Org_ID(), line.getM_AttributeSetInstance_ID(), getCostingMethod());
if (cost != null && cost.getCurrentCostPrice().compareTo(currentCost) != 0)
{
m_processMsg = "Current Cost for Line " + line.getLine() + " have changed.";
return DocAction.STATUS_Invalid;
}
}
MCost cost = product.getCostingRecord(as, getAD_Org_ID(), line.getM_AttributeSetInstance_ID(), getCostingMethod());
if (cost != null && cost.getCurrentCostPrice().compareTo(currentCost) != 0)
{
m_processMsg = "Current Cost for Line " + line.getLine() + " have changed.";
return DocAction.STATUS_Invalid;
}
}
}
//If Quantity Count minus Quantity Book = Zero, then no change in Inventory
if (qtyDiff.signum() == 0)
continue;
//Ignore the Material Policy when is Reverse Correction
if(!isReversal()){
BigDecimal qtyOnLineMA = MInventoryLineMA.getManualQty(line.getM_InventoryLine_ID(), get_TrxName());
if(qtyDiff.signum()<0){
if(qtyOnLineMA.compareTo(qtyDiff)<0){
m_processMsg = "@Over_Qty_On_Attribute_Tab@ " + line.getLine();
return DOCSTATUS_Invalid;
}
}else{
if(qtyOnLineMA.compareTo(qtyDiff)>0){
m_processMsg = "@Over_Qty_On_Attribute_Tab@ " + line.getLine();
return DOCSTATUS_Invalid;
//If Quantity Count minus Quantity Book = Zero, then no change in Inventory
if (qtyDiff.signum() == 0)
continue;
//Ignore the Material Policy when is Reverse Correction
if(!isReversal()){
BigDecimal qtyOnLineMA = MInventoryLineMA.getManualQty(line.getM_InventoryLine_ID(), get_TrxName());
if(qtyDiff.signum()<0){
if(qtyOnLineMA.compareTo(qtyDiff)<0){
m_processMsg = "@Over_Qty_On_Attribute_Tab@ " + line.getLine();
return DOCSTATUS_Invalid;
}
}else{
if(qtyOnLineMA.compareTo(qtyDiff)>0){
m_processMsg = "@Over_Qty_On_Attribute_Tab@ " + line.getLine();
return DOCSTATUS_Invalid;
}
}
checkMaterialPolicy(line, qtyDiff.subtract(qtyOnLineMA));
}
checkMaterialPolicy(line, qtyDiff.subtract(qtyOnLineMA));
}
// Stock Movement - Counterpart MOrder.reserveStock
if (product != null
&& product.isStocked() )
{
log.fine("Material Transaction");
MTransaction mtrx = null;
//If AttributeSetInstance = Zero then create new AttributeSetInstance use Inventory Line MA else use current AttributeSetInstance
if (line.getM_AttributeSetInstance_ID() == 0 || qtyDiff.compareTo(Env.ZERO) == 0)
// Stock Movement - Counterpart MOrder.reserveStock
if (product != null
&& product.isStocked() )
{
MInventoryLineMA mas[] = MInventoryLineMA.get(getCtx(),
line.getM_InventoryLine_ID(), get_TrxName());
for (int j = 0; j < mas.length; j++)
log.fine("Material Transaction");
MTransaction mtrx = null;
//If AttributeSetInstance = Zero then create new AttributeSetInstance use Inventory Line MA else use current AttributeSetInstance
if (line.getM_AttributeSetInstance_ID() == 0 || qtyDiff.compareTo(Env.ZERO) == 0)
{
MInventoryLineMA ma = mas[j];
BigDecimal QtyMA = ma.getMovementQty();
BigDecimal QtyNew = QtyMA.add(qtyDiff);
if (log.isLoggable(Level.FINE)) log.fine("Diff=" + qtyDiff
+ " - Instance OnHand=" + QtyMA + "->" + QtyNew);
MInventoryLineMA mas[] = MInventoryLineMA.get(getCtx(),
line.getM_InventoryLine_ID(), get_TrxName());
for (int j = 0; j < mas.length; j++)
{
MInventoryLineMA ma = mas[j];
BigDecimal QtyMA = ma.getMovementQty();
BigDecimal QtyNew = QtyMA.add(qtyDiff);
if (log.isLoggable(Level.FINE)) log.fine("Diff=" + qtyDiff
+ " - Instance OnHand=" + QtyMA + "->" + QtyNew);
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
line.getM_Locator_ID(),
line.getM_Product_ID(),
ma.getM_AttributeSetInstance_ID(),
QtyMA.negate(),ma.getDateMaterialPolicy(), get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory (MA) - " + lastError;
return DocAction.STATUS_Invalid;
}
// Only Update Date Last Inventory if is a Physical Inventory
if (MDocType.DOCSUBTYPEINV_PhysicalInventory.equals(docSubTypeInv))
{
MStorageOnHand storage = MStorageOnHand.get(getCtx(), line.getM_Locator_ID(),
line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),ma.getDateMaterialPolicy(),get_TrxName());
storage.setDateLastInventory(getMovementDate());
if (!storage.save(get_TrxName()))
{
m_processMsg = "Storage not updated(2)";
return DocAction.STATUS_Invalid;
}
}
String m_MovementType =null;
if(QtyMA.negate().compareTo(Env.ZERO) > 0 )
m_MovementType = MTransaction.MOVEMENTTYPE_InventoryIn;
else
m_MovementType = MTransaction.MOVEMENTTYPE_InventoryOut;
// Transaction
mtrx = new MTransaction (getCtx(), line.getAD_Org_ID(), m_MovementType,
line.getM_Locator_ID(), line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),
QtyMA.negate(), getMovementDate(), get_TrxName());
mtrx.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
if (!mtrx.save())
{
m_processMsg = "Transaction not inserted(2)";
return DocAction.STATUS_Invalid;
}
qtyDiff = QtyNew;
}
}
//sLine.getM_AttributeSetInstance_ID() != 0
// Fallback
if (mtrx == null)
{
Timestamp dateMPolicy= qtyDiff.signum() > 0 ? getMovementDate() : null;
if (line.getM_AttributeSetInstance_ID() > 0)
{
Timestamp t = MStorageOnHand.getDateMaterialPolicy(line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), line.get_TrxName());
if (t != null)
dateMPolicy = t;
}
//Fallback: Update Storage - see also VMatch.createMatchRecord
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
line.getM_Locator_ID(),
line.getM_Product_ID(),
ma.getM_AttributeSetInstance_ID(),
QtyMA.negate(),ma.getDateMaterialPolicy(), get_TrxName()))
line.getM_AttributeSetInstance_ID(),
qtyDiff,dateMPolicy,get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory (MA) - " + lastError;
m_processMsg = "Cannot correct Inventory OnHand (MA) - " + lastError;
return DocAction.STATUS_Invalid;
}
// Only Update Date Last Inventory if is a Physical Inventory
if (MDocType.DOCSUBTYPEINV_PhysicalInventory.equals(docSubTypeInv))
{
MStorageOnHand storage = MStorageOnHand.get(getCtx(), line.getM_Locator_ID(),
line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),ma.getDateMaterialPolicy(),get_TrxName());
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),dateMPolicy, get_TrxName());
storage.setDateLastInventory(getMovementDate());
if (!storage.save(get_TrxName()))
{
@ -541,87 +604,40 @@ public class MInventory extends X_M_Inventory implements DocAction
return DocAction.STATUS_Invalid;
}
}
String m_MovementType =null;
if(QtyMA.negate().compareTo(Env.ZERO) > 0 )
String m_MovementType = null;
if(qtyDiff.compareTo(Env.ZERO) > 0 )
m_MovementType = MTransaction.MOVEMENTTYPE_InventoryIn;
else
m_MovementType = MTransaction.MOVEMENTTYPE_InventoryOut;
// Transaction
mtrx = new MTransaction (getCtx(), line.getAD_Org_ID(), m_MovementType,
line.getM_Locator_ID(), line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),
QtyMA.negate(), getMovementDate(), get_TrxName());
mtrx.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
if (!mtrx.save())
{
m_processMsg = "Transaction not inserted(2)";
return DocAction.STATUS_Invalid;
}
qtyDiff = QtyNew;
}
}
//sLine.getM_AttributeSetInstance_ID() != 0
// Fallback
if (mtrx == null)
{
Timestamp dateMPolicy= qtyDiff.signum() > 0 ? getMovementDate() : null;
if (line.getM_AttributeSetInstance_ID() > 0)
{
Timestamp t = MStorageOnHand.getDateMaterialPolicy(line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), line.get_TrxName());
if (t != null)
dateMPolicy = t;
}
//Fallback: Update Storage - see also VMatch.createMatchRecord
if (!MStorageOnHand.add(getCtx(), getM_Warehouse_ID(),
line.getM_Locator_ID(),
line.getM_Product_ID(),
line.getM_AttributeSetInstance_ID(),
qtyDiff,dateMPolicy,get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory OnHand (MA) - " + lastError;
return DocAction.STATUS_Invalid;
}
// Only Update Date Last Inventory if is a Physical Inventory
if (MDocType.DOCSUBTYPEINV_PhysicalInventory.equals(docSubTypeInv))
{
MStorageOnHand storage = MStorageOnHand.get(getCtx(), line.getM_Locator_ID(),
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),dateMPolicy, get_TrxName());
storage.setDateLastInventory(getMovementDate());
if (!storage.save(get_TrxName()))
line.getM_Locator_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
qtyDiff, getMovementDate(), get_TrxName());
mtrx.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
if (!mtrx.save())
{
m_processMsg = "Storage not updated(2)";
m_processMsg = "Transaction not inserted(2)";
return DocAction.STATUS_Invalid;
}
}
String m_MovementType = null;
if(qtyDiff.compareTo(Env.ZERO) > 0 )
m_MovementType = MTransaction.MOVEMENTTYPE_InventoryIn;
else
m_MovementType = MTransaction.MOVEMENTTYPE_InventoryOut;
// Transaction
mtrx = new MTransaction (getCtx(), line.getAD_Org_ID(), m_MovementType,
line.getM_Locator_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
qtyDiff, getMovementDate(), get_TrxName());
mtrx.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
if (!mtrx.save())
{
m_processMsg = "Transaction not inserted(2)";
return DocAction.STATUS_Invalid;
}
} // Fallback
} // stock movement
}
} // Fallback
} // stock movement
}
catch (NegativeInventoryDisallowedException e)
{
log.severe(e.getMessage());
errors.append(Msg.getElement(getCtx(), "Line")).append(" ").append(line.getLine()).append(": ");
errors.append(e.getMessage()).append("\n");
}
} // for all lines
if (errors.toString().length() > 0)
{
m_processMsg = errors.toString();
return DocAction.STATUS_Invalid;
}
// User Validation
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
if (valid != null)

View File

@ -24,6 +24,7 @@ import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
import org.adempiere.exceptions.PeriodClosedException;
import org.compiere.process.DocAction;
import org.compiere.process.DocumentEngine;
@ -416,6 +417,7 @@ public class MMovement extends X_M_Movement implements DocAction
approveIt();
if (log.isLoggable(Level.INFO)) log.info(toString());
StringBuilder errors = new StringBuilder();
//
MMovementLine[] lines = getLines(false);
for (int i = 0; i < lines.length; i++)
@ -425,174 +427,190 @@ public class MMovement extends X_M_Movement implements DocAction
//Stock Movement - Counterpart MOrder.reserveStock
MProduct product = line.getProduct();
if (product != null
&& product.isStocked() )
try
{
//Ignore the Material Policy when is Reverse Correction
if(!isReversal()){
BigDecimal qtyOnLineMA = MMovementLineMA.getManualQty(line.getM_MovementLine_ID(), get_TrxName());
BigDecimal movementQty = line.getMovementQty();
if(qtyOnLineMA.compareTo(movementQty)>0)
{
// More then line qty on attribute tab for line 10
m_processMsg = "@Over_Qty_On_Attribute_Tab@ " + line.getLine();
return DOCSTATUS_Invalid;
}
checkMaterialPolicy(line,movementQty.subtract(qtyOnLineMA));
}
if (line.getM_AttributeSetInstance_ID() == 0)
if (product != null
&& product.isStocked() )
{
MMovementLineMA mas[] = MMovementLineMA.get(getCtx(),
line.getM_MovementLine_ID(), get_TrxName());
for (int j = 0; j < mas.length; j++)
//Ignore the Material Policy when is Reverse Correction
if(!isReversal()){
BigDecimal qtyOnLineMA = MMovementLineMA.getManualQty(line.getM_MovementLine_ID(), get_TrxName());
BigDecimal movementQty = line.getMovementQty();
if(qtyOnLineMA.compareTo(movementQty)>0)
{
// More then line qty on attribute tab for line 10
m_processMsg = "@Over_Qty_On_Attribute_Tab@ " + line.getLine();
return DOCSTATUS_Invalid;
}
checkMaterialPolicy(line,movementQty.subtract(qtyOnLineMA));
}
if (line.getM_AttributeSetInstance_ID() == 0)
{
MMovementLineMA ma = mas[j];
//
MMovementLineMA mas[] = MMovementLineMA.get(getCtx(),
line.getM_MovementLine_ID(), get_TrxName());
for (int j = 0; j < mas.length; j++)
{
MMovementLineMA ma = mas[j];
//
MLocator locator = new MLocator (getCtx(), line.getM_Locator_ID(), get_TrxName());
//Update Storage
if (!MStorageOnHand.add(getCtx(),locator.getM_Warehouse_ID(),
line.getM_Locator_ID(),
line.getM_Product_ID(),
ma.getM_AttributeSetInstance_ID(),
ma.getMovementQty().negate(),ma.getDateMaterialPolicy(), get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory OnHand (MA) - " + lastError;
return DocAction.STATUS_Invalid;
}
int M_AttributeSetInstanceTo_ID = line.getM_AttributeSetInstanceTo_ID();
//only can be same asi if locator is different
if (M_AttributeSetInstanceTo_ID == 0 && line.getM_Locator_ID() != line.getM_LocatorTo_ID())
{
M_AttributeSetInstanceTo_ID = ma.getM_AttributeSetInstance_ID();
}
//Update Storage
MLocator locatorTo = new MLocator (getCtx(), line.getM_LocatorTo_ID(), get_TrxName());
if (!MStorageOnHand.add(getCtx(),locatorTo.getM_Warehouse_ID(),
line.getM_LocatorTo_ID(),
line.getM_Product_ID(),
M_AttributeSetInstanceTo_ID,
ma.getMovementQty(),ma.getDateMaterialPolicy(), get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory OnHand (MA) - " + lastError;
return DocAction.STATUS_Invalid;
}
//
trxFrom = new MTransaction (getCtx(), line.getAD_Org_ID(),
MTransaction.MOVEMENTTYPE_MovementFrom,
line.getM_Locator_ID(), line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),
ma.getMovementQty().negate(), getMovementDate(), get_TrxName());
trxFrom.setM_MovementLine_ID(line.getM_MovementLine_ID());
if (!trxFrom.save())
{
m_processMsg = "Transaction From not inserted (MA)";
return DocAction.STATUS_Invalid;
}
//
MTransaction trxTo = new MTransaction (getCtx(), line.getAD_Org_ID(),
MTransaction.MOVEMENTTYPE_MovementTo,
line.getM_LocatorTo_ID(), line.getM_Product_ID(), M_AttributeSetInstanceTo_ID,
ma.getMovementQty(), getMovementDate(), get_TrxName());
trxTo.setM_MovementLine_ID(line.getM_MovementLine_ID());
if (!trxTo.save())
{
m_processMsg = "Transaction To not inserted (MA)";
return DocAction.STATUS_Invalid;
}
}
}
// Fallback - We have ASI
if (trxFrom == null)
{
Timestamp dateMPolicy= null;
MStorageOnHand[] storages = null;
if (line.getMovementQty().compareTo(Env.ZERO) > 0) {
// Find Date Material Policy bases on ASI
storages = MStorageOnHand.getWarehouse(getCtx(), 0,
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), null,
MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), false,
line.getM_Locator_ID(), get_TrxName());
} else {
//Case of reversal
storages = MStorageOnHand.getWarehouse(getCtx(), 0,
line.getM_Product_ID(), line.getM_AttributeSetInstanceTo_ID(), null,
MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), false,
line.getM_LocatorTo_ID(), get_TrxName());
}
for (MStorageOnHand storage : storages) {
if (storage.getQtyOnHand().compareTo(line.getMovementQty()) >= 0) {
dateMPolicy = storage.getDateMaterialPolicy();
break;
}
}
if (dateMPolicy == null && storages.length > 0)
dateMPolicy = storages[0].getDateMaterialPolicy();
MLocator locator = new MLocator (getCtx(), line.getM_Locator_ID(), get_TrxName());
//Update Storage
Timestamp effDateMPolicy = dateMPolicy;
if (dateMPolicy == null && line.getMovementQty().negate().signum() > 0)
effDateMPolicy = getMovementDate();
if (!MStorageOnHand.add(getCtx(),locator.getM_Warehouse_ID(),
line.getM_Locator_ID(),
line.getM_Product_ID(),
ma.getM_AttributeSetInstance_ID(),
ma.getMovementQty().negate(),ma.getDateMaterialPolicy(), get_TrxName()))
line.getM_AttributeSetInstance_ID(),
line.getMovementQty().negate(),effDateMPolicy, get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory OnHand (MA) - " + lastError;
return DocAction.STATUS_Invalid;
}
int M_AttributeSetInstanceTo_ID = line.getM_AttributeSetInstanceTo_ID();
//only can be same asi if locator is different
if (M_AttributeSetInstanceTo_ID == 0 && line.getM_Locator_ID() != line.getM_LocatorTo_ID())
{
M_AttributeSetInstanceTo_ID = ma.getM_AttributeSetInstance_ID();
}
//Update Storage
//Update Storage
effDateMPolicy = dateMPolicy;
if (dateMPolicy == null && line.getMovementQty().signum() > 0)
effDateMPolicy = getMovementDate();
MLocator locatorTo = new MLocator (getCtx(), line.getM_LocatorTo_ID(), get_TrxName());
if (!MStorageOnHand.add(getCtx(),locatorTo.getM_Warehouse_ID(),
line.getM_LocatorTo_ID(),
line.getM_Product_ID(),
M_AttributeSetInstanceTo_ID,
ma.getMovementQty(),ma.getDateMaterialPolicy(), get_TrxName()))
line.getM_AttributeSetInstanceTo_ID(),
line.getMovementQty(),effDateMPolicy, get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory OnHand (MA) - " + lastError;
return DocAction.STATUS_Invalid;
}
//
trxFrom = new MTransaction (getCtx(), line.getAD_Org_ID(),
MTransaction.MOVEMENTTYPE_MovementFrom,
line.getM_Locator_ID(), line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),
ma.getMovementQty().negate(), getMovementDate(), get_TrxName());
line.getM_Locator_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
line.getMovementQty().negate(), getMovementDate(), get_TrxName());
trxFrom.setM_MovementLine_ID(line.getM_MovementLine_ID());
if (!trxFrom.save())
{
m_processMsg = "Transaction From not inserted (MA)";
m_processMsg = "Transaction From not inserted";
return DocAction.STATUS_Invalid;
}
//
MTransaction trxTo = new MTransaction (getCtx(), line.getAD_Org_ID(),
MTransaction.MOVEMENTTYPE_MovementTo,
line.getM_LocatorTo_ID(), line.getM_Product_ID(), M_AttributeSetInstanceTo_ID,
ma.getMovementQty(), getMovementDate(), get_TrxName());
line.getM_LocatorTo_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstanceTo_ID(),
line.getMovementQty(), getMovementDate(), get_TrxName());
trxTo.setM_MovementLine_ID(line.getM_MovementLine_ID());
if (!trxTo.save())
{
m_processMsg = "Transaction To not inserted (MA)";
m_processMsg = "Transaction To not inserted";
return DocAction.STATUS_Invalid;
}
}
}
// Fallback - We have ASI
if (trxFrom == null)
{
Timestamp dateMPolicy= null;
MStorageOnHand[] storages = null;
if (line.getMovementQty().compareTo(Env.ZERO) > 0) {
// Find Date Material Policy bases on ASI
storages = MStorageOnHand.getWarehouse(getCtx(), 0,
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), null,
MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), false,
line.getM_Locator_ID(), get_TrxName());
} else {
//Case of reversal
storages = MStorageOnHand.getWarehouse(getCtx(), 0,
line.getM_Product_ID(), line.getM_AttributeSetInstanceTo_ID(), null,
MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), false,
line.getM_LocatorTo_ID(), get_TrxName());
}
for (MStorageOnHand storage : storages) {
if (storage.getQtyOnHand().compareTo(line.getMovementQty()) >= 0) {
dateMPolicy = storage.getDateMaterialPolicy();
break;
}
}
if (dateMPolicy == null && storages.length > 0)
dateMPolicy = storages[0].getDateMaterialPolicy();
MLocator locator = new MLocator (getCtx(), line.getM_Locator_ID(), get_TrxName());
//Update Storage
Timestamp effDateMPolicy = dateMPolicy;
if (dateMPolicy == null && line.getMovementQty().negate().signum() > 0)
effDateMPolicy = getMovementDate();
if (!MStorageOnHand.add(getCtx(),locator.getM_Warehouse_ID(),
line.getM_Locator_ID(),
line.getM_Product_ID(),
line.getM_AttributeSetInstance_ID(),
line.getMovementQty().negate(),effDateMPolicy, get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory OnHand (MA) - " + lastError;
return DocAction.STATUS_Invalid;
}
//Update Storage
effDateMPolicy = dateMPolicy;
if (dateMPolicy == null && line.getMovementQty().signum() > 0)
effDateMPolicy = getMovementDate();
MLocator locatorTo = new MLocator (getCtx(), line.getM_LocatorTo_ID(), get_TrxName());
if (!MStorageOnHand.add(getCtx(),locatorTo.getM_Warehouse_ID(),
line.getM_LocatorTo_ID(),
line.getM_Product_ID(),
line.getM_AttributeSetInstanceTo_ID(),
line.getMovementQty(),effDateMPolicy, get_TrxName()))
{
String lastError = CLogger.retrieveErrorString("");
m_processMsg = "Cannot correct Inventory OnHand (MA) - " + lastError;
return DocAction.STATUS_Invalid;
}
//
trxFrom = new MTransaction (getCtx(), line.getAD_Org_ID(),
MTransaction.MOVEMENTTYPE_MovementFrom,
line.getM_Locator_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
line.getMovementQty().negate(), getMovementDate(), get_TrxName());
trxFrom.setM_MovementLine_ID(line.getM_MovementLine_ID());
if (!trxFrom.save())
{
m_processMsg = "Transaction From not inserted";
return DocAction.STATUS_Invalid;
}
//
MTransaction trxTo = new MTransaction (getCtx(), line.getAD_Org_ID(),
MTransaction.MOVEMENTTYPE_MovementTo,
line.getM_LocatorTo_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstanceTo_ID(),
line.getMovementQty(), getMovementDate(), get_TrxName());
trxTo.setM_MovementLine_ID(line.getM_MovementLine_ID());
if (!trxTo.save())
{
m_processMsg = "Transaction To not inserted";
return DocAction.STATUS_Invalid;
}
} // Fallback
} // product stock
} // Fallback
} // product stock
}
catch (NegativeInventoryDisallowedException e)
{
log.severe(e.getMessage());
errors.append(Msg.getElement(getCtx(), "Line")).append(" ").append(line.getLine()).append(": ");
errors.append(e.getMessage()).append("\n");
}
} // for all lines
if (errors.toString().length() > 0)
{
m_processMsg = errors.toString();
return DocAction.STATUS_Invalid;
}
// User Validation
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
if (valid != null)

View File

@ -232,4 +232,19 @@ public class MPInstancePara extends X_AD_PInstance_Para
}
return -1;
}
/**
* Get existing AD_PInstance_Para record or create a new one if not found
* @param ctx
* @param AD_PInstance_ID
* @param SeqNo
*/
public static MPInstancePara getOrCreate(Properties ctx, int AD_PInstance_ID, int SeqNo)
{
Query query = new Query(ctx, Table_Name, "AD_PInstance_ID=? AND SeqNo=?", null);
MPInstancePara para = query.setParameters(AD_PInstance_ID, SeqNo).first();
if (para == null)
para = new MPInstancePara(ctx, AD_PInstance_ID, SeqNo);
return para;
}
} // MPInstance_Para

View File

@ -22,8 +22,11 @@ import java.sql.Timestamp;
import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
/**
* Project Issue Model
@ -172,9 +175,57 @@ public class MProjectIssue extends X_C_ProjectIssue
dateMPolicy = t;
}
if (MStorageOnHand.add(getCtx(), loc.getM_Warehouse_ID(), getM_Locator_ID(),
getM_Product_ID(), getM_AttributeSetInstance_ID(),
getMovementQty().negate(),dateMPolicy, get_TrxName()))
boolean ok = true;
try
{
if (getMovementQty().negate().signum() < 0)
{
String MMPolicy = product.getMMPolicy();
Timestamp minGuaranteeDate = getMovementDate();
int M_Warehouse_ID = getM_Locator_ID() > 0 ? getM_Locator().getM_Warehouse_ID() : getC_Project().getM_Warehouse_ID();
MStorageOnHand[] storages = MStorageOnHand.getWarehouse(getCtx(), M_Warehouse_ID, getM_Product_ID(), getM_AttributeSetInstance_ID(),
minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, getM_Locator_ID(), get_TrxName(), true);
BigDecimal qtyToIssue = getMovementQty();
for (MStorageOnHand storage: storages)
{
if (storage.getQtyOnHand().compareTo(qtyToIssue) >= 0)
{
storage.addQtyOnHand(qtyToIssue.negate());
qtyToIssue = BigDecimal.ZERO;
}
else
{
qtyToIssue = qtyToIssue.subtract(storage.getQtyOnHand());
storage.addQtyOnHand(storage.getQtyOnHand().negate());
}
if (qtyToIssue.signum() == 0)
break;
}
if (qtyToIssue.signum() > 0)
{
ok = MStorageOnHand.add(getCtx(), loc.getM_Warehouse_ID(), getM_Locator_ID(),
getM_Product_ID(), getM_AttributeSetInstance_ID(),
qtyToIssue.negate(),dateMPolicy, get_TrxName());
}
}
else
{
ok = MStorageOnHand.add(getCtx(), loc.getM_Warehouse_ID(), getM_Locator_ID(),
getM_Product_ID(), getM_AttributeSetInstance_ID(),
getMovementQty().negate(),dateMPolicy, get_TrxName());
}
}
catch (NegativeInventoryDisallowedException e)
{
log.severe(e.getMessage());
StringBuilder error = new StringBuilder();
error.append(Msg.getElement(getCtx(), "Line")).append(" ").append(getLine()).append(": ");
error.append(e.getMessage()).append("\n");
throw new AdempiereException(error.toString());
}
if (ok)
{
if (mTrx.save(get_TrxName()))
{

View File

@ -1328,6 +1328,7 @@ public class MSequence extends X_AD_Sequence
"AD_PINSTANCE",
"AD_PINSTANCE_LOG",
"AD_PINSTANCE_PARA",
"AD_PREFERENCE",
"AD_RECENTITEM",
"AD_REPLICATION_LOG",
"AD_SCHEDULERLOG",

View File

@ -27,11 +27,10 @@ import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
/**
@ -735,7 +734,8 @@ public class MStorageOnHand extends X_M_StorageOnHand
if (getQtyOnHand().signum() == -1) {
MWarehouse wh = MWarehouse.get(Env.getCtx(), getM_Warehouse_ID());
if (wh.isDisallowNegativeInv()) {
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "NegativeInventoryDisallowed"));
throw new NegativeInventoryDisallowedException(getCtx(), getM_Warehouse_ID(), getM_Product_ID(), getM_AttributeSetInstance_ID(), getM_Locator_ID(),
getQtyOnHand().subtract(addition), addition.negate());
}
}
}
@ -899,13 +899,15 @@ public class MStorageOnHand extends X_M_StorageOnHand
if (getQtyOnHand().compareTo(BigDecimal.ZERO) < 0 ||
QtyOnHand.compareTo(Env.ZERO) < 0)
{
log.saveError("Error", Msg.getMsg(getCtx(), "NegativeInventoryDisallowed"));
log.saveError("Error", new NegativeInventoryDisallowedException(getCtx(), getM_Warehouse_ID(), getM_Product_ID(),
getM_AttributeSetInstance_ID(), getM_Locator_ID(), QtyOnHand.subtract(getQtyOnHand()), getQtyOnHand().negate()));
return false;
}
if (getM_AttributeSetInstance_ID() > 0 && getQtyOnHand().signum() < 0)
{
log.saveError("Error", Msg.getMsg(getCtx(), "NegativeInventoryDisallowed"));
log.saveError("Error", new NegativeInventoryDisallowedException(getCtx(), getM_Warehouse_ID(), getM_Product_ID(),
getM_AttributeSetInstance_ID(), getM_Locator_ID(), QtyOnHand.subtract(getQtyOnHand()), getQtyOnHand().negate()));
return false;
}
}

View File

@ -27,6 +27,7 @@ import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.NegativeInventoryDisallowedException;
import org.compiere.model.MBPartner;
import org.compiere.model.MBPartnerLocation;
import org.compiere.model.MDocType;
@ -847,6 +848,7 @@ public class MDDOrder extends X_DD_Order implements DocAction
BigDecimal Volume = Env.ZERO;
BigDecimal Weight = Env.ZERO;
StringBuilder errors = new StringBuilder();
// Always check and (un) Reserve Inventory
for (MDDOrderLine line : lines)
{
@ -874,35 +876,47 @@ public class MDDOrder extends X_DD_Order implements DocAction
MProduct product = line.getProduct();
if (product != null)
{
if (product.isStocked())
try
{
// Update Storage
if (!MStorageOnHand.add(getCtx(), locator_to.getM_Warehouse_ID(), locator_to.getM_Locator_ID(),
line.getM_Product_ID(),
line.getM_AttributeSetInstance_ID(),
Env.ZERO,null, get_TrxName()))
if (product.isStocked())
{
throw new AdempiereException();
}
if (!MStorageOnHand.add(getCtx(), locator_from.getM_Warehouse_ID(), locator_from.getM_Locator_ID(),
line.getM_Product_ID(),
line.getM_AttributeSetInstanceTo_ID(),
Env.ZERO,null, get_TrxName()))
{
throw new AdempiereException();
}
} // stockec
// update line
line.setQtyReserved(line.getQtyReserved().add(reserved_ordered));
line.saveEx();
//
Volume = Volume.add(product.getVolume().multiply(line.getQtyOrdered()));
Weight = Weight.add(product.getWeight().multiply(line.getQtyOrdered()));
// Update Storage
if (!MStorageOnHand.add(getCtx(), locator_to.getM_Warehouse_ID(), locator_to.getM_Locator_ID(),
line.getM_Product_ID(),
line.getM_AttributeSetInstance_ID(),
Env.ZERO,null, get_TrxName()))
{
throw new AdempiereException();
}
if (!MStorageOnHand.add(getCtx(), locator_from.getM_Warehouse_ID(), locator_from.getM_Locator_ID(),
line.getM_Product_ID(),
line.getM_AttributeSetInstanceTo_ID(),
Env.ZERO,null, get_TrxName()))
{
throw new AdempiereException();
}
} // stockec
// update line
line.setQtyReserved(line.getQtyReserved().add(reserved_ordered));
line.saveEx();
//
Volume = Volume.add(product.getVolume().multiply(line.getQtyOrdered()));
Weight = Weight.add(product.getWeight().multiply(line.getQtyOrdered()));
}
catch (NegativeInventoryDisallowedException e)
{
log.severe(e.getMessage());
errors.append(Msg.getElement(getCtx(), "Line")).append(" ").append(line.getLine()).append(": ");
errors.append(e.getMessage()).append("\n");
}
} // product
} // reverse inventory
if (errors.toString().length() > 0)
throw new AdempiereException(errors.toString());
setVolume(Volume);
setWeight(Weight);
} // reserveStock

View File

@ -8,7 +8,7 @@
<cq:property key="target.os" value="*"/>
<cq:property key="target.ws" value="*"/>
<cq:advisorNode namePattern="^org\.objectweb\.asm(\..+)?" componentType="osgi.bundle" versionOverride="[5.0.1,6.0.0)"/>
<cq:advisorNode namePattern="^org\.eclipse\.jetty\.osgi-servlet-api$" useTargetPlatform="false" useWorkspace="false" versionOverride="[0.0.0,9.3.11]"/>
<cq:advisorNode namePattern="^org\.eclipse\.jetty\.osgi-servlet-api$" useTargetPlatform="false" useWorkspace="false" versionOverride="[0.0.0,4.0.0)"/>
<cq:advisorNode namePattern="^org\.eclipse\.jetty\.alpn\.api$" versionOverride="[0.0.0,9.3.11)"/>
<cq:advisorNode namePattern="^org\.mortbay\.jasper\.apache-jsp$" componentType="osgi.bundle" versionOverride="(8.0.0,8.0.33]"/>
<cq:advisorNode namePattern="^org\.eclipse\.jetty(\..+)?" useTargetPlatform="false" useWorkspace="false" versionOverride="[9.2.0,9.3.11)"/>

View File

@ -1,7 +1,7 @@
<!-- ====================================================== -->
<!-- Adempiere Distribution Setup -->
<!-- iDempiere Distribution Setup -->
<!-- ====================================================== -->
<!-- $Header: /cvs/adempiere/install/Adempiere/build.xml,v 1.4 2006/07/03 16:51:31 jjanke Exp $-->
<!-- $Header: org.adempiere.server-feature/build.xml $-->
<project name="setup" default="setup" basedir=".">
@ -52,6 +52,8 @@
<copy file="hazelcast-template.xml"
tofile="hazelcast.xml" filtering="yes" overwrite="yes"/>
<mkdir dir="jettyhome/work"/>
<mkdir dir="log"/>
</target>
<!-- ==================================================== -->
@ -110,6 +112,6 @@
<!-- Setup (Main) -->
<!-- ==================================================== -->
<target name="setup" depends="setupInit, setupWin, setupNonWin"
description="Setup Adempiere">
description="Setup iDempiere">
</target>
</project>

View File

@ -159,4 +159,5 @@
<Arg>org.eclipse.jetty.server.Request.maxFormContentSize</Arg>
<Arg>1048576</Arg>
</Call>
<Set class="org.eclipse.jetty.util.resource.Resource" name="defaultUseCaches">false</Set>
</Configure>

View File

@ -34,6 +34,7 @@ import org.compiere.model.MClient;
import org.compiere.model.MCost;
import org.compiere.model.MOrgInfo;
import org.compiere.model.MRole;
import org.compiere.model.MTable;
import org.compiere.model.MUser;
import org.compiere.util.DB;
import org.compiere.util.Env;
@ -224,7 +225,6 @@ public class AcctProcessor extends AdempiereServer
rs = pstmt.executeQuery();
while (!isInterrupted() && rs.next())
{
count[i]++;
boolean ok = true;
try
{
@ -238,6 +238,17 @@ public class AcctProcessor extends AdempiereServer
}
if (!ok)
countError[i]++;
else // only count the posted record.
{
MTable table = MTable.get(Env.getCtx(), AD_Table_ID);
int Record_ID = rs.getInt(table.getKeyColumns()[0]);
sql = new StringBuffer("SELECT COUNT(*) FROM ").append(table.getTableName());
sql.append(" WHERE Posted='Y' AND ").append(table.getTableName()).append("_ID=").append(Record_ID);
int no = DB.getSQLValue(null, sql.toString());
if (no > 0 )
count[i]++;
}
}
}
catch (Exception e)

View File

@ -207,7 +207,7 @@ public class ProcessParameterPanel extends CPanel implements VetoableChangeListe
+ "p.AD_Reference_ID, p.AD_Process_Para_ID, "
+ "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, "
+ "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, "
+ "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode, p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern "
+ "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode, p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern, p.MandatoryLogic "
+ "FROM AD_Process_Para p"
+ " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) "
+ "WHERE p.AD_Process_ID=?" // 1
@ -218,7 +218,7 @@ public class ProcessParameterPanel extends CPanel implements VetoableChangeListe
+ "p.AD_Reference_ID, p.AD_Process_Para_ID, "
+ "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, "
+ "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, "
+ "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode, p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern "
+ "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode, p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern, p.MandatoryLogic "
+ "FROM AD_Process_Para p"
+ " INNER JOIN AD_Process_Para_Trl t ON (p.AD_Process_Para_ID=t.AD_Process_Para_ID)"
+ " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) "

View File

@ -448,7 +448,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
String ua = Servlets.getUserAgent((ServletRequest) Executions.getCurrent().getNativeRequest());
clientInfo.userAgent = ua;
ua = ua.toLowerCase();
clientInfo.tablet = ua.indexOf("ipad") >= 0 || ua.indexOf("iphone") >= 0 || ua.indexOf("android") >= 0;
clientInfo.tablet = Executions.getCurrent().getBrowser("mobile") !=null;
if (getDesktop() != null && getDesktop().getSession() != null) {
getDesktop().getSession().setAttribute(CLIENT_INFO, clientInfo);
}
@ -456,6 +456,7 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
Env.setContext(Env.getCtx(), "#clientInfo_desktopWidth", clientInfo.desktopWidth);
Env.setContext(Env.getCtx(), "#clientInfo_desktopHeight", clientInfo.desktopHeight);
Env.setContext(Env.getCtx(), "#clientInfo_orientation", clientInfo.orientation);
Env.setContext(Env.getCtx(), "#clientInfo_mobile", clientInfo.tablet);
}
}

View File

@ -17,24 +17,21 @@ package org.adempiere.webui;
import java.util.Locale;
import java.util.Properties;
import javax.servlet.ServletRequest;
import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.part.AbstractUIPart;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.LoginWindow;
import org.zkoss.web.servlet.Servlets;
import org.zkoss.zhtml.Text;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.metainfo.PageDefinition;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Div;
import org.zkoss.zul.East;
import org.zkoss.zul.North;
import org.zkoss.zul.South;
import org.zkoss.zul.West;
import org.zkoss.zul.Div;
import org.zkoss.zul.Window;
/**
@ -82,15 +79,13 @@ public class WLogin extends AbstractUIPart
browserWarningWindow.doOverlapped();
}
String ua = Servlets.getUserAgent((ServletRequest) Executions.getCurrent().getNativeRequest());
ua = ua.toLowerCase();
boolean mobile = ua.indexOf("ipad") >= 0 || ua.indexOf("iphone") >= 0 || ua.indexOf("android") >= 0;
boolean mobile = Executions.getCurrent().getBrowser("mobile") !=null;
West west = layout.getWest();
if (west.getFirstChild() != null && west.getFirstChild().getFirstChild() != null) {
west.setCollapsible(true);
west.setSplittable(true);
if (mobile) {
west.setCollapsible(true);
west.setOpen(false);
}
} else {

View File

@ -644,6 +644,8 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
saveReportOptionToInstance(savedParams.get(i));
savedParams.get(i).saveEx();
getProcessInfo().setAD_PInstance_ID(0);
}
}
}

View File

@ -520,7 +520,7 @@ public class ProcessParameterPanel extends Panel implements
result2 = editor2.getValue();
// Create Parameter
MPInstancePara para = new MPInstancePara(Env.getCtx(),
MPInstancePara para = MPInstancePara.getOrCreate(Env.getCtx(),
m_processInfo.getAD_PInstance_ID(), i);
GridField mField = (GridField) m_mFields.get(i);
para.setParameterName(mField.getColumnName());

View File

@ -272,9 +272,11 @@ public class WPaySelect extends PaySelect
*/
private void loadBankInfo()
{
BankInfo bi = (BankInfo)fieldBankAccount.getSelectedItem().getValue();
if (bi == null)
if (fieldBankAccount.getItemCount() == 0)
return;
BankInfo bi = (BankInfo)fieldBankAccount.getSelectedItem().getValue();
labelCurrency.setText(bi.Currency);
labelBalance.setText(m_format.format(bi.Balance));
@ -301,7 +303,13 @@ public class WPaySelect extends PaySelect
miniTable.setColorCompare(payDate);
if (log.isLoggable(Level.CONFIG)) log.config("PayDate=" + payDate);
BankInfo bi = (BankInfo)fieldBankAccount.getSelectedItem().getValue();
if (fieldBankAccount.getItemCount() == 0) {
FDialog.error(m_WindowNo, form, "VPaySelectNoBank");
return;
}
BankInfo bi = fieldBankAccount.getSelectedItem().getValue();
ValueNamePair paymentRule = (ValueNamePair) fieldPaymentRule.getSelectedItem().getValue();
KeyNamePair bpartner = (KeyNamePair) fieldBPartner.getSelectedItem().getValue();

View File

@ -224,6 +224,13 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
boolean menuCollapsed= pref.isPropertyBool(UserPreference.P_MENU_COLLAPSED);
w.setOpen(!menuCollapsed);
boolean mobile = Executions.getCurrent().getBrowser("mobile") !=null;
w.setCollapsible(true);
if (mobile) {
w.setOpen(false);
}
East e = layout.getEast();
e.addEventListener(Events.ON_OPEN, new EventListener<Event>() {
@Override
@ -293,6 +300,11 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
helpController.render(e, this);
if (mobile) {
e.setVisible(false);
e.setOpen(false);
}
Center windowArea = layout.getCenter();
windowContainer.createPart(windowArea);

View File

@ -76,6 +76,7 @@ import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.model.GridField;
import org.compiere.model.GridFieldVO;
import org.compiere.model.GridTab;
import org.compiere.model.Lookup;
import org.compiere.model.MColumn;
import org.compiere.model.MLookup;
import org.compiere.model.MLookupFactory;
@ -92,9 +93,11 @@ import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.SecureEngine;
import org.compiere.util.Util;
import org.compiere.util.ValueNamePair;
import org.zkoss.zk.au.out.AuFocus;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Components;
import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
@ -122,10 +125,14 @@ import org.zkoss.zul.Vlayout;
*/
public class FindWindow extends Window implements EventListener<Event>, ValueChangeListener, DialogEvents
{
private static final String FIND_ROW_EDITOR = "find.row.editor";
private static final String FIND_ROW_EDITOR_TO = "find.row.editor.to";
/**
*
*/
private static final long serialVersionUID = -5747652133096022993L;
private static final long serialVersionUID = -4461202150492732658L;
// values and label for history combo
private static final String HISTORY_DAY_ALL = "All";
@ -221,7 +228,8 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
private Combobox historyCombo = new Combobox();
private Properties m_findCtx;
private Properties m_simpleCtx;
private Properties m_advanceCtx;
private static final String ON_POST_VISIBLE_ATTR = "onPostVisible.Event.Posted";
@ -251,7 +259,8 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
m_minRecords = minRecords;
m_isCancel = true;
//
m_findCtx = new Properties(Env.getCtx());
m_simpleCtx = new Properties(Env.getCtx());
m_advanceCtx = new Properties(Env.getCtx());
this.setBorder("normal");
this.setShadow(false);
@ -634,7 +643,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
if (mField.getVO().displayType == DisplayType.YesNo) {
// Make Yes-No searchable as list
GridFieldVO vo = mField.getVO();
GridFieldVO ynvo = vo.clone(vo.ctx, vo.WindowNo, vo.TabNo, vo.AD_Window_ID, vo.AD_Tab_ID, vo.tabReadOnly);
GridFieldVO ynvo = vo.clone(m_simpleCtx, vo.WindowNo, vo.TabNo, vo.AD_Window_ID, vo.AD_Tab_ID, vo.tabReadOnly);
ynvo.IsDisplayed = true;
ynvo.displayType = DisplayType.List;
ynvo.AD_Reference_Value_ID = REFERENCE_YESNO;
@ -642,6 +651,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
ynvo.lookupInfo = MLookupFactory.getLookupInfo (ynvo.ctx, ynvo.WindowNo, ynvo.AD_Column_ID, ynvo.displayType,
Env.getLanguage(ynvo.ctx), ynvo.ColumnName, ynvo.AD_Reference_Value_ID,
ynvo.IsParent, ynvo.ValidationCode);
ynvo.lookupInfo.tabNo = TABNO;
GridField ynfield = new GridField(ynvo);
@ -653,13 +663,14 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
GridFieldVO vo = mField.getVO();
if ( vo.AD_Reference_Value_ID > 0 )
{
GridFieldVO postedvo = vo.clone(vo.ctx, vo.WindowNo, vo.TabNo, vo.AD_Window_ID, vo.AD_Tab_ID, vo.tabReadOnly);
GridFieldVO postedvo = vo.clone(m_simpleCtx, vo.WindowNo, vo.TabNo, vo.AD_Window_ID, vo.AD_Tab_ID, vo.tabReadOnly);
postedvo.IsDisplayed = true;
postedvo.displayType = DisplayType.List;
postedvo.lookupInfo = MLookupFactory.getLookupInfo (postedvo.ctx, postedvo.WindowNo, postedvo.AD_Column_ID, postedvo.displayType,
Env.getLanguage(postedvo.ctx), postedvo.ColumnName, postedvo.AD_Reference_Value_ID,
postedvo.IsParent, postedvo.ValidationCode);
postedvo.lookupInfo.tabNo = TABNO;
GridField postedfield = new GridField(postedvo);
@ -669,7 +680,15 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
}
} else {
// clone the field and clean gridtab - IDEMPIERE-1105
GridField findField = (GridField) mField.clone(m_findCtx);
GridField findField = (GridField) mField.clone(m_simpleCtx);
if (findField.isLookup()) {
Lookup lookup = findField.getLookup();
if (lookup != null && lookup instanceof MLookup) {
MLookup mLookup = (MLookup) lookup;
mLookup.getLookupInfo().ctx = m_simpleCtx;
mLookup.getLookupInfo().tabNo = TABNO;
}
}
findField.setGridTab(null);
m_findFields[i] = findField;
mField = findField;
@ -1058,6 +1077,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
editor.setMandatory(false);
editor.setReadWrite(true);
editor.dynamicDisplay();
editor.addValueChangeListener(this);
Label label = editor.getLabel();
Component fieldEditor = editor.getComponent();
@ -1075,6 +1095,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
editorTo.setMandatory(false);
editorTo.setReadWrite(true);
editorTo.dynamicDisplay();
editorTo.addValueChangeListener(this);
//
if (displayLength > 0) // set it back
mField.setDisplayLength(displayLength);
@ -1916,7 +1937,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
GridField field = getTargetMField(columnName);
if(field == null) return new Label("");
GridField findField = (GridField) field.clone(m_findCtx);
GridField findField = (GridField) field.clone(m_advanceCtx);
findField.setGridTab(null);
WEditor editor = null;
if (findField.isKey()
@ -1928,6 +1949,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
{
if (findField.getAD_Reference_Value_ID() > 0) {
MLookupInfo info = MLookupFactory.getLookup_List(Env.getLanguage(Env.getCtx()), findField.getAD_Reference_Value_ID());
info.tabNo = TABNO;
MLookup mLookup = new MLookup(info, 0);
editor = new WTableDirEditor(columnName, false,false, true, mLookup);
findField.addPropertyChangeListener(editor);
@ -1945,7 +1967,13 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
//reload lookupinfo for find window
if (DisplayType.isLookup(findField.getDisplayType()) )
{
findField.loadLookupNoValidate();
findField.loadLookupNoValidate();
Lookup lookup = findField.getLookup();
if (lookup != null && lookup instanceof MLookup)
{
MLookup mLookup = (MLookup) lookup;
mLookup.getLookupInfo().tabNo = TABNO;
}
editor = WebEditorFactory.getEditor(findField, true);
findField.addPropertyChangeListener(editor);
}
@ -1970,6 +1998,10 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
((WPaymentEditor)editor).getComponent().setEnabled(true, false);
}
//
if (to)
row.setAttribute(FIND_ROW_EDITOR_TO, editor);
else
row.setAttribute(FIND_ROW_EDITOR, editor);
return editor.getComponent();
} // getTableCellEditorComponent
@ -2358,20 +2390,92 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
{
WEditor editor = (WEditor)evt.getSource();
// Editor component
Component component = editor.getComponent();
ListCell listcell = (ListCell)component.getParent();
listcell.setAttribute("value", evt.getNewValue());
if (evt.getNewValue() == null)
Env.setContext(m_findCtx, m_targetWindowNo, editor.getColumnName(), "");
else if (evt.getNewValue() instanceof Boolean)
Env.setContext(m_findCtx, m_targetWindowNo, editor.getColumnName(), (Boolean)evt.getNewValue());
else if (evt.getNewValue() instanceof Timestamp)
Env.setContext(m_findCtx, m_targetWindowNo, editor.getColumnName(), (Timestamp)evt.getNewValue());
ListCell listcell = null;
Properties ctx = null;
if (winMain.getComponent().getSelectedIndex() == 1)
{
Component component = editor.getComponent();
listcell = (ListCell)component.getParent();
listcell.setAttribute("value", evt.getNewValue());
ctx = m_advanceCtx;
}
else
Env.setContext(m_findCtx, m_targetWindowNo, editor.getColumnName(), evt.getNewValue().toString());
{
ctx = m_simpleCtx;
}
if (evt.getNewValue() == null)
{
Env.setContext(ctx, m_targetWindowNo, editor.getColumnName(), "");
Env.setContext(ctx, m_targetWindowNo, TABNO, editor.getColumnName(), "");
}
else if (evt.getNewValue() instanceof Boolean)
{
Env.setContext(ctx, m_targetWindowNo, editor.getColumnName(), (Boolean)evt.getNewValue());
Env.setContext(ctx, m_targetWindowNo, TABNO, editor.getColumnName(), (Boolean)evt.getNewValue());
}
else if (evt.getNewValue() instanceof Timestamp)
{
Env.setContext(ctx, m_targetWindowNo, editor.getColumnName(), (Timestamp)evt.getNewValue());
Env.setContext(ctx, m_targetWindowNo, TABNO + "|" + editor.getColumnName(), (Timestamp)evt.getNewValue());
}
else
{
Env.setContext(ctx, m_targetWindowNo, editor.getColumnName(), evt.getNewValue().toString());
Env.setContext(ctx, m_targetWindowNo, TABNO, editor.getColumnName(), evt.getNewValue().toString());
}
dynamicDisplay(editor, listcell);
}
}
private void dynamicDisplay(WEditor editor, ListCell listcell) {
if (winMain.getComponent().getSelectedIndex() == 1)
{
List<?> rowList = advancedPanel.getChildren();
for (int rowIndex = 1; rowIndex < rowList.size() ; rowIndex++)
{
// Column
ListItem row = (ListItem)rowList.get(rowIndex);
if (Components.isAncestor(row, listcell))
continue;
WEditor other = (WEditor) row.getAttribute(FIND_ROW_EDITOR);
if (other != null && other.getGridField() != null && other.getGridField().isLookup())
{
Lookup lookup = other.getGridField().getLookup();
if (!Util.isEmpty(lookup.getValidation()))
{
other.dynamicDisplay();
other = (WEditor) row.getAttribute(FIND_ROW_EDITOR_TO);
if (other != null)
other.dynamicDisplay();
}
}
}
}
else
{
for (int i = 0; i < m_sEditors.size(); i++)
{
WEditor wed = (WEditor)m_sEditors.get(i);
if (wed == editor)
continue;
if (wed.getGridField() != null && wed.getGridField().isLookup())
{
Lookup lookup = wed.getGridField().getLookup();
if (!Util.isEmpty(lookup.getValidation()))
{
wed.dynamicDisplay();
wed = m_sEditorsTo.get(i);
if (wed != null && wed != editor)
wed.dynamicDisplay();
}
}
}
}
}
public void OnPostVisible() {
removeAttribute(ON_POST_VISIBLE_ATTR);
if (m_sEditors.size() > 0)
@ -2410,7 +2514,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
private boolean isSearchLike(GridField field)
{
return DisplayType.isText(field.getDisplayType())
return DisplayType.isText(field.getDisplayType()) && !field.isVirtualColumn()
&& (field.isSelectionColumn() || MColumn.isSuggestSelectionColumn(field.getColumnName(), true));
}

View File

@ -231,3 +231,25 @@
height: 16px;
padding: 3px 3px;
}
@media screen and (min-width: 720px) {
.desktop-header > .z-hlayout-inner {
width: 50%;
height: 100%;
}
}
@media screen and (max-width: 720px) {
.desktop-header {
width: 100%;
height: 100%;
}
.desktop-user-panel {
float: none;
}
.desktop-header > .z-hlayout-inner {
width: 100%;
height: 40%;
display: block;
}
}

View File

@ -1,19 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<zk>
<div sclass="desktop-header" use="org.adempiere.webui.panel.HeaderPanel" id="header">
<borderlayout sclass="desktop-header">
<west width="50%" sclass="desktop-header-left">
<hbox height="100%" pack="center" align="left">
<hlayout vflex="1" sclass="desktop-header">
<hbox height="100%" pack="center" align="left" sclass="desktop-header-left">
<image id="logo"/>
<div id="menuLookup"/>
<button id="menuButton" sclass="btn-small"/>
</hbox>
</west>
<center sclass="desktop-header-right">
<vbox apply="org.adempiere.webui.panel.UserPanel" align="right"
hflex="1" vflex="1"
</hbox>
<vbox apply="org.adempiere.webui.panel.UserPanel" align="right"
sclass="desktop-user-panel">
<vbox align="right">
<vbox align="right">
<label use="org.adempiere.webui.component.Label" id="loginUserAndRole"
style="cursor: pointer;"
sclass="desktop-header-font desktop-header-username"/>
@ -32,7 +28,6 @@
</hbox>
</vbox>
</vbox>
</center>
</borderlayout>
</hlayout>
</div>
</zk>