Maintenance For Fixed Assets
Maintenance For Fixed Assets
Maintenance For Fixed Assets
REDHUAN D. OON
Sponsored by Sysnova
June 2011
ADempiere ERP Project
Fixed Assets & Maintenance
Most of the work here was done while encountering Australia for my very first time. The cover photo is taken
while jay-walking around Melbourne when I stayed with Steven Sackett, our ADempiere top contributor ac-
countant. The series of photos on the first chapter are:
1. I find Melbourne a very relaxed and wonderful city, with lots of amenities and a free tram that goes around
the city-centre. I also find many Asians studying or taking over the shops there. This is even more so in Syd-
ney
2. Prices are quite high, though okay if you work and earn there as the minimal wage is the highest at A$15 per
hour. But the appreciated exchange rate (thanks to China buying up their coal and other minerals for the
next 200 years) above the green-bag is hurting general Aussie businesses.
3. It is hard to hide the laid-back culture as Steven took me to his close buddy’s yacht club and look at his two
yachts.
4. At Sydney Harbour, I come into contact with the Stolen Generation for this first time.
5. I Wwoof-ed for the first time ever in Terrey Hills, Sydney, which involved shoveling compost into bags. Here,
my host family member takes the bags onto the truck to sell in the town.
This work stands on the shoulders of many giants and thus the best it can do is to be free for others to stand
back on, ad infinitum.
(www.red1.org)
TABLE OF CONTENTS
About Assets
4
Contributions to ADempiere
4
Gaps in Fixed Assets
5
Create Asset &om Invoice
7
Testing Fixed Assets
17
Getting Fixed Assets
23
Gaps in Asset Maintenance
24
Testing Asset Maintenance
32
Getting Asset Maintenance
34
About Assets
Fixed Assets was originally not present in Compiere during the ADempiere fork in Septem-
ber 2006. What was known as Assets in Compiere that time is just ‘Assetization during
Shipment’ where Customers are tagged as to what products they purchased that we wish to
track by their generated and contolled serial numbers during shipment.
In suit, Asset Maintenance is also not further catered for other than as stated above, they
are tracked by who has owned what via normal purchase and shipment. There are stub fields
for specifying if the asset is owned, depreciated and disposed but nothing further happens
around such information.
Contributions to ADempiere
Fixed Assets that does proper classification was first contributed by Robert Klein:
3. Depreciation formulas
5. Reporting
Robert’s work was integrated into the trunk for some time and is the basis i worked from.
Subsequently the next significant contribution is from Teo Sarca when he was working
from his previous company: Arhipac, Romania. However the framework of items in Fixed
Assets remained largely the same as contributed by Robert Klein. What Teo did was gener-
ally the refactoring of code with more use of Model classes as well as the more important
use of DocType conventions (Prepare and Complete of Documents) that can be eventually
used for WorkFlows.
However these contributions were not maintained and so we find Robert Klein’s work ei-
ther broken in few places or having some gaps. Teo’s work has not been integrated to the
trunk or synchronised with Robert’s, and also has few gaps within it when i was testing it.
My work here under sponsorship from Sysnova of Bangladesh is to do all that and see to
the other contribution called Asset Maintenance from Ramiro of OFBConsulting in
Chile:
I thus made the necessary changes to integrate the latest Fixed Assets and Maintenance to
the latest trunk by way of Carlos Ruiz’s ADempiere361. This should also work with the main
ADempiere project trunk.
Nevertheless the former Fixed Assets worked with its Asset Creation from Invoice (Vendor).
Here i start listing the gaps encountered while upgrading the trunk to Teo’s and when re-
solved or upgraded will go to the QA chapter to go through the tests. I commit to a new
branches/FixedAssets to avoid overiding Teo’s work.
Below is when i first used the trunk base that already has Robert’s work and began putting
in Teo’s code branch. Immediately there were some gaps.
a. Asset Type not accessible by role (just run Role Access Update)
b. Asset Group has no sample data with Accounting Defaults
c. Asset Group Acct has no Depreciation record needed by constraint > ===========>
Trx.commit: POSave_6d48560c-50&-4877-9bac-22aff(b503 [11]
org.postgresql.util.PSQLException: ERROR: insert or update on table "a_asset_group_acct" violates foreign key constraint
"adepreciation_aassetgroupacct"
Detail: Key (a_depreciation_id)=(1000003) is not present in table "a_depreciation".; State=23503; ErrorCode=0 (link to
solution)
3. Missing CalloutAsset. Solved with a blank stub committed in new branch (rev15275).
In order to keep track of the issues and changes raised you can go to the trackers that i
raised and maintained in Fixed Asset Tracker of SourceForge project space:
Many Romanian terms have also been translated wherever found within the code or output.
Teo’s Fixed Assets also does not create Asset from Invoice but via MatchInvoice process as
an lternative approach. Therefore i upgraded Robert’s CreateInvoicedAsset.java to work
with Teo’s better design. The intention is to ensure there is proper and common proof of
concept with such an Asset creation before proceeding further.
i indicated that this is Asset Related and gave the Asset Group. The product was first cre-
ated prior, where i also grouped it to the same Asset Group so that it is considered a real as-
set. I select it as a Capital and the Asset field is left blank as it is not created yet. After it is
created you can use Expense and fill the Asset value for it to charge to.
However the concept of Asset by Teo is based on it as a ‘product’ and not an expense which
according to Steven Sackett of Adaxa is not entirely correct. This bug was recently pointed
out by Steven and thus still present in Teo’s ModelValidator. Thus you cannot charge an ex-
pense to the Asset via this AP Invoice approach yet.
Next you complete the Invoice and then go to the Inbound Charges From AP to create your
Asset.
Oh, one more thing. Your AssetGroup has to have a AssetGroupAccts tab populated to de-
fine this group's life usage, depreciation method and default accounts to post to.
After the Inbound Charges is executed you will get the above Asset window populated. This
window has more tabs than Robert Klein's particularly the Product (AssetProduct) tab and
Expense (DepreciationExpense) tab.
I have to make the extra code to get this populated and it does obtain a new Attribute Set
Instance or Serial No. to attach to this Asset. Note that there are other 3 empty fields. I will
edit the code to populate this too.
By the way, some of these tabs were not supposed to show if the Asset is not to 'depreciate'.
That has an issue as some tabs get corrupted in its display. So i removed all such DisplayLo-
gic - @IsDepreciated@='Y' so now all tabs appear permanently. Later we can try to solve this
small issue.
The Asset Balances is a tab for DepreciationWorkfile. Note the Romanian terms to be
translated and the Update depreciation process button to investigate what it will really do. I
assume that this is a check-sheet to do the real depreciation.
Now the above Accounting Setup only appears when you activate the Show Accounting in
Preferences. This tab shows the Accounting defaults taken from the AssetGroupAccts. This
will be used in the Depreciation processing.
This Activation/Addition (AssetAddition) tab is 'read-only' with a process button too. Also
needing some further investigation. From what i read of the code this document is impor-
tant and referred to in some processes.
The Expense tab (DepreciationExp) takes care of the Journal entries where a pair of records
are created. One record is of contra or minus value to the other record. So in our case we get
another record that has the value '-$120,000'.
There is a Process Depreciation Expense which does the actual accounts posting. However
on pressing it, the class associated, ro.ARH1pac.adempiere.fa.process.A_Depreciation_Exp_Process
is not found. In actual fact that class exist and it is just a typo ARH1 = arhi, and after that it
does run. According to Teo here, it is for single record testing and actual processing is done
in batch.
Below are the other changes that happened after the process. The Asset tab shows its status
changed from NEW to ACTIVATED. The InvoiceLine also shows the Asset ID reference.
For Accounting Consequences, i managed to get it via Post Depreciation Entry window:
The Depreciation Expense report suffers a deep wound here. Thanks to Carlos, it is solved.
Below is a sample report from the trial above. Notice that the first line is ticked green show-
ing it is been processed at the Asset > Expense tab. Not necessarily posted to accounts.
Now there is left only one last matter which is the Disposal of Assets which should be a full
loop.
This is how we do disposals:
1. You use the window Asset Activation/Disposal under the Split Transfers and Disposal
menu.
2. You create a record of the asset you wish to dispose.
2.1 Asset must not have its current month already depreciated or else it will give a "Already
Depreciated" status and not allow it through.
2.2 Asset must be an activated asset with depreciation expense records.
2.3 You cannot change the status manually which will give you the Changed Status error.
3. Give the values in the fields displayed.
4. Press 'Complete'
5. Account tab when active will show 'Posting' button, if it is not automated, you can post it
and view the accounts.
Below is what you should see. In this case i am disposing the Asset after some depreciation,
thus the variance is recorded. You may set the account date to a future date to allow the dis-
posal. Otherwise the system will detect your present period which should not be depreci-
ated yet.
With this we have achieved a close loop process on Fixed Assets and other processes or
needs are workable as there is framework wide integrity.
I noted that Teo's methods are not activated as Rob's methods are still displayed. I managed
to correlate Accelerated Variable and below i test it out.
After Workfile Update Depreciation we get the following Depreciation Expenses records.
There are 48 expense records to depreciate the asset fully. Note that this method starts the
depreciation the 2nd year onwards (see next page). The first period of the year is depreci-
ated according to what percentage we set, which in this case is 5%.
1. Creating Fixed Assets from Invoice. This will create the file data:
A_Asset
A_AssetAccts
A_Depreciation_Workfile
A_Asset_Addition
A_AssetChange
Looking inside the code, the MAsset ckass creates ASI for new Asset beforeSave() and for
creating from MAsset (MInventory inventory, MInventoryLine invLine, BigDecimal qty,
BigDecimal costs) but deprecates away Shipment : MAsset (MInOut shipment, MInOut-
Line shipLine, int deliveryCount)
Menu Call: From Invoice window at InvoiceLine is set Fixed Assets information
Process Name: Inbound Charges &om AP takes those completed invoices to create the
above.
Process classes: There are two classes i looked into. One is the incumbent from Robert
Klein called BuildDepWorkFile. The other is from Teo Sarca's A_Depreciation_Work-
file_Build which i investigated if it properly deprecates Robert's which it is doing. I used
that as the process, upgrading some parts to make it work.
1. BuildDepWorkFile
//1. Delete previous Depreciation Expense records
//2. Initialize Depreciation Workfile records that fit the params
//3. Select where Asset from WorkFile and Depreciation Build falls within params, is depre-
ciated but not fully,
//4. For each Asset Workfile, get its accounting elements for the selected Asset
//5. for each Accounting Element, get its Depreciation and Depreciation Convention
//6. Record booked depreciation expense
//7. Set depreciation date and record in workfile, then save it.
//8. Calculate life to date depreciation
//9. Calculate necessary adjustment per period
v _ D e p _ E x p _ Ad j u s t m e n t =
DepreciationAdj.Dep_Adj(depreciation_method.getDepreciationTy pe(),rs2.getInt("A_Asset_ID") ,
(v_Dep_Exp_Inception.subtract(assetwk.getA_Accumulated_Depr())) , (Math.floor(DateAcctMonth)),
rs2.getString("PostingType") , rs2.getInt("A_ASSET_ACCT_ID"));
Below is the Fitnesse Testing done on Fixed Assets. The code is committed as Fitnesse Fixed
Assets in Project SVN. Note that this test is dynamic allowing to set the Depreciation
Method to be either Straight Line or Variable Accelerated. The duration of Usage Life can
also be set, i.e. 2 years instead of the 20 years in database record for 'Building'.
I processed 2 months or periods of depreciation records. The user can do more by replicating the
rows here and setting the 'Periods From Today' value as shown below.
You can see that 2 set of accounting facts above are produced and the Workfile is at the 2nd pe-
riod with both depreciations accumulated. (Sorry about the accidentally repeated image below.)
You can see in the above history file of the actions that has taken place. During disposal there
should also be a change record 'DIS' but left out in Teo's MAssetDisposed class. This can be im-
plemented by looking at Rob K's AssetDisposed class.
There is a latest FA.jar there to be used. Then you will need to apply the migration scripts
within the folder. There is a Readme text to give the steps.
For testing Fixed Assets, you can checkout the FitnesseFixedAssets and FitnesseStory pro-
jects. Again there is Readme text to guide.
In the testing there is regression testing checks that the ADempiere instance is backward
compatible with 361, Libero Manufacturing and Asset Maintenance. Under the branches/
Maintenance project you can apply the jar and migration scripts and still able to test the
Fixed Assets and backward compatible tests such as ‘Create New Product’, and ‘Make-
ToOrder’s.
This is the cabin that I stayed in for 10 days in the Terrey Hills farm. It
has an open kitchen all stocked up to last me quite well. But still I lost a
good 5 kilos after another 10 days of meditation with vegetarian food
minus dinners up in a Blue Mountains meditation centre.
For a start, as reported here, the 2Pack zip needs a small tweak. A tracker is opened for this.
All work is tracked in this contribution thread. Again, like the module before this, i commit
a fresh branch as Branches/Maintenance in the SVN of the project space.
Instead of 2Pack which is difficult to maintain for ongoing development work i have con-
v e r t e d i t i n t o a c o m p l e t e m i g r a t i o n s c r i p t . ( Fi n d t h a t u n d e r
/migration./../00_Maintenance_2Pack_postgresql.sql}
When the module is finally added to the ADempiere instance, we can get the Menu struc-
ture and the new windows as shown on the next page.
There were numerous errors and bugs in the Maintenance module which is stated and cross
linked in the contribution tracker. A list of the issues with most of them resolved here
http://sourceforge.net/tracker/?func=detail&aid=3311667&group_id=176962&atid=879332.
Here is a note about debugging in Eclipse. You will have the Maintenance project build path
dependent on both FixedAssets and Adempiere. However it may not take the FA's class but
the Adempiere class first. We can set that right by controlling the build output path. You do
that by going to:
After that the CreateInvoicedAsset will run properly (taking from FixedAssets rather than
adempiere361).
We got to the task tab and setup the following specifying the task UOM and duration.
With that done, we can go and define a proper maintenance job that takes from this stan-
dard template we just defined.
Note that we select the right Programming Type that we want. We also set the intervals of
readings. Then at the bottom we select the template we just defined above. This will popu-
late the other tabs with the same information. It is just a copy process or reusing the same
template as a convenience for other jobs that uses the same job specifications. But here in
the maintenance window we now tell the system to take note of the KM reading of an asset
and increment after each job. Users or maintenance crew can then take note of the next
reading to repeat the maintenance job. In the test later we shall see the sample output.
Now we are ready to start the job generation or called the Prognosis process. We do that by
clicking on the icon in the menu with the same name. The following dialog box shall appear.
Press start. You shall see a pop-up window below. The resulting row that appeared is pro-
duced by checking with the current system date, that the time-frame for a work order is due
or within the period defined.
Next you tick the checkbox on the left of the row and click on Generate OT. That shall
produce a work order for our next action.
You can do that by selecting the options in the Status field and choose appropriately. Once
the task is considered completed, you can return to the higher tab and process it. A pop-up
dialog box will appear and just select Complete for DocAction and click on the green tick
button. Note the status and processed boxes are updated as shown below.
Next as promised, we switch the Maintenance system to a calendar based format. We select
that in the Programming Type field below. Note that the column display changes. There is
now a Date last run and a Date next run fields.
Prognosis process will generate the needed tasks to run. Note that the MP and Description
Check the Generate OT box on the left and click on the Generate OT button below.
Then open the Work Order OT window to view the latest work order. Note the text in the
Descripton and as usual you may process the tasks at the Tasks tab and return to this main
tab to Process Now.
The above test data input is setting the Programming Type to be either M (meter) or C
(Calendar) which produces different calculation of maintenance logs.
You can see in the last image below where the maintenance record is requeried to show its
Next Run (for Calendar) and Next MP (for Meter) changed accordingly.
Note that the migration scripts in Branches/Maintenance are split to a new sub folder
‘TestData’ which you apply to get the test data with Asset sample setup. It is so that without
applying them you can run a Fixed Assets regression test which creates a similar Asset from
the same Invoice. This is done so that the user can ascertain the instance is backward com-
patible to Libero Mfg and FA.