From f75aeb5aba512928b9c0b79034cf9f5de212c211 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Wed, 24 Oct 2012 19:36:15 -0500 Subject: [PATCH] commit modified asset classes add workaround for customer service asset (not fixed assets) transplanted from https://bitbucket.org/edwin_ang/adempiere361-mbd/changeset/b421d5c https://bitbucket.org/edwin_ang/adempiere361-mbd/changeset/83eeb45 --- .../org/compiere/process/AssetDelivery.java | 2 +- .../src/org/compiere/model/MAsset.java | 1239 +++++++--------- .../src/org/compiere/model/MAssetAcct.java | 316 +++-- .../org/compiere/model/MAssetAddition.java | 1262 +++++++++++++++-- .../src/org/compiere/model/MAssetChange.java | 143 +- .../src/org/compiere/model/MAssetGroup.java | 203 ++- .../org/compiere/model/MAssetGroupAcct.java | 142 +- .../org/compiere/model/MAssetTransfer.java | 277 +++- .../src/org/compiere/model/MAssetUse.java | 30 +- .../compiere/model/MDepreciationWorkfile.java | 815 ++++++++++- .../src/org/compiere/model/MInOut.java | 3 +- .../src/org/compiere/model/MXIFAJournal.java | 137 +- .../src/org/compiere/util/TimeUtil.java | 70 +- 13 files changed, 3347 insertions(+), 1292 deletions(-) diff --git a/org.adempiere.base.process/src/org/compiere/process/AssetDelivery.java b/org.adempiere.base.process/src/org/compiere/process/AssetDelivery.java index ec77dafab0..0aa97ce1d6 100644 --- a/org.adempiere.base.process/src/org/compiere/process/AssetDelivery.java +++ b/org.adempiere.base.process/src/org/compiere/process/AssetDelivery.java @@ -299,7 +299,7 @@ public class AssetDelivery extends SvrProcess // log.fine((System.currentTimeMillis()-start) + " ms"); // success - StringBuilder msgreturn = new StringBuilder().append(user.getEMail()).append(" - ").append(asset.getProductVersionNo()); + StringBuilder msgreturn = new StringBuilder().append(user.getEMail()).append(" - ").append(asset.getVersionNo()); return msgreturn.toString(); } // deliverIt diff --git a/org.adempiere.base/src/org/compiere/model/MAsset.java b/org.adempiere.base/src/org/compiere/model/MAsset.java index 8ab6a316d4..e4ab6df078 100644 --- a/org.adempiere.base/src/org/compiere/model/MAsset.java +++ b/org.adempiere.base/src/org/compiere/model/MAsset.java @@ -1,766 +1,615 @@ -/****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. This program is distributed in the hope * - * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ package org.compiere.model; import java.math.BigDecimal; -import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Timestamp; -import java.util.List; +import java.util.ArrayList; +import java.util.Collection; import java.util.Properties; import javax.servlet.http.HttpServletRequest; -import org.compiere.util.CLogger; +import org.compiere.util.CLogMgt; import org.compiere.util.DB; import org.compiere.util.EMail; import org.compiere.util.Env; -import org.compiere.util.TimeUtil; +import org.compiere.util.Msg; /** - * Asset Model - * - * @author Jorg Janke - * @version $Id: MAsset.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $ - * @author red1 - FR: [ 2214883 ] Remove SQL code and Replace for Query + * Asset Model + * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ +@SuppressWarnings("serial") public class MAsset extends X_A_Asset + //implements MAssetType.Model //commented by @win { + /** ChangeType - Asset Group changed */ + public static final int CHANGETYPE_setAssetGroup = Table_ID * 100 + 1; + /** - * + * Get Asset + * @param ctx context + * @param A_Asset_ID asset + * @param trxName */ - private static final long serialVersionUID = -7537696364072606170L; - - - /** - * Get Asset From Shipment - * @param ctx context - * @param M_InOutLine_ID shipment line - * @param trxName transaction - * @return asset or null - */ - public static MAsset getFromShipment (Properties ctx, int M_InOutLine_ID, String trxName) + public static MAsset get (Properties ctx, int A_Asset_ID, String trxName) { - final String whereClause = I_A_Asset.COLUMNNAME_M_InOutLine_ID+"=?"; - MAsset retValue = new Query(ctx,I_A_Asset.Table_Name,whereClause,trxName) - .setParameters(M_InOutLine_ID) - .first(); - return retValue; - } // getFromShipment + return (MAsset)MTable.get(ctx, MAsset.Table_Name).getPO(A_Asset_ID, trxName); + } // get - /** Logger */ - private static CLogger s_log = CLogger.getCLogger (MAsset.class); - - - /************************************************************************** - * Asset Constructor - * @param ctx context - * @param A_Asset_ID asset - * @param trxName transaction name + /** + * Get Assets from given M_Product_ID and M_ASI_ID. + *

