IDEMPIERE-3947:add interface to easy implement FA depreciation method
Fixed Asset bugs and enhancements
This commit is contained in:
parent
9a6ab2b562
commit
d7cddaa9f2
|
@ -54,6 +54,7 @@ Export-Package: bsh,
|
|||
org.eevolution.model,
|
||||
org.idempiere.broadcast,
|
||||
org.idempiere.distributed,
|
||||
org.idempiere.fa.service.api,
|
||||
org.idempiere.model
|
||||
Comment: Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=1.11))"
|
||||
|
|
|
@ -48,6 +48,9 @@ import org.compiere.process.ProcessCall;
|
|||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.PaymentExport;
|
||||
import org.compiere.util.ReplenishInterface;
|
||||
import org.idempiere.fa.service.api.DepreciationFactoryLookupDTO;
|
||||
import org.idempiere.fa.service.api.IDepreciationMethod;
|
||||
import org.idempiere.fa.service.api.IDepreciationMethodFactory;
|
||||
|
||||
/**
|
||||
* This is a facade class for the Service Locator.
|
||||
|
@ -517,4 +520,25 @@ public class Core {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* lookup implement {@link IDepreciationMethod}
|
||||
* @param factoryLookupDTO
|
||||
* @return
|
||||
*/
|
||||
public static IDepreciationMethod getDepreciationMethod(DepreciationFactoryLookupDTO factoryLookupDTO) {
|
||||
|
||||
List<IDepreciationMethodFactory> factoryList =
|
||||
Service.locator().list(IDepreciationMethodFactory.class).getServices();
|
||||
if (factoryList != null) {
|
||||
for(IDepreciationMethodFactory factory : factoryList) {
|
||||
IDepreciationMethod depreciationMethod = factory.getDepreciationMethod(factoryLookupDTO);
|
||||
if (depreciationMethod != null) {
|
||||
return depreciationMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.compiere.model;
|
|||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
@ -13,6 +14,8 @@ import org.compiere.util.CLogger;
|
|||
import org.compiere.util.Env;
|
||||
import org.idempiere.fa.exceptions.AssetNotImplementedException;
|
||||
import org.idempiere.fa.exceptions.AssetNotSupportedException;
|
||||
import org.idempiere.fa.service.api.DepreciationDTO;
|
||||
import org.idempiere.fa.service.api.IDepreciationMethod;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -144,7 +147,7 @@ public class MDepreciation extends X_A_Depreciation
|
|||
* @return amortized value
|
||||
*/
|
||||
public BigDecimal invoke(MDepreciationWorkfile assetwk, MAssetAcct assetAcct,
|
||||
int A_Current_Period, BigDecimal Accum_Dep)
|
||||
int A_Current_Period, BigDecimal Accum_Dep, IDepreciationMethod depreciationMethod)
|
||||
{
|
||||
String depreciationType = getDepreciationType();
|
||||
BigDecimal retValue = null;
|
||||
|
@ -164,7 +167,24 @@ public class MDepreciation extends X_A_Depreciation
|
|||
{
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
if (depreciationType.equalsIgnoreCase("SL"))
|
||||
|
||||
if (depreciationMethod != null) {
|
||||
DepreciationDTO depreciationDTO = new DepreciationDTO();
|
||||
depreciationDTO.period = A_Current_Period;
|
||||
depreciationDTO.salvage = assetwk.getA_Salvage_Value();
|
||||
depreciationDTO.totalAmount = assetwk.getA_Asset_Cost();
|
||||
depreciationDTO.useFullLife = new BigDecimal(assetwk.getA_Life_Period());// at the moment, int is ok for Thai, but for other country BigDecima is suitable, need to change AD
|
||||
depreciationDTO.useFullLifeUnit = Calendar.MONTH;
|
||||
depreciationDTO.trxName = assetwk.get_TrxName();
|
||||
depreciationDTO.depreciationId = assetwk.get_ID();
|
||||
depreciationDTO.inServiceDate = assetwk.getA_Asset().getAssetServiceDate();
|
||||
depreciationDTO.accountDate = assetwk.getDateAcct();
|
||||
depreciationDTO.accumulatedCost = assetwk.getA_Accumulated_Depr();
|
||||
depreciationDTO.startPeriodDepreciation = assetwk.getA_Current_Period();
|
||||
depreciationDTO.scale = getPrecision();
|
||||
// calculate expense use implement of IDepreciationMethod
|
||||
retValue = depreciationMethod.caclulateDepreciation(depreciationDTO);
|
||||
}else if (depreciationType.equalsIgnoreCase("SL"))
|
||||
{
|
||||
retValue = apply_SL(assetwk, assetAcct, A_Current_Period, Accum_Dep);
|
||||
}
|
||||
|
|
|
@ -3,10 +3,12 @@ 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 java.util.logging.Level;
|
||||
|
||||
import org.adempiere.base.Core;
|
||||
import org.apache.commons.collections.keyvalue.MultiKey;
|
||||
import org.compiere.util.CCache;
|
||||
import org.compiere.util.CLogMgt;
|
||||
|
@ -16,6 +18,9 @@ import org.compiere.util.Env;
|
|||
import org.compiere.util.TimeUtil;
|
||||
import org.idempiere.fa.feature.UseLife;
|
||||
import org.idempiere.fa.feature.UseLifeImpl;
|
||||
import org.idempiere.fa.service.api.DepreciationDTO;
|
||||
import org.idempiere.fa.service.api.DepreciationFactoryLookupDTO;
|
||||
import org.idempiere.fa.service.api.IDepreciationMethod;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -649,6 +654,28 @@ public class MDepreciationWorkfile extends X_A_Depreciation_Workfile
|
|||
|
||||
truncDepreciation();
|
||||
int A_Current_Period = getA_Current_Period();
|
||||
|
||||
// lookup for implement of IDepreciationMethod
|
||||
DepreciationFactoryLookupDTO depreciationFactoryLookupDTO = new DepreciationFactoryLookupDTO();
|
||||
depreciationFactoryLookupDTO.depreciationType = depreciation_C.getDepreciationType();
|
||||
IDepreciationMethod depreciationMethod = Core.getDepreciationMethod (depreciationFactoryLookupDTO);
|
||||
|
||||
if(depreciationMethod != null) {
|
||||
DepreciationDTO depreciationDTO = new DepreciationDTO();
|
||||
depreciationDTO.useFullLife = new BigDecimal(this.getA_Life_Period());// at the moment, int is ok for Thai, but for other country BigDecima is suitable, need to change AD
|
||||
depreciationDTO.useFullLifeUnit = Calendar.MONTH;
|
||||
depreciationDTO.depreciationId = this.get_ID();
|
||||
depreciationDTO.inServiceDate = this.getA_Asset().getAssetServiceDate();
|
||||
depreciationDTO.accountDate = this.getDateAcct();
|
||||
depreciationDTO.startPeriodDepreciation = this.getA_Current_Period();
|
||||
lifePeriods = (int)depreciationMethod.getCountPeriod(depreciationDTO);
|
||||
|
||||
// it's safe, at the moment, core disable setting of lifePeriods_F
|
||||
lifePeriods_C = lifePeriods;
|
||||
lifePeriods_F = lifePeriods;
|
||||
}
|
||||
|
||||
|
||||
for (int currentPeriod = A_Current_Period, cnt = 1; currentPeriod <= lifePeriods; currentPeriod++, cnt++)
|
||||
{
|
||||
exp_C = Env.ZERO;
|
||||
|
@ -659,24 +686,32 @@ public class MDepreciationWorkfile extends X_A_Depreciation_Workfile
|
|||
if (lifePeriods_C > currentPeriod || !depreciation_C.requireLastPeriodAdjustment())
|
||||
{
|
||||
setFiscal(false);
|
||||
exp_C = depreciation_C.invoke(this, assetacct, currentPeriod, accumDep_C);
|
||||
exp_C = depreciation_C.invoke(this, assetacct, currentPeriod, accumDep_C, depreciationMethod);
|
||||
accumDep_C = accumDep_C.add(exp_C);
|
||||
}
|
||||
else if (lifePeriods_C == currentPeriod)
|
||||
{ // last period
|
||||
if (depreciationMethod != null && depreciationMethod.isPeriodAdjustment()) {
|
||||
exp_C = depreciation_C.invoke(this, assetacct, currentPeriod, accumDep_C, depreciationMethod);
|
||||
}else {
|
||||
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);
|
||||
exp_F = depreciation_F.invoke(this, assetacct, currentPeriod, accumDep_F, depreciationMethod);
|
||||
accumDep_F = accumDep_F.add(exp_F);
|
||||
}
|
||||
else if (lifePeriods_F == currentPeriod)
|
||||
{ // last period (fiscal)
|
||||
if (depreciationMethod != null && depreciationMethod.isPeriodAdjustment()) {
|
||||
exp_C = depreciation_C.invoke(this, assetacct, currentPeriod, accumDep_C, depreciationMethod);
|
||||
}else {
|
||||
exp_F = assetCost.subtract(accumDep_F);
|
||||
}
|
||||
accumDep_F = assetCost;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package org.idempiere.fa.service.api;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* parameter to calculate depreciation
|
||||
* @author hieplq
|
||||
*
|
||||
*/
|
||||
public class DepreciationDTO implements Serializable {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -748366297153525253L;
|
||||
/**
|
||||
* period calculate for
|
||||
*/
|
||||
public int period;
|
||||
/**
|
||||
* remain amount after full depreciation
|
||||
*/
|
||||
public BigDecimal salvage;
|
||||
/**
|
||||
* time to depreciation
|
||||
*/
|
||||
public BigDecimal useFullLife;
|
||||
/**
|
||||
* UOM for {@link #useFullLife}, use constant from {@link Calendar}
|
||||
* accept {@link Calendar#YEAR} {@link Calendar#MONTH} {@link Calendar#DATE}
|
||||
*/
|
||||
public int useFullLifeUnit;
|
||||
/**
|
||||
* date start depreciation
|
||||
*/
|
||||
public Timestamp inServiceDate;
|
||||
/**
|
||||
* date booking, at the moment {@link #inServiceDate} isn't mandatory, in case don't input {@link #inServiceDate}, can use accountDate as {@link #inServiceDate}
|
||||
*/
|
||||
public Timestamp accountDate;
|
||||
/**
|
||||
* date asset transfer to other org.
|
||||
* so days to depreciate of last period of source org like end period of life, it can not full month days
|
||||
* so days to depreciate of first period of destination org like start period of life, it can not full month days
|
||||
*/
|
||||
public Timestamp transferDay;
|
||||
/**
|
||||
* period start to calculate depreciate
|
||||
*/
|
||||
public int startPeriodDepreciation;
|
||||
/**
|
||||
* accumulated when start calculate for {@link #startPeriodDepreciation}
|
||||
*/
|
||||
public BigDecimal accumulatedCost;
|
||||
/**
|
||||
* asset cost
|
||||
*/
|
||||
public BigDecimal totalAmount;
|
||||
|
||||
public int scale = 4;
|
||||
/*** idempiere part ****/
|
||||
|
||||
/**
|
||||
* in case DTO isn't enough or not suitable for your method, use depreciationId to get X_A_Depreciation_Workfile so you can get more relate info
|
||||
*/
|
||||
public int depreciationId;
|
||||
|
||||
/**
|
||||
* name of current transaction
|
||||
*/
|
||||
public String trxName;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.idempiere.fa.service.api;
|
||||
|
||||
/**
|
||||
* pass to {@link IDepreciationMethodFactory} to lookup {@link IDepreciationMethod} implement
|
||||
* @author hieplq
|
||||
*
|
||||
*/
|
||||
public class DepreciationFactoryLookupDTO {
|
||||
public String depreciationType;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.idempiere.fa.service.api;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* implement this interface to provide depreciate calculate method
|
||||
* @author hieplq
|
||||
*
|
||||
*/
|
||||
public interface IDepreciationMethod {
|
||||
/**
|
||||
* calculate depreciation for each period
|
||||
* @param depreciationDTO
|
||||
* @return amount depreciation for {@link DepreciationDTO#period}
|
||||
*/
|
||||
public BigDecimal caclulateDepreciation (DepreciationDTO depreciationDTO);
|
||||
/**
|
||||
* get num of period to depreciation
|
||||
* @param depreciationDTO
|
||||
* @return
|
||||
*/
|
||||
public long getCountPeriod (DepreciationDTO depreciationDTO);
|
||||
/**
|
||||
* support to move all difference by round to end period
|
||||
* @return
|
||||
*/
|
||||
public boolean isPeriodAdjustment ();
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.idempiere.fa.service.api;
|
||||
|
||||
/**
|
||||
* factory for {@link IDepreciationMethod}
|
||||
* @author hieplq
|
||||
*
|
||||
*/
|
||||
public interface IDepreciationMethodFactory {
|
||||
/**
|
||||
* lookup {@link IDepreciationMethod}
|
||||
* @param factoryLookupDTO
|
||||
* @return
|
||||
*/
|
||||
public IDepreciationMethod getDepreciationMethod(DepreciationFactoryLookupDTO factoryLookupDTO);
|
||||
}
|
Loading…
Reference in New Issue