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') 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 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') 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 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()) if (isCalloutActive())
return ""; 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"); Integer InventoryLine = (Integer)mTab.getValue("M_InventoryLine_ID");
BigDecimal bd = null; BigDecimal bd = null;
@ -69,11 +78,13 @@ public class CalloutInventory extends CalloutEngine
} else { } else {
mTab.setValue("M_AttributeSetInstance_ID", null); mTab.setValue("M_AttributeSetInstance_ID", null);
} }
try { if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(docSubTypeInv)) {
bd = setQtyBook(M_AttributeSetInstance_ID, M_Product_ID, M_Locator_ID); try {
mTab.setValue("QtyBook", bd); bd = setQtyBook(M_AttributeSetInstance_ID, M_Product_ID, M_Locator_ID);
} catch (Exception e) { mTab.setValue("QtyBook", bd);
return mTab.setValue("QtyBook", bd); } catch (Exception e) {
return e.getLocalizedMessage();
}
} }
} }
return ""; return "";
@ -117,11 +128,13 @@ public class CalloutInventory extends CalloutEngine
// Set QtyBook from first storage location // Set QtyBook from first storage location
// kviiksaar: Call's now the extracted function // kviiksaar: Call's now the extracted function
try { if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(docSubTypeInv)) {
bd = setQtyBook(M_AttributeSetInstance_ID, M_Product_ID, M_Locator_ID); try {
mTab.setValue("QtyBook", bd); bd = setQtyBook(M_AttributeSetInstance_ID, M_Product_ID, M_Locator_ID);
} catch (Exception e) { mTab.setValue("QtyBook", bd);
return 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.MProduct;
import org.compiere.model.MProductCategoryAcct; import org.compiere.model.MProductCategoryAcct;
import org.compiere.model.X_I_Inventory; import org.compiere.model.X_I_Inventory;
import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.TimeUtil; import org.compiere.util.TimeUtil;
import org.compiere.util.ValueNamePair;
/** /**
* Import Physical Inventory from I_Inventory * Import Physical Inventory from I_Inventory
@ -372,6 +374,11 @@ public class ImportInventory extends SvrProcess
// //
if (!inventory.save()) 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"); log.log(Level.SEVERE, "Inventory not saved");
break; break;
} }
@ -443,6 +450,14 @@ public class ImportInventory extends SvrProcess
cost.saveEx(); 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) { if (inventory != null) {

View File

@ -24,10 +24,12 @@ import java.util.logging.Level;
import org.compiere.model.MAccount; import org.compiere.model.MAccount;
import org.compiere.model.MAcctSchema; import org.compiere.model.MAcctSchema;
import org.compiere.model.MCostDetail; import org.compiere.model.MCostDetail;
import org.compiere.model.MDocType;
import org.compiere.model.MInventory; import org.compiere.model.MInventory;
import org.compiere.model.MInventoryLine; import org.compiere.model.MInventoryLine;
import org.compiere.model.ProductCost; import org.compiere.model.ProductCost;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Util;
/** /**
* Post Inventory Documents. * Post Inventory Documents.
@ -84,27 +86,36 @@ public class Doc_Inventory extends Doc
*/ */
private DocLine[] loadLines(MInventory inventory) private DocLine[] loadLines(MInventory inventory)
{ {
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
String parentDocSubTypeInv = dt.getDocSubTypeInv();
ArrayList<DocLine> list = new ArrayList<DocLine>(); ArrayList<DocLine> list = new ArrayList<DocLine>();
MInventoryLine[] lines = inventory.getLines(false); MInventoryLine[] lines = inventory.getLines(false);
for (int i = 0; i < lines.length; i++) for (int i = 0; i < lines.length; i++)
{ {
MInventoryLine line = lines[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 // nothing to post
if (line.getQtyBook().compareTo(line.getQtyCount()) == 0 if (qtyDiff.signum() == 0)
&& line.getQtyInternalUse().signum() == 0)
continue; continue;
// //
DocLine docLine = new DocLine (line, this); DocLine docLine = new DocLine (line, this);
BigDecimal Qty = line.getQtyInternalUse(); docLine.setQty (qtyDiff, false); // -5 => -5
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.setReversalLine_ID(line.getReversalLine_ID()); docLine.setReversalLine_ID(line.getReversalLine_ID());
if (log.isLoggable(Level.FINE)) log.fine(docLine.toString()); if (log.isLoggable(Level.FINE)) log.fine(docLine.toString());
list.add (docLine); list.add (docLine);

View File

@ -31,6 +31,7 @@ import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Msg; import org.compiere.util.Msg;
import org.compiere.util.Util;
/** /**
* Physical Inventory Model * 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 */ /** Reversal Indicator */
public static String REVERSE_INDICATOR = "^"; public static String REVERSE_INDICATOR = "^";
@ -249,14 +249,8 @@ public class MInventory extends X_M_Inventory implements DocAction
{ {
if (getC_DocType_ID() == 0) if (getC_DocType_ID() == 0)
{ {
MDocType types[] = MDocType.getOfDocBaseType(getCtx(), MDocType.DOCBASETYPE_MaterialPhysicalInventory); log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_C_DocType_ID));
if (types.length > 0) // get first return false;
setC_DocType_ID(types[0].getC_DocType_ID());
else
{
log.saveError("Error", Msg.parseTranslation(getCtx(), "@NotFound@ @C_DocType_ID@"));
return false;
}
} }
return true; return true;
} // beforeSave } // beforeSave
@ -381,8 +375,12 @@ public class MInventory extends X_M_Inventory implements DocAction
public String completeIt() public String completeIt()
{ {
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); 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 // Re-Check
if (!m_justPrepared) if (!m_justPrepared)
{ {
@ -409,11 +407,11 @@ public class MInventory extends X_M_Inventory implements DocAction
MProduct product = line.getProduct(); MProduct product = line.getProduct();
BigDecimal qtyDiff = Env.ZERO; BigDecimal qtyDiff = Env.ZERO;
if (MDocType.DOCSUBTYPEInv_InternalUseInventory.equals(DocSubTypeInv)) if (MDocType.DOCSUBTYPEInv_InternalUseInventory.equals(docSubTypeInv))
qtyDiff = line.getQtyInternalUse().negate(); qtyDiff = line.getQtyInternalUse().negate();
else if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(DocSubTypeInv)) else if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(docSubTypeInv))
qtyDiff = line.getQtyCount().subtract(line.getQtyBook()); qtyDiff = line.getQtyCount().subtract(line.getQtyBook());
//If Quantity Count minus Quantity Book = Zero, then no change in Inventory //If Quantity Count minus Quantity Book = Zero, then no change in Inventory
if (qtyDiff.signum() == 0) if (qtyDiff.signum() == 0)
continue; continue;
@ -455,7 +453,7 @@ public class MInventory extends X_M_Inventory implements DocAction
} }
// Only Update Date Last Inventory if is a Physical Inventory // 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(), MStorageOnHand storage = MStorageOnHand.get(getCtx(), line.getM_Locator_ID(),
line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName()); 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 // 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(), MStorageOnHand storage = MStorageOnHand.get(getCtx(), line.getM_Locator_ID(),
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), get_TrxName()); line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), get_TrxName());
@ -537,7 +535,7 @@ public class MInventory extends X_M_Inventory implements DocAction
} // Fallback } // Fallback
} // stock movement } // stock movement
} // for all lines } // for all lines
// User Validation // User Validation
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE); 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()); setQtyInternalUse(getQtyInternalUse());
MDocType dt = MDocType.get(getCtx(), getParent().getC_DocType_ID()); MDocType dt = MDocType.get(getCtx(), getParent().getC_DocType_ID());
String DocSubTypeInv = dt.getDocSubTypeInv(); String docSubTypeInv = dt.getDocSubTypeInv();
// InternalUse Inventory
if (MDocType.DOCSUBTYPEInv_InternalUseInventory.equals(DocSubTypeInv)) { if (MDocType.DOCSUBTYPEInv_InternalUseInventory.equals(docSubTypeInv)) {
// Internal Use Inventory validations
if (!INVENTORYTYPE_ChargeAccount.equals(getInventoryType())) if (!INVENTORYTYPE_ChargeAccount.equals(getInventoryType()))
setInventoryType(INVENTORYTYPE_ChargeAccount); setInventoryType(INVENTORYTYPE_ChargeAccount);
// //
if (getC_Charge_ID() == 0) if (getC_Charge_ID() == 0)
{ {
log.saveError("FillMandatory", Msg.getElement(getCtx(), "C_Charge_ID")); log.saveError("InternalUseNeedsCharge", "");
return false; return false;
} }
} else if (MDocType.DOCSUBTYPEInv_PhysicalInventory.equals(DocSubTypeInv)) { // error if book or count are filled on an internal use inventory
setC_Charge_ID(0); // i.e. coming from import or web services
if (!INVENTORYTYPE_InventoryDifference.equals(getInventoryType())) if (getQtyBook().signum() != 0) {
setInventoryType(INVENTORYTYPE_InventoryDifference); 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; return true;
} // beforeSave } // beforeSave

View File

@ -1,3 +1,3 @@
,Physical count for Oak,Oak,Default HQ Locator,,0,1,0 Material Physical Inventory,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,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 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