Note: The A_Asset_Product table is not checked !!! + * @param ctx + * @param M_Product_ID (optional) + * @param M_ASI_ID + * @return array of MAsset */ + public static Collection forASI(Properties ctx, int M_Product_ID, int M_ASI_ID) + { + ArrayList params = new ArrayList(); + String whereClause = COLUMNNAME_M_AttributeSetInstance_ID + "=?"; + params.add(M_ASI_ID); + if (M_Product_ID > 0) { + whereClause += " AND " + COLUMNNAME_M_Product_ID + "=?"; + params.add(M_Product_ID); + } + // + return new Query(ctx, MAsset.Table_Name, whereClause, null) + .setParameters(params) + .list(); + } + + /** Create constructor */ public MAsset (Properties ctx, int A_Asset_ID, String trxName) { - super (ctx, A_Asset_ID, trxName); + super (ctx, A_Asset_ID,trxName); if (A_Asset_ID == 0) { - // setIsDepreciated (false); - // setIsFullyDepreciated (false); - // setValue (null); - // setName (null); - // setIsInPosession (false); - // setIsOwned (false); - // setA_Asset_Group_ID (0); - // setIsDisposed (false); - // setM_AttributeSetInstance_ID(0); - setQty(Env.ONE); + setA_Asset_Status(A_ASSET_STATUS_New); + //commented out by @win + /* + setA_Asset_Type("MFX"); + setA_Asset_Type_ID(1); // MFX + */ + //end comment by @win } } // MAsset /** - * Discontinued Asset Constructor - DO NOT USE (but don't delete either) - * @param ctx context - * @param A_Asset_ID asset - */ - public MAsset (Properties ctx, int A_Asset_ID) - { - this (ctx, A_Asset_ID, null); - } // MAsset - - /** - * Load Constructor - * @param ctx context - * @param rs result set record - * @param trxName transaction + * Load Constructor + * @param ctx context + * @param rs result set record */ public MAsset (Properties ctx, ResultSet rs, String trxName) { - super(ctx, rs, trxName); + super (ctx, rs, trxName); } // MAsset + + /** + * Construct from MMatchInv + * @param match match invoice + */ + protected MAsset (MMatchInv match) + { + this(match.getCtx(), 0, match.get_TrxName()); + + MInvoiceLine invoiceLine = new MInvoiceLine(getCtx(), match.getC_InvoiceLine_ID(), get_TrxName()); + MInOutLine inoutLine = new MInOutLine(getCtx(), match.getM_InOutLine_ID(), get_TrxName()); + + setIsOwned(true); + setIsInPosession(true); + setA_Asset_CreateDate(inoutLine.getM_InOut().getMovementDate()); + + // Asset Group: + int A_Asset_Group_ID = invoiceLine.getA_Asset_Group_ID(); + MProduct product = MProduct.get(getCtx(), invoiceLine.getM_Product_ID()); + if (A_Asset_Group_ID <= 0) { + A_Asset_Group_ID = product.getA_Asset_Group_ID(); + } + setA_Asset_Group_ID(A_Asset_Group_ID); + setHelp(Msg.getMsg(MClient.get(getCtx()).getAD_Language(), "CreatedFromInvoiceLine", + new Object[] {invoiceLine.getC_Invoice().getDocumentNo(), invoiceLine.getLine()})); + + String name = ""; + if (inoutLine.getM_Product_ID()>0) + { + name += product.getName() + "-"; + setM_Product_ID(inoutLine.getM_Product_ID()); + setM_AttributeSetInstance_ID(inoutLine.getM_AttributeSetInstance_ID()); + } + MBPartner bp = new MBPartner(getCtx(), invoiceLine.getC_Invoice().getC_BPartner_ID(), null); + name += bp.getName()+"-"+invoiceLine.getC_Invoice().getDocumentNo(); + log.fine("name=" + name); + setValue(name); + setName(name); + setDescription(invoiceLine.getDescription()); + } /** - * Shipment Constructor - * @param shipment shipment - * @param shipLine shipment line - * @param deliveryCount 0 or number of delivery + * Construct from MIFixedAsset (import) + * @param match match invoice */ - public MAsset (MInOut shipment, MInOutLine shipLine, int deliveryCount) + protected MAsset (MIFixedAsset ifa) { - this (shipment.getCtx(), 0, shipment.get_TrxName()); - setClientOrg(shipment); + this(ifa.getCtx(), 0, ifa.get_TrxName()); - setValueNameDescription(shipment, shipLine, deliveryCount); - // Header - setAssetServiceDate(shipment.getMovementDate()); + setAD_Org_ID(ifa.getAD_Org_ID()); //added by @win + setIsOwned(true); + setIsInPosession(true); + + String inventoryNo = ifa.getInventoryNo(); + if (inventoryNo != null) { + inventoryNo = inventoryNo.trim(); + setInventoryNo(inventoryNo); + setValue(inventoryNo); + } + setA_Asset_CreateDate(ifa.getAssetServiceDate()); + //setAssetServiceDate(ifa.getAssetServiceDate()); //commented by @win + /* commented by @win + setA_Asset_Class_ID(ifa.getA_Asset_Class_ID()); + */ // commented by @win + MProduct product = ifa.getProduct(); + if (product != null) { + setM_Product_ID(product.getM_Product_ID()); + setA_Asset_Group_ID(ifa.getA_Asset_Group_ID()); + MAttributeSetInstance asi = MAttributeSetInstance.create(getCtx(), product, get_TrxName()); + setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); + } + + setDateAcct(ifa.getDateAcct()); + setName(ifa.getName()); + setDescription(ifa.getDescription()); + } + + /** + * @author Edwin Ang + * @param project + */ + protected MAsset (MProject project) + { + this(project.getCtx(), 0, project.get_TrxName()); + setIsOwned(true); + setIsInPosession(true); + setA_Asset_CreateDate(new Timestamp(System.currentTimeMillis())); + setHelp(Msg.getMsg(MClient.get(getCtx()).getAD_Language(), "CreatedFromProject", new Object[] { project.getName()})); + setDateAcct(new Timestamp(System.currentTimeMillis())); + setDescription(project.getDescription()); + } + + public MAsset(MInOut mInOut, MInOutLine sLine, int deliveryCount) { + this(mInOut.getCtx(), 0, mInOut.get_TrxName()); setIsOwned(false); - setC_BPartner_ID(shipment.getC_BPartner_ID()); - setC_BPartner_Location_ID(shipment.getC_BPartner_Location_ID()); - setAD_User_ID(shipment.getAD_User_ID()); + setIsInPosession(false); + setA_Asset_CreateDate(new Timestamp(System.currentTimeMillis())); + setHelp(Msg.getMsg(MClient.get(getCtx()).getAD_Language(), "CreatedFromShipment: ", new Object[] { mInOut.getDocumentNo()})); + setDateAcct(new Timestamp(System.currentTimeMillis())); + setDescription(sLine.getDescription()); - // Line - MProduct product = shipLine.getProduct(); + } + + /** + * Create Asset from Inventory + * @param inventory inventory + * @param invLine inventory line + * @param deliveryCount 0 or number of delivery + * @return A_Asset_ID + */ + + public MAsset (MInventory inventory, MInventoryLine invLine, BigDecimal qty, BigDecimal costs) + { + super(invLine.getCtx(), 0, invLine.get_TrxName()); + setClientOrg(invLine); + + MProduct product = MProduct.get(getCtx(), invLine.getM_Product_ID()); + // Defaults from group: + MAssetGroup assetGroup = MAssetGroup.get(invLine.getCtx(), invLine.getM_Product().getM_Product_Category().getA_Asset_Group_ID()); + if (assetGroup == null) + assetGroup = MAssetGroup.get(invLine.getCtx(), product.getA_Asset_Group_ID()); + setAssetGroup(assetGroup); + + + //setValue(prod) + setName(product.getName()); + setHelp(invLine.getDescription()); + // Header + setAssetServiceDate(inventory.getMovementDate()); + setIsOwned(true); + setIsInPosession(true); + + // Product setM_Product_ID(product.getM_Product_ID()); - setA_Asset_Group_ID(product.getA_Asset_Group_ID()); // Guarantee & Version - setGuaranteeDate(TimeUtil.addDays(shipment.getMovementDate(), product.getGuaranteeDays())); + //setGuaranteeDate(TimeUtil.addDays(shipment.getMovementDate(), product.getGuaranteeDays())); setVersionNo(product.getVersionNo()); - if (shipLine.getM_AttributeSetInstance_ID() != 0) + // ASI + if (invLine.getM_AttributeSetInstance_ID() != 0) { - MAttributeSetInstance asi = new MAttributeSetInstance (getCtx(), shipLine.getM_AttributeSetInstance_ID(), get_TrxName()); - setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); - setLot(asi.getLot()); - setSerNo(asi.getSerNo()); + MAttributeSetInstance asi = new MAttributeSetInstance (getCtx(), invLine.getM_AttributeSetInstance_ID(), get_TrxName()); + setASI(asi); } - setHelp(shipLine.getDescription()); - if (deliveryCount != 0) - setQty(shipLine.getMovementQty()); - setM_InOutLine_ID(shipLine.getM_InOutLine_ID()); + //setSerNo(invLine.getSerNo()); + setQty(qty); - // Activate - MAssetGroup ag = MAssetGroup.get(getCtx(), getA_Asset_Group_ID()); - if (!ag.isCreateAsActive()) - setIsActive(false); - } // MAsset - - - /** Product Info */ - private MProduct m_product = null; - - /** - * Set Value Name Description - * @param shipment shipment - * @param line line - * @param deliveryCount - */ - public void setValueNameDescription(MInOut shipment, MInOutLine line, - int deliveryCount) - { - MProduct product = line.getProduct(); - MBPartner partner = shipment.getBPartner(); - setValueNameDescription(shipment, deliveryCount, product, partner); - } // setValueNameDescription - - /** - * Set Value, Name, Description - * @param shipment shipment - * @param deliveryCount count - * @param product product - * @param partner partner - */ - public void setValueNameDescription (MInOut shipment, - int deliveryCount, MProduct product, MBPartner partner) - { - StringBuilder documentNo = new StringBuilder("_").append(shipment.getDocumentNo()); - if (deliveryCount > 1) - documentNo.append("_").append(deliveryCount); - // Value - StringBuilder value = new StringBuilder().append(partner.getValue()).append("_").append(product.getValue()); - if (value.length() > 40-documentNo.length()) - value.delete(40-documentNo.length(), value.length()).append(documentNo); + // Costs: + //setA_Asset_Cost(costs); //commented by @win, set at asset addition - setValue(value.toString()); + // Activity + /* + if (invLine.getC_Activity_ID() > 0) + setC_Activity_ID(invLine.getC_Activity_ID()); + */ + if (inventory.getC_Activity_ID() > 0) + setC_Activity_ID(inventory.getC_Activity_ID()); - // Name MProduct.afterSave - StringBuilder name = new StringBuilder().append(partner.getName()).append(" - ").append(product.getName()); - if (name.length() > 60) - name.delete(60,name.length()); - setName(name.toString()); - // Description - String description = product.getDescription(); - setDescription(description); - } // setValueNameDescription - - /** - * Add to Description - * @param description text - */ - public void addDescription (String description) - { - String desc = getDescription(); - if (desc == null) - setDescription(description); - else{ - StringBuilder msgsd= new StringBuilder(desc).append(" | ").append(description); - setDescription(msgsd.toString()); - } - } // addDescription - - /** - * Get Qty - * @return 1 or Qty - */ - public BigDecimal getQty () - { - BigDecimal qty = super.getQty(); - if (qty == null || qty.compareTo(Env.ZERO)==0) - setQty(Env.ONE); - return super.getQty(); - } // getQty - - /** - * String representation - * @return info - */ - public String toString () - { - StringBuilder sb = new StringBuilder ("MAsset[") - .append (get_ID ()) - .append("-").append(getValue()) - .append ("]"); - return sb.toString (); - } // toString - - - /************************************************************************** - * Get Deliveries - * @return deliveries - */ - public MAssetDelivery[] getDeliveries() - { - final String whereClause = I_A_Asset_Delivery.COLUMNNAME_A_Asset_ID+"=?"; - List list = new Query(getCtx(),I_A_Asset_Delivery.Table_Name,whereClause,get_TrxName()) - .setParameters(getA_Asset_ID()) - .setOrderBy("Created DESC") - .list(); // - MAssetDelivery[] retValue = new MAssetDelivery[list.size()]; - list.toArray(retValue); - return retValue; - } // getDeliveries - - /** - * Get Delivery count - * @return delivery count - */ - public int getDeliveryCount() - { - String sql = "SELECT COUNT(*) FROM A_Asset_Delivery WHERE A_Asset_ID=?"; - return DB.getSQLValue(get_TrxName(), - sql, getA_Asset_ID()); - } // getDeliveries - - - /************************************************************************** - * Can we download. - * Based on guarantee date and availability of download - * @return true if downloadable - */ - public boolean isDownloadable() - { - if (!isActive()) - return false; - - // Guarantee Date - Timestamp guarantee = getGuaranteeDate(); - if (guarantee == null) - return false; - guarantee = TimeUtil.getDay(guarantee); - Timestamp now = TimeUtil.getDay(System.currentTimeMillis()); - // valid - if (!now.after(guarantee)) // not after guarantee date - { - getProduct(); - return m_product != null - && m_product.hasDownloads(); + + if (MAssetType.isFixedAsset(this)) { + setA_Asset_Status(A_ASSET_STATUS_New); } - // - return false; - } // isDownloadable - - /************************************************************************** - * Get Product Version No - * @return VersionNo - */ - public String getProductVersionNo() - { - return getProduct().getVersionNo(); - } // getProductVersionNo - - /** - * Get Product R_MailText_ID - * @return R_MailText_ID - */ - public int getProductR_MailText_ID() - { - return getProduct().getR_MailText_ID(); - } // getProductR_MailText_ID - - /** - * Get Product Info - * @return product - */ - private MProduct getProduct() - { - if (m_product == null) - m_product = MProduct.get (getCtx(), getM_Product_ID()); - return m_product; - } // getProductInfo - - /** - * Get Active Addl. Product Downloads - * @return array of downloads - */ - public MProductDownload[] getProductDownloads() - { - if (m_product == null) - getProduct(); - if (m_product != null) - return m_product.getProductDownloads(false); - return null; - } // getProductDownloads - - /** - * Get Additional Download Names - * @return names - */ - public String[] getDownloadNames() - { - MProductDownload[] dls = getProductDownloads(); - if (dls != null && dls.length > 0) - { - String[] retValue = new String[dls.length]; - for (int i = 0; i < retValue.length; i++) - retValue[i] = dls[i].getName(); - log.fine("#" + dls.length); - return retValue; + else { + setA_Asset_Status(A_ASSET_STATUS_Activated); + setProcessed(true); } - return new String[]{}; - } // addlDownloadNames + + //added by @win + setA_Asset_Status(A_ASSET_STATUS_New); + //end added by @win + + + } /** - * Get Additional Download URLs - * @return URLs + * Set Asset Group; also it sets other default fields + * @param assetGroup */ - public String[] getDownloadURLs() - { - MProductDownload[] dls = getProductDownloads(); - if (dls != null && dls.length > 0) - { - String[] retValue = new String[dls.length]; - for (int i = 0; i < retValue.length; i++) - { - String url = dls[i].getDownloadURL(); - int pos = Math.max(url.lastIndexOf('/'), url.lastIndexOf('\\')); - if (pos != -1) - url = url.substring(pos+1); - retValue[i] = url; - } - return retValue; - } - return new String[]{}; - } // addlDownloadURLs + public void setAssetGroup(MAssetGroup assetGroup) { + setA_Asset_Group_ID(assetGroup.getA_Asset_Group_ID()); + + /* commented out by @win + setA_Asset_Type_ID(assetGroup.getA_Asset_Type_ID()); + setGZ_TipComponenta(assetGroup.getGZ_TipComponenta()); // TODO: move to GZ + MAssetType assetType = MAssetType.get(getCtx(), assetGroup.getA_Asset_Type_ID()); + assetType.update(SetGetUtil.wrap(this), true); + */ //end commet by @win + } + + public MAssetGroup getAssetGroup() { + return MAssetGroup.get(getCtx(), getA_Asset_Group_ID()); + } /** - * Before Save - * @param newRecord new - * @return true + * Set ASI Info (M_AttributeSetInstance_ID, Lot, SerNo) + * @param asi */ + public void setASI(MAttributeSetInstance asi) { + setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); + setLot(asi.getLot()); + setSerNo(asi.getSerNo()); + } + + /** + * Before Save + * @param newRecord new + * @return true + */ + protected boolean beforeSave (boolean newRecord) { - getQty(); // set to 1 - if (getA_Parent_Asset_ID() < 1 ) - { - setA_Parent_Asset_ID(getA_Asset_ID()); + // Set parent asset: + if (getA_Parent_Asset_ID() <= 0) + { + setA_Parent_Asset_ID(getA_Asset_ID()); } + // Fix inventory number: + String invNo = getInventoryNo(); + if(invNo != null) + { + setInventoryNo(invNo.trim()); + } + // If no asset group, than set the default one: + if(getA_Asset_Group_ID() <= 0) + { + setA_Asset_Group_ID(MAssetGroup.getDefault_ID(SetGetUtil.wrap(this))); + } + /* @win temporary commented out + + if (getA_Asset_Class_ID() <= 0 && getA_Asset_Group_ID() > 0) + { + MAssetGroup.updateAsset(SetGetUtil.wrap(this), getA_Asset_Group_ID()); + } + */ + //end @win comment + + // Copy fields from C_BPartner_Location + if (is_ValueChanged(COLUMNNAME_C_BPartner_Location_ID) && getC_BPartner_Location_ID() > 0) + { + SetGetUtil.copyValues((SetGetModel)this, MBPartnerLocation.Table_Name, getC_BPartner_Location_ID(), + new String[]{MBPartnerLocation.COLUMNNAME_C_Location_ID} + ); + } + // + // Create ASI if not exist: + if (getM_Product_ID() > 0 && getM_AttributeSetInstance_ID() <= 0) + { + MProduct product = MProduct.get(getCtx(), getM_Product_ID()); + MAttributeSetInstance asi = new MAttributeSetInstance(getCtx(), 0, product.getM_AttributeSet_ID(), get_TrxName()); + asi.setSerNo(getSerNo()); + asi.setDescription(); + asi.saveEx(); + setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); + } + // TODO: With the lines below, after creating the asset, the whole system goes much slower ??? +// else if (is_ValueChanged(COLUMNNAME_SerNo) && getM_AttributeSetInstance_ID() > 0) { +// asi = new MAttributeSetInstance(getCtx(), getM_AttributeSetInstance_ID(), get_TrxName()); +// asi.setSerNo(getSerNo()); +// asi.setDescription(); +// asi.saveEx(); +// } +// else if ((newRecord || is_ValueChanged(COLUMNNAME_M_AttributeSetInstance_ID)) && getM_AttributeSetInstance_ID() > 0) { +// asi = new MAttributeSetInstance(getCtx(), getM_AttributeSetInstance_ID(), get_TrxName()); +// setASI(asi); +// } + // + + // Update status + updateStatus(); + + // Validate AssetType + //@win commented out + //MAssetType.validate(this); + //@win end + // + return true; } // beforeSave - /** - * After Save - * @param newRecord new - * @param success success - * @return saved - */ - protected boolean afterSave (boolean newRecord,boolean success) + + protected boolean afterSave (boolean newRecord, boolean success) { - log.info ("afterSave"); - - int p_A_Asset_ID = 0; - p_A_Asset_ID = getA_Asset_ID(); - - String sql = "SELECT COUNT(*) FROM A_Depreciation_Workfile WHERE A_Asset_ID=?"; - PreparedStatement pstmt = null; - - - if (DB.getSQLValue(get_TrxName(),sql, p_A_Asset_ID)== 0) - { - sql ="SELECT * FROM A_Asset_Group_Acct WHERE A_Asset_Group_ID = ? AND IsActive='Y'"; - pstmt = null; - pstmt = DB.prepareStatement(sql,get_TrxName()); - try { - pstmt.setInt(1, getA_Asset_Group_ID()); - ResultSet rs = pstmt.executeQuery(); - int uselifemonths = 0; - int uselifeyears = 0; - boolean isdepreciate = false; - - - MAssetChange change = new MAssetChange (getCtx(), 0, get_TrxName()); - X_A_Asset asset = new X_A_Asset (getCtx(), p_A_Asset_ID, get_TrxName()); - - if (getA_Parent_Asset_ID() < 1 ) - { - asset.setA_Parent_Asset_ID(getA_Asset_ID()); - asset.saveEx(); - } - - - while (rs.next()){ - MAssetGroupAcct assetgrpacct = new MAssetGroupAcct (getCtx(), rs, get_TrxName()); - MAssetAcct assetacct = new MAssetAcct (getCtx(), 0, get_TrxName()); - isdepreciate = assetgrpacct.isProcessing(); - if (isDepreciated()== true || isdepreciate == true) - { - assetacct.setPostingType(assetgrpacct.getPostingType()); - assetacct.setA_Split_Percent(assetgrpacct.getA_Split_Percent()); - assetacct.setA_Depreciation_Conv_ID(assetgrpacct.getConventionType()); - assetacct.setA_Salvage_Value(new BigDecimal(0.0)); - assetacct.setA_Asset_ID(p_A_Asset_ID); - assetacct.setA_Depreciation_ID(assetgrpacct.getDepreciationType()); - assetacct.setA_Asset_Spread_ID(assetgrpacct.getA_Asset_Spread_Type()); - assetacct.setA_Period_Start(1); - - - if (getUseLifeMonths() == 0 && getUseLifeYears() == 0){ - assetacct.setA_Period_End(assetgrpacct.getUseLifeMonths()); - asset.setUseLifeYears(assetgrpacct.getUseLifeYears()); - asset.setUseLifeMonths(assetgrpacct.getUseLifeMonths()); - asset.setIsDepreciated(true); - asset.setIsOwned(true); - asset.saveEx(); - uselifemonths = assetgrpacct.getUseLifeMonths(); - uselifeyears = assetgrpacct.getUseLifeYears(); - - } - else if(getUseLifeMonths() == 0){ - assetacct.setA_Period_End(getUseLifeYears()*12); - asset.setUseLifeMonths(getUseLifeYears()*12); - asset.setIsDepreciated(true); - asset.setIsOwned(true); - asset.saveEx(); - uselifemonths = getUseLifeYears()*12; - uselifeyears = getUseLifeYears(); - } - else{ - assetacct.setA_Period_End(getUseLifeMonths()); - uselifemonths = getUseLifeMonths(); - uselifeyears = getUseLifeYears();} - - assetacct.setA_Depreciation_Method_ID(assetgrpacct.getA_Depreciation_Calc_Type()); - assetacct.setA_Asset_Acct(assetgrpacct.getA_Asset_Acct()); - assetacct.setC_AcctSchema_ID(assetgrpacct.getC_AcctSchema_ID()); - assetacct.setA_Accumdepreciation_Acct(assetgrpacct.getA_Accumdepreciation_Acct()); - assetacct.setA_Depreciation_Acct(assetgrpacct.getA_Depreciation_Acct()); - assetacct.setA_Disposal_Revenue(assetgrpacct.getA_Disposal_Revenue()); - assetacct.setA_Disposal_Loss(assetgrpacct.getA_Disposal_Loss()); - assetacct.setA_Reval_Accumdep_Offset_Cur(assetgrpacct.getA_Reval_Accumdep_Offset_Cur()); - assetacct.setA_Reval_Accumdep_Offset_Prior(assetgrpacct.getA_Reval_Accumdep_Offset_Prior()); - if (assetgrpacct.getA_Reval_Cal_Method() == null) - assetacct.setA_Reval_Cal_Method("DFT"); - else - assetacct.setA_Reval_Cal_Method(assetgrpacct.getA_Reval_Cal_Method()); - assetacct.setA_Reval_Cost_Offset(assetgrpacct.getA_Reval_Cost_Offset()); - assetacct.setA_Reval_Cost_Offset_Prior(assetgrpacct.getA_Reval_Cost_Offset_Prior()); - assetacct.setA_Reval_Depexp_Offset(assetgrpacct.getA_Reval_Depexp_Offset()); - assetacct.setA_Depreciation_Manual_Amount(assetgrpacct.getA_Depreciation_Manual_Amount()); - assetacct.setA_Depreciation_Manual_Period(assetgrpacct.getA_Depreciation_Manual_Period()); - assetacct.setA_Depreciation_Table_Header_ID(assetgrpacct.getA_Depreciation_Table_Header_ID()); - assetacct.setA_Depreciation_Variable_Perc(assetgrpacct.getA_Depreciation_Variable_Perc()); - assetacct.setProcessing(false); - assetacct.saveEx(); - - change.setPostingType(assetacct.getPostingType()); - change.setA_Split_Percent(assetacct.getA_Split_Percent()); - change.setConventionType(assetacct.getA_Depreciation_Conv_ID()); - change.setA_Asset_ID(p_A_Asset_ID); - change.setDepreciationType(assetacct.getA_Depreciation_ID()); - change.setA_Asset_Spread_Type(assetacct.getA_Asset_Spread_ID()); - change.setA_Period_Start(assetacct.getA_Period_Start()); - change.setA_Period_End(assetacct.getA_Period_End()); - change.setIsInPosession(isOwned()); - change.setIsDisposed(isDisposed()); - change.setIsDepreciated(isDepreciated()); - change.setIsFullyDepreciated(isFullyDepreciated()); - change.setA_Depreciation_Calc_Type(assetacct.getA_Depreciation_Method_ID()); - change.setA_Asset_Acct(assetacct.getA_Asset_Acct()); - change.setC_AcctSchema_ID(assetacct.getC_AcctSchema_ID()); - change.setA_Accumdepreciation_Acct(assetacct.getA_Accumdepreciation_Acct()); - change.setA_Depreciation_Acct(assetacct.getA_Depreciation_Acct()); - change.setA_Disposal_Revenue(assetacct.getA_Disposal_Revenue()); - change.setA_Disposal_Loss(assetacct.getA_Disposal_Loss()); - change.setA_Reval_Accumdep_Offset_Cur(assetacct.getA_Reval_Accumdep_Offset_Cur()); - change.setA_Reval_Accumdep_Offset_Prior(assetacct.getA_Reval_Accumdep_Offset_Prior()); - if (assetacct.getA_Reval_Cal_Method() == null) - change.setA_Reval_Cal_Method("DFT"); - else - change.setA_Reval_Cal_Method(assetacct.getA_Reval_Cal_Method()); - change.setA_Reval_Cost_Offset(assetacct.getA_Reval_Cost_Offset()); - change.setA_Reval_Cost_Offset_Prior(assetacct.getA_Reval_Cost_Offset_Prior()); - change.setA_Reval_Depexp_Offset(assetacct.getA_Reval_Depexp_Offset()); - change.setA_Depreciation_Manual_Amount(assetacct.getA_Depreciation_Manual_Amount()); - change.setA_Depreciation_Manual_Period(assetacct.getA_Depreciation_Manual_Period()); - change.setA_Depreciation_Table_Header_ID(assetacct.getA_Depreciation_Table_Header_ID()); - change.setA_Depreciation_Variable_Perc(assetacct.getA_Depreciation_Variable_Perc()); - - } - - String sql2 = "SELECT COUNT(*) FROM A_Depreciation_Workfile WHERE A_Asset_ID=? AND PostingType = ?"; - if (DB.getSQLValue(get_TrxName(), sql2, asset.getA_Asset_ID(),assetgrpacct.getPostingType())== 0) - { - - if (isDepreciated()== true || isdepreciate == true) - { - X_A_Depreciation_Workfile assetwk = new X_A_Depreciation_Workfile (getCtx(), 0, get_TrxName()); - assetwk.setA_Asset_ID(p_A_Asset_ID); - assetwk.setA_Life_Period(uselifemonths); - assetwk.setA_Asset_Life_Years(uselifeyears); - assetwk.setIsDepreciated(isDepreciated()); - assetwk.setPostingType(assetgrpacct.getPostingType()); - assetwk.setA_Accumulated_Depr(new BigDecimal(0.0)); - assetwk.setA_QTY_Current(new BigDecimal(0.0)); - assetwk.setA_Asset_Cost(new BigDecimal(0.0)); - assetwk.setA_Period_Posted(0); - assetwk.saveEx(); - } - } - } - - change.setA_Asset_ID(p_A_Asset_ID); - change.setA_Parent_Asset_ID(asset.getA_Parent_Asset_ID()); - change.setChangeType("CRT"); - change.setTextDetails(MRefList.getListDescription (getCtx(),"A_Update_Type" , "CRT")); - change.setIsInPosession(isOwned()); - change.setIsDisposed(isDisposed()); - change.setIsDepreciated(isDepreciated()); - change.setIsFullyDepreciated(isFullyDepreciated()); - change.setLot(getLot()); - change.setSerNo(getSerNo()); - change.setVersionNo(getVersionNo()); - change.setUseLifeMonths(getUseLifeMonths()); - change.setUseLifeYears(getUseLifeYears()); - change.setLifeUseUnits(getLifeUseUnits()); - change.setAssetDisposalDate(getAssetDisposalDate()); - change.setAssetServiceDate(getAssetServiceDate()); - change.setC_BPartner_Location_ID(getC_BPartner_Location_ID()); - change.setC_BPartner_ID(getC_BPartner_ID()); - change.setA_QTY_Current(getA_QTY_Current()); - change.setA_QTY_Original(getA_QTY_Original()); - change.setA_Asset_CreateDate(getA_Asset_CreateDate()); - change.setAD_User_ID(getAD_User_ID()); - change.setC_Location_ID(getC_Location_ID()); - change.saveEx(); - - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.info("getAssets"+ e); - } - finally - { - try - { - if (pstmt != null) - pstmt.close (); - } - catch (Exception e) - {} - pstmt = null; - } - - - } - else + if(!success) { - int uselifemonths = 0; - int uselifeyears = 0; - sql ="SELECT * FROM A_Asset_Acct WHERE A_Asset_ID = ? AND IsActive='Y'"; - pstmt = null; - pstmt = DB.prepareStatement(sql,get_TrxName()); - - - try { - - pstmt.setInt(1, getA_Asset_ID()); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()){ - MAssetAcct assetacct = new MAssetAcct (getCtx(),rs, get_TrxName()); - assetacct.setProcessing(false); - assetacct.setA_Asset_ID(p_A_Asset_ID); - assetacct.setA_Period_Start(1); - if(getUseLifeMonths() == 0){ - assetacct.setA_Period_End(getUseLifeYears()*12); - setUseLifeMonths(getUseLifeYears()*12); - uselifemonths = getUseLifeYears()*12; - uselifeyears = getUseLifeYears(); - } - else{ - assetacct.setA_Period_End(getUseLifeMonths()); - uselifemonths = getUseLifeMonths(); - uselifeyears = getUseLifeYears(); - } - assetacct.saveEx(); - } - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.info("getAssets"+ e); - } - finally - { - try - { - if (pstmt != null) - pstmt.close (); - } - catch (Exception e) - {} - pstmt = null; - } - sql ="SELECT * FROM A_Depreciation_Workfile WHERE A_Asset_ID=? AND IsActive='Y'"; - pstmt = null; - try - { - pstmt = DB.prepareStatement(sql,get_TrxName()); - pstmt.setInt(1, p_A_Asset_ID); - ResultSet rs = pstmt.executeQuery(); - - while (rs.next()){ - - X_A_Depreciation_Workfile assetwk = new X_A_Depreciation_Workfile (getCtx(), rs, get_TrxName()); - - assetwk.setA_Asset_ID(p_A_Asset_ID); - assetwk.setA_Life_Period(uselifemonths); - assetwk.setA_Asset_Life_Years(uselifeyears); - assetwk.setIsDepreciated(isDepreciated()); - //assetwk.setA_QTY_Current(getA_QTY_Current()); - assetwk.saveEx(); - - if (isProcessing()== true){ - MAssetChange change = new MAssetChange (getCtx(), 0, get_TrxName()); - change.setA_Asset_ID(p_A_Asset_ID); - change.setChangeType("UPD"); - change.setTextDetails(MRefList.getListDescription (getCtx(),"A_Update_Type" , "UPD")); - change.setLot(getLot()); - change.setSerNo(getSerNo()); - change.setVersionNo(getVersionNo()); - change.setA_Parent_Asset_ID(getA_Parent_Asset_ID()); - change.setUseLifeMonths(getUseLifeMonths()); - change.setUseLifeYears(getUseLifeYears()); - change.setLifeUseUnits(getLifeUseUnits()); - change.setAssetDisposalDate(getAssetDisposalDate()); - change.setAssetServiceDate(getAssetServiceDate()); - change.setIsInPosession(isOwned()); - change.setA_Reval_Cal_Method("DFT"); - change.setIsDisposed(isDisposed()); - change.setIsDepreciated(isDepreciated()); - change.setIsFullyDepreciated(isFullyDepreciated()); - change.setC_BPartner_Location_ID(getC_BPartner_Location_ID()); - change.setC_BPartner_ID(getC_BPartner_ID()); - change.setPostingType("A"); - change.setA_QTY_Current(getA_QTY_Current()); - change.setA_QTY_Original(getA_QTY_Original()); - change.setA_Asset_CreateDate(getA_Asset_CreateDate()); - change.setAD_User_ID(getAD_User_ID()); - change.setC_Location_ID(getC_Location_ID()); - change.saveEx(); - } - else - { - X_A_Asset asset = new X_A_Asset (getCtx(), p_A_Asset_ID, get_TrxName()); - asset.setProcessing(true); - asset.saveEx(); - } - } - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) - { - log.info("getAssets"+ e); - } - finally - { - try - { - if (pstmt != null) - pstmt.close (); - } - catch (Exception e) - {} - pstmt = null; - } - + return success; } - + + // + // Set parent + if(getA_Parent_Asset_ID() <= 0) + { + int A_Asset_ID = getA_Asset_ID(); + setA_Parent_Asset_ID(A_Asset_ID); + DB.executeUpdateEx("UPDATE A_Asset SET A_Parent_Asset_ID=A_Asset_ID WHERE A_Asset_ID=" + A_Asset_ID, get_TrxName()); + log.fine("A_Parent_Asset_ID=" + getA_Parent_Asset_ID()); + } + + // + // Set inventory number: + String invNo = getInventoryNo(); + if(invNo == null || invNo.trim().length() == 0) + { + invNo = "" + get_ID(); + setInventoryNo(invNo); + DB.executeUpdateEx("UPDATE A_Asset SET InventoryNo=" + DB.TO_STRING(invNo) + " WHERE A_Asset_ID=" + getA_Asset_ID(), get_TrxName()); + log.fine("InventoryNo=" + getInventoryNo()); + } + + + // If new record, create accounting and workfile + if (newRecord) + { + //@win: set value at asset group as default value for asset + MAssetGroup assetgroup = new MAssetGroup(getCtx(), getA_Asset_Group_ID(), get_TrxName()); + String isDepreciated = (assetgroup.isDepreciated()) ? "Y" : "N"; + String isOwned = (assetgroup.isOwned()) ? "Y" : "N"; + setIsDepreciated(assetgroup.isDepreciated()); + setIsOwned(assetgroup.isOwned()); + DB.executeUpdateEx("UPDATE A_Asset SET IsDepreciated='" + isDepreciated + "', isOwned ='" + isOwned + "' WHERE A_Asset_ID=" + getA_Asset_ID(), get_TrxName()); + //end @win + + // for each asset group acounting create an asset accounting and a workfile too + for (MAssetGroupAcct assetgrpacct : MAssetGroupAcct.forA_Asset_Group_ID(getCtx(), getA_Asset_Group_ID())) + { + // Asset Accounting + MAssetAcct assetacct = new MAssetAcct(this, assetgrpacct); + assetacct.setAD_Org_ID(getAD_Org_ID()); //added by @win + assetacct.saveEx(); + + // Asset Depreciation Workfile + MDepreciationWorkfile assetwk = new MDepreciationWorkfile(this, assetacct.getPostingType(), assetgrpacct); + assetwk.setAD_Org_ID(getAD_Org_ID()); //added by @win + assetwk.setUseLifeYears(0); + assetwk.setUseLifeMonths(0); + assetwk.setUseLifeYears_F(0); + assetwk.setUseLifeMonths_F(0); + assetwk.saveEx(); + + // Change Log + MAssetChange.createAndSave(getCtx(), "CRT", new PO[]{this, assetwk, assetacct}, null); + } + + } + else + { + MAssetChange.createAndSave(getCtx(), "UPD", new PO[]{this}, null); + } + + // + // Update child.IsDepreciated flag + if (!newRecord && is_ValueChanged(COLUMNNAME_IsDepreciated)) + { + final String sql = "UPDATE " + MDepreciationWorkfile.Table_Name + +" SET " + MDepreciationWorkfile.COLUMNNAME_IsDepreciated+"=?" + +" WHERE " + MDepreciationWorkfile.COLUMNNAME_A_Asset_ID+"=?"; + DB.executeUpdateEx(sql, new Object[]{isDepreciated(), getA_Asset_ID()}, get_TrxName()); + } + return true; - } // afterSave - /************************************************************************* - * Confirm Asset EMail Delivery - * @param email email sent - * @param AD_User_ID recipient - * @return asset delivery - */ - public MAssetDelivery confirmDelivery (EMail email, int AD_User_ID) - { - setVersionNo(getProductVersionNo()); - MAssetDelivery ad = new MAssetDelivery (this, email, AD_User_ID); - return ad; - } // confirmDelivery - - /** - * Confirm Asset Download Delivery - * @param request request - * @param AD_User_ID recipient - * @return asset delivery - */ - public MAssetDelivery confirmDelivery (HttpServletRequest request, int AD_User_ID) - { - setVersionNo(getProductVersionNo()); - setLifeUseUnits(getLifeUseUnits()+1); - MAssetDelivery ad = new MAssetDelivery (this, request, AD_User_ID); - return ad; - } // confirmDelivery -} // MAsset + protected boolean beforeDelete() + { + // delete addition + { + String sql = "DELETE FROM "+MAssetAddition.Table_Name+" WHERE "+MAssetAddition.COLUMNNAME_Processed+"=? AND "+MAssetAddition.COLUMNNAME_A_Asset_ID+"=?"; + int no = DB.executeUpdateEx(sql, new Object[]{false, getA_Asset_ID()}, get_TrxName()); + log.info("@A_Asset_Addition@ @Deleted@ #" + no); + } + // + // update invoice line + { + final String sql = "UPDATE "+MInvoiceLine.Table_Name+" SET " + +" "+MInvoiceLine.COLUMNNAME_A_Asset_ID+"=?" + +","+MInvoiceLine.COLUMNNAME_A_Processed+"=?" + +" WHERE "+MInvoiceLine.COLUMNNAME_A_Asset_ID+"=?"; + int no = DB.executeUpdateEx(sql, new Object[]{null, false, getA_Asset_ID()}, get_TrxName()); + log.info("@C_InvoiceLine@ @Updated@ #" + no); + } + return true; + } // beforeDelete + + /** + * + * @see #beforeSave(boolean) + */ + public void updateStatus() + { + String status = getA_Asset_Status(); + setProcessed(!status.equals(A_ASSET_STATUS_New)); +// setIsDisposed(!status.equals(A_ASSET_STATUS_New) && !status.equals(A_ASSET_STATUS_Activated)); + setIsDisposed(status.equals(A_ASSET_STATUS_Disposed)); + setIsFullyDepreciated(status.equals(A_ASSET_STATUS_Depreciated)); + if(isFullyDepreciated() || status.equals(A_ASSET_STATUS_Disposed)) + { + setIsDepreciated(false); + } + /* commented by @win + MAssetClass assetClass = MAssetClass.get(getCtx(), getA_Asset_Class_ID()); + if (assetClass != null && assetClass.isDepreciated()) + { + setIsDepreciated(true); + } + */ //end comment by @win + if (status.equals(A_ASSET_STATUS_Activated) || getAssetActivationDate() == null) + { + setAssetActivationDate(getAssetServiceDate()); + } + } + + /** + * Change asset status to newStatus + * @param newStatus see A_ASSET_STATUS_ + * @param date state change date; if null context "#Date" will be used + */ + public void changeStatus(String newStatus, Timestamp date) + { + String status = getA_Asset_Status(); + if (CLogMgt.isLevelFinest()) log.finest("Entering: " + status + "->" + newStatus + ", date=" + date); + + // + // If date is null, use context #Date + if(date == null) { + date = Env.getContextAsDate(getCtx(), "#Date"); + } + + // + // Activation/Addition + if(newStatus.equals(A_ASSET_STATUS_Activated)) + { + setAssetActivationDate(date); + } + // + // Preservation + if(newStatus.equals(A_ASSET_STATUS_Preservation)) + { + setAssetDisposalDate(date); + // TODO: move to MAsetDisposal + Collection workFiles = MDepreciationWorkfile.forA_Asset_ID(getCtx(), getA_Asset_ID(), get_TrxName()); + for(MDepreciationWorkfile assetwk : workFiles) { + assetwk.truncDepreciation(); + assetwk.saveEx(); + } + } + // Disposal + if(newStatus.equals(A_ASSET_STATUS_Disposed)) + { // casat, vandut + setAssetDisposalDate(date); + } + + // Set new status + setA_Asset_Status(newStatus); + } // changeStatus + + // Temporary used variables: + /** */ + private int m_UseLifeMonths_F = 0; + public int getUseLifeMonths_F() { return m_UseLifeMonths_F; } + public void setUseLifeMonths_F(int UseLifeMonths_F) { m_UseLifeMonths_F = UseLifeMonths_F; } + /** */ + private int m_A_Current_Period = 0; + public int getA_Current_Period() { return m_A_Current_Period; } + public void setA_Current_Period(int A_Current_Period) { m_A_Current_Period = A_Current_Period; } + /** */ + private Timestamp m_DateAcct = null; + public Timestamp getDateAcct() { return m_DateAcct; } + public void setDateAcct(Timestamp DateAcct) { m_DateAcct = DateAcct; } + /** */ + private int m_A_Depreciation_ID = 0; + public int getA_Depreciation_ID() { return m_A_Depreciation_ID; } + public void setA_Depreciation_ID(int A_Depreciation_ID) { m_A_Depreciation_ID = A_Depreciation_ID; } + /** */ + private int m_A_Depreciation_F_ID = 0; + public int getA_Depreciation_F_ID() { return m_A_Depreciation_F_ID; } + public void setA_Depreciation_F_ID(int A_Depreciation_F_ID) { m_A_Depreciation_F_ID = A_Depreciation_F_ID; } + /** */ + private BigDecimal m_A_Asset_Cost = Env.ZERO; + private BigDecimal m_A_Accumulated_Depr = Env.ZERO; + private BigDecimal m_A_Accumulated_Depr_F = Env.ZERO; + public BigDecimal getA_Asset_Cost() { return m_A_Asset_Cost; } + public void setA_Asset_Cost(BigDecimal A_Asset_Cost) { m_A_Asset_Cost = A_Asset_Cost; } + public BigDecimal getA_Accumulated_Depr() { return m_A_Accumulated_Depr; } + public void setA_Accumulated_Depr(BigDecimal A_Accumulated_Depr) { m_A_Accumulated_Depr = A_Accumulated_Depr; } + public BigDecimal getA_Accumulated_Depr_F() { return m_A_Accumulated_Depr_F; } + public void setA_Accumulated_Depr_F(BigDecimal A_Accumulated_Depr_F) { m_A_Accumulated_Depr_F = A_Accumulated_Depr_F; } + + public MAssetDelivery confirmDelivery(EMail email, int ad_User_ID) { + // TODO Auto-generated method stub + return null; + } + + public MProductDownload[] getProductDownloads() { + // TODO Auto-generated method stub + return null; + } + + public MAssetDelivery confirmDelivery(HttpServletRequest request, + int ad_User_ID) { + // TODO Auto-generated method stub + return null; + } + + public MAssetDelivery[] getDeliveries() { + // TODO Auto-generated method stub + return null; + } + + public static MAsset getFromShipment(Properties ctx, int i, String trxName) { + // TODO Auto-generated method stub + return null; + } + + public int getProductR_MailText_ID() { + // IDEMPIERE-197 Stabilize Fixed Assets + // AssetDelivery is requiring this missing column + // Adding this method to compile correctly and future research, + // but the process AssetDelivery will fail with error "** Product Mail Text" + return 0; + } + + public boolean isDownloadable() { + // IDEMPIERE-197 Stabilize Fixed Assets + // AssetServlet is requiring this missing column + // Adding this method to compile correctly and future research + return false; + } +} diff --git a/org.adempiere.base/src/org/compiere/model/MAssetAcct.java b/org.adempiere.base/src/org/compiere/model/MAssetAcct.java index 259e882827..f5e23a3947 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetAcct.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetAcct.java @@ -1,168 +1,184 @@ -/****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. This program is distributed in the hope * - * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * -******************************************************************************/ package org.compiere.model; -import java.sql.PreparedStatement; +import java.math.BigDecimal; import java.sql.ResultSet; +import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Properties; -import org.compiere.util.DB; +import org.apache.commons.collections.keyvalue.MultiKey; +import org.compiere.model.MAccount; +import org.compiere.model.MAcctSchema; +import org.compiere.model.ProductCost; +import org.compiere.model.Query; +import org.compiere.util.CCache; +import org.compiere.util.Env; +import org.compiere.util.TimeUtil; /** - * Asset Addition Model - * - * + * Asset Acct Model + * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ -public class MAssetAcct extends X_A_Asset_Acct { - /** - * - */ - private static final long serialVersionUID = 4779953750434068382L; +public class MAssetAcct extends X_A_Asset_Acct +{ + private static final long serialVersionUID = 1L; /** - * Default ConstructorX_A_Asset_Group_Acct - * - * @param ctx - * context - * @param M_InventoryLine_ID - * line + * DO NOT USE DIRECTLY */ - public MAssetAcct(Properties ctx, int X_A_Asset_Acct_ID, String trxName) { - super(ctx, X_A_Asset_Acct_ID, trxName); - if (X_A_Asset_Acct_ID == 0) { - // + public MAssetAcct (Properties ctx, int X_A_Asset_Acct_ID, String trxName) + { + super (ctx,X_A_Asset_Acct_ID, trxName); + if (X_A_Asset_Acct_ID == 0) + { + setA_Salvage_Value(Env.ZERO); } - } // MAssetAddition - + } + + public MAssetAcct (Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } + + /** Static Cache: A_Asset_Acct_ID -> MAssetAcct */ + private static CCache s_cache = new CCache(Table_Name, 5); + /** Static Cache: Asset,PostingType,DateAcct -> MAssetAcct */ + private static CCache s_cacheAsset = new CCache(Table_Name+"_Asset", 5); + /** - * Load Constructor - * - * @param ctx - * context - * @param rs - * result set + * Get Asset Accounting (from cache) + * @param ctx context + * @param A_Asset_Acct_ID asset accounting id + * @return asset accounting or null if not found */ - public MAssetAcct(Properties ctx, ResultSet rs, String trxName) { - super(ctx, rs, trxName); - } // MInventoryLine - - protected boolean afterSave(boolean newRecord, boolean success) { - log.info("afterSave"); - int p_actasset_ID = getA_Asset_Acct_ID(); - int p_A_Asset_ID = getA_Asset_ID(); - - if (isProcessing() == true) { - MAssetChange change = new MAssetChange(getCtx(), 0, null); - change.setChangeType("SET"); - change.setTextDetails(MRefList.getListDescription(getCtx(), - "A_Update_Type", "SET")); - change.setPostingType(getPostingType()); - change.setA_Split_Percent(getA_Split_Percent()); - change.setConventionType(getA_Depreciation_Conv_ID()); - change.setA_Salvage_Value(getA_Salvage_Value()); - change.setA_Asset_ID(getA_Asset_ID()); - change.setDepreciationType(getA_Depreciation_ID()); - change.setA_Asset_Spread_Type(getA_Asset_Spread_ID()); - change.setA_Period_Start(getA_Period_Start()); - change.setA_Period_End(getA_Period_End()); - change.setA_Depreciation_Calc_Type(getA_Depreciation_Method_ID()); - change.setA_Asset_Acct(getA_Asset_Acct()); - change.setC_AcctSchema_ID(getC_AcctSchema_ID()); - change.setA_Accumdepreciation_Acct(getA_Accumdepreciation_Acct()); - change.setA_Depreciation_Acct(getA_Depreciation_Acct()); - change.setA_Disposal_Revenue(getA_Disposal_Revenue()); - change.setA_Disposal_Loss(getA_Disposal_Loss()); - change.setA_Reval_Accumdep_Offset_Cur(getA_Reval_Accumdep_Offset_Cur()); - change.setA_Reval_Accumdep_Offset_Prior(getA_Reval_Accumdep_Offset_Prior()); - if (getA_Reval_Cal_Method() == null) - change.setA_Reval_Cal_Method("DFT"); - else - change.setA_Reval_Cal_Method(getA_Reval_Cal_Method()); - change.setA_Reval_Cost_Offset(getA_Reval_Cost_Offset()); - change.setA_Reval_Cost_Offset_Prior(getA_Reval_Cost_Offset_Prior()); - change.setA_Reval_Depexp_Offset(getA_Reval_Depexp_Offset()); - change.setA_Depreciation_Manual_Amount(getA_Depreciation_Manual_Amount()); - change.setA_Depreciation_Manual_Period(getA_Depreciation_Manual_Period()); - change.setA_Depreciation_Table_Header_ID(getA_Depreciation_Table_Header_ID()); - change.setA_Depreciation_Variable_Perc(getA_Depreciation_Variable_Perc()); - change.saveEx(); - - String sql = "SELECT * FROM A_Depreciation_Workfile WHERE A_Asset_ID=? AND IsActive='Y'"; - PreparedStatement pstmt = null; - try { - pstmt = DB.prepareStatement(sql, null); - pstmt.setInt(1, p_A_Asset_ID); - ResultSet rs = pstmt.executeQuery(); - - while (rs.next()) { - // MADepreciationWorkfile asset = new MADepreciationWorkfile - // (getCtx(), rs.getInt("A_Depreciation_Workfile_ID")); - X_A_Depreciation_Workfile assetwk = new X_A_Depreciation_Workfile( - getCtx(), rs, null); - assetwk.setA_Salvage_Value(getA_Salvage_Value()); - assetwk.saveEx(); - } - rs.close(); - pstmt.close(); - pstmt = null; - } catch (Exception e) { - log.info("getAssets" + e); - } finally { - try { - if (pstmt != null) - pstmt.close(); - } catch (Exception e) { - } - pstmt = null; - } - - } else { - X_A_Asset_Acct assetacct = new X_A_Asset_Acct(getCtx(), - p_actasset_ID, this.get_TrxName()); - assetacct.setPostingType(getPostingType()); - assetacct.setA_Split_Percent(getA_Split_Percent()); - assetacct.setA_Depreciation_Conv_ID(getA_Depreciation_Conv_ID()); - assetacct.setA_Salvage_Value(getA_Salvage_Value()); - assetacct.setA_Asset_ID(getA_Asset_ID()); - assetacct.setA_Depreciation_ID(getA_Depreciation_ID()); - assetacct.setA_Asset_Spread_ID(getA_Asset_Spread_ID()); - assetacct.setA_Period_Start(getA_Period_Start()); - assetacct.setA_Depreciation_Method_ID(getA_Depreciation_Method_ID()); - assetacct.setA_Asset_Acct(getA_Asset_Acct()); - assetacct.setC_AcctSchema_ID(getC_AcctSchema_ID()); - assetacct.setA_Accumdepreciation_Acct(getA_Accumdepreciation_Acct()); - assetacct.setA_Depreciation_Acct(getA_Depreciation_Acct()); - assetacct.setA_Disposal_Revenue(getA_Disposal_Revenue()); - assetacct.setA_Disposal_Loss(getA_Disposal_Loss()); - assetacct.setA_Reval_Accumdep_Offset_Cur(getA_Reval_Accumdep_Offset_Cur()); - assetacct.setA_Reval_Accumdep_Offset_Prior(getA_Reval_Accumdep_Offset_Prior()); - assetacct.setA_Reval_Cal_Method(getA_Reval_Cal_Method()); - assetacct.setA_Reval_Cost_Offset(getA_Reval_Cost_Offset()); - assetacct.setA_Reval_Cost_Offset_Prior(getA_Reval_Cost_Offset_Prior()); - assetacct.setA_Reval_Depexp_Offset(getA_Reval_Depexp_Offset()); - assetacct.setA_Depreciation_Manual_Amount(getA_Depreciation_Manual_Amount()); - assetacct.setA_Depreciation_Manual_Period(getA_Depreciation_Manual_Period()); - assetacct.setA_Depreciation_Table_Header_ID(getA_Depreciation_Table_Header_ID()); - assetacct.setA_Depreciation_Variable_Perc(getA_Depreciation_Variable_Perc()); - assetacct.setProcessing(true); - assetacct.saveEx(); + public static MAssetAcct get (Properties ctx, int A_Asset_Acct_ID) + { + MAssetAcct acct = s_cache.get(A_Asset_Acct_ID); + if (acct != null) + { + return acct; + } + acct = new MAssetAcct(ctx, A_Asset_Acct_ID, null); + if (acct.get_ID() > 0) + { + addToCache(acct, null); + } + else + { + acct = null; + } + return acct; + } + + /** + * Get asset accounting. + * @param ctx context + * @param A_Asset_ID asset + * @param postingType Posting type + * @param dateAcct check ValidFrom + * @return asset accounting for the given asset + */ + public static MAssetAcct forA_Asset_ID (Properties ctx, int A_Asset_ID, String postingType, Timestamp dateAcct, String trxName) + { + MultiKey key = new MultiKey(A_Asset_ID, postingType, dateAcct); + MAssetAcct acct = null; + if (trxName == null) + { + // do not use cache + //acct = s_cacheAsset.get(key); + } + if (acct != null) + { + return acct; + } + // + ArrayList params = new ArrayList(); + StringBuffer whereClause = new StringBuffer(COLUMNNAME_A_Asset_ID+"=? AND "+COLUMNNAME_PostingType+"=?"); + params.add(A_Asset_ID); + params.add(postingType); + if (dateAcct != null) + { + whereClause.append(" AND " + COLUMNNAME_ValidFrom).append("<=?"); + params.add(dateAcct); + } + acct = new Query(ctx, Table_Name, whereClause.toString(), trxName) + .setParameters(params) + .setOrderBy(COLUMNNAME_ValidFrom+" DESC NULLS LAST") + .first(); + if (trxName == null) + { + addToCache(acct, key); + } + return acct; + } + + private static void addToCache(MAssetAcct acct, MultiKey keyAsset) + { + if (acct == null || acct.get_ID() <= 0) + { + return; + } + s_cache.put(acct.get_ID(), acct); + if (keyAsset != null) + { + s_cacheAsset.put(keyAsset, acct); + } + } + + /** + * Create new asset accounting from asset group accounting + * @param asset asset + * @param assetgrpacct asset group accounting + */ + public MAssetAcct(MAsset asset, MAssetGroupAcct assetgrpacct) + { + this(assetgrpacct.getCtx(), 0, asset.get_TrxName()); + + SetGetUtil.copyValues(this, assetgrpacct, null, null); + setA_Asset_ID(asset.getA_Asset_ID()); + if (asset.getA_Depreciation_ID() > 0) + { + setA_Depreciation_ID(asset.getA_Depreciation_ID()); + } + if (asset.getA_Depreciation_F_ID() > 0) + { + setA_Depreciation_F_ID(asset.getA_Depreciation_F_ID()); + } + setA_Period_Start(1); + setA_Period_End(asset.getUseLifeMonths()); + //~ setProcessing(false); + dump(); + } + + /** + * + */ + public BigDecimal getA_Depreciation_Variable_Perc(boolean fiscal) + { + return fiscal ? getA_Depreciation_Variable_Perc_F() : getA_Depreciation_Variable_Perc(); + } + + + public MAcctSchema getC_AcctSchema() + { + return MAcctSchema.get(getCtx(), getC_AcctSchema_ID()); + } + + public MAccount getP_Asset_Acct(int M_Product_ID) + { + MAcctSchema as = getC_AcctSchema(); + ProductCost pc = new ProductCost(getCtx(), M_Product_ID, 0, null); + return pc.getAccount(ProductCost.ACCTTYPE_P_Asset, as); + } + @Override + protected boolean beforeSave(boolean newRecord) { + if (getValidFrom() == null && newRecord) + { + setValidFrom(TimeUtil.getDay(1970, 01, 01)); // FIXME } return true; } - -} // MAssetAddition + + +} // class MAssetAcct diff --git a/org.adempiere.base/src/org/compiere/model/MAssetAddition.java b/org.adempiere.base/src/org/compiere/model/MAssetAddition.java index 62cc3a5af5..92df99c84b 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetAddition.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetAddition.java @@ -1,155 +1,1187 @@ -/****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. This program is distributed in the hope * - * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ package org.compiere.model; -import java.sql.PreparedStatement; +import java.io.File; +import java.math.BigDecimal; import java.sql.ResultSet; +import java.sql.Timestamp; +import java.util.List; import java.util.Properties; +import org.adempiere.exceptions.FillMandatoryException; +import org.compiere.process.DocAction; +import org.compiere.process.DocumentEngine; +import org.compiere.process.ProcessInfo; +import org.compiere.process.ProjectClose; +import org.compiere.util.CLogMgt; +import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.compiere.util.Trx; +import org.idempiere.fa.exceptions.AssetAlreadyDepreciatedException; +import org.idempiere.fa.exceptions.AssetException; +import org.idempiere.fa.exceptions.AssetNotImplementedException; +import org.idempiere.fa.exceptions.AssetNotSupportedException; +import org.idempiere.fa.feature.UseLifeImpl; +import org.idempiere.fa.util.POCacheLocal; + /** * Asset Addition Model + * @author Teo Sarca, SC ARHIPAC SERVICE SRL * - * + * TODO: BUG: REG in depexp creates a zero if they have more sites Addition during 0?! */ public class MAssetAddition extends X_A_Asset_Addition + implements DocAction { - /** - * - */ - private static final long serialVersionUID = 511552459407382309L; + private static final long serialVersionUID = 1L; + + /** Static Logger */ + private static CLogger s_log = CLogger.getCLogger(MAssetAddition.class); - /** - * Default Constructor - * @param ctx context - * @param M_InventoryLine_ID line - */ public MAssetAddition (Properties ctx, int A_Asset_Addition_ID, String trxName) { super (ctx, A_Asset_Addition_ID, trxName); if (A_Asset_Addition_ID == 0) { - // - + setDocStatus(DOCSTATUS_Drafted); + setDocAction(DOCACTION_Complete); + setProcessed(false); } } // MAssetAddition - /** - * Load Constructor - * @param ctx context - * @param rs result set - */ public MAssetAddition (Properties ctx, ResultSet rs, String trxName) { super (ctx, rs, trxName); } // MAAssetAddition - /** - * Before Save - * @param newRecord new - * @return true - */ + protected boolean beforeSave (boolean newRecord) { - log.info ("beforeSave"); - int p_A_Asset_ID = 0; - p_A_Asset_ID = getA_Asset_ID(); - String sql = "SELECT COUNT(*) FROM A_Depreciation_Workfile WHERE A_Asset_ID=?"; - if (DB.getSQLValue(null,sql, p_A_Asset_ID) == 0) - { - X_A_Depreciation_Workfile assetwk = new X_A_Depreciation_Workfile (getCtx(), 0, null); - assetwk.setA_Asset_ID(p_A_Asset_ID); - assetwk.setPostingType("A"); - assetwk.setA_QTY_Current(getA_QTY_Current()); - assetwk.setA_Asset_Cost(getAssetValueAmt()); - assetwk.saveEx(); - - MAsset asset = new MAsset (getCtx(), p_A_Asset_ID, null); - asset.setA_QTY_Original(getA_QTY_Current().add(asset.getA_QTY_Original())); - asset.setA_QTY_Current(getA_QTY_Current().add(asset.getA_QTY_Current())); - asset.saveEx(); - - MAssetChange change = new MAssetChange (getCtx(), 0,null); - change.setA_Asset_ID(p_A_Asset_ID); - change.setA_QTY_Current(getA_QTY_Current()); - change.setChangeType("ADD"); - change.setTextDetails(MRefList.getListDescription (getCtx(),"A_Update_Type" , "ADD")); - change.setPostingType("A"); - change.setAssetValueAmt(getAssetValueAmt()); - change.setA_QTY_Current(getA_QTY_Current()); - change.saveEx(); - - - } + setA_CreateAsset(); + if (isA_CreateAsset() && getA_QTY_Current().signum() == 0) + { + setA_QTY_Current(Env.ONE); + } + if (getC_Currency_ID() <= 0) + { + setC_Currency_ID(MClient.get(getCtx()).getAcctSchema().getC_Currency_ID()); + } + if (getC_ConversionType_ID() <= 0) + { + setC_ConversionType_ID(MConversionType.getDefault(getAD_Client_ID())); + } + getDateAcct(); + setAssetValueAmt(); + if (isA_CreateAsset()) + { + setA_CapvsExp(A_CAPVSEXP_Capital); + } + + // + // Check suspect asset values (UseLife, Amount etc): + /* arhipac: teo_sarca: TODO need to integrate + if (hasZeroValues() && (!m_confirmed_AssetValues && !isProcessed() && is_UserEntry())) + { + String msg = "@AssetValueAmt@="+getAssetValueAmt() + + "\n@DeltaUseLifeYears@="+getDeltaUseLifeYears() + + "\n@DeltaUseLifeYears_F@="+getDeltaUseLifeYears_F()+"\n"; + m_confirmed_AssetValues = UIFactory.getUI().ask(get_WindowNo(), null, "Confirm", Msg.parseTranslation(getCtx(), msg), true); + if (!m_confirmed_AssetValues) + { + throw new AssetCheckDocumentException(msg); + } + } + */ + + // set approved + setIsApproved(); + + return true; + } // beforeSave + +// private boolean m_confirmed_AssetValues = false; + + /** + * Create Asset and asset Addition from MMatchInv. + * MAssetAddition is saved. + * @param match match invoice + * @return asset addition + */ + public static MAssetAddition createAsset(MMatchInv match) + { + MAssetAddition assetAdd = new MAssetAddition(match); + assetAdd.dump(); + //@win add condition to prevent asset creation when expense addition or second addition + if (MAssetAddition.A_CAPVSEXP_Capital.equals(assetAdd.getA_CapvsExp()) + && match.getC_InvoiceLine().getA_Asset_ID() == 0 && assetAdd.isA_CreateAsset()) { + //end @win add condition to prevent asset creation when expense addition or second addition + MAsset asset = assetAdd.createAsset(); + asset.dump(); + //@win add + MAssetGroupAcct assetgrpacct = MAssetGroupAcct.forA_Asset_Group_ID(asset.getCtx(), asset.getA_Asset_Group_ID(), assetAdd.getPostingType()); + assetAdd.setDeltaUseLifeYears(assetgrpacct.getUseLifeYears()); + assetAdd.setDeltaUseLifeYears_F(assetgrpacct.getUseLifeYears_F()); + } else { + assetAdd.setA_Asset_ID(match.getC_InvoiceLine().getA_Asset_ID()); + assetAdd.setA_CreateAsset(false); + } + assetAdd.saveEx(); + return assetAdd; + } + + /** + * Create Asset and asset Addition from MIFixedAsset. MAssetAddition is saved. + * (@win note, not referenced from anywhere. incomplete feature) + * @param match match invoice + * @return asset addition + */ + public static MAssetAddition createAsset(MIFixedAsset ifa) + { + MAssetAddition assetAdd = new MAssetAddition(ifa); + assetAdd.dump(); + //@win add condition to prevent asset creation when expense addition or second addition + if (MAssetAddition.A_CAPVSEXP_Capital.equals(assetAdd.getA_CapvsExp()) + && ifa.getA_Asset_ID() == 0) { + //end @win add condition to prevent asset creation when expense addition or second addition + MAsset asset = assetAdd.createAsset(); + asset.dump(); + } + assetAdd.saveEx(); + return assetAdd; + } + + //@win create asset from Project + /** + * Create Asset and asset Addition from MProject. MAssetAddition is saved. + * Addition from Project only allows initial addition (will definitely create new asset) + * @param project + * @return asset addition + */ + public static MAssetAddition createAsset(MProject project, MProduct product) + { + MAssetAddition assetAdd = new MAssetAddition(project); + assetAdd.dump(); + + MAsset asset = assetAdd.createAsset(); + + if (product != null) { + asset.setM_Product_ID(product.getM_Product_ID()); + asset.setA_Asset_Group_ID(product.getA_Asset_Group_ID()); + MAttributeSetInstance asi = MAttributeSetInstance.create(Env.getCtx(), product, null); + asset.setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); + } + asset.setName(product.getName().concat(project.getName())); + asset.setValue(product.getName().concat(project.getName())); + asset.saveEx(); + asset.dump(); + + // Copy UseLife values from asset group to workfile + MAssetGroupAcct assetgrpacct = MAssetGroupAcct.forA_Asset_Group_ID(asset.getCtx(), asset.getA_Asset_Group_ID(), assetAdd.getPostingType()); + assetAdd.setDeltaUseLifeYears(assetgrpacct.getUseLifeYears()); + assetAdd.setDeltaUseLifeYears_F(assetgrpacct.getUseLifeYears_F()); + assetAdd.setA_Asset(asset); + assetAdd.saveEx(); + //@win add + + return assetAdd; + } + //end @win create asset from Project + /** + * Create Asset + */ + private MAsset createAsset() + { + MAsset asset = null; + if (getA_Asset_ID() <= 0) + { + String sourceType = getA_SourceType(); + if (A_SOURCETYPE_Invoice.equals(sourceType)) + { + asset = new MAsset(getMatchInv(false)); + asset.saveEx(); + setA_Asset(asset); + } + else if (A_SOURCETYPE_Imported.equals(sourceType)) + { + asset = new MAsset(getI_FixedAsset(false)); + asset.saveEx(); + setA_Asset(asset); + } + else if (A_SOURCETYPE_Project.equals(sourceType)) + { + //@win add code for generate from Project + asset = new MAsset(getC_Project(false)); + //end @win add code for generate from Project + } + else + { + throw new AssetNotSupportedException(COLUMNNAME_A_SourceType, sourceType); + } + } else { - sql ="SELECT * FROM A_Depreciation_Workfile WHERE A_Asset_ID=? AND IsActive='Y'"; - PreparedStatement pstmt = null; - try - { - pstmt = DB.prepareStatement(sql,null); - pstmt.setInt(1, p_A_Asset_ID); - ResultSet rs = pstmt.executeQuery(); + asset = getA_Asset(false); + } + // + return asset; + } + + /** + * Construct addition from match invoice + * @param match match invoice model + */ + private MAssetAddition (MMatchInv match) + { + this(match.getCtx(), 0, match.get_TrxName()); + setM_MatchInv(match); + } + + //added by @win + /** + * @author @win + * Construct addition from Project + * @param project + */ + private MAssetAddition (MProject project) + { + this(project.getCtx(), 0, project.get_TrxName()); + log.finest("Entering: Project=" + project); + setAD_Org_ID(project.getAD_Org_ID()); + setPostingType(POSTINGTYPE_Actual); + setA_SourceType(A_SOURCETYPE_Project); + // + setC_Currency_ID(project.getC_Currency_ID()); + if (project.get_ValueAsInt("C_ConversionType_ID")>0) { + setC_ConversionType_ID(project.get_ValueAsInt("C_ConversionType_ID")); + } + setSourceAmt(project.getProjectBalanceAmt()); + setDateDoc(new Timestamp (System.currentTimeMillis())); + setA_CreateAsset(true); //added by @win as create from project will certainly for createnew + setDeltaUseLifeYears(I_ZERO); + setDeltaUseLifeYears_F(I_ZERO); + + Timestamp dateAcct = new Timestamp (System.currentTimeMillis()); + if (dateAcct != null) + { + dateAcct = UseLifeImpl.getDateAcct(dateAcct, 1); + log.fine("DateAcct=" + dateAcct); + setDateAcct(dateAcct); + } + setC_Project(project); + } + + private final POCacheLocal m_cacheCProject = POCacheLocal.newInstance(this, MProject.class); + public MProject getC_Project(boolean requery) + { + return m_cacheCProject.get(requery); + } + private void setC_Project(MProject project) + { + set_Value("C_Project_ID", project.get_ID()); + m_cacheCProject.set(project); + } + //end added by @win + /**IDR + * Construct addition from import + * @param ifa fixed asset import + */ + private MAssetAddition (MIFixedAsset ifa) + { + this(ifa.getCtx(), 0, ifa.get_TrxName()); + log.finest("Entering: ifa=" + ifa); + setAD_Org_ID(ifa.getAD_Org_ID()); + setPostingType(POSTINGTYPE_Actual); + setA_SourceType(A_SOURCETYPE_Imported); + // + setM_Product_ID(ifa.getM_Product_ID()); + setSourceAmt(ifa.getA_Asset_Cost()); + setDateDoc(ifa.getAssetServiceDate()); + setM_Locator_ID(ifa.getM_Locator_ID()); + + boolean isAccmDeprAdjust = (ifa.getA_Accumulated_Depr().compareTo(Env.ZERO) > 0) ? true : false; + setA_Accumulated_Depr_Adjust(isAccmDeprAdjust); + setA_Period_Start(ifa.getA_Current_Period()); + + setA_Accumulated_Depr(ifa.getA_Accumulated_Depr()); + setA_Accumulated_Depr_F(ifa.getA_Accumulated_Depr_F()); + setDeltaUseLifeYears((int)(ifa.getUseLifeMonths() / 12)); + setDeltaUseLifeYears_F((int)(ifa.getUseLifeMonths_F() / 12)); + + setA_CapvsExp(MAssetAddition.A_CAPVSEXP_Capital); //added by zuhri, import must be in Capital + setA_CreateAsset(true); //added by zuhri, import must be create asset + setA_Salvage_Value(ifa.getA_Salvage_Value()); + + Timestamp dateAcct = ifa.getDateAcct(); + if (dateAcct != null) + { + //dateAcct = UseLifeImpl.getDateAcct(dateAcct, 1); //commented by @win -- i don't see why i should add 1 month + log.fine("DateAcct=" + dateAcct); + setDateAcct(dateAcct); + } + setI_FixedAsset(ifa); + } + + /** Match Invoice Cache */ + private final POCacheLocal m_cacheMatchInv = POCacheLocal.newInstance(this, MMatchInv.class); + + /** + * @param requery + * @return + */ + private MMatchInv getMatchInv(boolean requery) + { + return m_cacheMatchInv.get(requery); + } + + private void setM_MatchInv(MMatchInv mi) + { + mi.load(get_TrxName()); + setAD_Org_ID(mi.getAD_Org_ID()); + setPostingType(POSTINGTYPE_Actual); + setA_SourceType(A_SOURCETYPE_Invoice); + setM_MatchInv_ID(mi.get_ID()); + + if (MAssetAddition.A_CAPVSEXP_Capital.equals(mi.getC_InvoiceLine().getA_CapvsExp()) + && mi.getC_InvoiceLine().getA_Asset_ID() == 0) { + setA_CreateAsset(true); + } + + setC_Invoice_ID(mi.getC_InvoiceLine().getC_Invoice_ID()); + setC_InvoiceLine_ID(mi.getC_InvoiceLine_ID()); + setM_InOutLine_ID(mi.getM_InOutLine_ID()); + setM_Product_ID(mi.getM_Product_ID()); + setM_AttributeSetInstance_ID(mi.getM_AttributeSetInstance_ID()); + setA_QTY_Current(mi.getQty()); + setLine(mi.getC_InvoiceLine().getLine()); + setM_Locator_ID(mi.getM_InOutLine().getM_Locator_ID()); + setA_CapvsExp(mi.getC_InvoiceLine().getA_CapvsExp()); + setAssetAmtEntered(mi.getC_InvoiceLine().getLineNetAmt()); + setAssetSourceAmt(mi.getC_InvoiceLine().getLineNetAmt()); + setC_Currency_ID(mi.getC_InvoiceLine().getC_Invoice().getC_Currency_ID()); + setC_ConversionType_ID(mi.getC_InvoiceLine().getC_Invoice().getC_ConversionType_ID()); + setDateDoc(mi.getM_InOutLine().getM_InOut().getMovementDate()); + setDateAcct(mi.getM_InOutLine().getM_InOut().getMovementDate()); + m_cacheMatchInv.set(mi); + } + + /** + * Copy fields from MatchInv+InvoiceLine+InOutLine + * @param model - to copy from + * @param M_MatchInv_ID - matching invoice id + * @param newRecord new object model is created + */ + public static boolean setM_MatchInv(SetGetModel model, int M_MatchInv_ID) + { + boolean newRecord = false; + String trxName = null; + if (model instanceof PO) + { + PO po = (PO)model; + newRecord = po.is_new(); + trxName = po.get_TrxName(); - while (rs.next()){ - //MADepreciationWorkfile asset = new MADepreciationWorkfile (getCtx(), rs.getInt("A_Depreciation_Workfile_ID")); - X_A_Depreciation_Workfile assetwk = new X_A_Depreciation_Workfile (getCtx(), rs, null); - assetwk.setA_Asset_Cost(getAssetValueAmt().add(assetwk.getA_Asset_Cost())); - assetwk.setA_QTY_Current(getA_QTY_Current().add(assetwk.getA_QTY_Current())); - assetwk.saveEx(); - - MAssetChange change = new MAssetChange (getCtx(), 0, null); - change.setA_Asset_ID(p_A_Asset_ID); - change.setA_QTY_Current(getA_QTY_Current()); - change.setChangeType("ADD"); - change.setTextDetails(MRefList.getListDescription (getCtx(),"A_Update_Type" , "ADD")); - change.setPostingType(rs.getString("PostingType")); - change.setAssetValueAmt(getAssetValueAmt()); - change.setA_QTY_Current(getA_QTY_Current()); - change.saveEx(); - - MAsset asset = new MAsset (getCtx(), p_A_Asset_ID, null); - asset.setA_QTY_Original(getA_QTY_Current().add(asset.getA_QTY_Original())); - asset.setA_QTY_Current(getA_QTY_Current().add(asset.getA_QTY_Current())); - asset.setProcessing(false); - asset.saveEx(); - } - rs.close(); - pstmt.close(); - pstmt = null; - } - catch (Exception e) + } + + if(CLogMgt.isLevelFine()) s_log.fine("Entering: model=" + model + ", M_MatchInv_ID=" + M_MatchInv_ID + ", newRecord=" + newRecord + ", trxName=" + trxName); + + final String qMatchInv_select = "SELECT" + + " C_Invoice_ID" + + ", C_InvoiceLine_ID" + + ", M_InOutLine_ID" + + ", M_Product_ID" + + ", M_AttributeSetInstance_ID" + + ", Qty AS "+COLUMNNAME_A_QTY_Current + + ", InvoiceLine AS "+COLUMNNAME_Line + + ", M_Locator_ID" + + ", A_CapVsExp" + + ", MatchNetAmt AS "+COLUMNNAME_AssetAmtEntered + + ", MatchNetAmt AS "+COLUMNNAME_AssetSourceAmt + + ", C_Currency_ID" + + ", C_ConversionType_ID" + + ", MovementDate AS "+COLUMNNAME_DateDoc + ; + final String qMatchInv_from = " FROM mb_matchinv WHERE M_MatchInv_ID="; //@win change M_MatchInv_ARH to M_MatchInv + + String query = qMatchInv_select; + if (newRecord) { + query += ", A_Asset_ID, A_CreateAsset"; + } + query += qMatchInv_from + M_MatchInv_ID; + + /* + PreparedStatement pstmt = null; + ResultSet rs = null; + + try + { + pstmt = DB.prepareStatement(query, trxName); + DB.setParameters(pstmt, params); + rs = pstmt.executeQuery(); + updateColumns(models, columnNames, rs); + } + catch (SQLException e) + { + throw new DBException(e, query); + } + finally + { + DB.close(rs, pstmt); + rs = null; pstmt = null; + } + */ + SetGetUtil.updateColumns(model, null, query, trxName); + + if(CLogMgt.isLevelFine()) s_log.fine("Leaving: RETURN TRUE"); + return true; + } + + private final POCacheLocal m_cacheIFixedAsset = POCacheLocal.newInstance(this, MIFixedAsset.class); + public MIFixedAsset getI_FixedAsset(boolean requery) + { + return m_cacheIFixedAsset.get(requery); + } + private void setI_FixedAsset(MIFixedAsset ifa) + { + setI_FixedAsset_ID(ifa.get_ID()); + m_cacheIFixedAsset.set(ifa); + } + + /** + * Sets the AssetValueAmt from AssetSourceAmt using C_Currency_ID and C_ConversionRate_ID + */ + private void setAssetValueAmt() + { + getDateAcct(); + MConversionRateUtil.convertBase(SetGetUtil.wrap(this), + COLUMNNAME_DateAcct, + COLUMNNAME_AssetSourceAmt, + COLUMNNAME_AssetValueAmt, + null); + } + + public void setSourceAmt(BigDecimal amt) + { + setAssetAmtEntered(amt); + setAssetSourceAmt(amt); + } + + /** + * + */ + public void setIsApproved() + { + if(!isProcessed()) + { + String str = Env.getContext(getCtx(), "#IsCanApproveOwnDoc"); + boolean isApproved = "Y".equals(str); //ARHIPAC.toBoolean(str, false); + log.fine("#IsCanApproveOwnDoc=" + str + "=" + isApproved); + setIsApproved(isApproved); + } + } + + + public Timestamp getDateAcct() + { + Timestamp dateAcct = super.getDateAcct(); + if (dateAcct == null) { + dateAcct = getDateDoc(); + setDateAcct(dateAcct); + } + return dateAcct; + } + + + 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() + { + log.info("unlockIt - " + toString()); + // setProcessing(false); + return true; + } // unlockIt + + + public boolean invalidateIt() + { + log.info("invalidateIt - " + toString()); + return false; + } // invalidateIt + + + public String prepareIt() + { + log.info(toString()); + + // Call model validators + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE); + if (m_processMsg != null) + { + return DocAction.STATUS_Invalid; + } + + MPeriod.testPeriodOpen(getCtx(), getDateAcct(), MDocType.DOCBASETYPE_GLJournal, getAD_Org_ID()); + + // Check AssetValueAmt != 0 + if (getAssetValueAmt().signum() == 0) { + m_processMsg="@Invalid@ @AssetValueAmt@=0"; + return DocAction.STATUS_Invalid; + } + + MAsset asset = getA_Asset(true); + + // Additions may be made ​​only on sites that depreciates FA + // (WARNING: FA sites scrapped / sold not depreciate) + + /* @win temporary comment as some assets are not depreciated + if(!isA_CreateAsset() && !asset.isDepreciated()) + { + m_processMsg = "@AssetIsNotDepreciating@"; + return DocAction.STATUS_Invalid; + } + */ + + // If new assets (not renewals) must have nonzero values + if (isA_CreateAsset() && hasZeroValues()) + { + throw new AssetException("New document has nulls"); + } + + // Only New assets can be activated + if (isA_CreateAsset() && !MAsset.A_ASSET_STATUS_New.equals(asset.getA_Asset_Status())) + { + throw new AssetException("Only new assets can be activated"); + } + // + // Validate Source - Project + if (A_SOURCETYPE_Project.equals(getA_SourceType())) + { + if (getC_Project_ID() <= 0) { - log.info("getAssets"+ e); + throw new FillMandatoryException(COLUMNNAME_C_Project_ID); } - finally + final String whereClause = COLUMNNAME_C_Project_ID+"=?" + +" AND DocStatus IN ('IP','CO','CL')" + +" AND "+COLUMNNAME_A_Asset_Addition_ID+"<>?"; + List list = new Query(getCtx(), Table_Name, whereClause, get_TrxName()) + .setParameters(new Object[]{getC_Project_ID(), get_ID()}) + .list(); + if (list.size() > 0) { - try + StringBuffer sb = new StringBuffer("You can not create project for this asset," + +" Project already has assets. View: "); + for (MAssetAddition aa : list) { - if (pstmt != null) - pstmt.close (); + sb.append(aa.getDocumentInfo()).append("; "); } - catch (Exception e) - {} - pstmt = null; + throw new AssetException(sb.toString()); } - } - return true; - } // beforeSave + } + + // Call model validators + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_PREPARE); + if (m_processMsg != null) + { + return DocAction.STATUS_Invalid; + } + + // Done + m_justPrepared = true; + if (!DOCACTION_Complete.equals(getDocAction())) + setDocAction(DOCACTION_Complete); + return DocAction.STATUS_InProgress; + } // prepareIt + + + public boolean approveIt() + { + log.info("approveIt - " + toString()); + setIsApproved(true); + return true; + } // approveIt + + + public boolean rejectIt() + { + 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; + } + // User Validation + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE); + if (m_processMsg != null) { + return DocAction.STATUS_Invalid; + } + + // Implicit Approval + if (!isApproved()) + approveIt(); + log.info(toString()); + // + + // Check/Create ASI: + checkCreateASI(); + + //loading asset + MAsset asset = getA_Asset(!m_justPrepared); // requery if not just prepared + log.fine("asset=" + asset); + // + // Get/Create Asset Workfile: + // If there Worksheet creates a new file in this asset + MDepreciationWorkfile assetwk = MDepreciationWorkfile.get(getCtx(), getA_Asset_ID(), getPostingType(), get_TrxName()); + if (assetwk == null) + { + assetwk = new MDepreciationWorkfile(asset, getPostingType(), null); + } + log.fine("workfile: " + assetwk); + // + // Can not upgrade a previous period + /* + if (!isA_CreateAsset() && assetwk.isDepreciated(getDateAcct())) + { + throw new AssetAlreadyDepreciatedException(); + } + */ + // + // Do we have entries that are not processed and before this date: + if (this.getA_CapvsExp().equals(A_CAPVSEXP_Capital)) { + //@win modification to asset value and use life should be restricted to Capital + MDepreciationExp.checkExistsNotProcessedEntries(assetwk.getCtx(), assetwk.getA_Asset_ID(), getDateAcct(), assetwk.getPostingType(), assetwk.get_TrxName()); + // + if (this.getA_Salvage_Value().signum() > 0) { + assetwk.setA_Salvage_Value(this.getA_Salvage_Value()); + } + assetwk.adjustCost(getAssetValueAmt(), getA_QTY_Current(), isA_CreateAsset()); // reset if isA_CreateAsset + assetwk.adjustUseLife(getDeltaUseLifeYears(), getDeltaUseLifeYears_F(), isA_CreateAsset()); // reset if isA_CreateAsset + assetwk.setDateAcct(getDateAcct()); + assetwk.setProcessed(true); + assetwk.saveEx(); + } + MAssetChange.createAddition(this, assetwk); + + // Setting locator if is CreateAsset + if (isA_CreateAsset() && getM_Locator_ID() > 0) + { + asset.setM_Locator_ID(getM_Locator_ID()); + } + + // Creating/Updating asset product + updateA_Asset_Product(false); + // + // Changing asset status to Activated or Depreciated + if (isA_CreateAsset()) + { + asset.setAssetServiceDate(getDateDoc()); + } + asset.changeStatus(MAsset.A_ASSET_STATUS_Activated, getDateAcct()); + asset.saveEx(); + + //@win set initial depreciation period = 1 + if (isA_CreateAsset() && !isA_Accumulated_Depr_Adjust()) + { + assetwk.setA_Current_Period(1); + assetwk.saveEx(); + } + // + + if (isA_Accumulated_Depr_Adjust()) + { + if (isA_CreateAsset() && isA_Accumulated_Depr_Adjust()) + { + assetwk.setA_Current_Period(getA_Period_Start()); + assetwk.setA_Accumulated_Depr(getA_Accumulated_Depr()); + assetwk.setA_Accumulated_Depr_F(getA_Accumulated_Depr_F()); + assetwk.saveEx(); + } + } + + // Accumulated depreciation (if any): + /* + if (isA_Accumulated_Depr_Adjust()) + { + Collection expenses = MDepreciationExp.createDepreciation(assetwk, + 1, // PeriodNo + getDateAcct(), + getA_Accumulated_Depr(), getA_Accumulated_Depr_F(), + null, // Accum Amt + null, // Accum Amt (F) + null, // Help + null); + for (MDepreciationExp exp : expenses) + { + exp.setA_Asset_Addition_ID(getA_Asset_Addition_ID()); + exp.process(); + } + + if (isA_CreateAsset() && isA_Accumulated_Depr_Adjust()) + { + assetwk.setA_Current_Period(getA_Period_Start()); + assetwk.saveEx(); + } + } + */ + + // Rebuild depreciation: + assetwk.buildDepreciation(); + + // + updateSourceDocument(false); + + // finish + setProcessed(true); + setDocAction(DOCACTION_Close); + // + // User Validation + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE); + if (m_processMsg != null) { + return DocAction.STATUS_Invalid; + } + // + return DocAction.STATUS_Completed; + } // completeIt + + + public boolean voidIt() + { + // Before Void + m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_VOID); + if (m_processMsg != null) + return false; + + reverseIt(false); + + // User Validation + String errmsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_VOID); + if (errmsg != null) + { + m_processMsg = errmsg; + return false; + } + + // finish + setProcessed(true); + setDocAction(DOCACTION_None); + return true; + } // voidIt + + private void reverseIt(boolean isReActivate) + { + if (DOCSTATUS_Closed.equals(getDocStatus()) + || DOCSTATUS_Reversed.equals(getDocStatus()) + || DOCSTATUS_Voided.equals(getDocStatus())) + { + setDocAction(DOCACTION_None); + throw new AssetException("Document Closed: " + getDocStatus()); + } + + // Handling Workfile + MDepreciationWorkfile assetwk = MDepreciationWorkfile.get(getCtx(), getA_Asset_ID(), getPostingType(), get_TrxName()); + if (assetwk == null) + { + throw new AssetException("@NotFound@ @A_DepreciationWorkfile_ID"); + } + + // TODO: Check if there are Additions after this one + + if (assetwk.isFullyDepreciated()) + { + throw new AssetNotImplementedException("Unable to verify if it is fully depreciated"); + } + + // cannot update a previous period + if (!isA_CreateAsset() && assetwk.isDepreciated(getDateAcct())) + { + throw new AssetAlreadyDepreciatedException(); + } + + // adjust the asset value + assetwk.adjustCost(getAssetValueAmt().negate(), getA_QTY_Current().negate(), false); + assetwk.adjustUseLife(0 - getDeltaUseLifeYears(), 0 - getDeltaUseLifeYears_F(), false); + assetwk.saveEx(); + + // + // Delete Expense Entries that were created by this addition + { + final String whereClause = MDepreciationExp.COLUMNNAME_A_Asset_Addition_ID+"=?" + +" AND "+MDepreciationExp.COLUMNNAME_PostingType+"=?"; + List + list = new Query(getCtx(), MDepreciationExp.Table_Name, whereClause, get_TrxName()) + .setParameters(new Object[]{get_ID(), assetwk.getPostingType()}) + .setOrderBy(MDepreciationExp.COLUMNNAME_DateAcct+" DESC, "+MDepreciationExp.COLUMNNAME_A_Depreciation_Exp_ID+" DESC") + .list(); + for (MDepreciationExp depexp: list) + { + depexp.deleteEx(true); + } + } + // + // Update/Delete working file (after all entries were deleted) + if (isA_CreateAsset()) + { + assetwk.deleteEx(true); + } + else + { + assetwk.setA_Current_Period(); + assetwk.saveEx(); + assetwk.buildDepreciation(); + } + + // Creating/Updating asset product + updateA_Asset_Product(true); + + // Change Asset Status + if (isA_CreateAsset()) + { + MAsset asset = getA_Asset(true); + asset.changeStatus(MAsset.A_ASSET_STATUS_New, getDateAcct()); + //asset.isDepreciated(); + //asset.setIsDepreciated(true); + asset.saveEx(); + + + if (!isReActivate) + { + setA_CreateAsset(false); // reset flag + } + } + + MFactAcct.deleteEx(get_Table_ID(), get_ID(), get_TrxName()); + + updateSourceDocument(true); + } + + + public boolean closeIt() + { + log.info("closeIt - " + toString()); + setDocAction(DOCACTION_None); + return true; + } // closeIt + + + public boolean reverseCorrectIt() + { + throw new AssetNotImplementedException("reverseCorrectIt"); + } // reverseCorrectionIt + + + public boolean reverseAccrualIt() + { + throw new AssetNotImplementedException("reverseAccrualIt"); + } // reverseAccrualIt + + + public boolean reActivateIt() + { + // Before + m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REACTIVATE); + if (m_processMsg != null) + return false; + + reverseIt(true); + + // User Validation + String errmsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_REACTIVATE); + if (errmsg != null) { + m_processMsg = errmsg; + return false; + } + + // finish + setProcessed(false); + setDocAction(DOCACTION_Complete); + return true; + } // reActivateIt + + + public String getSummary() + { + MAsset asset = getA_Asset(false); + StringBuffer sb = new StringBuffer(); + sb.append("@DocumentNo@ #").append(getDocumentNo()) + .append(": @A_CreateAsset@=@").append(isA_CreateAsset() ? "Y" : "N").append("@") + ; + if (asset != null) + { + sb.append(", @A_Asset_ID@=").append(asset.getName()); + } + + return Msg.parseTranslation(getCtx(), sb.toString()); + } // getSummary + + + public String getProcessMsg() + { + return m_processMsg; + } // getProcessMsg + + + public int getDoc_User_ID() + { + return getCreatedBy(); + } // getDoc_User_ID + + + public BigDecimal getApprovalAmt() + { + return getAssetValueAmt(); + } // getApprovalAmt + + + /** Asset Cache */ + private final POCacheLocal m_cacheAsset = POCacheLocal.newInstance(this, MAsset.class); + + /** + * Get Asset + * @param requery + * @return asset + */ + public MAsset getA_Asset(boolean requery) + { + return m_cacheAsset.get(requery); + } + + /** + * Set Asset + * @return asset + */ + private void setA_Asset(MAsset asset) + { + setA_Asset_ID(asset.getA_Asset_ID()); + m_cacheAsset.set(asset); + } // setAsset + + + protected boolean afterSave (boolean newRecord, boolean success) + { + if(!success) + { + return false; + } + updateSourceDocument(false); + return true; + } // afterSave + + /** + * Update Source Document (Invoice, Project etc) Status + * @param isReversal is called from a reversal action (like Void, Reverse-Correct). + * We need this flag because that when we call the method from voidIt() + * the document is not marked as voided yet. Same thing applies for reverseCorrectIt too. + */ + private void updateSourceDocument(final boolean isReversalParam) + { + boolean isReversal = isReversalParam; + // Check if this document is reversed/voided + String docStatus = getDocStatus(); + if (!isReversal && (DOCSTATUS_Reversed.equals(docStatus) || DOCSTATUS_Voided.equals(docStatus))) + { + isReversal = true; + } + final String sourceType = getA_SourceType(); + // + // Invoice: mark C_InvoiceLine.A_Processed='Y' and set C_InvoiceLine.A_Asset_ID + if (A_SOURCETYPE_Invoice.equals(sourceType) && isProcessed()) + { + int C_InvoiceLine_ID = getC_InvoiceLine_ID(); + MInvoiceLine invoiceLine = new MInvoiceLine(getCtx(), C_InvoiceLine_ID, get_TrxName()); + invoiceLine.setA_Processed(!isReversal); + invoiceLine.setA_Asset_ID(isReversal ? 0 : getA_Asset_ID()); + invoiceLine.saveEx(); + } + // + // Project + else if (A_SOURCETYPE_Project.equals(sourceType) && isProcessed()) + { + if (isReversal) + { + // Project remains closed. We just void/reverse/reactivate the Addition + } + else + { + //TODO decide whether to close project first or later + + int project_id = getC_Project_ID(); + ProcessInfo pi = new ProcessInfo("", 0, MProject.Table_ID, project_id); + pi.setAD_Client_ID(getAD_Client_ID()); + pi.setAD_User_ID(Env.getAD_User_ID(getCtx())); + // + ProjectClose proc = new ProjectClose(); + proc.startProcess(getCtx(), pi, Trx.get(get_TrxName(), false)); + if (pi.isError()) + { + throw new AssetException(pi.getSummary()); + } + + } + } + // + // Import + else if (A_SOURCETYPE_Imported.equals(sourceType) && !isProcessed()) + { + if (is_new() && getI_FixedAsset_ID() > 0) + { + MIFixedAsset ifa = getI_FixedAsset(false); + if (ifa != null) + { + ifa.setI_IsImported(true); + ifa.setA_Asset_ID(getA_Asset_ID()); + ifa.saveEx(get_TrxName()); + } + } + } + // + // Manual + else if (A_SOURCETYPE_Manual.equals(sourceType) && isProcessed()) + { + // nothing to do + log.fine("Nothing to do"); + } + } + + /** + * Check/Create ASI for Product (if any). If there is no product, no ASI will be created + */ + private void checkCreateASI() + { + MProduct product = MProduct.get(getCtx(), getM_Product_ID()); + // Check/Create ASI: + MAttributeSetInstance asi = null; + if (product != null && getM_AttributeSetInstance_ID() == 0) + { + asi = new MAttributeSetInstance(getCtx(), 0, get_TrxName()); + asi.setAD_Org_ID(0); + asi.setM_AttributeSet_ID(product.getM_AttributeSet_ID()); + asi.saveEx(); + setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); + } + } + + /** + * Creating/Updating asset product + * @param isReversal + */ + private void updateA_Asset_Product(boolean isReversal) + { + // Skip if no product + if (getM_Product_ID() <= 0) + { + return; + } + // + MAssetProduct assetProduct = MAssetProduct.getCreate(getCtx(), + getA_Asset_ID(), getM_Product_ID(), getM_AttributeSetInstance_ID(), + get_TrxName()); + // + if (assetProduct.get_ID() <= 0 && isReversal) + { + log.warning("No Product found "+this+" [IGNORE]"); + return; + } + // + BigDecimal adjQty = getA_QTY_Current(); + + if (isReversal) + { + adjQty = adjQty.negate(); + } + // + assetProduct.addA_Qty_Current(getA_QTY_Current()); + assetProduct.setAD_Org_ID(getA_Asset().getAD_Org_ID()); + assetProduct.saveEx(); + if (isA_CreateAsset()) + { + MAsset asset = getA_Asset(false); + assetProduct.updateAsset(asset); + asset.saveEx(); + } + } + + public boolean hasZeroValues() + { + return + getDeltaUseLifeYears() <= 0 || getDeltaUseLifeYears_F() <= 0 + || getDeltaUseLifeYears() != getDeltaUseLifeYears_F() || + getAssetValueAmt().signum() <= 0 + ; + } + + + public File createPDF () + { + return null; + } // createPDF + + + public String getDocumentInfo() + { + return getDocumentNo() + " / " + getDateDoc(); + } // getDocumentInfo + + + public String toString() + { + StringBuffer sb = new StringBuffer("@DocumentNo@: " + getDocumentNo()); + MAsset asset = getA_Asset(false); + if(asset != null && asset.get_ID() > 0) + { + sb.append(", @A_Asset_ID@: ").append(asset.getName()); + } + return sb.toString(); + } // toString + + private void setA_CreateAsset() + { + if (DOCSTATUS_Voided.equals(getDocStatus())) + { + setA_CreateAsset(false); + } + else + { + final String sql = "SELECT COUNT(*) FROM A_Asset_Addition WHERE A_Asset_ID=? AND A_CreateAsset='Y'" + +" AND DocStatus<>'VO' AND IsActive='Y'" + +" AND A_Asset_Addition_ID<>?"; + int cnt = DB.getSQLValueEx(null, sql, getA_Asset_ID(), getA_Asset_Addition_ID()); + if(isA_CreateAsset()) + { + // A_CreateAsset='Y' must be unique + if (cnt >= 1) + { + setA_CreateAsset(false); + } + } + else + { + // Succesfull creation of Asset + if (cnt == 0) + { + setA_CreateAsset(true); + } + } + } + } } // MAssetAddition diff --git a/org.adempiere.base/src/org/compiere/model/MAssetChange.java b/org.adempiere.base/src/org/compiere/model/MAssetChange.java index 1dda43a325..d4e6ed2440 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetChange.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetChange.java @@ -1,36 +1,38 @@ /****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. This program is distributed in the hope * - * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * + * The contents of this file are subject to the Compiere License Version 1.1 + * ("License"); You may not use this file except in compliance with the License + * You may obtain a copy of the License at http://www.compiere.org/license.html + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * The Original Code is Compiere ERP & CRM Smart Business Solution + * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc. + * Portions created by Jorg Janke are Copyright (C) 1999-2003 Jorg Janke, parts + * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved. + * Contributor(s): ______________________________________. *****************************************************************************/ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.model.MRefList; +import org.compiere.model.PO; +import org.compiere.util.CLogMgt; +import org.compiere.util.CLogger; + /** * Asset Addition Model - * + * @author Teo Sarca, SC ARHIPAC SERVICE SRL * */ public class MAssetChange extends X_A_Asset_Change { - /** - * - */ - private static final long serialVersionUID = 5906751299228645904L; - + private static final long serialVersionUID = 1L; + + /** Static Logger */ + private static CLogger s_log = CLogger.getCLogger(MAssetChange.class); + /** * Default Constructor * @param ctx context @@ -39,12 +41,8 @@ public class MAssetChange extends X_A_Asset_Change public MAssetChange (Properties ctx, int A_Asset_Change_ID, String trxName) { super (ctx, A_Asset_Change_ID, trxName); - if (A_Asset_Change_ID == 0) - { - // - - } - } // MAssetAddition + } // MAssetChange + /** * Load Constructor * @param ctx context @@ -61,11 +59,94 @@ public class MAssetChange extends X_A_Asset_Change * @return true */ protected boolean beforeSave (boolean newRecord) - { - if (getA_Reval_Cal_Method() == null) - setA_Reval_Cal_Method("DFT"); + { + String textDetails = getTextDetails(); + if (textDetails == null || textDetails.length() == 0) { + setTextDetails(MRefList.getListDescription (getCtx(),"A_Update_Type" , getChangeType())); + } return true; } // beforeSave - -} // MAssetAddition + /** ARHIPAC: TEO: BEGIN ------------------------------------------------------------------ */ + public void setSerno(String value) { setSerNo(value); } + public void setVersionno(String value) { setVersionNo(value); } + public void setAd_User_ID(int value) { setAD_User_ID(value); } + + public static MAssetChange createAddition(MAssetAddition assetAdd, MDepreciationWorkfile assetwk) { + MAssetChange change = new MAssetChange (assetAdd.getCtx(), 0, assetAdd.get_TrxName()); + change.setAD_Org_ID(assetAdd.getAD_Org_ID()); //@win added + change.setA_Asset_ID(assetAdd.getA_Asset_ID()); + change.setA_QTY_Current(assetAdd.getA_QTY_Current()); + change.setChangeType("ADD"); + change.setTextDetails(MRefList.getListDescription (assetAdd.getCtx(),"A_Update_Type" , "ADD")); + change.setPostingType(assetwk.getPostingType()); + change.setAssetValueAmt(assetAdd.getAssetValueAmt()); + change.setA_QTY_Current(assetAdd.getA_QTY_Current()); + change.saveEx(); + + return change; + } + + public static MAssetChange create(Properties ctx, String changeType, PO[] pos, String trxName) { + return create(ctx, changeType, pos, false, trxName); + } + + /** + * TODO + * @param ctx + * @param changeType + * @param pos + * @param trxName + * @return + */ + public static MAssetChange createAndSave(Properties ctx, String changeType, PO[] pos, String trxName) { + return null; + //~ return create(ctx, changeType, pos, true, trxName); + } + + public static MAssetChange create(Properties ctx, String changeType, PO[] pos, boolean save, String trxName) { + s_log.fine("Entering: changeType=" + changeType); + if (pos == null || pos.length == 0) { + s_log.fine("Entering/Leaving: POs is empty"); + return null; + } + MAssetChange change = new MAssetChange (ctx, 0, trxName); + change.setChangeType(changeType); + for (PO po : pos) { + change.addChanges(po); + } + if (save) { + change.saveEx(); + } + // + s_log.fine("Leaving: change=" + change); + return change; + } + + public void addChanges(PO po) { + if(CLogMgt.isLevelFine()) log.fine("Entering: po=" + po); + if (po == null) { + return; + } + /* arhipac: teo_sarca: TODO need to integrate + for(int idx = 0; idx < po.get_ColumnCount_P(); idx++) { + //~ if(!po.is_ValueChanged(idx)) { + //~ continue; + //~ } + String colName = po.get_ColumnName_P(idx); + int idx2 = get_ColumnIndex(colName); + if(idx2 < 0) { + if(CLogMgt.isLevelFine()) log.fine("Setting " + colName + ": SKIP (idx2 < 0)"); + continue; + } + + Object value = po.get_Value(idx2); + set_Value(colName, value); + if(CLogMgt.isLevelFine()) log.fine("Setting " + colName + "=" + value + " (from " + po.getClass() + ", idx=" + idx + ", idx2=" + idx2 + ")"); + } + */ + // + if(CLogMgt.isLevelFine()) log.fine("Leaving: po=" + po); + } + /** ARHIPAC: TEO: END ------------------------------------------------------------------ */ +} // MAssetChange \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/MAssetGroup.java b/org.adempiere.base/src/org/compiere/model/MAssetGroup.java index 2a784e32f8..422b6ece9a 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetGroup.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetGroup.java @@ -1,86 +1,169 @@ -/****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. This program is distributed in the hope * - * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; import org.compiere.util.CCache; +import org.compiere.util.DB; /** - * Asset Group Model - * - * @author Jorg Janke - * @version $Id: MAssetGroup.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ + * Asset Group Model + * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ public class MAssetGroup extends X_A_Asset_Group { + private static final long serialVersionUID = 1L; + + /** Cache: ID -> MAssetGroup */ + private static CCache s_cache = new CCache(Table_Name, 10, 0); + /** - * - */ - private static final long serialVersionUID = 1364948077775028283L; - - /** - * Get from Cache + * Default Constructor * @param ctx context - * @param A_Asset_Group_ID id - * @return category - */ - public static MAssetGroup get (Properties ctx, int A_Asset_Group_ID) - { - Integer ii = new Integer (A_Asset_Group_ID); - MAssetGroup pc = (MAssetGroup)s_cache.get(ii); - if (pc == null) - pc = new MAssetGroup (ctx, A_Asset_Group_ID, null); - return pc; - } // get - - /** Categopry Cache */ - private static CCache s_cache = new CCache ("A_Asset_Group", 10); - - /** - * Standard Constructor - * @param ctx context - * @param A_Asset_Group_ID id - * @param trxName trx + * @param A_Asset_Group_ID */ public MAssetGroup (Properties ctx, int A_Asset_Group_ID, String trxName) { - super (ctx, A_Asset_Group_ID, trxName); - if (A_Asset_Group_ID == 0) - { - // setName (null); - setIsDepreciated (false); - setIsOneAssetPerUOM (false); - setIsOwned (false); - setIsCreateAsActive(true); - setIsTrackIssues(false); - } + super (ctx,A_Asset_Group_ID, trxName); } // MAssetGroup - + /** - * Load Cosntructor + * Load Constructor * @param ctx context * @param rs result set - * @param trxName trx */ public MAssetGroup (Properties ctx, ResultSet rs, String trxName) { - super (ctx, rs, trxName); + super (ctx, rs, trxName); } // MAssetGroup + /** + * Get Asset Group [CACHE] + * @param ctx context + * @param A_Asset_Group_ID asset group id + * @return asset group or null + */ + public static MAssetGroup get(Properties ctx, int A_Asset_Group_ID) + { + if (A_Asset_Group_ID <= 0) + return null; + // Try cache + MAssetGroup ag = s_cache.get(A_Asset_Group_ID); + if (ag != null) + return ag; + // Load + ag = new MAssetGroup(ctx, A_Asset_Group_ID, null); + if (ag != null && ag.get_ID() != A_Asset_Group_ID) + ag = null; + // + return ag; + } + + /** + * Get default asset group ID for given model. + * WARNING: trxName = null. + * @param m reference model (used to get AD_Client_ID) + * @return default asset group ID or 0 if not found + */ + public static int getDefault_ID(SetGetModel m) + { + int AD_Client_ID = SetGetUtil.get_AttrValueAsInt(m, "AD_Client_ID"); + /* commented by @win + int A_AssetType_ID = SetGetUtil.get_AttrValueAsInt(m, MAssetType.COLUMNNAME_A_Asset_Type_ID); + */ + final String sql = "SELECT "+COLUMNNAME_A_Asset_Group_ID + + " FROM "+Table_Name + + " WHERE AD_Client_ID=?" + // + " AND NVL("+COLUMNNAME_A_Asset_Type_ID+",0) IN (0,?)" //commented by @win + + " ORDER BY "+COLUMNNAME_IsDefault+" DESC" + +", "+COLUMNNAME_A_Asset_Group_ID+" ASC" // default first, older first + ; + /* modify by @win + int id = DB.getSQLValueEx(null, sql, AD_Client_ID, A_AssetType_ID); + */ + int id = DB.getSQLValueEx(null, sql, AD_Client_ID); + // modify by @win + + return id; + } + + /** + * Update Asset + * - updates asset M_AssetGroup_ID if is null + */ + public static void updateAsset(SetGetModel m, int A_Asset_Group_ID) + { + /* commented by @win + int i = (Integer) m.get_AttrValue(MAsset.COLUMNNAME_A_Asset_Type_ID); + MAssetType type = MAssetType.get(m.getCtx(), m.get_AttrValue(MAsset.COLUMNNAME_A_Asset_Type_ID)); + if (type == null) + return; + + if (A_Asset_Group_ID > 0) + { + if (!type.isFixedAsset()) + { + return; + } + MAssetGroup assetGrp = MAssetGroup.get(m.getCtx(), A_Asset_Group_ID); + int A_Asset_Class_ID = assetGrp.getA_Asset_Class_ID(); + if (A_Asset_Class_ID > 0) + { + m.set_AttrValue(MAsset.COLUMNNAME_A_Asset_Class_ID, A_Asset_Class_ID); + } + } + else + { + A_Asset_Group_ID = MAssetGroup.getDefault_ID(SetGetUtil.wrap(m)); + m.set_AttrValue(MAsset.COLUMNNAME_A_Asset_Group_ID, A_Asset_Group_ID); + } + */ + if (A_Asset_Group_ID < 0) { + A_Asset_Group_ID = MAssetGroup.getDefault_ID(SetGetUtil.wrap(m)); + m.set_AttrValue(MAsset.COLUMNNAME_A_Asset_Group_ID, A_Asset_Group_ID); + } + + //end modify by @win + } + + + protected boolean beforeSave (boolean newRecord) + { + /* commented by @win + MAssetType type = MAssetType.get(getCtx(), getA_Asset_Type_ID()); + if (type != null) + { + type.update(SetGetUtil.wrap(this), newRecord == true); + } + */ + //end commented by @win + + return true; + } + + + protected boolean afterSave (boolean newRecord, boolean success) + { + if(!success) + { + return false; + } + // + if (newRecord) + { + // If this is not the default group, then copy accounting settings from default group + int default_id = getDefault_ID(SetGetUtil.wrap(this)); + if (default_id > 0 && default_id != get_ID()) + { + for (MAssetGroupAcct acct : MAssetGroupAcct.forA_Asset_Group_ID(getCtx(), default_id)) + { + MAssetGroupAcct newAcct = acct.copy(this); + newAcct.saveEx(get_TrxName()); + } + } + } + // + return true; + } } // MAssetGroup + diff --git a/org.adempiere.base/src/org/compiere/model/MAssetGroupAcct.java b/org.adempiere.base/src/org/compiere/model/MAssetGroupAcct.java index 2714974b14..6bfc1750d7 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetGroupAcct.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetGroupAcct.java @@ -1,48 +1,54 @@ -/****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. This program is distributed in the hope * - * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ package org.compiere.model; import java.sql.ResultSet; +import java.sql.Timestamp; +import java.util.List; import java.util.Properties; +import org.compiere.model.Query; +import org.idempiere.fa.feature.UseLife; +import org.idempiere.fa.feature.UseLifeImpl; + /** - * Asset Addition Model - * - * + * Asset Group Accounting Model + * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ public class MAssetGroupAcct extends X_A_Asset_Group_Acct + implements UseLife { + private static final long serialVersionUID = 1L; + /** - * + * Get Asset Group Accountings for given group */ - private static final long serialVersionUID = 1097065220838511473L; + public static List forA_Asset_Group_ID(Properties ctx, int A_Asset_Group_ID) + { + return new Query(ctx, Table_Name, COLUMNNAME_A_Asset_Group_ID+"=?", null) + .setParameters(new Object[]{A_Asset_Group_ID}) + .list(); + } + + /** + * Get Asset Group Accountings for given group + */ + public static MAssetGroupAcct forA_Asset_Group_ID(Properties ctx, int A_Asset_Group_ID, String postingType) + { + final String whereClause = COLUMNNAME_A_Asset_Group_ID+"=? AND "+COLUMNNAME_PostingType+"=?"; + return new Query(ctx, Table_Name, whereClause, null) + .setParameters(new Object[]{A_Asset_Group_ID, postingType}) + .firstOnly(); + } + /** * Default ConstructorX_A_Asset_Group_Acct * @param ctx context - * @param M_InventoryLine_ID line + * @param X_A_Asset_Group_Acct_ID id */ public MAssetGroupAcct (Properties ctx, int X_A_Asset_Group_Acct_ID, String trxName) { super (ctx,X_A_Asset_Group_Acct_ID, trxName); - if (X_A_Asset_Group_Acct_ID == 0) - { - // - } - } // MAssetAddition + } // MAssetGroupAcct + /** * Load Constructor * @param ctx context @@ -51,9 +57,81 @@ public class MAssetGroupAcct extends X_A_Asset_Group_Acct public MAssetGroupAcct (Properties ctx, ResultSet rs, String trxName) { super (ctx, rs, trxName); - } // MInventoryLine + } // MAssetGroupAcct + + /** Asset Group */ + private MAssetGroup m_parent = null; + + /** + * Get Asset Group + */ + public MAssetGroup getParent() + { + if (m_parent == null) + { + int A_Asset_Group_ID = getA_Asset_Group_ID(); + if (is_new()) + { + m_parent = new MAssetGroup(getCtx(), A_Asset_Group_ID, get_TrxName()); + } + else + { + m_parent = MAssetGroup.get(getCtx(), A_Asset_Group_ID); + } + } + return m_parent; + } + + /* commented by @win + public int getA_Asset_Class_ID() + { + return getParent().getA_Asset_Class_ID(); + } + */ + + public Timestamp getAssetServiceDate() + { + return null; + } + + /** + * Clone this object, using specified group + * @param grp the new asset group + * @return new asset group accounting (NOTE: it's not saved) + */ + public MAssetGroupAcct copy(MAssetGroup grp) + { + MAssetGroupAcct newAcct = new MAssetGroupAcct(grp.getCtx(), 0, grp.get_TrxName()); + copyValues(this, newAcct, grp.getAD_Client_ID(), grp.getAD_Org_ID()); + newAcct.setA_Asset_Group_ID(grp.getA_Asset_Group_ID()); + return newAcct; + } - - - -} // MAssetAddition + public boolean beforeSave(boolean newRecord) + { + if (! UseLifeImpl.get(this).validate()) + { + return false; + } + return true; + } + + public boolean set_AttrValue(String ColumnName, Object value) { + int index = get_ColumnIndex(ColumnName); + if (index < 0) + return false; + return set_ValueNoCheck(ColumnName, value); + } + public Object get_AttrValue(String ColumnName) { + int index = get_ColumnIndex(ColumnName); + if (index < 0) + return null; + return get_Value(index); + } + public boolean is_AttrValueChanged(String ColumnName) { + int index = get_ColumnIndex(ColumnName); + if (index < 0) + return false; + return is_ValueChanged(index); + } +} // MAssetGroupAcct diff --git a/org.adempiere.base/src/org/compiere/model/MAssetTransfer.java b/org.adempiere.base/src/org/compiere/model/MAssetTransfer.java index 8f81a2fd93..c85be7ad7d 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetTransfer.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetTransfer.java @@ -1,60 +1,267 @@ /****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. This program is distributed in the hope * - * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * + * The contents of this file are subject to the Compiere License Version 1.1 + * ("License"); You may not use this file except in compliance with the License + * You may obtain a copy of the License at http://www.compiere.org/license.html + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * The Original Code is Compiere ERP & CRM Smart Business Solution + * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc. + * Portions created by Jorg Janke are Copyright (C) 1999-2003 Jorg Janke, parts + * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved. + * Contributor(s): ______________________________________. *****************************************************************************/ package org.compiere.model; +import java.io.File; +import java.math.BigDecimal; import java.sql.ResultSet; import java.util.Properties; +import org.adempiere.exceptions.AdempiereException; +import org.compiere.model.MDocType; +import org.compiere.model.MPeriod; +import org.compiere.model.ModelValidationEngine; +import org.compiere.model.ModelValidator; +import org.compiere.model.PO; +import org.compiere.process.DocAction; +import org.compiere.process.DocumentEngine; +import org.compiere.util.Env; +import org.idempiere.fa.exceptions.AssetAlreadyDepreciatedException; + + /** - * Asset Trnasfer Model - * + * Asset Transfer Model + * @author www.arhipac.ro * */ public class MAssetTransfer extends X_A_Asset_Transfer +implements DocAction { - /** - * - */ - private static final long serialVersionUID = 6542200284709386238L; - /** - * Default ConstructorX_A_Asset_Group_Acct - * @param ctx context - * @param M_InventoryLine_ID line - */ + private static final long serialVersionUID = 1L; + /** Just Prepared Flag */ + private boolean m_justPrepared = false; + public MAssetTransfer (Properties ctx, int X_A_Asset_Transfer_ID, String trxName) - { + { super (ctx,X_A_Asset_Transfer_ID, trxName); if (X_A_Asset_Transfer_ID == 0) { - // + setDocStatus(DOCSTATUS_Drafted); + setDocAction(DOCACTION_Complete); + setProcessed(false); } - } // MAssetAddition - /** - * Load Constructor - * @param ctx context - * @param rs result set - */ + } + public MAssetTransfer (Properties ctx, ResultSet rs, String trxName) { super (ctx, rs, trxName); - } // MInventoryLine + } + + + protected boolean beforeSave(boolean newRecord) + { + setC_Period_ID(); + return true; + } + + public void setC_Period_ID() + { + MPeriod period = MPeriod.get(getCtx(), getDateAcct(), getAD_Org_ID()); + if (period == null) + { + throw new AdempiereException("@NotFound@ @C_Period_ID@"); + } + setC_Period_ID(period.get_ID()); + } + + + public boolean approveIt() { + return false; + } + + public boolean closeIt() { + setDocAction(DOCACTION_None); + return true; + } + + public File createPDF() { + return null; + } + + public BigDecimal getApprovalAmt() { + return Env.ZERO; + } + + public int getC_Currency_ID() { + return 0; + } + + public int getDoc_User_ID() { + return getCreatedBy(); + } + + public String getDocumentInfo() { + return getDocumentNo() + "/" + getDateAcct(); + } + + public String getProcessMsg() { + return m_processMsg; + } + private String m_processMsg = null; + + + public String getSummary() { + StringBuffer sb = new StringBuffer(); + sb.append("@DocumentNo@ #").append(getDocumentNo()); + return sb.toString(); + } + + public boolean invalidateIt() { + return false; + } + + public String prepareIt() + { + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE); + if (m_processMsg != null) + { + return DocAction.STATUS_Invalid; + } + // test if period is open + MPeriod.testPeriodOpen(getCtx(), getDateAcct(), MDocType.DOCBASETYPE_GLJournal, getAD_Org_ID()); + + MDepreciationWorkfile assetwk = MDepreciationWorkfile.get(getCtx(), getA_Asset_ID(), getPostingType()); + if (assetwk.isDepreciated(getDateAcct())) + { + throw new AssetAlreadyDepreciatedException(); + } + + // Check if the accounts have changed in the meantime + MAssetAcct assetAcct = MAssetAcct.forA_Asset_ID(getCtx(), getA_Asset_ID(), getPostingType(), getDateAcct(), get_TrxName()); + if (assetAcct.getA_Asset_Acct() != getA_Asset_Acct() + || assetAcct.getA_Accumdepreciation_Acct() != getA_Accumdepreciation_Acct() + || assetAcct.getA_Depreciation_Acct() != getA_Depreciation_Acct() + || assetAcct.getA_Disposal_Revenue_Acct() != getA_Disposal_Revenue_Acct() + || assetAcct.getA_Disposal_Loss_Acct() != getA_Disposal_Loss_Acct() + ) + { + throw new AdempiereException("The accounts have been changed"); + } + //Check that at least one account is changed + { + MAssetAcct acct = MAssetAcct.forA_Asset_ID(getCtx(), getA_Asset_ID(), getPostingType(), getDateAcct(), get_TrxName()); + if (acct.getA_Asset_Acct() == getA_Asset_New_Acct() + && acct.getA_Accumdepreciation_Acct() == getA_Accumdepreciation_New_Acct() + && acct.getA_Depreciation_Acct() == getA_Depreciation_New_Acct() + && acct.getA_Disposal_Revenue_Acct() == getA_Disposal_Revenue_New_Acct() + && acct.getA_Disposal_Loss_Acct() == getA_Disposal_Loss_New_Acct() + ) + { + throw new AdempiereException("An account has been changed"); + } + } + //doc check if the date is equal to its accounting for the expense table + if (assetwk.getDateAcct().equals(getDateAcct())) + { + throw new AdempiereException("Last day of month. Accounts will be changed next month"); + } + + //check if they are unprocessed records + 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; + if (!DOCACTION_Complete.equals(getDocAction())) + setDocAction(DOCACTION_Complete); + return DocAction.STATUS_InProgress; + } + + + public String completeIt() + { + // Re-Check + if (!m_justPrepared) + { + String status = prepareIt(); + if (!DocAction.STATUS_InProgress.equals(status)) + return status; + } + + + m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE); + if (m_processMsg != null) + return DocAction.STATUS_Invalid; + // create new MAssetAcct + MAssetAcct assetAcctPrev = MAssetAcct.forA_Asset_ID(getCtx(), getA_Asset_ID(), getPostingType(), getDateAcct(), get_TrxName()); + MAssetAcct assetAcct = new MAssetAcct(getCtx(), 0, get_TrxName()); + PO.copyValues(assetAcctPrev, assetAcct); + assetAcct.setA_Asset_Acct(getA_Asset_New_Acct()); + assetAcct.setA_Accumdepreciation_Acct(getA_Accumdepreciation_New_Acct()); + assetAcct.setValidFrom(getDateAcct()); + assetAcct.saveEx(); + + MDepreciationWorkfile wk = MDepreciationWorkfile.get(getCtx(), getA_Asset_ID(), getPostingType(), get_TrxName()); + /* commented out by @win, deprecating existing design + wk.buildDepreciation(); + */ + + // User Validation + String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE); + if (valid != null) + { + m_processMsg = valid; + return DocAction.STATUS_Invalid; + } + + // Set the definite document number after completed (if needed) + //setDefiniteDocumentNo(); + setProcessed(true); + setDocAction(DOCACTION_Close); + return DocAction.STATUS_Completed; + } + + + public boolean processIt(String action) throws Exception { + m_processMsg = null; + DocumentEngine engine = new DocumentEngine (this, getDocStatus()); + return engine.processIt (action, getDocAction()); + } + + public boolean reActivateIt() { + return false; + } + + public boolean rejectIt() { + return false; + } + + public boolean reverseAccrualIt() { + return false; + } + + public boolean reverseCorrectIt() { + return false; + } + + public boolean unlockIt() { + return false; + } + + public boolean voidIt() { + return false; + } -} // MAssetAddition + + public String getDocumentNo() { + // TODO Auto-generated method stub + return null; + } +} // MAssetTransfer diff --git a/org.adempiere.base/src/org/compiere/model/MAssetUse.java b/org.adempiere.base/src/org/compiere/model/MAssetUse.java index 1cd4aa19bb..8a22615c63 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssetUse.java +++ b/org.adempiere.base/src/org/compiere/model/MAssetUse.java @@ -1,36 +1,14 @@ -/****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. This program is distributed in the hope * - * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - * Copyright (C) 2005 Robert KLEIN. robeklein@gmail.com * - * Contributor(s): ______________________________________. - *****************************************************************************/ - package org.compiere.model; + import java.sql.ResultSet; import java.util.Properties; +import org.compiere.model.MRefList; import org.compiere.util.DB; /** Generated Model for A_Asset_Use ** @version $Id: X_A_Asset.java,v 1.88 2004/08/27 21:26:37 jjanke Exp $ */ public class MAssetUse extends X_A_Asset_Use { - /** - * - */ - private static final long serialVersionUID = -1247516669047870893L; - public MAssetUse (Properties ctx, int A_Asset_Use_ID, String trxName) { super (ctx, A_Asset_Use_ID, trxName); @@ -65,9 +43,9 @@ protected boolean afterSave (boolean newRecord,boolean success) String sql = "SELECT SUM(USEUNITS) FROM A_Asset_use WHERE A_Asset_ID=? and usedate <= SYSDATE"; - total_unitsused = DB.getSQLValue(null, sql, getA_Asset_ID()); + total_unitsused = DB.getSQLValueEx(null, sql, getA_Asset_ID()); - MAsset asset = new MAsset (getCtx(), p_A_Asset_ID, null); + MAsset asset = MAsset.get(getCtx(), p_A_Asset_ID, null); asset.setUseUnits(total_unitsused); asset.setProcessing(false); asset.saveEx(); diff --git a/org.adempiere.base/src/org/compiere/model/MDepreciationWorkfile.java b/org.adempiere.base/src/org/compiere/model/MDepreciationWorkfile.java index 774e032ecc..de63f5d164 100644 --- a/org.adempiere.base/src/org/compiere/model/MDepreciationWorkfile.java +++ b/org.adempiere.base/src/org/compiere/model/MDepreciationWorkfile.java @@ -1,38 +1,39 @@ -/****************************************************************************** - * The contents of this file are subject to the Compiere License Version 1.1 - * ("License"); You may not use this file except in compliance with the License - * You may obtain a copy of the License at http://www.compiere.org/license.html - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * The Original Code is Compiere ERP & CRM Smart Business Solution - * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc. - * Portions created by Jorg Janke are Copyright (C) 1999-2003 Jorg Janke, parts - * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved. - * Contributor(s): ______________________________________. - *****************************************************************************/ package org.compiere.model; import java.math.BigDecimal; import java.sql.ResultSet; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Collection; import java.util.Properties; +import org.adempiere.exceptions.AdempiereException; +import org.apache.commons.collections.keyvalue.MultiKey; +import org.compiere.model.Query; +import org.compiere.util.CCache; +import org.compiere.util.CLogMgt; +import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.TimeUtil; +import org.idempiere.fa.feature.UseLife; +import org.idempiere.fa.feature.UseLifeImpl; + /** * Depreciation Workfile Model - * - * + * @author Teo Sarca, SC ARHIPAC SERVICE SRL */ public class MDepreciationWorkfile extends X_A_Depreciation_Workfile + implements UseLife { /** * */ - private static final long serialVersionUID = 9075233803956474274L; + private static final long serialVersionUID = -3814417671427820714L; /** - * Default Constructor X_A_Depreciation_Workfile + * Default Constructor * @param ctx context * @param M_InventoryLine_ID line */ @@ -41,9 +42,15 @@ public class MDepreciationWorkfile extends X_A_Depreciation_Workfile super (ctx,A_Depreciation_Workfile_ID, trxName); if (A_Depreciation_Workfile_ID == 0) { - // + setPostingType(POSTINGTYPE_Actual); + setA_QTY_Current(Env.ZERO); + setA_Asset_Cost(Env.ZERO); + setA_Accumulated_Depr(Env.ZERO); + setA_Period_Posted(0); + setA_Current_Period(0); } - } // MAssetAddition + } // MDepreciationWorkfile + /** * Load Constructor * @param ctx context @@ -52,71 +59,733 @@ public class MDepreciationWorkfile extends X_A_Depreciation_Workfile public MDepreciationWorkfile (Properties ctx, ResultSet rs, String trxName) { super (ctx, rs, trxName); - } // MInventoryLine - + } // MDepreciationWorkfile + /** Asset (parent) */ + private MAsset m_asset = null; + + /** Get Asset */ + public MAsset getAsset() { + return getAsset(false); + } + + /** Get asset using this trxName + * @param requery requery asset + * @return parent asset + */ + public MAsset getAsset(boolean requery) + { + if (m_asset == null || requery) { + m_asset = MAsset.get(getCtx(), getA_Asset_ID(), get_TrxName()); + } + if (m_asset.get_ID() <= 0) { + m_asset = null; + } + return m_asset; + } + + /** Set asset + * @param asset + */ + public void setAsset(MAsset asset) + { + setA_Asset_ID(asset.get_ID()); + m_asset = asset; + } + + /** Gets asset's service date (commissioning) + * @return asset service date + */ + + public Timestamp getAssetServiceDate() + { + MAsset asset = getAsset(); + if (asset == null) { + return null; + } + return asset.getAssetServiceDate(); + } + + + /** Gets asset's class + * @return asset class id + */ + /* commented out by @win + public int getA_Asset_Class_ID() + { + MAsset asset = getAsset(); + if (asset == null) { + return 0; + } + return asset.getA_Asset_Class_ID(); + } + */ // end comment by @win + + /** After save + * @param newRecord + * @return true on success + */ protected boolean afterSave (boolean newRecord) { - - log.info ("beforeSave"); - //int p_A_Asset_ID = 0; - int p_wkasset_ID = 0; - //p_A_Asset_ID = getA_Asset_ID(); - p_wkasset_ID = getA_Depreciation_Workfile_ID(); - StringBuilder sqlB = new StringBuilder ("UPDATE A_Depreciation_Workfile ") - .append("SET Processing = 'Y'") - .append(" WHERE A_Depreciation_Workfile_ID = " ).append(p_wkasset_ID ); - - int no = DB.executeUpdate (sqlB.toString(),null); - if (no == -1) - log.info("Update to Deprecaition Workfile failed"); + if(m_buildDepreciation) + { + buildDepreciation(); + } return true; } - /** - * after Save - * @param newRecord new - * @return true - */ + protected boolean beforeSave (boolean newRecord) { + log.info ("Entering: trxName=" + get_TrxName()); - log.info ("beforeSave"); - int p_A_Asset_ID = 0; - //int p_wkasset_ID = 0; - p_A_Asset_ID = getA_Asset_ID(); - //p_wkasset_ID = getA_Depreciation_Workfile_ID(); + // copy UseLife to A_Life + if (newRecord) { //@win: should only update only if newrecord + setA_Life_Period(getUseLifeMonths()); + setA_Asset_Life_Years(getUseLifeYears()); + setA_Life_Period_F(getUseLifeMonths_F()); + setA_Asset_Life_Years_F(getUseLifeYears_F()); + } - log.info ("afterSave"); - X_A_Asset asset = new X_A_Asset (getCtx(), p_A_Asset_ID, null); - asset.setA_QTY_Current(getA_QTY_Current()); - asset.setA_QTY_Original(getA_QTY_Current()); - asset.saveEx(); - - if (getA_Accumulated_Depr().equals(null)) - setA_Accumulated_Depr(new BigDecimal(0.0)); - - if (new BigDecimal(getA_Period_Posted()).equals(null)) - setA_Period_Posted(0); - - - MAssetChange change = new MAssetChange (getCtx(), 0,null); - log.info("0"); - String sql2 = "SELECT COUNT(*) FROM A_Depreciation_Workfile WHERE A_Asset_ID=? AND PostingType = ?"; - if (DB.getSQLValue(null, sql2, p_A_Asset_ID,getPostingType())!= 0) + // If it is fully amortized, change the state's FA + MAsset asset = getAsset(true); + if (MAsset.A_ASSET_STATUS_Activated.equals(asset.getA_Asset_Status()) + && isFullyDepreciated()) { - change.setA_Asset_ID(p_A_Asset_ID); - change.setChangeType("BAL"); - change.setTextDetails(MRefList.getListDescription (getCtx(),"A_Update_Type" , "BAL")); - change.setPostingType(getPostingType()); - change.setAssetValueAmt(getA_Asset_Cost()); - change.setA_QTY_Current(getA_QTY_Current()); - change.setA_QTY_Original(getA_QTY_Current()); - change.setAssetAccumDepreciationAmt(getA_Accumulated_Depr()); - change.saveEx(); - } - return true; + asset.changeStatus(MAsset.A_ASSET_STATUS_Depreciated, null); + asset.saveEx(); + } + + // Fix DateAcct + if(is_ValueChanged(COLUMNNAME_DateAcct)) + { + setDateAcct(TimeUtil.getMonthLastDay(getDateAcct())); + } + + // + BigDecimal cost = getA_Asset_Cost(); + BigDecimal accumDep_C = getA_Accumulated_Depr(); + setA_Asset_Remaining(cost.subtract(accumDep_C)); + BigDecimal accumDep_F = getA_Accumulated_Depr_F(); + setA_Asset_Remaining_F(cost.subtract(accumDep_F)); + + // Financing + { + String mainColumnName = null; + if (newRecord || is_ValueChanged(COLUMNNAME_A_Asset_Cost)) + { + mainColumnName = COLUMNNAME_A_Asset_Cost; + } + else if (is_ValueChanged(COLUMNNAME_A_Valoare_Cofinantare)) + { + mainColumnName = COLUMNNAME_A_Valoare_Cofinantare; + } + else if (is_ValueChanged(COLUMNNAME_A_Valoare_Tert)) + { + mainColumnName = COLUMNNAME_A_Valoare_Tert; + } + updateFinantare(this, mainColumnName); + } + + + log.info("Leaving: trxName=" + get_TrxName() + " [RETURN TRUE]"); + return true; } // beforeSave + + /** + * Asset is fully depreciated + *
    + *
  • If PostingType != ACTUAL then return false + *
  • Do not check your current asset + *
+ * @return true if the asset is fully depreciated, false otherwise + */ + public boolean isFullyDepreciated() + { + if(!getPostingType().equals(POSTINGTYPE_Actual)) + { + return false; + } + + // check if is fully depreciated + BigDecimal remainingAmt_C = getRemainingCost(null, false); + BigDecimal remainingAmt_F = getRemainingCost(null, true); + if(remainingAmt_C.signum() == 0 && remainingAmt_F.signum() == 0) + { + //if A_Asset_Cost is 0 have a voided addition, in this case asset is not full depreciated + if (getA_Asset_Cost().signum() == 0) + { + return false; + } + // + return true; + } + + return false; + } + + /** + * + */ + public MDepreciationWorkfile(MAsset asset, String postingType, MAssetGroupAcct assetgrpacct) + { + this(asset.getCtx(), 0, asset.get_TrxName()); + setA_Asset_ID(asset.getA_Asset_ID()); + setAD_Org_ID(asset.getAD_Org_ID()); //@win added + setA_Asset_Cost(asset.getA_Asset_Cost()); + setA_Accumulated_Depr(asset.getA_Accumulated_Depr()); + setA_Accumulated_Depr_F(asset.getA_Accumulated_Depr_F()); + setA_Current_Period(asset.getA_Current_Period()); + + setIsDepreciated(asset.isDepreciated()); + setPostingType(postingType); + // + // Copy UseLife values from asset group to workfile + if (assetgrpacct == null) + { + assetgrpacct = MAssetGroupAcct.forA_Asset_Group_ID(asset.getCtx(), asset.getA_Asset_Group_ID(), postingType); + } + UseLifeImpl.copyValues(this, assetgrpacct); + + // + // Set Date Acct from Asset + Timestamp dateAcct = asset.getDateAcct(); + if (dateAcct != null) + { + dateAcct = TimeUtil.addMonths(dateAcct, 1); + setDateAcct(dateAcct); + } + // + // Set UseLife values from asset (if any) + if (asset.getUseLifeMonths() > 0) + { + UseLifeImpl.get(this, false).setUseLifeMonths(asset.getUseLifeMonths()); + } + if (asset.getUseLifeMonths_F() > 0) + { + UseLifeImpl.get(this, true).setUseLifeMonths(asset.getUseLifeMonths_F()); + } + // + dump(); + } + + /** Logger */ + private CLogger log = CLogger.getCLogger(getClass()); + public static Collection forA_Asset_ID(Properties ctx, int asset_id, String trxName) + { + return new Query(ctx, Table_Name, MDepreciationWorkfile.COLUMNNAME_A_Asset_ID+"=?", trxName) + .setParameters(new Object[]{asset_id}) + .list(); + } + + /** + * + * @param ctx + * @param A_Asset_ID + * @param postingType + * @return workfile + * @see #get(Properties, int, String, String) + */ + public static MDepreciationWorkfile get (Properties ctx, int A_Asset_ID, String postingType) + { + return get(ctx, A_Asset_ID, postingType, null); + } + + /** + * Get/load workfile from cache (if trxName is null) + * @param ctx + * @param A_Asset_ID + * @param postingType + * @param trxName + * @return workfile + */ + public static MDepreciationWorkfile get (Properties ctx, int A_Asset_ID, String postingType, String trxName) + { + if (A_Asset_ID <= 0 || postingType == null) + { + return null; + } + + final MultiKey key = new MultiKey(A_Asset_ID, postingType); + if (trxName == null) + { + MDepreciationWorkfile wk = s_cacheAsset.get(key); + if (wk != null) + return wk; + } + /* @win temporary change as this code is causing duplicate create MDepreciationWorkfile on asset addition + final String whereClause = COLUMNNAME_A_Asset_ID+"=?" + +" AND "+COLUMNNAME_PostingType+"=? AND "+COLUMNNAME_A_QTY_Current+">?"; + MDepreciationWorkfile wk = new Query(ctx, MDepreciationWorkfile.Table_Name, whereClause, trxName) + .setParameters(new Object[]{A_Asset_ID, postingType, 0}) + .firstOnly(); + */ + final String whereClause = COLUMNNAME_A_Asset_ID+"=?" + +" AND "+COLUMNNAME_PostingType+"=? "; + MDepreciationWorkfile wk = new Query(ctx, MDepreciationWorkfile.Table_Name, whereClause, trxName) + .setParameters(new Object[]{A_Asset_ID, postingType}) + .firstOnly(); + + + if (trxName == null && wk != null) + { + s_cacheAsset.put(key, wk); + } + return wk; + } + /** Static cache: Asset/PostingType -> Workfile */ + private static CCache + s_cacheAsset = new CCache(Table_Name+"_Asset", 10); + + /** Returns the date of the last action + */ + public Timestamp getLastActionDate() + { + return TimeUtil.getMonthLastDay(TimeUtil.addMonths(getDateAcct(), -1)); + } + + /** Check if the asset is depreciated at the specified date + * @param date + * @return true if you amortized until the specified date, otherwise false + */ + public boolean isDepreciated(Timestamp date) + { + Timestamp lastActionDate = getLastActionDate(); + boolean isDepr = !date.after(lastActionDate); // date <= lastActionDate + + log.fine("LastActionDate=" + lastActionDate + ", GivenDate=" + date + " => isDepreciated=" + isDepr); + return isDepr; + } + + /** + * Get Asset Accounting for this workfile + * @return asset accounting model + */ + public MAssetAcct getA_AssetAcct(Timestamp dateAcct, String trxName) + { + return MAssetAcct.forA_Asset_ID(getCtx(), getA_Asset_ID(), getPostingType(), dateAcct, trxName); + } -} // MAssetAddition + /** Returns the current cost of FAs. It is calculated as the difference between acquisition value and the value that you (A_Salvage_Value) + * @return the current cost of FAs + */ + public BigDecimal getActualCost() + { + return getActualCost(getA_Asset_Cost()); + } + + /** */ + public BigDecimal getActualCost(BigDecimal assetCost) + { + return assetCost.subtract(getA_Salvage_Value()); + } + + /** + * + * @param deltaAmt + * @param deltaQty + * @param reset + */ + public void adjustCost(BigDecimal deltaAmt, BigDecimal deltaQty, boolean reset) + { + BigDecimal newCost = Env.ZERO; + BigDecimal newQty = Env.ZERO; + if (!reset) + { + newCost = getA_Asset_Cost(); + newQty = getA_QTY_Current(); + } + newCost = newCost.add(deltaAmt); + newQty = newQty.add(deltaQty); + + // TODO: crashes if I cancel an Issue: +// if (newQty.signum() < 0) { +// throw new ArhRuntimeException(getCtx(), "@A_QTY_Current@ < 0"); +// } + + // + // There must be verified that the remaining value to be greater than the amount diminished + // total devaluation because if the entire asset value (A_Asset_Cost) must be brought to 0. +// if (deltaAmt.signum() < 0) +// { +// BigDecimal remainingAmt_C = getRemainingCost(null, false); +// if (remainingAmt_C.compareTo(deltaAmt.negate()) < 0) +// { +// throw new ArhRuntimeException(getCtx(), "@A_Asset_Remaining@ < @DeltaAmt@") +// .addInfo("@A_Asset_Cost@=", getA_Asset_Cost()) +// .addInfo("@A_Accumulated_Depr@=", getA_Accumulated_Depr()); +// } +// BigDecimal remainingAmt_F = getRemainingCost(null, true); +// if (remainingAmt_F.compareTo(deltaAmt.negate()) < 0) +// { +// throw new ArhRuntimeException(getCtx(), "@A_Asset_Remaining_F@ < @DeltaAmt@") +// .addInfo("@A_Asset_Cost=@", getA_Asset_Cost()) +// .addInfo("@A_Accumulated_Depr@=", getA_Accumulated_Depr_F()); +// } +// } + + setA_Asset_Cost(newCost); + setA_QTY_Current(newQty); + + if(CLogMgt.isLevelFine()) log.fine("adjustCost(" + deltaAmt + ", " + deltaQty + ", reset=" + reset + ") => amt=" + getA_Asset_Cost() + ", qty=" + getA_QTY_Current()); + } + + /** + * Adjust Accumulated depreciation + * @param amt + * @param amt_F + * @param reset + * @return + */ + public boolean adjustAccumulatedDepr(BigDecimal amt, BigDecimal amt_F, boolean reset) + { + if (amt == null) + { + amt = Env.ZERO; + } + if (amt_F == null) + { + amt_F = Env.ZERO; + } + setA_Accumulated_Depr(amt.add(reset ? Env.ZERO : getA_Accumulated_Depr())); + setA_Accumulated_Depr_F(amt_F.add(reset ? Env.ZERO : getA_Accumulated_Depr_F())); + return true; + } + + /** + * Adjust use life years + */ + public void adjustUseLife(int deltaUseLifeYears, int deltaUseLifeYears_F, boolean reset) + { + if(CLogMgt.isLevelFine()) log.fine("Entering: deltaUseLifeYears=" + deltaUseLifeYears + ", deltaUseLifeYears_F=" + deltaUseLifeYears_F); + // + UseLifeImpl.get(this, false).adjustUseLifeYears(deltaUseLifeYears, reset); + UseLifeImpl.get(this, true).adjustUseLifeYears(deltaUseLifeYears_F, reset); + // + if(CLogMgt.isLevelFine()) log.fine("Leaving"); + } + + /** */ + public int getUseLifeMonths(boolean fiscal) + { + return fiscal ? getUseLifeMonths_F() : getUseLifeMonths(); + } + + /** */ + public BigDecimal getA_Accumulated_Depr(boolean fiscal) + { + return fiscal ? getA_Accumulated_Depr_F() : getA_Accumulated_Depr(); + } + + /** */ + public BigDecimal getAccumulatedCost() + { + return getA_Accumulated_Depr(isFiscal()); + } + + /** */ + public BigDecimal getReevaluationCost() + { + return Env.ZERO; + } + + /** + * Returns the residual (remaining) value + */ + public BigDecimal getRemainingCost(BigDecimal accumAmt, boolean fiscal) + { + BigDecimal cost = getActualCost(); + if (accumAmt == null) { + accumAmt = getA_Accumulated_Depr(fiscal); + } + return cost.subtract(accumAmt); + } + + /** + * Returns the residual (remaining) value + */ + public BigDecimal getRemainingCost(BigDecimal accumAmt) + { + return getRemainingCost(accumAmt, isFiscal()); + } + + /** */ + public int getRemainingPeriods(int A_Current_Period, MDepreciation method) + { + int useLifePeriods = getUseLifeMonths(isFiscal()); + if (method != null) { + useLifePeriods += method.getFixMonthOffset(); + } + int currentPeriod = (A_Current_Period >= 0 ? A_Current_Period : getA_Current_Period()); + return useLifePeriods - currentPeriod; + } + /** */ + public int getRemainingPeriods(int A_Current_Period) + { + return getRemainingPeriods(A_Current_Period, null); + } + + /** */ + private boolean m_isFiscal = false; + /** */ + public boolean isFiscal() + { + return m_isFiscal; + } + /** + * Set fiscal flag (temporary - is not modifing the workfile) + * @param fiscal + */ + public void setFiscal(boolean fiscal) + { + m_isFiscal = fiscal; + } + + /** Increment the current period (A_Current_Period) 1, and a month DateAcct */ + public void incA_Current_Period() + { + int old_period = getA_Current_Period(); + Timestamp old_date = getDateAcct(); + int new_period = old_period + 1; + Timestamp new_date = TimeUtil.addMonths(getDateAcct(), 1); + setA_Current_Period(new_period); + setDateAcct(new_date); + // + if(CLogMgt.isLevelFine()) log.fine("(A_Current_Period, DateAcct)=(" + old_period + ", " + old_date + ")->(" + new_period + ", " + new_date + ")"); + } + + /** + * Set A Current Period (and Data Act) processed just after the last expense. + * Do not save. + */ + public void setA_Current_Period() + { + String whereClause = MDepreciationExp.COLUMNNAME_A_Asset_ID+"=?" + +" AND "+MDepreciationExp.COLUMNNAME_PostingType+"=?" + +" AND "+MDepreciationExp.COLUMNNAME_Processed+"=? AND IsActive=?" + ; + // + MDepreciationExp depexp = new Query(getCtx(), MDepreciationExp.Table_Name, whereClause, get_TrxName()) + .setParameters(new Object[]{getA_Asset_ID(), getPostingType(), true, true}) + .setOrderBy(MDepreciationExp.COLUMNNAME_A_Period+" DESC" + +","+MDepreciationExp.COLUMNNAME_DateAcct+" DESC") + .first(); + if (depexp != null) + { + setA_Current_Period(depexp.getA_Period()); + setDateAcct(depexp.getDateAcct()); + incA_Current_Period(); + } + else + { + log.info("There are no records from which to infer its"); + } + + } + + /** Build depreciation flag - if true, the depreciation should be built after save */ + private boolean m_buildDepreciation = false; + + /** + * Build depreciation (A_Depreciation_Exp) entries. More exactly, is deleting not Processed entries. + * and create new ones again. + * WARNING: IS NOT modifying workfile (this) + */ + + public void buildDepreciation() + { + if (!isDepreciated()) + { + return; + } + + StringBuffer sb = new StringBuffer(); + load(get_TrxName()); // reload workfile + MAssetAcct assetacct = getA_AssetAcct(null, get_TrxName()); + // TODO: teo_sarca: need to evaluate what happens when we change Depreciation method !!! + MDepreciation depreciation_C = MDepreciation.get(getCtx(), assetacct.getA_Depreciation_ID()); + MDepreciation depreciation_F = MDepreciation.get(getCtx(), assetacct.getA_Depreciation_F_ID()); + //~ int offset_C = depreciation_C.getFixMonthOffset(); + //~ int offset_F = depreciation_F.getFixMonthOffset(); + int offset_C = 0, offset_F = 0; + + BigDecimal assetCost = getActualCost(); + BigDecimal accumDep_C = getA_Accumulated_Depr(false); + BigDecimal accumDep_F = getA_Accumulated_Depr(true); + int lifePeriods_C = getUseLifeMonths(false) + offset_C; + int lifePeriods_F = getUseLifeMonths(true) + offset_F; + int lifePeriods = (lifePeriods_C > lifePeriods_F ? lifePeriods_C : lifePeriods_F); + BigDecimal exp_C = Env.ZERO; + BigDecimal exp_F = Env.ZERO; + + //logging + if(CLogMgt.isLevelFine()) + { + sb.append("currentPeriod=" + getA_Current_Period() + ", AssetServiceDate=" + getAssetDepreciationDate() + "\n"); + sb.append("offset: C|F=" + offset_C + "|" + offset_F + "\n"); + sb.append("life: C|F=" + lifePeriods_C + "|" + lifePeriods_F + " + offset =" + lifePeriods + "\n"); + } + + truncDepreciation(); + int A_Current_Period = getA_Current_Period(); + for (int currentPeriod = A_Current_Period, cnt = 1; currentPeriod <= lifePeriods; currentPeriod++, cnt++) + { + exp_C = Env.ZERO; + exp_F = Env.ZERO; + + String help = "" + accumDep_C + "|" + accumDep_F + " + "; + + if (lifePeriods_C > currentPeriod || !depreciation_C.requireLastPeriodAdjustment()) + { + setFiscal(false); + exp_C = depreciation_C.invoke(this, assetacct, currentPeriod, accumDep_C); + accumDep_C = accumDep_C.add(exp_C); + } + else if (lifePeriods_C == currentPeriod) + { // last period + exp_C = assetCost.subtract(accumDep_C); + accumDep_C = assetCost; + } + + if (lifePeriods_F > currentPeriod || !depreciation_F.requireLastPeriodAdjustment()) + { + setFiscal(true); + exp_F = depreciation_F.invoke(this, assetacct, currentPeriod, accumDep_F); + accumDep_F = accumDep_F.add(exp_F); + } + else if (lifePeriods_F == currentPeriod) + { // last period (fiscal) + exp_F = assetCost.subtract(accumDep_F); + accumDep_F = assetCost; + } + + help += "" + exp_C + "|" + exp_F + " = " + accumDep_C + "|" + accumDep_F; + + // added by zuhri + int months = 0; + + months = months + (currentPeriod - A_Current_Period); + Timestamp dateAcct = TimeUtil.getMonthLastDay(TimeUtil.addMonths(getDateAcct(), months)); + + MDepreciationExp.createDepreciation (this, currentPeriod, dateAcct, + exp_C, exp_F, + accumDep_C, accumDep_F, + help, get_TrxName()); + if(CLogMgt.isLevelFine()) + { + String info = "" + cnt + ": period=" + currentPeriod + "/" + lifePeriods_C + "|" + lifePeriods_F + + ", exp=" + exp_C + "|" + exp_F + ", accumDep=" + accumDep_C + "|" + accumDep_F + + ", DateAcct=" + dateAcct; + log.fine("=> " + info + Env.NL + Env.NL); + sb.append(info + Env.NL); + } + } // for + log.fine(sb.toString()); + + m_buildDepreciation = false; + } // buildDepreciation + + + + /** + * Truncate not processed depreciation entries. + * IS NOT modifying workfile. + */ + public void truncDepreciation() + { + String trxName = get_TrxName(); + + int A_Current_Period = getA_Current_Period(); + final String sql = "DELETE FROM "+MDepreciationExp.Table_Name + +" WHERE " + +MDepreciationExp.COLUMNNAME_Processed+"=?" + +" AND "+MDepreciationExp.COLUMNNAME_A_Period+">=?" + +" AND "+MDepreciationExp.COLUMNNAME_A_Asset_ID+"=?" + +" AND "+MDepreciationExp.COLUMNNAME_PostingType+"=?" + ; + Object[] params = new Object[]{false, A_Current_Period, getA_Asset_ID(), getPostingType()}; + int no = DB.executeUpdateEx(sql, params, trxName); + log.fine("sql=" + sql + "\nDeleted #" + no); + } // truncDepreciation + + /** + * Update Founding Mode related fields + * @param m model + * @param changedColumnName column name that has been changed + */ + public static void updateFinantare(SetGetModel m, String changedColumnName) + { + //Own contribution: + BigDecimal valCofinantare = SetGetUtil.get_AttrValueAsBigDecimal(m, COLUMNNAME_A_Valoare_Cofinantare); + // Asset Value: + BigDecimal assetCost = SetGetUtil.get_AttrValueAsBigDecimal(m, COLUMNNAME_A_Asset_Cost); + // Third value: + BigDecimal valTert = SetGetUtil.get_AttrValueAsBigDecimal(m, COLUMNNAME_A_Valoare_Tert); + + // Calculate values + if (valCofinantare.signum() == 0 && valTert.signum() == 0) + { + // Values ​​have never been set, so put everything on their own financing + valCofinantare = assetCost; + valTert = Env.ZERO; + } + else if (COLUMNNAME_A_Asset_Cost.equals(changedColumnName)) + { + valCofinantare = assetCost.subtract(valTert); + } + else if (COLUMNNAME_A_Valoare_Cofinantare.equals(changedColumnName)) + { + valTert = assetCost.subtract(valCofinantare); + } + else if (COLUMNNAME_A_Valoare_Tert.equals(changedColumnName)) + { + valCofinantare = assetCost.subtract(valTert); + } + else + { + valTert = assetCost.subtract(valCofinantare); + } + + // Financing Type + String tipFinantare = A_TIP_FINANTARE_Cofinantare; + if (valTert.signum() == 0) + { + tipFinantare = A_TIP_FINANTARE_Proprie; + } + else if (valCofinantare.signum() == 0) + { + tipFinantare = A_TIP_FINANTARE_Terti; + } + // + // Set values + m.set_AttrValue(COLUMNNAME_A_Tip_Finantare, tipFinantare); + m.set_AttrValue(COLUMNNAME_A_Valoare_Cofinantare, valCofinantare); + m.set_AttrValue(COLUMNNAME_A_Valoare_Tert, valTert); + // + // If the method is invoked for a persistent object when reset mode of financing + if (A_TIP_FINANTARE_Proprie.equals(tipFinantare) && SetGetUtil.isPersistent(m)) + { + m.set_AttrValue(COLUMNNAME_A_FundingMode_ID, null); + } + } + + public boolean set_AttrValue(String ColumnName, Object value) { + int index = get_ColumnIndex(ColumnName); + if (index < 0) + return false; + return set_ValueNoCheck(ColumnName, value); + } + public Object get_AttrValue(String ColumnName) { + int index = get_ColumnIndex(ColumnName); + if (index < 0) + return null; + return get_Value(index); + } + public boolean is_AttrValueChanged(String ColumnName) { + int index = get_ColumnIndex(ColumnName); + if (index < 0) + return false; + return is_ValueChanged(index); + } +} // MDepreciationWorkfile diff --git a/org.adempiere.base/src/org/compiere/model/MInOut.java b/org.adempiere.base/src/org/compiere/model/MInOut.java index cd4aef7e28..6d318112cd 100644 --- a/org.adempiere.base/src/org/compiere/model/MInOut.java +++ b/org.adempiere.base/src/org/compiere/model/MInOut.java @@ -2105,8 +2105,7 @@ public class MInOut extends X_M_InOut implements DocAction if (asset != null) { asset.setIsActive(false); - StringBuilder msgadd = new StringBuilder("(").append(reversal.getDocumentNo()).append(" #").append(rLine.getLine()).append("<-)"); - asset.addDescription(msgadd.toString()); + asset.setDescription(asset.getDescription() + " (" + reversal.getDocumentNo() + " #" + rLine.getLine() + "<-)"); asset.saveEx(); } } diff --git a/org.adempiere.base/src/org/compiere/model/MXIFAJournal.java b/org.adempiere.base/src/org/compiere/model/MXIFAJournal.java index f067b90a8c..a66446b4d4 100644 --- a/org.adempiere.base/src/org/compiere/model/MXIFAJournal.java +++ b/org.adempiere.base/src/org/compiere/model/MXIFAJournal.java @@ -1,83 +1,78 @@ -/****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * - * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it * - * under the terms version 2 of the GNU General Public License as published * - * by the Free Software Foundation. This program is distributed in the hope * - * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along * - * with this program; if not, write to the Free Software Foundation, Inc., * - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * - * For the text or an alternative of this public license, you may reach us * - * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * - * or via info@compiere.org or http://www.compiere.org/license.html * - *****************************************************************************/ package org.compiere.model; - -import java.math.BigDecimal; -import java.sql.ResultSet; -import java.util.Properties; - -import org.compiere.util.Env; - -/******************************************************************************* - * Generated Model for A_Asset - * - * @version $Id: X_A_Asset.java,v 1.88 2004/08/27 21:26:37 jjanke Exp $ * - ******************************************************************************/ -public class MXIFAJournal extends X_I_FAJournal { - /** - * - */ - private static final long serialVersionUID = -3922040740843729868L; - - public MXIFAJournal(Properties ctx, int I_FAJournal_ID, String trxName) { - super(ctx, I_FAJournal_ID, trxName); - if (I_FAJournal_ID == 0) { - // setIsDepreciated (false); - // setIsFullyDepreciated (false); - // setValue (null); - // setName (null); - // setIsInPosession (false); - // setIsOwned (false); - // setA_Asset_Group_ID (0); - // setIsDisposed (false); - // setM_AttributeSetInstance_ID(0); - } - } // MAsset +import java.util.*; +import java.sql.*; +import java.math.*; +import org.compiere.model.*; +import org.compiere.util.*; +/** Generated Model for A_Asset + ** @version $Id: X_A_Asset.java,v 1.88 2004/08/27 21:26:37 jjanke Exp $ */ +public class MXIFAJournal extends X_I_FAJournal +{ + public MXIFAJournal (Properties ctx, int I_FAJournal_ID, String trxName) + { + super (ctx, I_FAJournal_ID, trxName); + // if (I_FAJournal_ID == 0) + // { + // setIsDepreciated (false); + // setIsFullyDepreciated (false); + // setValue (null); + // setName (null); + // setIsInPosession (false); + // setIsOwned (false); + // setA_Asset_Group_ID (0); + // setIsDisposed (false); + // setM_AttributeSetInstance_ID(0); + // } + } // MXIFAJournal /** - * Load Constructor - * - * @param ctx - * context - * @param rs - * result set record + * Load Constructor + * @param ctx context + * @param rs result set record */ - public MXIFAJournal(Properties ctx, ResultSet rs, String trxName) { - super(ctx, rs, trxName); - } // MAsset + public MXIFAJournal (Properties ctx, ResultSet rs, String trxName) + { + super (ctx, rs, trxName); + } // MAsset - public BigDecimal getExpenseDr() { - BigDecimal bd = getAmtAcctDr(); - return bd; + + public BigDecimal getExpenseDr() + { + BigDecimal bd = getAmtAcctDr(); + return bd; } - public BigDecimal getExpenseCr() { - BigDecimal bd = getAmtAcctCr(); - return bd; + public BigDecimal getExpenseCr() + { + BigDecimal bd = getAmtAcctCr(); + return bd; } - public BigDecimal getAmtAcctTotal() { - BigDecimal dr = getAmtAcctDr(); - BigDecimal cr = getAmtAcctCr(); - BigDecimal bd = (dr).subtract(cr); - if (bd == null) - return Env.ZERO; - return bd; - } + public BigDecimal getAmtAcctTotal() + { + BigDecimal dr = getAmtAcctDr(); + BigDecimal cr = getAmtAcctCr(); + BigDecimal bd = (dr).subtract(cr); + if (bd == null) return Env.ZERO; + return bd; + } + /** Set Currency Type. + Currency Conversion Rate Type */ + public void setC_ConversionType_ID (int C_ConversionType_ID) + { + if (C_ConversionType_ID == 0) set_Value ("C_ConversionType_ID", null); + else + set_Value ("C_ConversionType_ID", Integer.valueOf(C_ConversionType_ID)); + } + /** Get Currency Type. + Currency Conversion Rate Type */ + public int getC_ConversionType_ID() + { + Integer ii = (Integer)get_Value("C_ConversionType_ID"); + if (ii == null) return 0; + return ii.intValue(); + } + } diff --git a/org.adempiere.base/src/org/compiere/util/TimeUtil.java b/org.adempiere.base/src/org/compiere/util/TimeUtil.java index 829786eec3..0e4156905e 100644 --- a/org.adempiere.base/src/org/compiere/util/TimeUtil.java +++ b/org.adempiere.base/src/org/compiere/util/TimeUtil.java @@ -1,5 +1,5 @@ /****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * + * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * @@ -728,4 +728,72 @@ public class TimeUtil System.out.println(isSameDay(t3, t5) + " == false"); } // main +// ARHIPAC: TEO: ADDITION ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + /** + * [ ARHIPAC ] Gets calendar instance of given date + * @param date calendar initialization date; if null, the current date is used + * @return calendar + * @author Teo Sarca, SC ARHIPAC SERVICE SRL + */ + static public Calendar getCalendar(Timestamp date) + { + GregorianCalendar cal = new GregorianCalendar(Language.getLoginLanguage().getLocale()); + if (date != null) { + cal.setTimeInMillis(date.getTime()); + } + return cal; + } + + /** + * [ ARHIPAC ] Get first date in month + * @param day day; if null current time will be used + * @return first day of the month (time will be 00:00) + */ + static public Timestamp getMonthFirstDay (Timestamp day) + { + if (day == null) + day = new Timestamp(System.currentTimeMillis()); + Calendar cal = getCalendar(day); + cal.setTimeInMillis(day.getTime()); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + // + cal.set(Calendar.DAY_OF_MONTH, 1); // first + return new Timestamp (cal.getTimeInMillis()); + } // getMonthFirstDay + + /** + * [ ARHIPAC ] Return Day + offset (truncates) + * @param day Day; if null current time will be used + * @param offset months offset + * @return Day + offset (time will be 00:00) + * @return Teo Sarca, SC ARHIPAC SERVICE SRL + */ + static public Timestamp addMonths (Timestamp day, int offset) + { + if (day == null) + day = new Timestamp(System.currentTimeMillis()); + // + GregorianCalendar cal = new GregorianCalendar(); + cal.setTime(day); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + if (offset == 0) + return new Timestamp (cal.getTimeInMillis()); + cal.add(Calendar.MONTH, offset); + return new Timestamp (cal.getTimeInMillis()); + } // addMonths + + public static int getMonthsBetween (Timestamp start, Timestamp end) + { + Calendar startCal = getCalendar(start); + Calendar endCal = getCalendar(end); + // + return endCal.get(Calendar.YEAR) * 12 + endCal.get(Calendar.MONTH) + - (startCal.get(Calendar.YEAR) * 12 + startCal.get(Calendar.MONTH)); + } } // TimeUtil