From 9d0f01656640e87f7d178f5ff80ee894634dda57 Mon Sep 17 00:00:00 2001 From: hodianto Date: Tue, 25 Dec 2018 19:16:47 +0700 Subject: [PATCH] Unrealized Gain Loss --HG-- branch : EDII --- .../callout/MID_CalloutInventoryLine.java | 2 + .../midsuit/factory/MID_ModelFactory.java | 2 + .../midsuit/factory/MID_ValidatorFactory.java | 9 ++++ .../midsuit/model/MID_MMovement.java | 35 +++++++++++++ .../src/andromedia/midsuit/model/MID_PPO.java | 2 +- .../midsuit/model/MID_UnrealizedRateLine.java | 6 ++- .../MID_ProcessCompleteUnrealized.java | 29 +++++++++++ .../MID_ProcessUnrealizedGainLoss.java | 52 ++++++++++++++++--- .../validator/MID_InventoryLineValidator.java | 4 ++ .../validator/MID_JournalValidator.java | 40 ++++++++++++++ 10 files changed, 171 insertions(+), 10 deletions(-) create mode 100644 andromeida.midsuit.project/src/andromedia/midsuit/model/MID_MMovement.java create mode 100644 andromeida.midsuit.project/src/andromedia/midsuit/process/MID_ProcessCompleteUnrealized.java create mode 100644 andromeida.midsuit.project/src/andromedia/midsuit/validator/MID_JournalValidator.java diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/callout/MID_CalloutInventoryLine.java b/andromeida.midsuit.project/src/andromedia/midsuit/callout/MID_CalloutInventoryLine.java index ae3848c..e8b24e3 100644 --- a/andromeida.midsuit.project/src/andromedia/midsuit/callout/MID_CalloutInventoryLine.java +++ b/andromeida.midsuit.project/src/andromedia/midsuit/callout/MID_CalloutInventoryLine.java @@ -35,6 +35,8 @@ public class MID_CalloutInventoryLine extends CalloutEngine implements IColumnCa isEnd = DB.getSQLValueStringEx(null, "SELECT IsEndProduct FROM PS_PPOLine WHERE PS_PPOLine_ID =?", new Object[] { PS_PPO_ID }); if(isEnd.equals("Y")) retValue = retValue.multiply(new BigDecimal(-1)); + else + retValue = retValue.abs(); } mTab.setValue(X_M_InventoryLine.COLUMNNAME_QtyInternalUse, retValue); diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_ModelFactory.java b/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_ModelFactory.java index 7776722..81529e8 100644 --- a/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_ModelFactory.java +++ b/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_ModelFactory.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.Properties; import org.adempiere.base.IModelFactory; +import org.compiere.model.MMovement; import org.compiere.model.PO; import org.compiere.util.Env; @@ -60,6 +61,7 @@ public class MID_ModelFactory implements IModelFactory{ mapTableModels.put(MID_UnrealizedRate.Table_Name, "andromedia.midsuit.model.MID_UnrealizedRate"); mapTableModels.put(MID_UnrealizedRateLine.Table_Name, "andromedia.midsuit.model.MID_UnrealizedRateLine"); mapTableModels.put(MID_MOrder.Table_Name, "andromedia.midsuit.model.MID_MOrder"); + mapTableModels.put(MMovement.Table_Name, "andromedia.midsuit.model.MID_MMovement"); } @Override diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_ValidatorFactory.java b/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_ValidatorFactory.java index 88c45b8..50ebf67 100644 --- a/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_ValidatorFactory.java +++ b/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_ValidatorFactory.java @@ -8,6 +8,7 @@ import org.compiere.model.MInOut; import org.compiere.model.MInventory; import org.compiere.model.MInventoryLine; import org.compiere.model.MInventoryLineMA; +import org.compiere.model.MJournal; import org.compiere.model.MOrder; import org.compiere.model.MOrderLine; import org.compiere.model.MPaymentAllocate; @@ -25,6 +26,7 @@ import andromedia.midsuit.validator.MID_InOutValidator; import andromedia.midsuit.validator.MID_InventoryLineMAValidator; import andromedia.midsuit.validator.MID_InventoryLineValidator; import andromedia.midsuit.validator.MID_InventoryValidator; +import andromedia.midsuit.validator.MID_JournalValidator; import andromedia.midsuit.validator.MID_OrderLineValidator; import andromedia.midsuit.validator.MID_OrderValidator; import andromedia.midsuit.validator.MID_ProductionLineValidator; @@ -66,6 +68,8 @@ public class MID_ValidatorFactory extends AbstractEventHandler { msg = MID_InventoryValidator.executeEvent(event, getPO(event)); if(getPO(event).get_TableName().equals(MDepreciationWorkfile.Table_Name)) msg = MID_DeprWorkfileValidator.executeEvent(event, getPO(event)); + if(getPO(event).get_TableName().equals(MJournal.Table_Name)) + msg = MID_JournalValidator.executeEvent(event, getPO(event)); logEvent(event, getPO(event), msg); } @@ -125,6 +129,11 @@ public class MID_ValidatorFactory extends AbstractEventHandler { registerTableEvent(IEventTopics.PO_BEFORE_NEW, MProduction.Table_Name); registerTableEvent(IEventTopics.DOC_BEFORE_COMPLETE, MProduction.Table_Name); registerTableEvent(IEventTopics.PO_BEFORE_NEW, MProductionLine.Table_Name); + + registerTableEvent(IEventTopics.DOC_BEFORE_COMPLETE, MJournal.Table_Name); + registerTableEvent(IEventTopics.DOC_BEFORE_REVERSEACCRUAL, MJournal.Table_Name); + registerTableEvent(IEventTopics.DOC_BEFORE_REVERSECORRECT, MJournal.Table_Name); + // registerTableEvent(IEventTopics.PO_AFTER_NEW,MInvoice.Table_Name); } diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_MMovement.java b/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_MMovement.java new file mode 100644 index 0000000..3c9e751 --- /dev/null +++ b/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_MMovement.java @@ -0,0 +1,35 @@ +package andromedia.midsuit.model; + +import java.sql.ResultSet; +import java.util.Properties; + +import org.compiere.model.X_M_Movement; +import org.compiere.util.DB; + +public class MID_MMovement extends X_M_Movement{ + + /** + * + */ + private static final long serialVersionUID = 2444828850416277798L; + + public MID_MMovement(Properties ctx, int M_Movement_ID, String trxName) { + super(ctx, M_Movement_ID, trxName); + // TODO Auto-generated constructor stub + } + public MID_MMovement(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + // TODO Auto-generated constructor stub + } + + @Override + protected boolean beforeSave(boolean newRecord) { + if(!newRecord) + if(is_ValueChanged("M_Locator_ID") || is_ValueChanged("M_LocatorTo_ID")){ + DB.executeUpdateEx("UPDATE M_MovementLine SET M_Locator_ID =?, M_LocatorTo_ID =? WHERE M_Movement_ID =?", new Object[] { get_ValueAsInt("M_Locator_ID") + ,get_ValueAsInt("M_LocatorTo_ID"), getM_Movement_ID()}, get_TrxName()); + } + return super.beforeSave(newRecord); + } + +} diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_PPO.java b/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_PPO.java index 1fb819e..2021dd5 100644 --- a/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_PPO.java +++ b/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_PPO.java @@ -40,7 +40,7 @@ public class MID_PPO extends X_ps_ppo implements DocAction, DocOptions{ public boolean processIt(String action) throws Exception { log.warning("Processing Action=" + action + " - DocStatus=" + getDocStatus() + " - DocAction=" + getDocAction()); DocumentEngine engine = new DocumentEngine(this, getDocStatus()); - return engine.processIt(getDocAction(), getDocAction()); + return engine.processIt(action, getDocAction()); } @Override diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_UnrealizedRateLine.java b/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_UnrealizedRateLine.java index 8f7f4ba..8bf5c15 100644 --- a/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_UnrealizedRateLine.java +++ b/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_UnrealizedRateLine.java @@ -18,6 +18,10 @@ public class MID_UnrealizedRateLine extends X_MID_UnrealizedRateLine{ // TODO Auto-generated constructor stub } - + @Override + protected boolean beforeDelete() { + log.saveError("Error", "Line cannot be deleted !!!"); + return false; + } } diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/process/MID_ProcessCompleteUnrealized.java b/andromeida.midsuit.project/src/andromedia/midsuit/process/MID_ProcessCompleteUnrealized.java new file mode 100644 index 0000000..af558ee --- /dev/null +++ b/andromeida.midsuit.project/src/andromedia/midsuit/process/MID_ProcessCompleteUnrealized.java @@ -0,0 +1,29 @@ +package andromedia.midsuit.process; + +import org.adempiere.exceptions.AdempiereException; +import org.compiere.process.SvrProcess; + +import andromedia.midsuit.model.MID_UnrealizedRate; + +public class MID_ProcessCompleteUnrealized extends SvrProcess { + MID_UnrealizedRate unRate = null; + + @Override + protected void prepare() { + unRate = new MID_UnrealizedRate(getCtx(), getRecord_ID(), get_TrxName()); + + + } + + @Override + protected String doIt() throws Exception { + if(unRate.isProcessed()){ + throw new AdempiereException("Already Processed !!!"); + }else{ + unRate.setProcessed(true); + unRate.saveEx(); + } + return ""; + } + +} diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/process/MID_ProcessUnrealizedGainLoss.java b/andromeida.midsuit.project/src/andromedia/midsuit/process/MID_ProcessUnrealizedGainLoss.java index 18d7d04..2103d33 100644 --- a/andromeida.midsuit.project/src/andromedia/midsuit/process/MID_ProcessUnrealizedGainLoss.java +++ b/andromeida.midsuit.project/src/andromedia/midsuit/process/MID_ProcessUnrealizedGainLoss.java @@ -1,6 +1,9 @@ package andromedia.midsuit.process; import java.math.BigDecimal; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.List; import org.adempiere.exceptions.AdempiereException; @@ -27,6 +30,11 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ @Override protected void prepare() { unRate = new MID_UnrealizedRate(getCtx(), getRecord_ID(), get_TrxName()); + + if(unRate.getGL_Journal_ID()>0){ + if(!unRate.getGL_Journal().getDocStatus().equals(DocAction.STATUS_Reversed)) + throw new AdempiereException("Journal Already Created Draft / Completed !!!"); + } } @Override @@ -49,7 +57,9 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ unRate.saveEx(); } + DB.executeUpdateEx("DELETE FROM MID_UnrealizedRateLine WHERE MID_UnrealizedRate_ID =?", new Object[] { unRate.getMID_UnrealizedRate_ID() }, null); for(MInvoice invoice : Invoices){ + BigDecimal lastUnrealizedRate = getUnrealizedLastJournal(invoice.get_ID()); MID_UnrealizedRateLine unRateLine = new MID_UnrealizedRateLine(getCtx(), 0, get_TrxName()); BigDecimal openAmt = invoice.getOpenAmt(); unRateLine.setAD_Org_ID(unRate.getAD_Org_ID()); @@ -65,9 +75,10 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ , ass[0].getC_Currency_ID(), period.getEndDate(), unRate.getC_ConversionType_ID(), invoice.getAD_Client_ID(), invoice.getAD_Org_ID()); + if(lastUnrealizedRate != null) + transactionRate = lastUnrealizedRate; if(transactionRate == null) throw new AdempiereException("Transaction Rate Invoice No."+invoice.getDocumentNo()+" at "+invoice.getDateAcct().toString()+" not found !!!"); - if(endMonthRate == null) throw new AdempiereException("Rate Period End Not Found !!!"); unRateLine.setCurrencyRate(transactionRate); @@ -90,9 +101,9 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ new Object[] { invoice.getC_BPartner_ID(), ass[0].getC_AcctSchema_ID() }); if(invoice.isSOTrx()){ if(gainLossAmt.signum()<0){ - drJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationGain_ID).getAccount_ID(), Env.ZERO, gainLossAmt, + drJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationGain_ID).getAccount_ID(), Env.ZERO, gainLossAmt.abs(), "AR Gain/Loss for Invoice No. "+invoice.getDocumentNo()); - crJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationAR_ID).getAccount_ID(), gainLossAmt, Env.ZERO, + crJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationAR_ID).getAccount_ID(), gainLossAmt.abs(), Env.ZERO, "AR Gain/Loss for Invoice No. "+invoice.getDocumentNo()); }else{ drJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationLoss_ID).getAccount_ID(), gainLossAmt, Env.ZERO, @@ -102,14 +113,14 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ } }else{ if(gainLossAmt.signum()<0){ - drJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationAP_ID).getAccount_ID(), Env.ZERO, gainLossAmt, + drJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationAP_ID).getAccount_ID(), Env.ZERO, gainLossAmt.abs(), "AR Gain/Loss for Invoice No. "+invoice.getDocumentNo()); - crJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationGain_ID).getAccount_ID(), gainLossAmt, Env.ZERO, + crJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationLoss_ID).getAccount_ID(), gainLossAmt.abs(),Env.ZERO, "AR Gain/Loss for Invoice No. "+invoice.getDocumentNo()); }else{ - drJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationAP_ID).getAccount_ID(), gainLossAmt, Env.ZERO, + drJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationAP_ID).getAccount_ID(), gainLossAmt,Env.ZERO, "AR Gain/Loss for Invoice No. "+invoice.getDocumentNo()); - crJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationGain_ID).getAccount_ID(), Env.ZERO, gainLossAmt, + crJournal = createJournalLines(journal, unRateLine, MAccount.get(getCtx(), C_ValidCombinationGain_ID).getAccount_ID(), Env.ZERO,gainLossAmt, "AR Gain/Loss for Invoice No. "+invoice.getDocumentNo()); } } @@ -121,7 +132,6 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ unRateLine.saveEx(); } - unRate.setProcessed(true); unRate.saveEx(); return ""; } @@ -145,6 +155,8 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ retValue.setC_DocType_ID(C_DocType_ID); retValue.setGL_Category_ID(GL_Category_ID); retValue.setC_Period_ID(unRate.getC_Period_ID()); + retValue.setDateAcct(unRate.getC_Period().getEndDate()); + retValue.setDateDoc(unRate.getC_Period().getEndDate()); retValue.setC_Currency_ID(acctSchema.getC_Currency_ID()); retValue.setC_ConversionType_ID(unRate.getC_ConversionType_ID()); retValue.setDescription("Journal Unrealized Gain/Loss For Period "+unRate.getC_Period().getName()); @@ -152,4 +164,28 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ return retValue; } + private BigDecimal getUnrealizedLastJournal(int C_Invoice_ID){ + PreparedStatement pstmt = null; + ResultSet rs = null; + String sql = " SELECT url.CurrencyRateEnd, p.EndDate " + + " FROM MID_UnrealizedRateLine url JOIN MID_UnrealizedRate ur on url.MID_UnrealizedRate_ID = ur.MID_UnrealizedRate_ID JOIN C_Period p on P.C_Period_ID = ur.C_Period_ID " + + " WHERE ur.Processed='Y' AND C_Invoice_ID =? ORDER BY p.EndDate DESC"; + BigDecimal retValue = Env.ZERO; + + pstmt = DB.prepareStatement(sql, null); + try { + pstmt.setInt(1, C_Invoice_ID); + rs = pstmt.executeQuery(); + if (rs.next()) { + retValue = rs.getBigDecimal(1); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DB.close(rs, pstmt); + pstmt = null; + rs = null; + } + return retValue; + } } diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/validator/MID_InventoryLineValidator.java b/andromeida.midsuit.project/src/andromedia/midsuit/validator/MID_InventoryLineValidator.java index 958a780..7a1f59b 100644 --- a/andromeida.midsuit.project/src/andromedia/midsuit/validator/MID_InventoryLineValidator.java +++ b/andromeida.midsuit.project/src/andromedia/midsuit/validator/MID_InventoryLineValidator.java @@ -24,6 +24,8 @@ public class MID_InventoryLineValidator { MID_PPOLine line = new MID_PPOLine(inv.getCtx(), PS_PPOLine_ID,inv.get_TrxName()); if(line.isEndProduct() && inv.getQtyInternalUse().signum()>0) inv.setQtyInternalUse(inv.getQtyInternalUse().negate()); + else + inv.setQtyInternalUse(inv.getQtyInternalUse().abs()); } else if (inv.getM_Product().getM_Product_Category().getValue().contains("SCRAP")) { if(inv.getQtyInternalUse().signum()>0) @@ -38,6 +40,8 @@ public class MID_InventoryLineValidator { MID_PPOLine line = new MID_PPOLine(inv.getCtx(), PS_PPOLine_ID,inv.get_TrxName()); if(line.isEndProduct() && inv.getQtyInternalUse().signum()>0) inv.setQtyInternalUse(inv.getQtyInternalUse().negate()); + else + inv.setQtyInternalUse(inv.getQtyInternalUse().abs()); }else if (inv.getM_Product().getM_Product_Category().getValue().contains("SCRAP")) { if(inv.getQtyInternalUse().signum()>0) inv.setQtyInternalUse(inv.getQtyInternalUse().negate()); diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/validator/MID_JournalValidator.java b/andromeida.midsuit.project/src/andromedia/midsuit/validator/MID_JournalValidator.java new file mode 100644 index 0000000..069de29 --- /dev/null +++ b/andromeida.midsuit.project/src/andromedia/midsuit/validator/MID_JournalValidator.java @@ -0,0 +1,40 @@ +package andromedia.midsuit.validator; + +import org.adempiere.base.event.IEventTopics; +import org.compiere.model.MJournal; +import org.compiere.model.PO; +import org.compiere.util.DB; +import org.osgi.service.event.Event; + +import andromedia.midsuit.model.MID_UnrealizedRate; + +public class MID_JournalValidator { + public static String executeEvent(Event e, PO po) { + MJournal j = (MJournal) po; + if (e.getTopic().equals(IEventTopics.DOC_BEFORE_COMPLETE)) + return beforeComplete(j); + else if (e.getTopic().equals(IEventTopics.DOC_BEFORE_REVERSEACCRUAL) + || e.getTopic().equals(IEventTopics.DOC_BEFORE_REVERSECORRECT)) + return beforeReverse(j); + return ""; + } + private static String beforeReverse(MJournal j) { + int MID_UnrealizedRate_ID = DB.getSQLValue(j.get_TrxName(), "SELECT MID_UnrealizedRate_ID FROM MID_UnrealizedRate WHERE GL_Journal_ID =?", new Object[] { j.getGL_Journal_ID()}); + if(MID_UnrealizedRate_ID>0){ + MID_UnrealizedRate unRate = new MID_UnrealizedRate(j.getCtx(), MID_UnrealizedRate_ID, j.get_TrxName()); + unRate.setProcessed(false); + unRate.setGL_Journal_ID(0); + unRate.saveEx(); + } + return ""; + } + private static String beforeComplete(MJournal j) { + int MID_UnrealizedRate_ID = DB.getSQLValue(j.get_TrxName(), "SELECT MID_UnrealizedRate_ID FROM MID_UnrealizedRate WHERE GL_Journal_ID =?", new Object[] { j.getGL_Journal_ID()}); + if(MID_UnrealizedRate_ID>0){ + MID_UnrealizedRate unRate = new MID_UnrealizedRate(j.getCtx(), MID_UnrealizedRate_ID, j.get_TrxName()); + unRate.setProcessed(true); + unRate.saveEx(); + } + return ""; + } +}