From 64abb6420043ec8204bc07c12fe5ae60a9981274 Mon Sep 17 00:00:00 2001 From: faisolavolut Date: Mon, 7 Jul 2025 11:31:56 +0700 Subject: [PATCH] Enhance MID_DocFactory, MID_CalloutMovement, and MID_CalloutPPO with new locator logic; update inventory handling in MID_MInventory and MID_MMovement; introduce MID_CalloutInventory and Doc_PSPPO for improved document processing. --- .../OSGI-INF/MID_DocFactory.xml | 2 +- .../midsuit/callout/MID_CalloutInventory.java | 37 +++++++++++++++++++ .../midsuit/callout/MID_CalloutMovement.java | 23 ++++++++++++ .../midsuit/callout/MID_CalloutPPO.java | 34 ++++++++++++++++- .../src/balinusa/midsuit/doc/Doc_PSPPO.java | 35 ++++++++++++++++++ .../midsuit/factory/MID_CalloutFactory.java | 4 ++ .../midsuit/factory/MID_DocFactory.java | 4 +- .../src/balinusa/midsuit/model/I_ps_ppo.java | 2 +- .../balinusa/midsuit/model/I_ps_ppoline.java | 4 +- .../midsuit/model/MID_MInventory.java | 2 + .../balinusa/midsuit/model/MID_MMovement.java | 37 +++++++++++++++++++ .../balinusa/midsuit/model/MID_MOrder.java | 2 +- .../src/balinusa/midsuit/model/MID_PPO.java | 12 +++--- .../balinusa/midsuit/model/MID_PPOLine.java | 3 -- .../balinusa/midsuit/model/X_ps_ppoline.java | 7 ++++ .../process/MID_InventoryLineCreate.java | 1 + 16 files changed, 195 insertions(+), 14 deletions(-) create mode 100644 balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutInventory.java create mode 100644 balinusa.midsuit.project/src/balinusa/midsuit/doc/Doc_PSPPO.java diff --git a/balinusa.midsuit.project/OSGI-INF/MID_DocFactory.xml b/balinusa.midsuit.project/OSGI-INF/MID_DocFactory.xml index 29b7068..680563f 100644 --- a/balinusa.midsuit.project/OSGI-INF/MID_DocFactory.xml +++ b/balinusa.midsuit.project/OSGI-INF/MID_DocFactory.xml @@ -1,5 +1,5 @@ - + diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutInventory.java b/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutInventory.java new file mode 100644 index 0000000..85bea91 --- /dev/null +++ b/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutInventory.java @@ -0,0 +1,37 @@ +package balinusa.midsuit.callout; + +import java.math.BigDecimal; +import java.util.Properties; + +import org.adempiere.base.IColumnCallout; +import org.compiere.model.CalloutEngine; +import org.compiere.model.GridField; +import org.compiere.model.GridTab; +import org.compiere.model.X_M_InventoryLine; +import org.compiere.util.DB; + +import balinusa.midsuit.model.MID_PPO; + +public class MID_CalloutInventory extends CalloutEngine implements IColumnCallout { + + @Override + public String start(Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value, Object oldValue) { + if (mField.getColumnName().equals("PS_PPO_ID")) + return setWarehouseByPPO(ctx, WindowNo, mTab, mField, value, oldValue); + return null; + } + + public String setWarehouseByPPO(Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value, Object oldValue) { + if (value == null) { + return ""; + } + MID_PPO pspo = new MID_PPO(ctx, (int) value, null); + if(pspo.get_ID() <= 0) { + return ""; + } + int warehouseId = pspo.getM_Warehouse_ID(); + mTab.setValue("M_Warehouse_ID", warehouseId); + return ""; + } + +} \ No newline at end of file diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutMovement.java b/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutMovement.java index 506bf1b..7a4a354 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutMovement.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutMovement.java @@ -6,6 +6,8 @@ import org.adempiere.base.IColumnCallout; import org.compiere.model.CalloutEngine; import org.compiere.model.GridField; import org.compiere.model.GridTab; +import org.compiere.model.MLocator; +import org.compiere.model.Query; public class MID_CalloutMovement extends CalloutEngine implements IColumnCallout{ @@ -15,6 +17,27 @@ public class MID_CalloutMovement extends CalloutEngine implements IColumnCallout if(mField.getColumnName().equals("M_Warehouse_ID")) setMovement(ctx, WindowNo, mTab, mField, value, oldValue); + else if(mField.getColumnName().equals("M_WarehouseTo_ID")) + setLocatorTo(ctx, WindowNo, mTab, mField, value, oldValue); + return null; + } + + public String setLocatorTo(Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value, Object oldValue) { + if(value==null) + mTab.setValue("M_LocatorTo_ID", null); + else if((Integer) mTab.getValue("M_WarehouseTo_ID")>0){ + int M_Warehouse_ID = (Integer) mTab.getValue("M_WarehouseTo_ID"); + // search locator M_LocatorType name is POS and IsDefault='Y' in M_Locator and M_Warehouse_ID + int M_Locator_ID = new Query(ctx, MLocator.Table_Name, "M_Warehouse_ID=? AND EXISTS (SELECT 1 FROM M_LocatorType lt WHERE lt.M_LocatorType_ID = M_Locator.M_LocatorType_ID AND lt.Name='POS')", null) + .setParameters(new Object[] { M_Warehouse_ID }) + .setOnlyActiveRecords(true) + .firstId(); + if(M_Locator_ID > 0) { + mTab.setValue("M_LocatorTo_ID", M_Locator_ID); + } else { + mTab.setValue("M_LocatorTo_ID", null); + } + } return null; } diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutPPO.java b/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutPPO.java index b3b942a..e086ed8 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutPPO.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/callout/MID_CalloutPPO.java @@ -6,7 +6,10 @@ import org.adempiere.base.IColumnCallout; import org.compiere.model.CalloutEngine; import org.compiere.model.GridField; import org.compiere.model.GridTab; +import org.compiere.model.MLocator; +import org.compiere.model.MPriceList; import org.compiere.model.MProduct; +import org.compiere.model.Query; import balinusa.midsuit.model.X_ps_ppo; @@ -17,9 +20,38 @@ public class MID_CalloutPPO extends CalloutEngine implements IColumnCallout{ if(mField.getColumnName().equals(X_ps_ppo.COLUMNNAME_M_Product_ID)){ return product(ctx, WindowNo, mTab, mField, value, oldValue); } + if(mField.getColumnName().equals(X_ps_ppo.COLUMNNAME_C_DocTypeTarget_ID)) { + // set C_DocType_ID same with C_DocTypeTarget_ID + if (value != null) { + mTab.setValue(X_ps_ppo.COLUMNNAME_C_DocType_ID, value); + } else { + mTab.setValue(X_ps_ppo.COLUMNNAME_C_DocType_ID, 0); + } + return ""; + } + if(mField.getColumnName().equals(X_ps_ppo.COLUMNNAME_M_Warehouse_ID)) { + setLocator(ctx, WindowNo, mTab, mField, value, oldValue); + return ""; + } return null; } - + // set M_Locator_ID from Warehouse Locator Default checked + private String setLocator(Properties ctx, int windowNo, GridTab mTab, GridField mField, Object value, Object oldValue) { + if (value == null) return ""; + int M_Warehouse_ID = (int) value; + String sql = "SELECT M_Locator_ID FROM M_Locator WHERE IsDefault='Y' AND M_Warehouse_ID=?"; + int M_Locator_ID = new Query(ctx, MLocator.Table_Name, "IsDefault='Y' AND M_Warehouse_ID=?", null) + .setParameters(new Object[] { M_Warehouse_ID }) + .setOnlyActiveRecords(true) + .firstId(); + if (M_Locator_ID > 0) { + mTab.setValue("M_Locator_ID", M_Locator_ID); + } else { + mTab.setValue("M_Locator_ID", null); + } + return ""; + } + // set C_DocType_ID same with C_DocTypeTarget_ID private String product(Properties ctx, int windowNo, GridTab mTab, GridField mField, Object value, Object oldValue) { if (value==null) return ""; diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/doc/Doc_PSPPO.java b/balinusa.midsuit.project/src/balinusa/midsuit/doc/Doc_PSPPO.java new file mode 100644 index 0000000..fafb755 --- /dev/null +++ b/balinusa.midsuit.project/src/balinusa/midsuit/doc/Doc_PSPPO.java @@ -0,0 +1,35 @@ +package balinusa.midsuit.doc; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.util.ArrayList; + +import org.compiere.acct.Doc; +import org.compiere.acct.Fact; +import org.compiere.model.MAcctSchema; + +import balinusa.midsuit.model.MID_PPO;; + +public class Doc_PSPPO extends Doc{ + + public Doc_PSPPO (MAcctSchema as, ResultSet rs, String trxName) + { + super (as, MID_PPO.class, rs, null, trxName); + } + + @Override + protected String loadDocumentDetails() { + return null; + } + + @Override + public BigDecimal getBalance() { + return BigDecimal.ZERO; + } + + @Override + public ArrayList createFacts(MAcctSchema as) { + ArrayList facts = new ArrayList(); + return facts; + } +} \ No newline at end of file diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/factory/MID_CalloutFactory.java b/balinusa.midsuit.project/src/balinusa/midsuit/factory/MID_CalloutFactory.java index 922f31d..7040148 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/factory/MID_CalloutFactory.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/factory/MID_CalloutFactory.java @@ -7,6 +7,7 @@ import org.adempiere.base.IColumnCallout; import org.adempiere.base.IColumnCalloutFactory; import org.compiere.model.MInOut; import org.compiere.model.MInOutLine; +import org.compiere.model.MInventory; import org.compiere.model.MInventoryLine; import org.compiere.model.MInventoryLineMA; import org.compiere.model.MMovementLineMA; @@ -20,6 +21,7 @@ import balinusa.midsuit.callout.MID_CalloutAnalysisQC; import balinusa.midsuit.callout.MID_CalloutCeisaUpload; import balinusa.midsuit.callout.MID_CalloutInOut; import balinusa.midsuit.callout.MID_CalloutInOutLine; +import balinusa.midsuit.callout.MID_CalloutInventory; import balinusa.midsuit.callout.MID_CalloutInventoryLine; import balinusa.midsuit.callout.MID_CalloutInventoryLineMA; import balinusa.midsuit.callout.MID_CalloutIsReturnCeisa; @@ -70,6 +72,8 @@ public class MID_CalloutFactory implements IColumnCalloutFactory{ list.add(new MID_CalloutInOutLine()); if(tableName.equals(MInventoryLine.Table_Name)) list.add(new MID_CalloutInventoryLine()); + if(tableName.equals(MInventory.Table_Name)) + list.add(new MID_CalloutInventory()); if(tableName.equals(MMovementLineMA.Table_Name)) list.add(new MID_CalloutMovementLineMA()); if(tableName.equals(MInventoryLineMA.Table_Name)) diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/factory/MID_DocFactory.java b/balinusa.midsuit.project/src/balinusa/midsuit/factory/MID_DocFactory.java index 7189443..cea9acf 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/factory/MID_DocFactory.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/factory/MID_DocFactory.java @@ -30,7 +30,8 @@ import balinusa.midsuit.model.MID_MRequisitionTrx; import balinusa.midsuit.model.MID_PPO; public class MID_DocFactory implements IDocFactory{ - + + protected transient CLogger log = CLogger.getCLogger (getClass()); private final static CLogger s_log = CLogger.getCLogger(MID_DocFactory.class); @Override @@ -63,6 +64,7 @@ public class MID_DocFactory implements IDocFactory{ public Doc getDocument(MAcctSchema as, int AD_Table_ID, ResultSet rs, String trxName) { String tableName = MTable.getTableName(Env.getCtx(), AD_Table_ID); + log.info("getDocument - TableName=" + tableName + ", AD_Table_ID=" + AD_Table_ID ); // if(tableName.equals(MID_MRequisitionTrx.Table_Name)) // return new MID_DocMidRequsiition(as,rs,trxName); if(tableName.equals(MID_PPO.Table_Name)) diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/model/I_ps_ppo.java b/balinusa.midsuit.project/src/balinusa/midsuit/model/I_ps_ppo.java index 538b216..e980eb4 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/model/I_ps_ppo.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/model/I_ps_ppo.java @@ -30,7 +30,7 @@ public interface I_ps_ppo { /** TableName=ps_ppo */ - public static final String Table_Name = "ps_ppo"; + public static final String Table_Name = "PS_PPO"; /** AD_Table_ID=30013 */ public static final int Table_ID = 1000001; diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/model/I_ps_ppoline.java b/balinusa.midsuit.project/src/balinusa/midsuit/model/I_ps_ppoline.java index e0043b1..7704d02 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/model/I_ps_ppoline.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/model/I_ps_ppoline.java @@ -30,7 +30,7 @@ public interface I_ps_ppoline { /** TableName=ps_ppoline */ - public static final String Table_Name = "ps_ppoline"; + public static final String Table_Name = "PS_PPOLine"; /** AD_Table_ID=30103 */ public static final int Table_ID = 1000012; @@ -121,6 +121,8 @@ public interface I_ps_ppoline /** Column name M_Inventory_Issue_ID */ public static final String COLUMNNAME_M_Inventory_Issue_ID = "M_Inventory_Issue_ID"; + + public static final String COLUMNNAME_M_Locator_ID = "M_Locator_ID"; /** Set Inventory Issue */ public void setM_Inventory_Issue_ID (int M_Inventory_Issue_ID); diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MInventory.java b/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MInventory.java index 2733fc8..d96a0c6 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MInventory.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MInventory.java @@ -492,6 +492,8 @@ public class MID_MInventory extends MInventory { inventoryLine.setAD_Org_ID(getAD_Org_ID()); inventoryLine.setM_Inventory_ID(getM_Inventory_ID()); inventoryLine.setM_Product_ID(ppoLine.getM_Product_ID()); + // set Locator + inventoryLine.setM_Locator_ID(ppoLine.getM_Locator_ID()); // QtyEntered inventoryLine.setC_Charge_ID(1000000); BigDecimal qty = BigDecimal.valueOf(ppoLine.get_ValueAsInt("QtyUsed")); diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MMovement.java b/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MMovement.java index 9617cb4..75e4864 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MMovement.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MMovement.java @@ -1,9 +1,13 @@ package balinusa.midsuit.model; import java.sql.ResultSet; +import java.util.List; import java.util.Properties; +import org.compiere.model.MInventoryLine; import org.compiere.model.MMovement; +import org.compiere.model.Query; +import org.compiere.process.DocAction; import org.compiere.util.DB; public class MID_MMovement extends MMovement{ @@ -56,5 +60,38 @@ public class MID_MMovement extends MMovement{ return super.beforeSave(newRecord); } + + @Override + protected boolean afterSave(boolean newRecord, boolean success) { + if(success && !newRecord) { + int M_Inventory_ID = get_ValueAsInt("M_Inventory_ID"); + int M_LocatorTo_ID = get_ValueAsInt("M_LocatorTo_ID"); + if(M_Inventory_ID > 0) { + MID_MInventory inv = new MID_MInventory(getCtx(), M_Inventory_ID, get_TrxName()); + if(inv.get_ID() > 0 && M_LocatorTo_ID > 0) { + List lines = new Query(getCtx(), MInventoryLine.Table_Name, "M_InventoryLine.m_inventory_id =?", get_TrxName()) + .addJoinClause(" JOIN M_Inventory i ON i.M_Inventory_ID=M_InventoryLine.M_Inventory_ID ") + .setOnlyActiveRecords(true) + .setParameters(new Object[] { M_Inventory_ID }) + .list(); + for(MInventoryLine line : lines) { + // create movement line for inventory line + if(line.get_ID() > 0 && line.getM_Product_ID() > 0 && line.getMovementQty().signum() != 0) { + MID_MMovementLine moveLine = new MID_MMovementLine(getCtx(), 0, get_TrxName()); + moveLine.setM_Movement_ID(getM_Movement_ID()); + moveLine.setM_Product_ID(line.getM_Product_ID()); + moveLine.setMovementQty(line.getMovementQty()); + moveLine.setM_Locator_ID(line.getM_Locator_ID()); + moveLine.setM_LocatorTo_ID(M_LocatorTo_ID); + moveLine.saveEx(); + } + } + + } + } + } + return super.afterSave(newRecord, success); + } + } diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MOrder.java b/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MOrder.java index 4d96e17..5e5d620 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MOrder.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_MOrder.java @@ -377,7 +377,7 @@ public class MID_MOrder extends MOrder implements DocOptions{ if(newRecord) { // check same org warehouse and ad_org MWarehouse warehouse = MWarehouse.get(getCtx(), getM_Warehouse_ID()); - if (warehouse.getAD_Org_ID() != getAD_Org_ID()) { + if (warehouse.getAD_Org_ID() > 0 && warehouse.getAD_Org_ID() != getAD_Org_ID()) { setAD_Org_ID(warehouse.getAD_Org_ID()); } } diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_PPO.java b/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_PPO.java index 71d65d8..24f2e32 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_PPO.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_PPO.java @@ -97,10 +97,10 @@ public class MID_PPO extends X_ps_ppo implements DocAction, DocOptions{ .count(); - if(countReceipt<=0 && countIssue<=0) { - if(countDisposal<=0 && countWaste<=0) - throw new AdempiereException("Pastikan ada Issue/Receipt yang diproses !!!"); - } +// if(countReceipt<=0 && countIssue<=0) { +// if(countDisposal<=0 && countWaste<=0) +// throw new AdempiereException("Pastikan ada Issue/Receipt yang diproses !!!"); +// } return DocAction.STATUS_InProgress; @@ -126,11 +126,13 @@ public class MID_PPO extends X_ps_ppo implements DocAction, DocOptions{ .setOnlyActiveRecords(true) .setParameters(new Object[] { getps_ppo_ID(),DocAction.STATUS_Completed }) .list(); - DB.executeUpdateEx(" UPDATE PS_PPOLine SET QtyUsed=0 WHERE PS_PPO_ID =? ", new Object[] { getps_ppo_ID() }, get_TrxName() ); + // DB.executeUpdateEx(" UPDATE PS_PPOLine SET QtyUsed=0 WHERE PS_PPO_ID =? ", new Object[] { getps_ppo_ID() }, get_TrxName() ); for(MInventoryLine line : lines) { int PS_PPOLine_ID = line.get_ValueAsInt("ps_ppoline_ID"); if(PS_PPOLine_ID >0) { + log.info("Update Existing PS_PPOLine ID="+PS_PPOLine_ID+" for Product ID="+line.getM_Product_ID()+" Qty="+line.getQtyInternalUse()); MID_PPOLine ppoLine = new MID_PPOLine(getCtx(), line.get_ValueAsInt("ps_ppoline_ID"), get_TrxName()); + log.info("Qty Used Before="+ppoLine.getQtyUsed()); ppoLine.setQtyUsed(ppoLine.getQtyUsed().add((BigDecimal) line.get_Value("QtyEntered"))); ppoLine.saveEx(); }else { diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_PPOLine.java b/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_PPOLine.java index 8930673..670eee1 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_PPOLine.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/model/MID_PPOLine.java @@ -19,7 +19,4 @@ public class MID_PPOLine extends X_ps_ppoline { super(ctx, rs, trxName); // TODO Auto-generated constructor stub } - - - } diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/model/X_ps_ppoline.java b/balinusa.midsuit.project/src/balinusa/midsuit/model/X_ps_ppoline.java index 1e9d510..78dae47 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/model/X_ps_ppoline.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/model/X_ps_ppoline.java @@ -126,6 +126,13 @@ public class X_ps_ppoline extends PO implements I_ps_ppoline, I_Persistent else set_Value (COLUMNNAME_M_Inventory_Issue_ID, Integer.valueOf(M_Inventory_Issue_ID)); } + + public int getM_Locator_ID() { + Integer ii = (Integer)get_Value(COLUMNNAME_M_Locator_ID); + if (ii == null) + return 0; + return ii.intValue(); + } /** Get Inventory Issue. @return Inventory Issue */ diff --git a/balinusa.midsuit.project/src/balinusa/midsuit/process/MID_InventoryLineCreate.java b/balinusa.midsuit.project/src/balinusa/midsuit/process/MID_InventoryLineCreate.java index ac0b099..2af3d6b 100644 --- a/balinusa.midsuit.project/src/balinusa/midsuit/process/MID_InventoryLineCreate.java +++ b/balinusa.midsuit.project/src/balinusa/midsuit/process/MID_InventoryLineCreate.java @@ -50,6 +50,7 @@ public class MID_InventoryLineCreate extends SvrProcess{ invL.setAD_Org_ID(inv.getAD_Org_ID()); invL.setM_Inventory_ID(inv.getM_Inventory_ID()); invL.setM_Product_ID(line.getM_Product_ID()); + invL.setM_Locator_ID(line.getM_Locator_ID()); if(line.isEndProduct()) invL.setQtyInternalUse(line.getQtyUsed().multiply(new BigDecimal(-1))); else