IDEMPIERE-675 - Internal Use with zero qty is dropping the inventory / Peer review

This commit is contained in:
Carlos Ruiz 2013-04-03 11:56:33 -05:00
parent a8804b11f9
commit c72fecccbe
12 changed files with 265 additions and 55 deletions

View File

@ -328,4 +328,6 @@ UPDATE M_Inventory SET C_DocType_ID=144,Updated=TO_DATE('2013-03-24 10:49:58','Y
INSERT INTO M_Inventory (GenerateList,Posted,UpdateQty,M_Inventory_ID,Processed,M_Warehouse_ID,C_DocType_ID,IsApproved,DocStatus,ApprovalAmt,MovementDate,DocumentNo,Created,CreatedBy,IsActive,Processing,UpdatedBy,AD_Client_ID,M_Inventory_UU,AD_Org_ID,Updated,DocAction) VALUES ('N','N','N',200001,'N',50002,144,'N','DR',0,TO_DATE('2013-03-24','YYYY-MM-DD'),'10000002',TO_DATE('2013-03-24 10:50:07','YYYY-MM-DD HH24:MI:SS'),100,'Y','N',100,11,'6486b648-fdea-49d2-a2b2-9d87c2598e44',50001,TO_DATE('2013-03-24 10:50:07','YYYY-MM-DD HH24:MI:SS'),'CO')
;
SELECT register_migration_script('201304030854_IDEMPIERE-675_1.sql') FROM dual
;

View File

@ -9,3 +9,6 @@ UPDATE AD_Tab SET WhereClause='(SELECT COUNT(*) FROM C_DocType WHERE C_DocType.
UPDATE AD_Tab SET WhereClause='(SELECT COUNT(*) FROM C_DocType WHERE C_DocType.C_DocType_ID=M_Inventory.C_DocType_ID AND C_DocType.DocBaseType=''MMI'' AND C_DocType.DocSubTypeInv=''IU'') > 0',Updated=TO_DATE('2013-03-29 12:04:00','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=682
;
SELECT register_migration_script('201304030855_IDEMPIERE-675_2.sql') FROM dual
;

View File

@ -0,0 +1,63 @@
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Element SET Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)', Name='Inv Sub Type', Description='Inventory Sub Type', PrintName='Inv Sub Type',Updated=TO_DATE('2013-04-03 10:51:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=202506
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Column SET ColumnName='DocSubTypeInv', Name='Inv Sub Type', Description='Inventory Sub Type', Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)' WHERE AD_Element_ID=202506
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Process_Para SET ColumnName='DocSubTypeInv', Name='Inv Sub Type', Description='Inventory Sub Type', Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)', AD_Element_ID=202506 WHERE UPPER(ColumnName)='DOCSUBTYPEINV' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Process_Para SET ColumnName='DocSubTypeInv', Name='Inv Sub Type', Description='Inventory Sub Type', Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)' WHERE AD_Element_ID=202506 AND IsCentrallyMaintained='Y'
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_InfoColumn SET ColumnName='DocSubTypeInv', Name='Inv Sub Type', Description='Inventory Sub Type', Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)' WHERE AD_Element_ID=202506 AND IsCentrallyMaintained='Y'
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Field SET Name='Inv Sub Type', Description='Inventory Sub Type', Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)' WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=202506) AND IsCentrallyMaintained='Y'
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_PrintFormatItem SET PrintName='Inv Sub Type', Name='Inv Sub Type' WHERE IsCentrallyMaintained='Y' AND EXISTS (SELECT * FROM AD_Column c WHERE c.AD_Column_ID=AD_PrintFormatItem.AD_Column_ID AND c.AD_Element_ID=202506)
;
-- Apr 3, 2013 10:54:01 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Column SET EntityType='D',Updated=TO_DATE('2013-04-03 10:54:01','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=210208
;
-- Apr 3, 2013 10:59:14 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Val_Rule SET EntityType='D',Updated=TO_DATE('2013-04-03 10:59:14','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Val_Rule_ID=200034
;
-- Apr 3, 2013 11:47:25 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Tab SET WhereClause='M_Inventory.C_DocType_ID IN (SELECT C_DocType_ID FROM C_DocType Where DocBaseType=''MMI'' AND (DocSubTypeInv=''PI'' OR DocSubTypeInv IS NULL))',Updated=TO_DATE('2013-04-03 11:47:25','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=255
;
-- Apr 3, 2013 11:47:56 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Tab SET WhereClause='M_Inventory.C_DocType_ID IN (SELECT C_DocType_ID FROM C_DocType Where DocBaseType=''MMI'' AND (DocSubTypeInv=''IU'' OR DocSubTypeInv IS NULL))',Updated=TO_DATE('2013-04-03 11:47:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=682
;
-- Apr 3, 2013 11:53:18 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Field SET MandatoryLogic='@DocBaseType@=''MMI''',Updated=TO_DATE('2013-04-03 11:53:18','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201886
;
SELECT register_migration_script('201304031155_IDEMPIERE-675_3.sql') FROM dual
;

View File

@ -328,3 +328,6 @@ UPDATE M_Inventory SET C_DocType_ID=144,Updated=TO_TIMESTAMP('2013-03-24 10:49:5
INSERT INTO M_Inventory (GenerateList,Posted,UpdateQty,M_Inventory_ID,Processed,M_Warehouse_ID,C_DocType_ID,IsApproved,DocStatus,ApprovalAmt,MovementDate,DocumentNo,Created,CreatedBy,IsActive,Processing,UpdatedBy,AD_Client_ID,M_Inventory_UU,AD_Org_ID,Updated,DocAction) VALUES ('N','N','N',200001,'N',50002,144,'N','DR',0,TO_TIMESTAMP('2013-03-24','YYYY-MM-DD'),'10000002',TO_TIMESTAMP('2013-03-24 10:50:07','YYYY-MM-DD HH24:MI:SS'),100,'Y','N',100,11,'6486b648-fdea-49d2-a2b2-9d87c2598e44',50001,TO_TIMESTAMP('2013-03-24 10:50:07','YYYY-MM-DD HH24:MI:SS'),'CO')
;
SELECT register_migration_script('201304030854_IDEMPIERE-675_1.sql') FROM dual
;

View File

@ -9,3 +9,6 @@ UPDATE AD_Tab SET WhereClause='(SELECT COUNT(*) FROM C_DocType WHERE C_DocType.
UPDATE AD_Tab SET WhereClause='(SELECT COUNT(*) FROM C_DocType WHERE C_DocType.C_DocType_ID=M_Inventory.C_DocType_ID AND C_DocType.DocBaseType=''MMI'' AND C_DocType.DocSubTypeInv=''IU'') > 0',Updated=TO_TIMESTAMP('2013-03-29 12:04:00','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=682
;
SELECT register_migration_script('201304030855_IDEMPIERE-675_2.sql') FROM dual
;

View File

@ -0,0 +1,63 @@
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Element SET Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)', Name='Inv Sub Type', Description='Inventory Sub Type', PrintName='Inv Sub Type',Updated=TO_TIMESTAMP('2013-04-03 10:51:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=202506
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Column SET ColumnName='DocSubTypeInv', Name='Inv Sub Type', Description='Inventory Sub Type', Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)' WHERE AD_Element_ID=202506
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Process_Para SET ColumnName='DocSubTypeInv', Name='Inv Sub Type', Description='Inventory Sub Type', Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)', AD_Element_ID=202506 WHERE UPPER(ColumnName)='DOCSUBTYPEINV' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Process_Para SET ColumnName='DocSubTypeInv', Name='Inv Sub Type', Description='Inventory Sub Type', Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)' WHERE AD_Element_ID=202506 AND IsCentrallyMaintained='Y'
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_InfoColumn SET ColumnName='DocSubTypeInv', Name='Inv Sub Type', Description='Inventory Sub Type', Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)' WHERE AD_Element_ID=202506 AND IsCentrallyMaintained='Y'
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Field SET Name='Inv Sub Type', Description='Inventory Sub Type', Help='The Inventory Sub Type indicates the type of inventory this document refers to. This field only appears when the Document Base Type is Material Physical Inventory. The selection made here will determine which window must be used and which data in the lines is relevant for the document. Internal Use inventory (based on Internal Used Quantity) or Physical Inventory (based on difference between Qty Counted vs Qty Book)' WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=202506) AND IsCentrallyMaintained='Y'
;
-- Apr 3, 2013 10:51:54 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_PrintFormatItem SET PrintName='Inv Sub Type', Name='Inv Sub Type' WHERE IsCentrallyMaintained='Y' AND EXISTS (SELECT * FROM AD_Column c WHERE c.AD_Column_ID=AD_PrintFormatItem.AD_Column_ID AND c.AD_Element_ID=202506)
;
-- Apr 3, 2013 10:54:01 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Column SET EntityType='D',Updated=TO_TIMESTAMP('2013-04-03 10:54:01','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=210208
;
-- Apr 3, 2013 10:59:14 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Val_Rule SET EntityType='D',Updated=TO_TIMESTAMP('2013-04-03 10:59:14','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Val_Rule_ID=200034
;
-- Apr 3, 2013 11:47:25 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Tab SET WhereClause='M_Inventory.C_DocType_ID IN (SELECT C_DocType_ID FROM C_DocType Where DocBaseType=''MMI'' AND (DocSubTypeInv=''PI'' OR DocSubTypeInv IS NULL))',Updated=TO_TIMESTAMP('2013-04-03 11:47:25','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=255
;
-- Apr 3, 2013 11:47:56 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Tab SET WhereClause='M_Inventory.C_DocType_ID IN (SELECT C_DocType_ID FROM C_DocType Where DocBaseType=''MMI'' AND (DocSubTypeInv=''IU'' OR DocSubTypeInv IS NULL))',Updated=TO_TIMESTAMP('2013-04-03 11:47:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=682
;
-- Apr 3, 2013 11:53:18 AM COT
-- IDEMPIERE-675 Internal Use with zero qty is dropping the inventory
UPDATE AD_Field SET MandatoryLogic='@DocBaseType@=''MMI''',Updated=TO_TIMESTAMP('2013-04-03 11:53:18','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201886
;
SELECT register_migration_script('201304031155_IDEMPIERE-675_3.sql') FROM dual
;

View File

@ -49,6 +49,15 @@ public class CalloutInventory extends CalloutEngine
{
if (isCalloutActive())
return "";
// set docSubTypeInv
int doctypeid = Env.getContextAsInt(ctx, WindowNo, "C_DocType_ID");
String docSubTypeInv = null;
if (doctypeid > 0) {
MDocType dt = MDocType.get(ctx, doctypeid);
docSubTypeInv = dt.getDocSubTypeInv();
}
Integer InventoryLine = (Integer)mTab.getValue("M_InventoryLine_ID");
BigDecimal bd = null;
@ -69,11 +78,13 @@ public class CalloutInventory extends CalloutEngine
} else {
mTab.setValue("M_AttributeSetInstance_ID", null);
}
try {
bd = setQtyBook(M_AttributeSetInstance_ID, M_Product_ID, M_Locator_ID);
mTab.setValue("QtyBook", bd);
} catch (Exception e) {
return mTab.setValue("QtyBook", bd);
if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(docSubTypeInv)) {
try {
bd = setQtyBook(M_AttributeSetInstance_ID, M_Product_ID, M_Locator_ID);
mTab.setValue("QtyBook", bd);
} catch (Exception e) {
return e.getLocalizedMessage();
}
}
}
return "";
@ -117,11 +128,13 @@ public class CalloutInventory extends CalloutEngine
// Set QtyBook from first storage location
// kviiksaar: Call's now the extracted function
try {
bd = setQtyBook(M_AttributeSetInstance_ID, M_Product_ID, M_Locator_ID);
mTab.setValue("QtyBook", bd);
} catch (Exception e) {
return mTab.setValue("QtyBook", bd);
if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(docSubTypeInv)) {
try {
bd = setQtyBook(M_AttributeSetInstance_ID, M_Product_ID, M_Locator_ID);
mTab.setValue("QtyBook", bd);
} catch (Exception e) {
return e.getLocalizedMessage();
}
}
//

View File

@ -32,8 +32,10 @@ import org.compiere.model.MInventoryLine;
import org.compiere.model.MProduct;
import org.compiere.model.MProductCategoryAcct;
import org.compiere.model.X_I_Inventory;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.TimeUtil;
import org.compiere.util.ValueNamePair;
/**
* Import Physical Inventory from I_Inventory
@ -372,6 +374,11 @@ public class ImportInventory extends SvrProcess
//
if (!inventory.save())
{
ValueNamePair vnp = CLogger.retrieveError();
if (vnp != null) {
imp.setI_ErrorMsg(vnp.getValue() + ": " + vnp.getName());
imp.saveEx();
}
log.log(Level.SEVERE, "Inventory not saved");
break;
}
@ -443,6 +450,14 @@ public class ImportInventory extends SvrProcess
cost.saveEx();
}
}
} else {
ValueNamePair vnp = CLogger.retrieveError();
if (vnp != null) {
imp.setI_ErrorMsg(vnp.getValue() + ": " + vnp.getName());
imp.saveEx();
}
log.log(Level.SEVERE, "Inventory Line not saved");
break;
}
}
if (inventory != null) {

View File

@ -24,10 +24,12 @@ import java.util.logging.Level;
import org.compiere.model.MAccount;
import org.compiere.model.MAcctSchema;
import org.compiere.model.MCostDetail;
import org.compiere.model.MDocType;
import org.compiere.model.MInventory;
import org.compiere.model.MInventoryLine;
import org.compiere.model.ProductCost;
import org.compiere.util.Env;
import org.compiere.util.Util;
/**
* Post Inventory Documents.
@ -84,27 +86,36 @@ public class Doc_Inventory extends Doc
*/
private DocLine[] loadLines(MInventory inventory)
{
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
String parentDocSubTypeInv = dt.getDocSubTypeInv();
ArrayList<DocLine> list = new ArrayList<DocLine>();
MInventoryLine[] lines = inventory.getLines(false);
for (int i = 0; i < lines.length; i++)
{
MInventoryLine line = lines[i];
String docSubTypeInv;
if (Util.isEmpty(parentDocSubTypeInv)) {
// IDEMPIERE-675: for backward compatibility - to post old documents that could have subtypeinv empty
if (line.getQtyInternalUse().signum() != 0) {
docSubTypeInv = MDocType.DOCSUBTYPEInv_InternalUseInventory;
} else {
docSubTypeInv = MDocType.DOCSUBTYPEInv_PhysicalInventory;
}
} else {
docSubTypeInv = parentDocSubTypeInv;
}
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());
// nothing to post
if (line.getQtyBook().compareTo(line.getQtyCount()) == 0
&& line.getQtyInternalUse().signum() == 0)
if (qtyDiff.signum() == 0)
continue;
//
DocLine docLine = new DocLine (line, this);
BigDecimal Qty = line.getQtyInternalUse();
if (Qty.signum() != 0)
Qty = Qty.negate(); // Internal Use entered positive
else
{
BigDecimal QtyBook = line.getQtyBook();
BigDecimal QtyCount = line.getQtyCount();
Qty = QtyCount.subtract(QtyBook);
}
docLine.setQty (Qty, false); // -5 => -5
docLine.setQty (qtyDiff, false); // -5 => -5
docLine.setReversalLine_ID(line.getReversalLine_ID());
if (log.isLoggable(Level.FINE)) log.fine(docLine.toString());
list.add (docLine);

View File

@ -31,6 +31,7 @@ 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;
/**
* Physical Inventory Model
@ -50,8 +51,7 @@ public class MInventory extends X_M_Inventory implements DocAction
/**
*
*/
private static final long serialVersionUID = -7137974064086172763L;
private static final long serialVersionUID = -2155186682727239214L;
/** Reversal Indicator */
public static String REVERSE_INDICATOR = "^";
@ -249,14 +249,8 @@ public class MInventory extends X_M_Inventory implements DocAction
{
if (getC_DocType_ID() == 0)
{
MDocType types[] = MDocType.getOfDocBaseType(getCtx(), MDocType.DOCBASETYPE_MaterialPhysicalInventory);
if (types.length > 0) // get first
setC_DocType_ID(types[0].getC_DocType_ID());
else
{
log.saveError("Error", Msg.parseTranslation(getCtx(), "@NotFound@ @C_DocType_ID@"));
return false;
}
log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_C_DocType_ID));
return false;
}
return true;
} // beforeSave
@ -381,8 +375,12 @@ public class MInventory extends X_M_Inventory implements DocAction
public String completeIt()
{
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
String DocSubTypeInv = dt.getDocSubTypeInv();
String docSubTypeInv = dt.getDocSubTypeInv();
if (Util.isEmpty(docSubTypeInv)) {
m_processMsg = "Document inventory subtype not configured, cannot complete";
return DocAction.STATUS_Invalid;
}
// Re-Check
if (!m_justPrepared)
{
@ -409,11 +407,11 @@ public class MInventory extends X_M_Inventory implements DocAction
MProduct product = line.getProduct();
BigDecimal qtyDiff = Env.ZERO;
if (MDocType.DOCSUBTYPEInv_InternalUseInventory.equals(DocSubTypeInv))
if (MDocType.DOCSUBTYPEInv_InternalUseInventory.equals(docSubTypeInv))
qtyDiff = line.getQtyInternalUse().negate();
else if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(DocSubTypeInv))
else if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(docSubTypeInv))
qtyDiff = line.getQtyCount().subtract(line.getQtyBook());
//If Quantity Count minus Quantity Book = Zero, then no change in Inventory
if (qtyDiff.signum() == 0)
continue;
@ -455,7 +453,7 @@ public class MInventory extends X_M_Inventory implements DocAction
}
// Only Update Date Last Inventory if is a Physical Inventory
if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(DocSubTypeInv))
if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(docSubTypeInv))
{
MStorageOnHand storage = MStorageOnHand.get(getCtx(), line.getM_Locator_ID(),
line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName());
@ -506,7 +504,7 @@ public class MInventory extends X_M_Inventory implements DocAction
}
// Only Update Date Last Inventory if is a Physical Inventory
if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(DocSubTypeInv))
if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(docSubTypeInv))
{
MStorageOnHand storage = MStorageOnHand.get(getCtx(), line.getM_Locator_ID(),
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), get_TrxName());
@ -537,7 +535,7 @@ public class MInventory extends X_M_Inventory implements DocAction
} // Fallback
} // stock movement
} // for all lines
} // for all lines
// User Validation
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);

