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 4dd5efd..7776722 100644 --- a/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_ModelFactory.java +++ b/andromeida.midsuit.project/src/andromedia/midsuit/factory/MID_ModelFactory.java @@ -14,6 +14,7 @@ import andromedia.midsuit.model.MID_Analysis; import andromedia.midsuit.model.MID_AnalysisLine; import andromedia.midsuit.model.MID_AnalysisPro; import andromedia.midsuit.model.MID_MAssetAddition; +import andromedia.midsuit.model.MID_MAssetDisposed; import andromedia.midsuit.model.MID_MBillingList; import andromedia.midsuit.model.MID_MBillingListLine; import andromedia.midsuit.model.MID_MDDOrder; @@ -55,6 +56,7 @@ public class MID_ModelFactory implements IModelFactory{ mapTableModels.put(MID_MRequisitionLine.Table_Name, "andromedia.midsuit.model.MID_MRequisitionLine"); mapTableModels.put(MID_MDepreciationEntry.Table_Name, "andromedia.midsuit.model.MID_MDepreciationEntry"); mapTableModels.put(MID_MAssetAddition.Table_Name, "andromedia.midsuit.model.MID_MAssetAddition"); + mapTableModels.put(MID_MAssetDisposed.Table_Name, "andromedia.midsuit.model.MID_MAssetDisposed"); 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"); diff --git a/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_MAssetDisposed.java b/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_MAssetDisposed.java new file mode 100644 index 0000000..7d8f194 --- /dev/null +++ b/andromeida.midsuit.project/src/andromedia/midsuit/model/MID_MAssetDisposed.java @@ -0,0 +1,401 @@ +package andromedia.midsuit.model; + +import java.io.File; + + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.sql.ResultSet; +import java.util.Properties; +import java.util.logging.Level; + +import org.adempiere.exceptions.AdempiereException; +import org.compiere.model.I_A_Asset_Disposed; +import org.compiere.model.MAsset; +import org.compiere.model.MClient; +import org.compiere.model.MDepreciationExp; +import org.compiere.model.MDepreciationWorkfile; +import org.compiere.model.MDocType; +import org.compiere.model.MInvoiceLine; +import org.compiere.model.MPeriod; +import org.compiere.model.ModelValidationEngine; +import org.compiere.model.ModelValidator; +import org.compiere.model.SetGetUtil; +import org.compiere.model.X_A_Asset_Disposed; +import org.compiere.process.DocAction; +import org.compiere.process.DocOptions; +import org.compiere.process.DocumentEngine; +import org.compiere.util.Env; +//import org.idempiere.fa.exceptions.AssetAlreadyDepreciatedException; +//import org.idempiere.fa.exceptions.AssetNotImplementedException; +//import org.idempiere.fa.exceptions.AssetNotSupportedException; + +/** + * Asset Disposal Model + * + * @author Teo Sarca, SC ARHIPAC SERVICE SRL + */ +public class MID_MAssetDisposed extends X_A_Asset_Disposed implements DocAction, DocOptions { + /** + * + */ + private static final long serialVersionUID = 1763997880662445638L; + + public MID_MAssetDisposed(Properties ctx, int A_Asset_Disposed_ID, String trxName) { + super(ctx, A_Asset_Disposed_ID, trxName); + if (A_Asset_Disposed_ID == 0) { + setProcessed(false); + setProcessing(false); + } + + } + + public static MID_MAssetDisposed createAssetDisposed(MInvoiceLine invLine) { + MID_MAssetDisposed assetDisposed = new MID_MAssetDisposed(invLine); + return assetDisposed; + } + + private MID_MAssetDisposed(MInvoiceLine invLine) { + this(invLine.getCtx(), 0, invLine.get_TrxName()); + if (log.isLoggable(Level.FINEST)) + log.finest("Entering: Invoice Line=" + invLine); + MAsset asset = new MAsset(getCtx(), invLine.getA_Asset_ID(), get_TrxName()); + + setAD_Org_ID(asset.getAD_Org_ID()); + setPostingType(POSTINGTYPE_Actual); + setDateDoc(invLine.getC_Invoice().getDateInvoiced()); + setDateAcct(invLine.getC_Invoice().getDateInvoiced()); + setA_Disposed_Date(invLine.getC_Invoice().getDateInvoiced()); + setA_Disposed_Method(A_DISPOSED_METHOD_Trade); + setA_Asset_ID(asset.getA_Asset_ID()); + setC_Invoice_ID(invLine.getC_Invoice_ID()); + setC_InvoiceLine_ID(invLine.get_ID()); + + MDepreciationWorkfile assetwk = MDepreciationWorkfile.get(getCtx(), invLine.getA_Asset_ID(), POSTINGTYPE_Actual, + get_TrxName()); + setA_Asset_Cost(assetwk.getA_Asset_Cost()); + setA_Accumulated_Depr(assetwk.getA_Accumulated_Depr()); + setA_Disposal_Amt(assetwk.getA_Asset_Cost()); + setA_Accumulated_Depr_Delta(assetwk.getA_Accumulated_Depr()); + setExpense(assetwk.getA_Asset_Cost().subtract(assetwk.getA_Accumulated_Depr())); + saveEx(); + + } + + public MID_MAssetDisposed(Properties ctx, ResultSet rs, String trxName) { + super(ctx, rs, trxName); + } + + public MAsset getAsset() { + return MAsset.get(getCtx(), getA_Asset_ID(), null); + } + + public boolean processIt(String processAction) { + m_processMsg = null; + DocumentEngine engine = new DocumentEngine(this, getDocStatus()); + return engine.processIt(processAction, getDocAction()); + } // processIt + + /** Process Message */ + private String m_processMsg = null; + + /** Just Prepared Flag */ + private boolean m_justPrepared = false; + + public boolean unlockIt() { + setProcessing(false); + return true; + } // unlockIt + + public boolean invalidateIt() { + return false; + } // invalidateIt + + public String prepareIt() { + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE); + if (m_processMsg != null) + return DocAction.STATUS_Invalid; + + MPeriod.testPeriodOpen(getCtx(), getDateAcct(), MDocType.DOCBASETYPE_FixedAssetsDisposal, getAD_Org_ID()); + + // Check that the FA is not just depreciated + MDepreciationWorkfile assetwk = MDepreciationWorkfile.get(getCtx(), getA_Asset_ID(), getPostingType(), + get_TrxName()); + if (assetwk.isDepreciated(getDateAcct())) { + throw new AdempiereException("Asset Already Depreciated !!!"); +// throw new AssetAlreadyDepreciatedException(); + } + + MDepreciationExp.checkExistsNotProcessedEntries(getCtx(), getA_Asset_ID(), getDateAcct(), getPostingType(), + get_TrxName()); + + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_PREPARE); + if (m_processMsg != null) + return DocAction.STATUS_Invalid; + + m_justPrepared = true; + setDocAction(DOCACTION_Complete); + return DocAction.STATUS_InProgress; + } // prepareIt + + public boolean approveIt() { + if (log.isLoggable(Level.INFO)) + log.info("approveIt - " + toString()); + setIsApproved(true); + return true; + } // approveIt + + public boolean rejectIt() { + if (log.isLoggable(Level.INFO)) + log.info("rejectIt - " + toString()); + setIsApproved(false); + return true; + } // rejectIt + + public String completeIt() { + // Re-Check + if (!m_justPrepared) { + String status = prepareIt(); + if (!DocAction.STATUS_InProgress.equals(status)) + return status; + } + + String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE); + + if (valid != null) { + m_processMsg = valid; + return DocAction.STATUS_Invalid; + } + + // Implicit Approval + if (!isApproved()) + approveIt(); + if (log.isLoggable(Level.INFO)) + log.info(toString()); + // + + // loading asset + MAsset asset = getAsset(); + if (log.isLoggable(Level.FINE)) + log.fine("asset=" + asset); + + String method = getA_Disposed_Method(); + if (A_DISPOSED_METHOD_Preservation.equals(method)) { + asset.changeStatus(MAsset.A_ASSET_STATUS_Preservation, getDateDoc()); + updateAssetWK(); + } + + else if (A_DISPOSED_METHOD_Simple.equals(method) || A_DISPOSED_METHOD_Simple_.equals(method) + || A_DISPOSED_METHOD_Trade.equals(method)) { + asset.changeStatus(MAsset.A_ASSET_STATUS_Disposed, getDateDoc()); + setA_Disposal_Amt(getA_Asset_Cost()); + setA_Accumulated_Depr_Delta(getA_Accumulated_Depr()); + setExpense(getA_Disposal_Amt().subtract(getA_Accumulated_Depr_Delta())); + updateAssetWK(); + } else if (A_DISPOSED_METHOD_PartialRetirement.equals(method)) + updateAssetWK(); + + else + throw new AdempiereException("Asset Already Depreciated !!!"); +// throw new AssetNotSupportedException(COLUMNNAME_A_Disposed_Method, method); + + asset.saveEx(get_TrxName()); + + // User Validation + valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE); + if (valid != null) { + m_processMsg = valid; + return DocAction.STATUS_Invalid; + } + + // Done + setProcessed(true); + setDocAction(DOCACTION_Close); + return DocAction.STATUS_Completed; + } // completeIt + + public boolean voidIt() { + if (log.isLoggable(Level.INFO)) + log.info("voidIt - " + toString()); + // Before Void + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_VOID); + if (m_processMsg != null) + return false; + + setA_Disposal_Amt(Env.ZERO); + setA_Accumulated_Depr_Delta(Env.ZERO); + setExpense(Env.ZERO); + setProcessed(true); + + setDocAction(DocAction.ACTION_None); + setDocStatus(DOCACTION_Void); + // After Void + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_VOID); + if (m_processMsg != null) + return false; + + return true; + } // voidIt + + public boolean closeIt() { + if (log.isLoggable(Level.INFO)) + log.info("closeIt - " + toString()); + // Before Close + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_CLOSE); + if (m_processMsg != null) + return false; + + setDocAction(DocAction.ACTION_None); + + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_CLOSE); + if (m_processMsg != null) + return false; + + return true; + } // closeIt + + public boolean reverseCorrectIt() { + throw new AdempiereException("Asset Already Depreciated !!!"); +// throw new AssetNotImplementedException(""); + } // reverseCorrectionIt + + public boolean reverseAccrualIt() { + throw new AdempiereException("Asset Already Depreciated !!!"); +// throw new AssetNotImplementedException(""); + } + + public boolean reActivateIt() { + throw new AdempiereException("Asset Already Depreciated !!!"); +// throw new AssetNotImplementedException(""); + } + + public String getSummary() { + return new StringBuffer().append(getDocumentNo()).append("/").append(getDateDoc()).toString(); + } + + public String getProcessMsg() { + return m_processMsg; + } // getProcessMsg + + public int getDoc_User_ID() { + return getCreatedBy(); + } + + public BigDecimal getApprovalAmt() { + return Env.ZERO; + } + + public int getC_Currency_ID() { + return MClient.get(getCtx(), getAD_Client_ID()).getAcctSchema().getC_Currency_ID(); + } + + protected boolean beforeSave(boolean newRecord) { + if (getDateAcct() == null) { + setDateAcct(getDateDoc()); + } + + /* + * if (newRecord || is_ValueChanged(COLUMNNAME_DateAcct)) { try { + * setC_Period_ID(MPeriod.get(getCtx(), getDateAcct(), getAD_Org_ID(), + * get_TrxName()).get_ID()); } catch (Exception e) { return false; } } + */ + + if (getA_Disposed_Date() == null) { + setA_Disposed_Date(getDateAcct()); + } + + return true; + } + + /** + * Copy fields from A_Asset + * + * @param model + * @param A_Asset_ID + */ + public static void updateFromAsset(I_A_Asset_Disposed bean) { + int asset_id = bean.getA_Asset_ID(); + SetGetUtil.copyValues(SetGetUtil.wrap(bean), MAsset.Table_Name, asset_id, new String[] { + MAsset.COLUMNNAME_IsDisposed, MAsset.COLUMNNAME_A_Asset_Status, MAsset.COLUMNNAME_AD_Org_ID }); + + MDepreciationWorkfile wk = MDepreciationWorkfile.get(Env.getCtx(), asset_id, bean.getPostingType(), null); + if (wk != null) { + bean.setA_Asset_Cost(wk.getA_Asset_Cost()); + bean.setA_Accumulated_Depr(wk.getA_Accumulated_Depr()); + } else { + bean.setA_Asset_Cost(Env.ZERO); + bean.setA_Accumulated_Depr(Env.ZERO); + } + } + + public File createPDF() { + return null; + } // createPDF + + public String getDocumentInfo() { + return getDocumentNo(); + } // getDocumentInfo + + /** + * Check if this is a disposal (if the asset is not disposed) + * + * @return true if is disposal + */ + public boolean isDisposal() { + return !isDisposed(); + } + + public static void setA_Disposal_Amt(I_A_Asset_Disposed bean) { + // TODO: Set Precision from Currency + int precision = 2; + BigDecimal A_Asset_Cost = bean.getA_Asset_Cost(); + BigDecimal A_Disposal_Amt = bean.getA_Disposal_Amt(); + BigDecimal coef = Env.ZERO; + if (A_Asset_Cost.signum() != 0) { + coef = A_Disposal_Amt.divide(A_Asset_Cost, 12, RoundingMode.HALF_UP); + } + // + BigDecimal A_Accumulated_Depr = bean.getA_Accumulated_Depr(); + BigDecimal A_Accumulated_Depr_Delta = A_Accumulated_Depr.multiply(coef).setScale(precision, + RoundingMode.HALF_UP); + BigDecimal Expense = A_Disposal_Amt.subtract(A_Accumulated_Depr_Delta); + // + bean.setA_Accumulated_Depr_Delta(A_Accumulated_Depr_Delta); + bean.setExpense(Expense); + } + + private void updateAssetWK() { + MDepreciationWorkfile assetwk = MDepreciationWorkfile.get(getCtx(), getA_Asset_ID(), getPostingType(), + get_TrxName()); + assetwk.adjustCost(getA_Asset_Cost().negate(),Env.ZERO, false); + assetwk.adjustAccumulatedDepr(null, null, true); + assetwk.saveEx(); + assetwk.truncDepreciation(); + // + } + + @Override + public int customizeValidActions(String docStatus, Object processing, String orderType, String isSOTrx, + int AD_Table_ID, String[] docAction, String[] options, int index) { + + for (int i = 0; i < options.length; i++) { + options[i] = null; + } + + index = 0; + + if (docStatus.equals(DocAction.STATUS_Drafted)) { + options[index++] = DocAction.ACTION_Complete; + options[index++] = DocAction.ACTION_Void; + } else if (docStatus.equals(DocAction.STATUS_InProgress)) { + options[index++] = DocAction.ACTION_Complete; + options[index++] = DocAction.ACTION_Void; + } else if (docStatus.equals(DocAction.STATUS_Invalid)) { + options[index++] = DocAction.ACTION_Complete; + options[index++] = DocAction.ACTION_Void; + } + + return index; + + } +} 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 edc551c..94786bf 100644 --- a/andromeida.midsuit.project/src/andromedia/midsuit/process/MID_ProcessUnrealizedGainLoss.java +++ b/andromeida.midsuit.project/src/andromedia/midsuit/process/MID_ProcessUnrealizedGainLoss.java @@ -40,6 +40,8 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ .setClient_ID(true) .list(); + + if(Invoices.size()>0){ period = new MPeriod(getCtx(), unRate.getC_Period_ID(), get_TrxName()); journal = createGL_Journal(ass[0]); @@ -81,10 +83,10 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ int C_ValidCombinationGain_ID = ass[0].getAcctSchemaDefault().getUnrealizedGain_Acct(); int C_ValidCombinationLoss_ID = ass[0].getAcctSchemaDefault().getUnrealizedLoss_Acct(); int C_ValidCombinationAR_ID = DB.getSQLValueEx(get_TrxName(), - "SELECT C_Receiveable_Acct FROM C_BP_Customer_Acct WHERE C_BPartner_ID =? AND C_AcctSchema_ID =?", + "SELECT C_Receivable_Acct FROM C_BP_Customer_Acct WHERE C_BPartner_ID =? AND C_AcctSchema_ID =?", new Object[] { invoice.getC_BPartner_ID(), ass[0].getC_AcctSchema_ID() }); int C_ValidCombinationAP_ID = DB.getSQLValueEx(get_TrxName(), - "SELECT C_Receiveable_Acct FROM C_BP_Vendor_Acct WHERE C_BPartner_ID =? AND C_AcctSchema_ID =?", + "SELECT V_Liability_Acct FROM C_BP_Vendor_Acct WHERE C_BPartner_ID =? AND C_AcctSchema_ID =?", new Object[] { invoice.getC_BPartner_ID(), ass[0].getC_AcctSchema_ID() }); if(invoice.isSOTrx()){ if(gainLossAmt.signum()<0){ @@ -116,6 +118,9 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ unRateLine.setGL_JournalLineDr_ID(drJournal.get_ID()); unRateLine.saveEx(); } + + unRate.setProcessed(true); + unRate.saveEx(); return ""; } @@ -130,8 +135,8 @@ public class MID_ProcessUnrealizedGainLoss extends SvrProcess{ } private MJournal createGL_Journal(MAcctSchema acctSchema) { - int C_DocType_ID = DB.getSQLValueEx(get_TrxName(), "SELECT C_DocType_ID FROM C_DocType WHERE Name =?", new Object[] {"GL Journal"}); - int GL_Category_ID = DB.getSQLValueEx(get_TrxName(), "SELECT GL_Category_ID FROM GL_Category WHERE Name =?", new Object[] {"Manual"}); + int C_DocType_ID = DB.getSQLValueEx(get_TrxName(), "SELECT C_DocType_ID FROM C_DocType WHERE Name =? AND AD_Client_ID =?", new Object[] {"GL Journal", getAD_Client_ID()}); + int GL_Category_ID = DB.getSQLValueEx(get_TrxName(), "SELECT GL_Category_ID FROM GL_Category WHERE Name =? AND AD_Client_ID =?", new Object[] {"Manual", getAD_Client_ID()}); MJournal retValue = new MJournal(getCtx(), 0, get_TrxName()); retValue.setAD_Org_ID(Env.getAD_Org_ID(getCtx())); retValue.setC_AcctSchema_ID(acctSchema.getC_AcctSchema_ID());