View File

@ -298,26 +298,62 @@ public class MInventoryLine extends X_M_InventoryLine
setQtyInternalUse(getQtyInternalUse());
MDocType dt = MDocType.get(getCtx(), getParent().getC_DocType_ID());
String DocSubTypeInv = dt.getDocSubTypeInv();
// InternalUse Inventory
if (MDocType.DOCSUBTYPEInv_InternalUseInventory.equals(DocSubTypeInv)) {
String docSubTypeInv = dt.getDocSubTypeInv();
if (MDocType.DOCSUBTYPEInv_InternalUseInventory.equals(docSubTypeInv)) {
// Internal Use Inventory validations
if (!INVENTORYTYPE_ChargeAccount.equals(getInventoryType()))
setInventoryType(INVENTORYTYPE_ChargeAccount);
//
if (getC_Charge_ID() == 0)
{
log.saveError("FillMandatory", Msg.getElement(getCtx(), "C_Charge_ID"));
log.saveError("InternalUseNeedsCharge", "");
return false;
}
} else if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(DocSubTypeInv)) {
setC_Charge_ID(0);
if (!INVENTORYTYPE_InventoryDifference.equals(getInventoryType()))
setInventoryType(INVENTORYTYPE_InventoryDifference);
// error if book or count are filled on an internal use inventory
// i.e. coming from import or web services
if (getQtyBook().signum() != 0) {
log.saveError("Quantity", Msg.getElement(getCtx(), COLUMNNAME_QtyBook));
return false;
}
if (getQtyCount().signum() != 0) {
log.saveError("Quantity", Msg.getElement(getCtx(), COLUMNNAME_QtyCount));
return false;
}
if (getQtyInternalUse().signum() == 0) {
log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_QtyInternalUse));
return false;
}
} else if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(docSubTypeInv)) {
// Physical Inventory validations
if (INVENTORYTYPE_ChargeAccount.equals(getInventoryType()))
{
if (getC_Charge_ID() == 0)
{
log.saveError("FillMandatory", Msg.getElement(getCtx(), "C_Charge_ID"));
return false;
}
}
else if (getC_Charge_ID() != 0) {
setC_Charge_ID(0);
}
if (getQtyInternalUse().signum() != 0) {
log.saveError("Quantity", Msg.getElement(getCtx(), COLUMNNAME_QtyInternalUse));
return false;
}
} else {
log.saveError("Error", "Document inventory subtype not configured, cannot complete");
return false;
}
setAD_Org_ID(getParent().getAD_Org_ID());
// Set AD_Org to parent if not charge
if (getC_Charge_ID() == 0)
setAD_Org_ID(getParent().getAD_Org_ID());
return true;
} // beforeSave

View File

@ -1,3 +1,3 @@
,Physical count for Oak,Oak,Default HQ Locator,,0,1,0
,Physical count for Elm,Elm,Default HQ Locator,Commissions Paid,1,3,0
Material Physical Inventory,Internal consumption of 1 chair,PChair,Default HQ Locator,Bank Charge,0,0,1
Material Physical Inventory,Physical count for Oak,Oak,Default HQ Locator,,0,1,0
Material Physical Inventory,Physical count for Elm,Elm,Default HQ Locator,Commissions Paid,1,3,0
Internal Use Inventory,Internal consumption of 1 chair,PChair,Default HQ Locator,Bank Charge,0,0,1

1 Material Physical Inventory Physical count for Oak Oak Default HQ Locator 0 1 0
2 Material Physical Inventory Physical count for Elm Elm Default HQ Locator Commissions Paid Commissions Paid 1 3 0
3 Internal Use Inventory Internal consumption of 1 chair PChair Default HQ Locator Bank Charge Material Physical Inventory Bank Charge 0 0 1