Difference between pages "User:Chdrsto" and "User:Trifonnt"

From ADempiere
(Difference between pages)
Jump to: navigation, search
This Wiki is read-only for reference purposes to avoid broken links.
(Quotation)
 
m (BOM price explained.)
 
Line 1: Line 1:
= '''Prozesse''' =
+
{{Userboxtop}}
 +
{{User real name|Trifon Nikolaev Trifonov}}
 +
{{User Bulgaria}}
 +
{{User en}}
 +
{{User bg}}
 +
{{User council}}
 +
{{User IT Consultant}}
 +
{{User developer}}
 +
{{User Sourceforge|http://sourceforge.net/users/trifonnt/}}
 +
{{User Wikipedia|http://en.wikipedia.org/wiki/User:Trifonnt}}
 +
{{Userboxbottom}}
  
{| align="right"
 
  | __TOC__
 
  |}
 
  
= Geschäftsprozesse =
 
== Quotation ==
 
  
In dieser Anleitung wird beschrieben wie ein Angebot für einen Kunden erstellt wird.
+
= About Me =
  
1) Sales Order öffnen
+
I started my own company last year providing Adempiere and Compiere consultancy and development.
 +
I like developing business systems. This makes me headache from time to time, but also makes me very happy when i see system working.
  
Bei einem Angebot handelt es sich um den gleichen Dokumententyp wie beim Kundenauftrag.. Um eine Offerte zu erstellen startet man die Transaktion [[Sales order]] und wählt als Dokumententyp "Quotation" aus.
+
* I'm SUN Certified Programmer 1.4.
 +
* Graduated High School of Economics and Computer Science
 +
* Bachelor degree in Mathematics
  
Transaktion: '''Sales Order'''
+
As a member of ADempiere Council i like to review patches and SVN commits in order to be sure that code remains stable and system functional.
  
[[Image:TX_SalesOrder.png]]
+
== My Blogs ==
 +
* [http://trifonnt.blogspot.com/ My blog in blogspot]
 +
** [http://trifonnt.blogspot.com/2007/08/compiere-begging-of-end.html Compiere - Beginning of the end!] Bye, Bye Compiere Inc. no more Open Source. Actualy you never understood what it really means.
 +
** [http://test-edi.blogspot.com/ EDI test]
  
----
+
* [http://www.jroller.com/trifon My blog in jroller.com]
  
2) Dokumenttyp wählen
+
= Trifon's Paid Services =
  
Um ein Angebot zu erstellen, wählt man im neu geöffneten Fenster [[Sales Order]] unter Target Document Type den Typ [[Quotation]]. Anschliessend
+
== Adempiere customized with client's own brand ==
 +
* Client must send two images.
 +
* Price 200 EURO.
  
'''INFO:'''
+
* Services created for small and mid-sized implementation companies which do not have own java developers and find modifying of source code impossible task.
  
Hat man einen [[Business Partner]] ausgwählt, werden alle im Kundenstamm hinterlegten und verfügbaren Informationen automatisch ergänzt. Bsp:
+
== Adempiere Virtual Appliance ==
<blockquote>
+
* Fully setup and ready to use Adempiere!
* Invoice Partner
+
* Standard users: Garden Admin and Garden Users can send emails!
* Partner Location
+
 
* Invoice Location
+
* VMWare with Linux - Fedora Core - 5/7
* User/Contact
+
* Adempiere
* Invoice Contact
+
* Sun JDK
* Price List
+
* Database - Oracle or Postgres
* Currency
+
* Jakarta James email server
* Payment Rule
+
* Price 45 EURO
* Payment Term
+
 
</blockquote>
+
== On demand Adempiere build ==
Als nächster Schritt speichern.
+
* Build of Adempiere upon user request.
 +
* Price - 125 EUR
 +
* 17 EUR will be donated to Adempiere.
 +
 
 +
Users can donate smaller amount and when 125 EUR is reached a build will be made.
 +
 
 +
* Build can include additional functionality like Fixed Asset or other not included in trunk.
 +
 
 +
== Adempiere DVD by Trifon ==
 +
* DVD with complete Adempiere sources, Eclipse IDE and Sun JDK. Developer need to copy one directory to his local hard drive and can start customizing Adempiere.
 +
* Available version for Linux and Windows.
 +
* Price is: 30 EURO + shipping cost to your place or only 30 EUR and download from FTP Server.
 +
* Jakarta James email server.
 +
* Please contact me if you would like to have it.
 +
 
 +
== Paid Adempiere support ==
 +
* Need urgent advice for your Adempiere implementation or need to talk with experienced Adempiere developer &#45; call now to get friendly help&#46; Ask for Trifon&#46;
 +
* Price is 0.80 EUR per minute
 +
[http://www.skype.com/go/joinskypeprime?call&skypename=trifonnt Use Skype Prime service to call now.]
 +
[http://skypeprime.skype.com/ More info about Skype Prime]
 +
 
 +
* [http://www.bitwine.com/advisors/trifonnt?auid=25850&amp;ctx=button http://www.bitwine.com/presence/1/25850.gif] 0.80 EUR per minute
 +
 
 +
 
 +
* [http://www.ether.com Ether] Another pay per call service
 +
 
 +
== Paid on site Adempiere training ==
 +
* 1500 EUR per week + ticket + hotel
 +
 
 +
* Example training plan
 +
<pre>
 +
1) General overview of Adempiere ERP-CRM system.
 +
2) Introduction to user interface.
 +
3) How to setup new Company in Adempiere.
 +
4) How to setup new Organization in Adempiere.
 +
5) How to create and import Chart of Accounts.
 +
6) How to create new Product and set Product Price and Price List.
 +
7) How to import Products from external sources/systems.
 +
8) How to create Discount Schema and Price List and apply specific discount/overcharge for specific Group/Product, e.t.c.
 +
9) How to create create new Business Partner(Client, Vendor and Employee).
 +
10) How to import Business Partners from external sources/systems.
 +
11) How to create Purchase Order.
 +
12) How to Create Material Receipt.
 +
13) How to create Invoice (Vendor)
 +
14) how to create Sales Order.
 +
15) How to create Shipment (Customer)
 +
16) How to create Shipment Confirmation.
 +
17) How to create Invoice (Customer).
 +
18) How to create Payment.
 +
19) How to match Purchase Order - Material Receipt - Invoice (Vendor).
 +
20) How to match Sales Order - Shipment - Invoice (Customer).
 +
21) How to create Cash Payment and Cash Receipt.
 +
22) How to create Bank Account and Bank transaction.
 +
23) How to modify Print Format of documents.
 +
24) How to setup emails of Adempiere users and send emails with attached document(Purchase Order, Invoice, e.t.c) to clients.
 +
25) How to create Users and assign User permissions.
 +
26) How to setup Window, Tab and Field permissions for specific Roles and Users.
 +
27) How to share data between Organizations and users.
 +
28) How to setup records to be readable only by their creators.
 +
</pre>
 +
 
 +
** http://www.adempiere.com/wiki/index.php/Training_Courses
 +
** http://www.adempiere.com/wiki/index.php/Implementation_Manuals
 +
 
 +
== Paid EDI @ Adempiere support and training ==
 +
* If you need training or support for EDI in Adempiere, please do not hesitate to contact me.
 +
* Prices start from 30 EUR per hour.
 +
 
 +
== Paid [http://www.liferay.com Liferay] setup and extensions development ==
 +
* Leading Open Source Enterprise Portal
 +
* JSR-168 compliant
 +
* Business Friendly Open Source License: MIT License
 +
 
 +
 
 +
== Paid OpenXava Development ==
 +
* Development of custom applications based on [http://www.gestion400.com/web/guest/openxava OpenXava framework].
 +
 
 +
* Suitable for:
 +
** Small applications which need to be developed from scratch
 +
** Development of applications which must be part of a [http://en.wikipedia.org/wiki/Web_portal Web Portal].
 +
** Applications based on OpenXava can run on any DB which is supported by [http://www.hibernate.org/ Hibernate].
 +
** Licensed under LGPL. You can develop commercial application using OpenXava.
 +
 
 +
* Features:
 +
** Applications based on OpenXava can choose [http://en.wikipedia.org/w/index.php?title=Enterprise_JavaBean#EJB_3.0.2C_final_release_.282006-05-02.29 EJB3 JPA], [http://www.hibernate.org/ Hibernate] or [http://en.wikipedia.org/w/index.php?title=Enterprise_JavaBean#EJB_2.1.2C_final_release_.282003-11-24.29 EJB2 CMP] as persistence engine.
 +
 
 +
** Applications based on OpenXava have [http://en.wikipedia.org/wiki/Multitier_architecture Multitier architecture] or [http://en.wikipedia.org/wiki/Client-server_architecture Client-server architecture].
 +
 
 +
** Applications based on OpenXava can run on any application server (Tomcat, JBoss, WebSphere, etc).
 +
 
 +
** Applications based on Openxava have easy integration of reports made with JasperReports.
 +
 
 +
=== Trifon's contributions to OpenXava ===
 +
 
 +
* [http://sourceforge.net/tracker/index.php?func=detail&aid=1749402&group_id=123187&atid=695746 1749402 - GUI display field size]
 +
 
 +
* [http://sourceforge.net/forum/forum.php?thread_id=1755705&forum_id=419691 Bulgarian flag]
 +
 
 +
* [http://sourceforge.net/tracker/index.php?func=detail&aid=1784323&group_id=123187&atid=695746 1784323 - Generate constant PROPERTY_Xxx in java interfaces] Will be part of OpenXava 2.2.2 release.
 +
 
 +
* Please contact me for quotation.
 +
 
 +
== Paid Java Development ==
 +
* Development of java applications.
 +
* Please contact me for quotation.
 +
 
 +
= Trifon's projects based on Compiere/Adempiere =
 +
 
 +
== Project 0 (area: Supply Chain Management) ==
 +
<pre>
 +
 
 +
Migrated from Microsoft Access based application to Compiere ERP-CRM
 +
Company is the biggest distributor of newspapers in Bulgaria.
 +
Huge migration effort.
 +
Imported definitions of:
 +
Vendors, Customers, Sales Agents, Products, Price Lists, Accounts, Purchase Orders, Sales Orders, Billing addresses, Warehouses.
 +
Imported ~  20 000 Product definitions.
 +
Imported ~ 100 000 Purchase Orders.
 +
Imported ~ 100 000 Sales Orders.
 +
Developed new module in Compiere ERP-CRM in order to fit company needs in Product Distribution area.
 +
Developed mobile application and data synchronization module for real time tracking of products.
 +
Implemented:
 +
Product Attributes, Purchase Orders, Material Receipts, Invoices (Vendor), Sales Orders, Shipments, Invoices (Customer), Warehouse management, Price Lists, Accounting, Discount Schema.
 +
</pre>
 +
 
 +
 
 +
== Project 1 (area: ERP) ==
 +
<pre>
 +
Migrated from 20 years old application to Compiere ERP-CRM.
 +
Huge effort in import of data from legacy system.
 +
Imported definitions of:
 +
Vednors, Customers, Sales Agents, Products, Price Lists, Accounts, Purchase Orders, Sales Orders, Shippers, Billing addresses, Discount Schema.
 +
Developed import functionality in Compiere ERP-CRM.
 +
Developed Slading Scale Commissions in Compiere ERP-CRM.
 +
Developed Bill of Ladding in Compiere ERP-CRM.
 +
 
 +
Implemented:
 +
Purchase Orders, Material Receipts, Invoices (Vendor), Sales Orders, Shipments, Invoices (Customer), Warehouse management, Price Lists, Accounting.
 +
</pre>
 +
 
 +
 
 +
== Project 2 (area: ERP) ==
 +
<pre>
 +
Migrated from Microsoft Solomon to Compiere ERP-CRM.
 +
Fast migration path.
 +
Imported definitions of:
 +
Vendors, Customers, Products, Accounts.
 +
Developed better user interface to fit needs of users used to work with Microsoft Solomon.
 +
Developed export from Compiere ERP-CRM to People Soft system.
 +
Improved traceability of Orders to fit needs of purchasing agency.
 +
 
 +
Implemented:
 +
Purchase Orders, Material Receipts, Invoices (Vendor), Sales Orders, Shipments, Invoices (Customer), Warehouse management, Price Lists, Accounting.
 +
</pre>
 +
 
 +
 
 +
== Project 3 (area: Supply Chain Management) ==
 +
<pre>
 +
Extension for Compiere MFG-SCM project.
 +
Developed java application for java enabled mobile phones.
 +
Developed web application.
 +
Developed connection module that enables data scanned with bluetooth enabled barcode scanner to be transferred to mobile phone and after that to web application.
 +
Application allows factory to track in real time product/part availability.
 +
Used Java, JSP, Servlet, AJAX and J2ME technologies.
 +
</pre>
 +
 
 +
= Trifon's Recent thoughts =
 +
 
 +
== Open Source’s Missed Opportunity ==
 +
* [http://www.thevarguy.com/2008/01/14/open-sources-missed-opportunity/ Open Source’s Missed Opportunity] Interesting post from The VAR Guy
 +
 
 +
[[User:Trifonnt|Trifonnt]] 03:07, 18 January 2008 (EST)
 +
 
 +
 
 +
== Requirements of very small companies ==
 +
* [https://sourceforge.net/forum/message.php?msg_id=4676521 sf.net]Interesting post from OpenBravo forums.
 +
 
 +
== How customers should approach Open source vendor ==
 +
Very good post from Matt Asay
 +
* [http://blogs.cnet.com/8301-13505_1-9832883-16.html link]
 +
 
 +
 
 +
Yes, I get quite a few requests to have Alfresco integrate with JBoss and Liferay, and I've done business with both. But I didn't need a committee to tell me that. Customers did. Customers have yet to request integration with Compiere, for example, so we haven't done it. Someday we probably will. But when customers vote with dollars.
 +
 
 +
 
 +
== Interesting requirement: Map Your Contacts By Region ==
 +
* [http://www.sugarcrm.com/forums/showthread.php?p=93524#post93524]
 +
 
 +
 
 +
Select a group of accounts based on geography...let's say all accounts in Texas. Then be able to map those accounts on an interactive map that will show the locations of each of those accounts as push pins. When you roll over each push pin, it pops up the name of the account and any specified modules like opportunities, calendar etc. Another cool feature would be select any two accounts to calculate the distance/drive time and even download directions.
 +
 
 +
[[User:Trifonnt|Trifonnt]] 02:07, 11 December 2007 (EST)
 +
 
 +
 
 +
== Number of Adempiere developers ==
 +
11 December 2007.
 +
 
 +
Adempiere has 56 registered developers in sf.net.
 +
 
 +
[[User:Trifonnt|Trifonnt]] 02:07, 11 December 2007 (EST)
 +
 
 +
== Risk to be Open Source developer ==
 +
Here i will try to identify some of the negative sides of being Open Source developer. This are real examples which happen to me and make me sad.
 +
 
 +
* Help a user and after few days/weeks/months receive a spam message from the company where user work or from him personally.
 +
** NEVER help a user in private emails. Private emails are for paid support only! RULE NUMBER ONE.
 +
 
 +
* Many times colleagues or other people tell me that i must increase my prices. It sounds quite good as advice, but the bad side is when they start working with you they are not so happy to pay you recommended by them price. ALWAYS RESPECT YOUR PRICE! RULE NUMBER TWO.  It is your price which is good for you and under your conditions.
 +
 
 +
[[User:Trifonnt|Trifonnt]] 14:43, 1 November 2007 (EDT)
 +
 
 +
== Idea for additional meta data: AD_Table NamedQuery ==
 +
JPA has very nice feature 'Named Query'. It would make Application Dictionary more reach if Adempiere has such feature. This idea is very near to Finders, but it allows more wide range of queries.
 +
[[User:Trifonnt|Trifonnt]] 19:17, 26 October 2007 (EDT)
 +
 
 +
 
 +
== Idea for additional java interface: DocumentConversion ==
 +
Adempiere ERP-CRM has processes which generate new document from existing document. For example Generate Invoice from Sales Order. This are quite useful processes, but currently they are not designed with the idea for extendability's. For example if user define new fields in  Sales Order and would like to see values of this fields transfered to Invoice and Shipment later then he must modify source code of GenerateInvoice and GenerateShipment processes. This is not easy and i think that design can be improved. Possible improvements:
 +
* Define new java interface and invoke classes which implement this interface. This require changes in existing GenerateXxx classes.
 +
* Define new structure in Application Dictionary which will describe which fields must be transfered during Document Generation process.
 +
[[User:Trifonnt|Trifonnt]] 17:59, 26 October 2007 (EDT)
 +
 
 +
 
 +
== Data Services ==
 +
Rob Cardwell has very interesting article: [http://www.alignjournal.com/index.cfm?section=article&aid=139 Data Services: A Fundamental Building Block of SOA].
 +
 
 +
In middle of this article i found that Adempiere has this beautiful functionality.
 +
<pre>
 +
This approach requires tools that can capture existing data structures from reverse-engineered relational database schema's, and can map these existing structures into more business-oriented data views.
 +
</pre>
 +
 
 +
Adempiere AD(Application dictionary) on which all tables and windows are based provides meta data for all data structures in the system and even for all graphical components! But with Adempiere user do not need to reverse-engineer database system, all data structures have business oriented view by design.
 +
 
 +
[[User:Trifonnt|Trifonnt]] 22:51, 28 September 2007 (EDT)
 +
 
 +
 
 +
== Why fights in Open Source projects are bad? ==
 +
Link to Adempiere post: [https://sourceforge.net/forum/message.php?msg_id=4501509 here]
 +
 
 +
== What an ERP system MUST NOT allow user to do? ==
 +
Recently i read a urgent [https://sourceforge.net/forum/message.php?msg_id=4499883 post] in OpenBravo forum.
 +
<pre>
 +
i have deleted "big bazzar and System", the default clients and i can't enter to OpenBravo now what is the solution?
 +
</pre>
 +
 
 +
Interesting? This sounds like:
 +
<pre>
 +
i have deleted "Local Disk C and D" and i can't enter my windows system what is the solution?
 +
</pre>
 +
 
 +
One of the most valuable ideas in Compiere is IsActive column and restriction to delete records in most of the tables. It is good if user can delete some Client, but System records must never be deletable!
 +
This makes another question to me. Is ERP for every user? My answer at this moment is NO. User who implement ERP must be very careful, conscious and most importantly must always make backup of data.
 +
 
 +
[[User:Trifonnt|Trifonnt]] 17:01, 4 September 2007 (EDT)
 +
 
 +
 
 +
== OpenBravo Green? ==
 +
Recently OpenBravo Green came into my mind(Jordi Mash told me about OpenBravo Green at Adempiere conference in Belrin) and i decided to review it and to check status.
 +
 
 +
First of all they have good document with intentions and requirements. Good number of frameworks and technologies are listed at this page:
 +
[http://wiki.openbravo.com/wiki/index.php/Design_principles_for_Openbravo_Green Design principles for Openbravo Green]
 +
 
 +
They have a prototype and online demo, but i failed to login into demo page.
 +
[http://demo.openbravo.com/green/ OpenBravo Green demo]
 +
 
 +
Source code of prototye was more interesting for me and it was the reason that made me write this post.
 +
 
 +
* I expected to see more commnents and more TODOs. It is prototype and important is to see what developer intend to do than what has been done. Visibility of ideas and intentions is more important than actual work finished. This is not a minus it is just a note and wish from my side.
 +
 
 +
* Source code dissapointed me, because:
 +
** I saw one regular web based application. No trace from the idea of Model Driven Architecture or Application dictionary. Probably model classes were generated by some tool, but no evidence or comment in the code or in the wiki pages.
 +
** Only one author, no participataion from community.
 +
** Author is Adrian Romero, who is very good POS developer(Tina POS), but i doubt about his experience in ERP systems and Application Driven systems. It looks that he is the only active visible OpenBravo developer.
 +
 
 +
 
 +
== Adempiere: Which is first Data or Code? ==
 +
Recently i modified very deeply core of Adempiere in order to simplify development and to speed it up. I wasn't sure that such modification is possible and i was very happy when it happened and when at the end it even worked. After some tests i decided to revert to old version of persistent classes (X_xxx) and i deleted newly generated classes and started well known old GenerateModel, but... It failed because GenerateModel needs persistent classes in order to connect to Database. But developer can't generate persistent classes because GenerateModel can't connect to DB. So we got cycle... And here comes my question: Which is first Data or Code?
 +
I think that design of GenerateModel can be improved:
 +
 
 +
* In order to connect to DB it should not need Adempiere Client.
 +
* Data from DB can be moved to external location like (CSV or xml file), but this could creation duplication of data(stored in DB and in file). Not so good idea.
 +
** CsvJdbc is a good driver which can be used to query CSV files like DB tables: [http://csvjdbc.sourceforge.net/ CsvJdbc - a JDBC driver for CSV files]
 +
** xlSQL Excel JDBC Driver is another alternative [http://xlsql.sourceforge.net/ xlSQL Excel JDBC Driver]
 +
** Super CSV [http://supercsv.sourceforge.net/ Super CSV sf.net page]
 +
** Jxcell [http://www.jxcell.net/index.htm www.jxcell.net]Paid!
 +
** Xelem [http://xelem.sourceforge.net/index.html xelem.sourceforge.net]
 +
 
 +
 
 +
[[User:Trifonnt|Trifonnt]] 12:55, 19 August 2007 (EDT)
 +
 
 +
== Does Community Open Source project need roadmap? ==
 +
* What does Roadmap means for a project?
 +
* [http://www.google.com/search?as_q=define%3ARoadmap&hl=en&num=10&btnG=Google+Search&as_epq=&as_oq=&as_eq=&lr=&as_ft=i&as_filetype=&as_qdr=all&as_nlo=&as_nhi=&as_occt=any&as_dt=i&as_sitesearch=&as_rights=&safe=images Goolge define:Roadmap] says few things, but i like mostly one of them:
 +
<pre>
 +
A program for future development indicating what will be developed and when.
 +
</pre>
 +
My opinion is that it must be more like:
 +
<pre>
 +
A program for future development indicating what will be developed, by who will be developed and when.
 +
</pre>
 +
 
 +
* Three very important conditions in order to have Roadmap:
 +
 
 +
** Functionality
 +
This is easy to be done. All we need functionality and all we with pleasure advice what to be done. So i think that here ANY project can produce good number of items.
 +
 
 +
** Who will develop it?
 +
UPS, here the problems come. In order to develop something WE need knowledge, so from the big list of ALL only developers can participate in development. All this means that in Roadmap, Open Source project must identify developers or companies that will create new functionality. Ok, let's say that i would like to build this new functionality and i write my name against the feature.
 +
 
 +
** When functionality will be developed?
 +
Who knows? Who can answer? Who is responsible?
 +
It looks that WHEN brings more question than it answers. In Open Source project if no one commit his time to develop given functionality no one can answer the questions. Moreover if someone commit his free time does anyone has rights to push him for specific date? I do not think so... It is developers free will to participate and create functionality. And as you guess in most of the time it is hard to find free time for building big functionality.
 +
 
 +
My personal opinion is that spending time to create Roadmap without committed developers/companies against specific functionality is just good wast of time. Even worst it is confusing for the end user who read Roadmap and wait for new version and new functionality.
 +
 
 +
My big excuse to the users who will be frustrated from ssch Roadmaps.
 +
[[User:Trifonnt|Trifonnt]] 19:31, 8 August 2007 (EDT)
 +
 
 +
== To be Adempiere Developer or Adempiere Businessman(Seller) ==
 +
I work with Adempiere/Compiere since more than 3 years. I must say that i like the product and area very much. I like to develop extensions for Adempiere and i do it everyday for 10-12 hours a day and sometimes more. I know it is not healthy, but...
 +
But last weeks i started to feel tired from all the rules for Developers and all fights in forums and in email lists. Also i realized that Business people around Adempiere do not have such limitations as Developers. For example:
 +
 
 +
* On [http://www.adempierebusiness.com/ www.adempierebusiness.com] there are 30 registered Implementation Partners. Good number.
 +
** What does this Implementation Partners give to Adempiere project?
 +
Some of them nothing. Well business people say that if we limit and ask for money then this will stop add option of Adempiere. But may i ask how developers can survive?
 +
** What they get?
 +
FREE Advertisement. Perfect... I think that Adempiere is the only project that allows such thing. Most of other Open Source projects take money for advertisement and put money back into the project.
 +
 
 +
* I have read that some of Adempiere Implementation Partners do not work for less than 50 000 USD. Amount which i as developer do not had chance to see till now. Who knows someday Clients may find that contracting developer is much faster and cheaper...
 +
 
 +
* User expect developers to provide FREE help in Adempiere forums, which gives additional workload to developers.
 +
 
 +
* Developers are expected to be open and expose all their information to community.
 +
 
 +
So:
 +
* I found that i had made mistake.
 +
It looks that to be Businessman and make money around Adempiere is much easy and painless than to be Adempiere developer. :(
 +
* I think to reconsider my role in Adempiere project. Role of Implementation Partner looks much safer and giving more incomes.
 +
* I should start making advertisements from now... So here it is: I can provide Adempiere on Site Implementation for 1500 EURO / week + expenses(hotel + ticket) in case i need to move to other location.
 +
 
 +
= Adempiere trackers =
 +
 
 +
== Submitted by Trifon and Assigned to Trifon ==
 +
:*{{User:Hengsin/SF_Tracker|Bugs|trifonnt|879332}}
 +
:*{{User:Hengsin/SF_Tracker|Contributions|trifonnt|883808}}
 +
:*{{User:Hengsin/SF_Tracker|Feature Requests|trifonnt|879335}}
 +
:*{{User:Hengsin/SF_Tracker|Patches|trifonnt|879334}}
 +
 
 +
== Assigned to Trifon ==
 +
:*{{User:Hengsin/SF_Contribution|Bugs|195397|879332}}
 +
:*[http://sourceforge.net/tracker/index.php?group_id=176962&atid=883808&_category=100&_group=100&order=artifact_id&sort=DESC Contributions]
 +
:*{{User:Hengsin/SF_Contribution|Feature Requests|195397|879335}}
 +
:*{{User:Hengsin/SF_Contribution|Patches|195397|879334}}
 +
 
 +
== Adempiere contributions ==
 +
 
 +
=== Functionality Contributions ===
 +
 
 +
==== EDI @ Adempiere - [[Sponsored Development: EDI Import/Export]] ====
 +
 
 +
* [http://www.stylusstudio.com/convert_edi_to_xml.html Convert EDI to XML]
 +
 
 +
==== Replication @ Adempiere - [[ Sponsored Development: Replication]] ====
 +
 
 +
* Links:
 +
* [http://www.afceurope.com/JMS.html http://www.afceurope.com/JMS.html]
 +
* [http://www.manageability.org/blog/stuff/open-source-jms-java Open Source JMS (Java Message Service) Implementations]
 +
* [http://www.theserverside.com/tt/articles/article.tss?l=IntegratingPresenceJ2EEEnvironments Integrating Presence into J2EE Environment]
 +
 
 +
* [http://hermesjms.com/confluence/display/HJMS/Home HermesJMS]A console that helps you interact with JMS providers making it easy to browse or seach queues and topics, copy messages around and delete them.
 +
 
 +
* [http://www-128.ibm.com/developerworks/library/i-jms/ Example the Replication with JMS]
 +
 
 +
* [http://openjms.sourceforge.net/usersguide/using.html Use the JMS Synchrony and Asynchrony ]
 +
 
 +
* [http://www.javalobby.org/articles/distributed-jms/ Using JMS For Distributed Software Development]
 +
 
 +
* [http://www.onjava.com/lpt/a/951 Developing a Simple JMS Example]
 +
 
 +
 
 +
JMS @ Salesforce.com:
 +
* [http://www.webservices.org/categories/development/interoperability/strikeiron_introduces_web_services_via_salesforce_com_s_appexchange/(go)/Articles
 +
 
 +
* Status: [http://community.salesforce.com/sforce/board/message?board.id=JAVA_development&message.id=3516 feature is called Outbound Messaging and will be in Winter 07]
 +
 
 +
* [http://www.tibco.com/resources/company/partners/integration_bundle_salesforce_ds.pdf TIBCO and salesforce.com]
 +
 
 +
* [http://wiki.apexdevnet.com/index.php/Enterprise_Integration_Series salesforce.com Enterprise Integration Series]
 +
 
 +
 
 +
====  Swing POS @ Adempiere - [[Sponsored Development: Swing POS]] ====
 +
 
 +
==== Simplify and Speedup Adempiere development ====
 +
SF.NET forum post [http://sourceforge.net/forum/forum.php?thread_id=1804539&forum_id=610548 here]
 +
 
 +
Feature Requests:
 +
* [http://sourceforge.net/tracker/index.php?func=detail&aid=1772015&group_id=176962&atid=879335 1772015 Generate java Interface and implementation instead of X_ classes]
 +
 
 +
* [http://sourceforge.net/tracker/index.php?func=detail&aid=1777239&group_id=176962&atid=879335 1777239 Refactor PO class: save() to be static method]
 +
 
 +
This enhancement allows Adempiere developers to:
 +
* Speedup thier day to day work and to have more Object friendly code.
 +
* Work with Java Interfaces instead of Java Classes.
 +
 
 +
For example:
 +
 
 +
** Adempiere - Old code
 +
<pre>
 +
Trx trx = Trx.get(Trx.createTrxName("Test"), true);
 +
trx.start();
 +
 
 +
MAlert alertOldWay = new MAlert(Env.getCtx(), 100, trx.getTrxName());
 +
log.info(alertOldWay.toString());
 +
 +
X_AD_AlertProcessor alertProcessorOldWay = new X_AD_AlertProcessor(Env.getCtx(), alertOldWay.getAD_AlertProcessor_ID(), trx.getTrxName());
 +
log.info("alertProcessorOldWay.getAD_AlertProcessor_ID = " + alertProcessorOldWay.getAD_AlertProcessor_ID());
 +
 
 +
alertOldWay.setDescription("Trifon test");
 +
//--- Save;
 +
resultSave = alertOldWay.save();
 +
log.info("resultSave = " + resultSave);
 +
 +
System.out.println("New value of Description = " + alertOldWay.getDescription());
 +
 
 +
trx.commit();
 +
trx.close();
 +
</pre>
 +
 
 +
** Adempiere - New code
 +
<pre>
 +
Trx trx = Trx.get(Trx.createTrxName("Test"), true);
 +
trx.start();
 +
 
 +
I_AD_Alert alert = new MAlert(Env.getCtx(), 100, trx.getTrxName());
 +
log.info(alert.toString());
 +
 
 +
I_AD_AlertProcessor alertProcessor = alert.getI_AD_AlertProcessor();
 +
log.info("I_AD_AlertProcessor.getAD_AlertProcessor_ID = " + alertProcessor.getAD_AlertProcessor_ID());
 +
 
 +
alert.setDescription("Trifon Description modified!");
 +
//--- Save; PO.save(PO) must be static method!!! Two way of usage: PO.save(Object) or PO.save(PO)
 +
//resultSave = PO.save((PO)alert);
 +
resultSave = PO.save(alert);  // Overloaded save method; For simple usage!
 +
log.info("resultSave = " + resultSave);
 +
 +
System.out.println("New value of Description = " + alert.getDescription());
 +
 
 +
trx.commit();
 +
trx.close();
 +
</pre>
 +
 
 +
This modificationas make Adempiere code closer to [http://www.hibernate.org/ Hibernate]
 +
** Hibernate code. Example code from [http://www.hibernate.org/hib_docs/reference/en/html/tutorial.html here].
 +
<pre>
 +
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
 +
 
 +
session.beginTransaction();
 +
 
 +
Event theEvent = new Event();
 +
theEvent.setTitle(title);
 +
theEvent.setDate(theDate);
 +
 
 +
session.save(theEvent);
 +
 
 +
session.getTransaction().commit();
 +
</pre>
 +
 
 +
Proposed by Hengsin modification:
 +
* [http://en.wikipedia.org/wiki/Active_record_pattern Active record pattern]
 +
* [http://blog.emmanuelbernard.com/2007/01/activerecord-pattern-so-what.html  ActiveRecord pattern, so what?]
 +
 
 +
Add second interface I_Persistent with one method save()
 +
<pre>
 +
public interface I_Persistent {
 +
public boolean save();
 +
}
 +
</pre>
 +
 
 +
 
 +
* Using the coding pattern below instead of the old new MAlert(Env.getCtx(), 100, trx.getTrxName()) approach would ensure your code always using the correct model class.
 +
 
 +
How to load:
 +
<pre>
 +
// to load existing record
 +
int AD_Alert_ID = 100;
 +
MTable table = MTable.get(Env.getCtx(), I_AD_Alert.Table_ID);
 +
I_AD_Alert alert = (I_AD_Alert)table.getPO(AD_Alert_ID, trxName);
 +
 
 +
</pre>
 +
 
 +
How to create new record:
 +
<pre>
 +
// to create new record
 +
MTable table = MTable.get(Env.getCtx(), I_AD_Alert.Table_ID);
 +
I_AD_Alert alert = (I_AD_Alert)table.getPO(0, trxName);
 +
...
 +
</pre>
 +
 
 +
 
 +
* Classes which override save() method:
 +
<pre>
 +
org.compiere.process.DocActionTemplate
 +
org.compiere.model.MClient
 +
org.compiere.model.MClientInfo
 +
org.compiere.model.MSystem
 +
</pre>
 +
 
 +
Generated Model class must implement both interfaces and extend PO.
 +
 
 +
Weak sides that need to be improved:
 +
* Hard coded Document Engine
 +
* Hard coded lookup of model class
 +
* Hard coded list of document type for new client
 +
* Incomplete Security Implementation
 +
* No plugin/module support. Both ADCK and 2Pack support dynamic deployment of AD changes but doesn't address the need to deploy java code extension ( especially problematic/messy if your extension needs to use additional third party library).
 +
* Incomplete web client port
 +
* Incomplete workflow engine implementation
 +
* Various swing client bug and limitation
 +
 
 +
===== Links =====
 +
* [http://blog.springframework.com/markf/archives/2006/03/22/pojo-aspects-in-spring-20-a-simple-example/ POJO Aspects in Spring]
 +
* [http://www.jdocs.com/hibernate/2.1.8/net/sf/hibernate/persister/ClassPersister.html Hibenrate ClassPersister interface]
 +
* [http://www.koders.com/java/fid2E46C5E6D43D933CBC3E4E7E63EE7DEAE6853542.aspx org.hibernate.test.CustomPersister]
 +
 
 +
=== Planned Contributions and Tasks ===
 +
* [https://sourceforge.net/forum/forum.php?thread_id=1748020&forum_id=611167 sf.net thread regarding Pentaho training]
 +
* [[Adempiere GUI Enhancements]]
 +
 
 +
* Restrict form "Generate Invoices (manual)" to show only public records (hide locked records) [http://sourceforge.net/tracker/index.php?func=detail&aid=1713337&group_id=176962&atid=879332 BUG - 1713337]
 +
 
 +
* Restrict form "Generate Shipments (manual)" to show only public records (hide locked records) [https://sourceforge.net/tracker/index.php?func=detail&aid=1713317&group_id=176962&atid=879332 BUG - 1713317]
 +
 
 +
== Interesting bugs/patches/Feature Requests ==
 +
* [https://sourceforge.net/tracker/?func=detail&atid=879332&aid=1721710&group_id=176962 1721710 Changing BPartner in a completed document should be denied]
 +
* [https://sourceforge.net/tracker/index.php?func=detail&aid=1722049&group_id=176962&atid=879332 1711594 Workflow is not taking account of "Access All Orgs"]
 +
* [https://sourceforge.net/tracker/?func=detail&atid=879332&aid=1704785&group_id=176962 1704785 VFile is not firing Vetoable Change]
 +
 
 +
Feature Requests
 +
* [https://sourceforge.net/tracker/?func=detail&atid=879335&aid=1776484&group_id=176962 Adempiere Google Gadgets]
 +
 
 +
= My favorite readings =
 +
== General ==
 +
* [http://www.onlamp.com/lpt/a/7005 Tools for Geographically Distributed Software Development]
 +
* Geocode
 +
** [http://googlemapsapi.blogspot.com/2006/06/geocoding-at-last.html Geocoding at last!]
 +
 
 +
* [http://www.oasis-open.org/committees/ciq/ciq.html#6 OASIS Customer Information Quality Committee]
 +
* [http://www.timeanddate.com/ Time and zone info]
 +
* [http://coinmill.com/ Currency convert]
 +
 
 +
 
 +
* [http://www.x-rates.com Exchange Rates]
 +
* [http://ist.berkeley.edu/as/ag/tools/usage/svn-govern-commit-permission.html SVN Repositories: Governing Commit Permissons]
 +
* [http://www.barcodeman.com/faq/2d.php 2d Barcode explained]
 +
** [http://reader.kaywa.com/ Reader for Mobile phones with java]
 +
 
 +
* [http://openqa.org/selenium/ OpenQA - Selenium] a test tool for web applications. Selenium tests run directly in a browser, just as real users do.
 +
 
 +
* [http://winmerge.org/ WinMerge] My favorite diff tool.
 +
 
 +
* [https://inmail24.com email] offer IMAP access
 +
 
 +
* [http://www.alignjournal.com Align Journal]
 +
* [http://www.bgoncalves.com/notes/2007/10/03/setting-up-your-very-own-subversion-repository/ Setting up your very own Subversion repository]
 +
* Open Office interesting
 +
** [http://www.linux.com/feature/119718 A simple task manager for OpenOffice.org]
 +
** [http://www.linux.com/feature/119245 Adding a basket tool to OpenOffice.org]
 +
 
 +
* Google Web Toolking - interesting
 +
** [http://timepedia.blogspot.com/2007/10/designing-really-simple-gwt-accordion.html Designing a really simple GWT Accordion control]
 +
 
 +
* [http://www.businesscreditcards.com/bootstrapper/the-100-tools-freelancers-cant-live-without/ The 100 Tools Freelancers Can’t Live Without]
 +
 
 +
* [http://persony.net/purchase/ PERSONY]WEB Conference software.
 +
 
 +
* [http://www.rootsweb.com/~bgrwgw/researchguide/tips.html Bulgarian alphabet] Bg alphabet and it's transcript into Latin Alphabet
 +
* [http://www.studybulgarian.com/Bulgarian%20alphabet.htm THE BULGARIAN ALPHABET] Bg alphabet and it's transcript into Latin Alphabet
 +
 
 +
 
 +
* [http://dnes.dir.bg/2007/11/03/news2284792.html BANKRUPTCY of Communism]In Bulgarian.
 +
 
 +
== Interesting ==
 +
* [http://www.readingcpl.com/activity-based-costing/2007/05/variable-costing-direct-costing-marginal-costing.php  Variable Costing/Direct Costing/Marginal Costing]
 +
* [http://martinfowler.com/articles/languageWorkbench.html Martin Fowler; Language Workbenches: The Killer-App for Domain Specific Languages?]
 +
* [http://buildix.thoughtworks.com/ Continuous Integration, Source Control, a Wiki and a Bug-Tracker; by ThoughtWorks]
 +
* [http://www.businessweek.com/innovate/content/feb2007/id20070215_251519.htm?chan=globalbiz_europe_the+businessweek+wikinomics+series Ideagoras]
 +
* [http://www.eureka.be/contacts/AcFindContact.do?memId=BG Eureka - A network for market oriented R&D]
 +
* [http://portableapps.com/ Portable Applications] Way to run applications from USB.
 +
* [http://sourceforge.net/projects/freedict/ Free Dictionary]The data is kept as XML complying to the TEI DTD.
 +
* [http://www.manageability.org manageability] Site with categorized open source applications
 +
 
 +
 
 +
=== Pivot Tables ===
 +
* [http://video.about.com/spreadsheets/Create-Excel-Pivot-Tables.htm How to create Pivot tables in Excel]
 +
* [http://www.cpearson.com/excel/pivots.htm Another guide to Excel Pivot tables]
 +
* [http://www.linuxjournal.com/node/1000252 OpenOffice.org Calc: Pivot tables by another name]
 +
* [http://www.learnopenoffice.org/CalcTutorial33.htm Open Office - Using the data pilot]
 +
* [http://jpivot.sourceforge.net/ JPivot]JSP custom tag library that renders an OLAP table and let users perform typical OLAP navigations like slice and dice, drill down and roll up. It uses Mondrian as its OLAP Server. JPivot also supports XMLA datasource access.
 +
 
 +
 
 +
=== Mozilla - Firefox Extensions ===
 +
* [http://www.foxmarks.com/ FoxMark - The Bookmark Synchronizer]
 +
* [https://addons.mozilla.org/en-US/firefox/addon/673 InFormEnter adds a small, clickable icon next to every input field in a web form, from where you can select the item to be inserted]
 +
* [https://addons.mozilla.org/en-US/firefox/addon/60 Web Developer - Adds a menu and a toolbar with various web developer tools.]
 +
* [https://addons.mozilla.org/en-US/firefox/addon/824 XForms support for Firefox and Mozilla] A must have Add-on.
 +
* [http://www.zotero.org/ Zotero]help you collect, manage, and cite your research sources.
 +
* [http://www.google.com/tools/firefox/browsersync/ Google Browser Sync]
 +
 
 +
=== Project/Time management ===
 +
* [http://pdune.sourceforge.net/index.html Project Dune] Web-based issue tracker. Integration with subversion or cvs, code inspections in the browser, SCRUM project management.
 +
* [http://www.openproj.org/ Open Proj] - free, open source desktop alternative to Microsoft Project.
 +
* [http://www.openworkbench.org/ Open Workbench] - Open source project similar to Microsoft Project.
 +
* [https://workeffort.dev.java.net/ workeffort] Businesses perform work efforts within their organizations to accomplish tasks such as producing products, developing software, mantaining assets etc. This system helps in managing these kind of tasks. It also includes a time tracking system.
 +
* [http://www.ehour.nl/index.phtml eHour]Timesheet Management
 +
* [http://www.opnworks.com/opentime/ OpenTime]Eclipse, SWT/JFace, Hibernate, embedded relational databases, XML.
 +
 
 +
=== Communication ===
 +
* [http://www.worldtrans.org/TP/TP1/TP1-17.HTML A Communication Model]
 +
* [http://www.cs.tut.fi/~jkorpela/wiio.html How all human communication fails, except by accident, or a commentary of Wiio's laws]
 +
 
 +
* Alan Greenspan [https://sourceforge.net/forum/message.php?msg_id=4653656 sf.net post] posted by Colin
 +
<pre>
 +
"I guess I should warn you, if I turn out to be particularly clear, you've probably misunderstood what I've said."
 +
</pre>
 +
 
 +
 
 +
 
 +
=== Software Engineers Salaries ===
 +
* [http://blogs.payscale.com/ask_dr_salary/2008/01/software-develo.html Software Developer Salaries: Ruby on Rails vs. Java]
 +
* [http://ifbywhiskey.com/blog/2007/04/20/acts_as_french_fries/ Rails - do you want fries with that?]
 +
 
 +
=== Open Source articles ===
 +
* [http://www.networkworld.com/news/2007/082307-open-source-to-watch.html Open source companies to watch]
 +
* [http://itmanagement.earthweb.com/career/article.php/11067_3687096_1 Will Open Source Developers be Well Paid?]
 +
* [http://www.riehle.org/computer-science/research/2007/computer-2007-article.html The Economic Motivation of Open Source Software: Stakeholder Perspectives]
 +
* [http://enigmastation.com/technology/fsf.jsp Why I Can't Stand the FSF]Very interesting. Real experience with FSF.
 +
* [http://news.com.com/8301-10784_3-9753687-7.html Resurrecting Marc Fleury] - very interesting
 +
** Can you create an open-source developer? You were able to find them. Did you ever "build" one?
 +
 
 +
<pre>
 +
We tried once to create an open-source developer out of a normal developer, but it completely failed.
 +
We never tried it again. Truth be told, I had an aversion to it.
 +
</pre>
 +
 
 +
<pre>
 +
An open source developer is a self-starter.
 +
He's competitive - this is someone that wants to prove that they can do something better than you can.
 +
As such, it's a great recruitment/qualification vehicle, because you can see their work before you ever think of hiring them.
 +
You can see if they'll work out for the company.
 +
We definitely took that approach to hiring.
 +
</pre>
 +
 
 +
* [http://webdev.computer.org/blog/?p=62 The Beauty of Source Code] found the solution — but only because we had the source code ...
 +
* [http://www.mattmcalister.com/blog/2006/07/23/80/open-source-software-as-a-customer-capture-tool/ Open source software as a customer capture tool]
 +
* [http://www.follars.com/ Follars]Making Money from Free & Open Source Software
 +
* [http://blog.thomas.heute.name/2007/09/why-should-i-ever-contribute-just-give.html Why should i ever contribute? Just give me your stuff.] Interesting article and very true. I likes this sentence:
 +
<pre>
 +
, but don't beg for help, the guys who work owe you nothing.
 +
</pre>
 +
 
 +
* [http://www.redhat.com/magazine/015jan06/features/review_fogel/ Book review: Producing Open Source Software]
 +
* [http://producingoss.com Site of Producing Open Source]
 +
* [http://vitki.liber.us/ VITKI]A user who feel completely lost in finding accounting software.
 +
 
 +
==== OSS Etiquette & Culture ====
 +
* [http://www.mozilla.org/community/etiquette.html Mozilla Forum Etiquette]
 +
* [http://wiki.archlinux.org/index.php/Forum_Etiquette ArchLinux Forum Etiquette]
 +
* [http://www.wikimatrix.org/forum/viewtopic.php?id=387 WikiMatrix Forum Etiquette]
 +
* [http://www.lilbeginnings.com/forum/et/ Forum Etiquette & Rules]
 +
 
 +
 
 +
==== Open Source Models ====
 +
* [http://fptiny.blogspot.com/2007/10/open-source-business-model-of-tiny-erp.html Model of Tiny ERP]
 +
 
 +
 
 +
==== Giving It Away ====
 +
* [http://www.forbes.com/home/technology/2006/11/30/cory-doctorow-copyright-tech-media_cz_cd_books06_1201doctorow.html Giving It Away]Books
 +
 
 +
=== My wish list - Books ===
 +
Ordered by my desire!!!
 +
* [http://www.eclipsewtp.org/ Discover WTP, the End-to-End Toolset for Java-Based Web Development]
 +
* [http://www.packtpub.com/OSWorkflow-Java-open-source-Business-Process-Management/book OSWorkflow Java open source Business Process Management]
 +
* [http://www.packtpub.com/Customize-SugarCRM-PHP-MySQL-Open-Source-Developer-Manual/book SugarCRM Developer's Manual: Customize and extend SugarCRM]
 +
* [http://www.mergere.com/m2book_download.jsp Better Builds with Maven]
 +
* [http://www.pragmaticprogrammer.com/titles/jaerlang/ Programming Erlang Software for a Concurrent World]
 +
 
 +
 
 +
=== Online books ===
 +
* [http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/book.pdf Designing Enterprise Applications
 +
with the J2EETM Platform, Second Edition]
 +
* [https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/fdb09490-0201-0010-e09e-a76388646ad0 SAP J2EE
 +
Engine 6.20 - Administration Manual] Something which i have been part of!!!
 +
 
 +
=== Articles and posts from Martin Fowler ===
 +
* [http://martinfowler.com/eaaDev/EventCollaboration.html Event Collaboration]
 +
 
 +
=== Financial based ===
 +
* [http://www.xbrl.org/WhatIsXBRL/ XBRL stands for eXtensible Business Reporting Language]
 +
Read and respond to this message at:
 +
https://sourceforge.net/forum/message.php?msg_id=4366156
 +
By: drhayderaziz
 +
 
 +
I think that Adempiere would get a lot of kudos if Adempiere went the XBRL route www.xbrl.org for financial reporting. For listed companies (and even for unlisted) XBRL will be the way to go especially for any international company that has to consolidate accounts from multiple legal entities in multiple countries in a standardized manner. This would be an essential component of an ERP system in the 2008-2009 time frame. If Adempiere would have its COA structured the XBRL way and have XBRL compliant financial statements at  company/consolidated level it would be an AMAZING value proposition to so many organizations.
 +
 
 +
* [http://buddi.sourceforge.net/en/index.php Personal finance and budgeting program in Java; Well programmed]
 +
 
 +
* [http://media.netpr.pl/notatka_92301.html Open Source Business Foundation]
 +
 
 +
 
 +
==== CS and ROT explained ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4724881 sf.net post]
 +
In UK two methods of trading are popular with manufactures and wholesalers - Consignment Stocking(CS) and Retention of Title (ROT).
 +
The question is does ERP handle these types correctly?
 +
 
 +
CS is where stock is supplied and title transferred on sale to the end user.
 +
 
 +
ROT is where title is transferred on payment by the wholesaler.
 +
 
 +
This means that some goods held in the wholesalers warehouse will not belong to him and should not be counted as assets until title is transferred in the case of ROT and not at all in the case of CS unless the wholesaler uses ROT himself.
 +
 
 +
=== Non IT Technology ===
 +
* [http://www.horizonfuelcell.com/store/rees.htm Technology of Future]
 +
* [http://netinfo.bg/?tid=40&oid=1062999 Article In Bulgarian]
 +
* [http://www.steventalcottsmith.com/2007/3/9/when-non-programmers-write-software When Non-Programmers Write Software]
 +
 
 +
=== Social networks ===
 +
* [http://www.xing.com/ www.xing.com; Formerly know as openBC; Very strong in Europe]
 +
* [http://www.linkedin.com www.linkedin.com] Emerging at the moment; [http://www.linkedin.com/in/trifon My page]
 +
* [http://www.ecademy.com/ http://www.ecademy.com/user/trifontrifonov]
 +
* [http://www.bitwine.com/ BitWine] Trusted advice from real people - [http://www.bitwine.com/users/trifonnt My account]
 +
  [http://www.bitwine.com/advisors/trifonnt?auid=25850&amp;ctx=button Call me now] http://www.bitwine.com/presence/1/25850.gif
 +
 
 +
 
 +
==== Developer oriented social network ====
 +
* [http://www.ohloh.net/ Ohloh] accounts/7957
 +
* [http://www.sourcekibitzer.org SourceKibitzer] - [http://www.sourcekibitzer.org/Bio.ext?sp=l133 my account]
 +
 
 +
 
 +
===  The Semantic Web - Information sharing - machine-readable way ===
 +
* [http://www.foaf-project.org The Friend of a Friend (FOAF) project]The Friend of a Friend (FOAF) project is creating a Web of machine-readable pages describing people, the links between them and the things they create and do.
 +
 
 +
** [http://www.ibm.com/developerworks/xml/library/x-foaf.html Finding friends with XML and RDF]The Friend-of-a-Friend vocabulary can make it easier to manage online communities
 +
 
 +
== Adempiere ==
 +
* [http://www.goodwill.co.id/download/AmountInWords.pdf Amount in words]
 +
* [http://www.adempiere.com/wiki/index.php/Foundation_Project Adempiere Foundation]
 +
* [http://zkoss.org/demo/adempiereOnZK/adempiereOnZK.html Adempiere on ZK Demo]
 +
* [http://www.adempiere.com/wiki/index.php/Marketing_Materials Adempiere Marketing Materials]
 +
* [http://www.adempiere.com/wiki/index.php/ADempiere_3.5 Adempiere 3.5 plan]
 +
* [http://www.graysonconsulting.biz:8000/ Radio station to help people learn Adempiere libero by Tim]
 +
* [http://www.its-simon.com/adempiere/ Adempiere screen cast by simon]
 +
* [http://www.nickelnetworks.com/ADempiere/C5-AVA-3.3.0-Dev-NODB.zip CentOS adempiere VMWare]
 +
* [http://adempiere.com/wiki/index.php/HOWTO_Use_Jasper_On_Financial_Reports HOWTO Use Jasper On Financial Reports]
 +
 
 +
 
 +
* Libero Podcasts by Tim
 +
** [http://www.graysonconsulting.biz/show3.ogg]
 +
** [http://www.graysonconsulting.biz/show_3.ogg]
 +
** [http://www.graysonconsulting.biz/export.ogg]
 +
** [http://www.graysonconsulting.biz/attempt2.ogg]
 +
 
 +
 
 +
* [http://adempiere.com/wiki/index.php/ADempiere_Accounting ADempiere Accounting] by Carlos
 +
* [http://adempiere.com/wiki/index.php/Default_Accounts_Usage Default Accounts Usage] by Carlos
 +
* [http://www.adempiere.com/wiki/index.php/How_to_Configure_Dynamic_Approval_Workflow How to Configure Dynamic Approval Workflow]
 +
* [http://sourceforge.net/forum/message.php?msg_id=4675084 Quality Management Module]Some requirements on Quality Management by Reda Sultan.
 +
* [http://sourceforge.net/forum/message.php?msg_id=4674656 Thoughts from a Adempiere SME]
 +
* [http://www.adempiere.com/wiki/index.php/ADempiere_Motto_Contest ADempiere Motto Contest]
 +
* [http://www.adempiere.com/wiki/index.php/ADempiere_Motto_Contest/Qualification_Round Qualification Round ADempiere Motto Contest]
 +
* [http://oslabs.dnsalias.org:8080/adempiere/ WEB interface from Robert]
 +
* [http://www.adempiere.com/wiki/index.php/Accounting Accounting initiative]
 +
* [http://picasaweb.google.com/goanookie/ADempiereEuropeanConference Pictures from Adempiere Conference - Berlin 2007]
 +
* [http://www.adempiere.com/wiki/index.php/ADempiere_Institute_%26_Center_of_Excellence ADempiere Institute & Center of Excellence]
 +
* [https://sourceforge.net/forum/message.php?msg_id=4355888 Making Workflows more predictable]
 +
* [http://svn.sourceforge.net/adempiere/?rev=2725&view=rev Revision: 2725; Grid Collapse & Horizontal Tab Improve]
 +
* [https://sourceforge.net/tracker/?func=detail&atid=879334&aid=1734897&group_id=176962 Feature Request] - 1734897 Making Workflows more predictable
 +
* [https://sourceforge.net/forum/message.php?msg_id=4496774 Proof of concept for Loans System within ERP]
 +
* [http://blogs.cnet.com/8301-13505_1-9791116-16.html Article on CNET]
 +
* [http://www.ibm.com/developerworks/forums/dw_thread.jsp?message=13966527&cat=19&thread=167397&treeDisplayType=threadmode1&forum=805#13966527 Adempiere post on IBM site]
 +
* [https://sourceforge.net/forum/message.php?msg_id=4451073 Other Architectures for Adempiere - MUMPS]
 +
* [https://sourceforge.net/forum/message.php?msg_id=4567330 Central Reservation of IDs] Very good idea and implementation from Carlos
 +
** HTTP request:
 +
<pre>
 +
http://adempiere.globalqss.com/cgi-bin/get_ID?
 +
USER=user
 +
&PASSWORD=pass
 +
&TABLE=AD_Column
 +
&ALTKEY=
 +
&COMMENT=SomeCommentHere
 +
</pre>
 +
** Show log
 +
<pre>
 +
http://adempiere.globalqss.com/cgi-bin/showlog?AD_Column
 +
</pre>
 +
 
 +
 
 +
Adempiere Brazil Localization effort
 +
people that are cooperating with Adempiere LBR (LBR = Localization Brazil).
 +
Those are their names, followed by their sourceforge username.
 +
 
 +
Eduardo Montenegro (emontenegro)
 +
Alvaro Montenegro (amontenegro)
 +
Mario Grigioni (mgrigioni)
 +
 
 +
 
 +
 
 +
=== Adempiere commit schema ===
 +
* [[Committers|Committers]]
 +
 
 +
* [http://sourceforge.net/forum/message.php?msg_id=4384940 Structure and idea of Commit Level]
 +
 
 +
* Mentor/Commiter approach approved with 11/11 votes, according to this [https://sourceforge.net/forum/forum.php?thread_id=1765233&forum_id=611167 thread].
 +
 
 +
=== VERY IMPORTANT ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4432961 EU funding Adempiere Development; Postponed as deadlines was passed.]
 +
 
 +
=== Incoming events ===
 +
 
 +
 
 +
 
 +
Time: xx:xx GMT
 +
Day: Tuesday June 26
 +
Venue: IRC channel #adempiere-team (on irc.freenode.net)
 +
 
 +
1 - Xxx
 +
 
 +
2 - Xxx
 +
 
 +
=== Possible integrations with external systems ===
 +
* Hospital Information System
 +
** [http://care2x.org care2x] Care2x is a hospital information system which has lots of feature but no accounting at all.
 +
** [http://sourceforge.net/projects/netepi/ NetEpi] Open Source, network-enabled tools for epidemiology and public health practice.
 +
** [http://openmrs.org/wiki/OpenMRS OpenMRS]
 +
 
 +
 
 +
* [http://code.google.com/apis/blogger/developers_guide_java.html EDI 2 Blog or XML Export 2 Blog]
 +
 
 +
* Integration with WEB Shops
 +
** [http://www.oscommerce.com OS-Commerce] PHP based.
 +
** [http://www.magentocommerce.com Magento Commerce] PHP based. Well written with Object Oriented Approach.
 +
 
 +
=== Adempiere Application dictionary vs. Axapta Data dictionary ===
 +
* [http://adempiere.com/wiki/index.php/Improvements_on_Adempiere_Data_Dictionary Improvements on Adempiere Data Dictionary] - Thank's to Emilio Arrufat
 +
 
 +
* [https://sourceforge.net/forum/message.php?msg_id=4442156 Improvements on Data Dictionary; Thank's to Emilio Arrufat]
 +
 
 +
* [http://www.freshpatents.com/Semantic-model-development-and-deployment-dt20070208ptan20070033212.php?type=description Microsoft trying to patent AD idea; Can't anyone get rid of this stupid company???]
 +
 
 +
=== Performance tests & results made by me ===
 +
This are slower than on my laptop.
 +
On laptop result was around 17 products / second.
 +
 
 +
<pre>
 +
Processors..........: 2 x Pentium2 800MHz
 +
RAM.................: 2 GB
 +
OS..................: Linux, Fedora Core 5
 +
DB..................: Oracle XE
 +
JDK.................: Sun JDK 1.5.0_11
 +
Adempiere version...: 3.3.0
 +
Note................: Adempiere client on the same machine as DB.
 +
 
 +
Tables where records are inserted:
 +
AD_TREENODEPR    1095095
 +
M_PRODUCT        1095095
 +
M_PRODUCT_ACCT    1095095
 +
M_PRODUCT_TRL    1095095
 +
 
 +
Performance table
 +
 
 +
Start Time      = Thu Aug 09 04:57:01 EEST 2007
 +
End Time        = Thu Aug 09 05:13:54 EEST 2007
 +
Duration(ms)    = 1012585
 +
Duration(sec.)  = 1012
 +
Duration(min.)  = 16
 +
Products        = 5000
 +
Time(seconds)  = 1012
 +
Produsts/Second = 4.9407115
 +
 
 +
Start Time      = Thu Aug 09 05:17:04 EEST 2007
 +
End Time        = Thu Aug 09 09:14:23 EEST 2007
 +
Duration(ms)    = 14239657
 +
Duration(sec.)  = 14239
 +
Duration(min.)  = 237
 +
Products        = 144000
 +
Time(seconds)  = 14239
 +
Produsts/Second = 10.11307
 +
 
 +
 
 +
Start Time      = Fri Aug 10 03:43:13 EEST 2007
 +
End Time        = Fri Aug 10 07:42:25 EEST 2007
 +
Duration(ms)    = 14351454
 +
Duration(sec.)  = 14351
 +
Duration(min.)  = 239
 +
Duration(hours.) = 3
 +
Products        = 144000
 +
Time(seconds)    = 239
 +
Produsts/Second  = 10.03
 +
 +
Start Time      = Fri Aug 10 13:00:23 EEST 2007
 +
End Time        = Fri Aug 10 16:58:42 EEST 2007
 +
Duration(ms)    = 14298664
 +
Duration(sec.)  = 14298
 +
Duration(min.)  = 238
 +
Duration(hours.) = 3
 +
Products        = 144000
 +
Time(seconds)    = 14298
 +
Produsts/Second  = 10.071339
 +
 
 +
Start Time      = Fri Aug 10 19:59:38 EEST 2007
 +
End Time        = Sat Aug 11 03:59:55 EEST 2007
 +
Duration(ms)    = 28817002
 +
Duration(sec.)  = 28817
 +
Duration(min.)  = 480
 +
Duration(hours.) = 8
 +
Products        = 288000
 +
Time(seconds)    = 28817
 +
Produsts/Second  = 9.994101
 +
 
 +
Start Time      = Sat Aug 11 17:53:38 EEST 2007
 +
End Time        = Sun Aug 12 02:18:17 EEST 2007
 +
Duration(ms)    = 30278812
 +
Duration(sec.)  = 30278
 +
Duration(min.)  = 504
 +
Duration(hours.) = 8
 +
Products        = 288000
 +
Time(seconds)    = 30278
 +
Produsts/Second  = 9.511857
 +
 
 +
</pre>
 +
 
 +
=== Postal Code Web Service ===
 +
* [http://sourceforge.net/tracker/index.php?func=detail&aid=1741222&group_id=176962&atid=879335 1741222 Webservice connector for address lookups]
 +
* [https://sourceforge.net/forum/message.php?msg_id=4377879 1-Postcode lookup propsal by Michael Judd]
 +
* [https://sourceforge.net/forum/message.php?msg_id=4377901 2-Postcode lookup propsal by Michael Judd]
 +
* [https://sourceforge.net/forum/message.php?msg_id=4381779 Proposal from Teo]
 +
 
 +
 
 +
=== Interesting Proposal for Web services ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4504791 sf.net post]
 +
 
 +
1. Products - When entering a new product, call an UPC/EAN webservice
 +
(http://www.gepir.org/) that validates a product UPC/EAN and populates the item
 +
description and trade info (size, weight, etc).
 +
 
 +
2. Business Partners - When entering a new Business Partner, call a Company
 +
Registrar to validate (and populate)  company registration / vat numbers and
 +
registered address, directors, etc.
 +
 
 +
3. Credit Checking - When entering a new Business Partner, call a webservice
 +
to perform a credit vetting / check after which the report can be populated
 +
into a credit check table or attached to the record.
 +
 
 +
 
 +
=== Comparison of Posterita Web UI and Robert Klein Ajax Web UI ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4664348 sf.net post]
 +
 
 +
* Robert Klein Ajax is more usable than Posterita WebUI
 +
** Attachment works in Robert Klein but not in Posterita.
 +
** Grid of Posterita is mess up.
 +
** Scrolling and navigation are mess up in Posterita.
 +
** Decimal point of numeric has many zeros in Posterita.
 +
** Robert Klein Web UI runs fast than Posterita.
 +
 
 +
=== Adempiere Frequently Asked Question ===
 +
 
 +
==== Practical Use of Document Type & Sequence ====
 +
* What is its real purpose of Document Sequence
 +
 
 +
The purpose is to have different sequence (Document No) for each document type.
 +
For example: Imagine you want to difference the PO depending on what you buy.
 +
You could have the document type "Purchase Order-A" and the "Purchase Order-B".
 +
 
 +
"Purchase Order-A" --> Sequence (Document no):A00001
 +
"Purchase Order-B" --> Sequence (Document no):B00001
 +
 
 +
So for the same transaction (Purchase order) you can difference distinct sequence numbers.
 +
 
 +
 
 +
==== How to create new user and restricted access rights? ====
 +
Define Role for User
 +
Create Role:
 +
<pre>
 +
Click on the General Setup -> Security -> Role
 +
Click on the New button(ex: MyRole).
 +
Select the Organization from drop down.
 +
Enter the Name for role.
 +
Select the User Level from User Level drop down.
 +
Tick on the Manual Checkbox.
 +
Click on the Save button.
 +
Click on the Grant Access button (eg:Access to All for Sale Module).
 +
Select the Module from drop down that you have to include.
 +
Select the Access To from drop down that you have to include.
 +
Click on the OK button.
 +
Click on the Save button.
 +
 
 +
Click on the Org Access tab.
 +
Select the Organization for newely defined role.
 +
Click on the Save button.
 +
</pre>
 +
 
 +
Create User:
 +
<pre>
 +
Click on the General Setup -> Security -> User.
 +
Select the Organization from organization drop down.
 +
(Note: user organization and define role organization must be same.)
 +
Enter the Name for user(ex: ABC).
 +
Set the Password for user.
 +
Click on the Save button.
 +
</pre>
 +
 
 +
Assign Role to User:
 +
<pre>
 +
-    Click on the User Roles tab.
 +
Select Role from drop down(ex:MyRole).
 +
Click on the Save button.
 +
</pre>
 +
 
 +
Click on the User tab.
 +
Select the Default Role from drop down(ex:MyRole).
 +
Select Default Client from drop down.
 +
Select the Default Organization from drop down.
 +
Click on the Save button.
 +
Login as ABC user.
 +
 
 +
 
 +
==== How to modify Invoice Posting? ====
 +
 
 +
Default Adempiere Account posting:
 +
<pre>
 +
----------------------------------------------------------------
 +
Account                    Debit              Credit
 +
----------------------------------------------------------------
 +
Account Receivable        55.000.000       
 +
  A tax                                        5.000.000
 +
  Service Revenue                            50.000.000
 +
----------------------------------------------------------------
 +
</pre>
 +
 
 +
 
 +
Desired Adempiere Account posting:
 +
<pre>
 +
----------------------------------------------------------------
 +
Account                    Debit              Credit
 +
----------------------------------------------------------------
 +
Account Receivable        52.750.000                         
 +
An Account                  2.250.000 - which is 4.5%x50.000.000
 +
  A tax                                        5.000.000       
 +
  Service Revenue                            50.000.000
 +
----------------------------------------------------------------
 +
<pre>
 +
 
 +
Desired functionality can be achieved with Account splitting.
 +
Rule must be defined in the system which will split posting into Account Receivable on two account entries.
 +
 
 +
=== Implementor hints ===
 +
 
 +
==== Show where products are located ====
 +
Submitted By: Jan Kantert (jab_doa)
 +
 
 +
Summary: Show where products are located
 +
 
 +
sf.net tracker: [https://sourceforge.net/tracker/?func=detail&atid=879335&aid=1768749&group_id=176962 here]
 +
 
 +
 
 +
Initial Comment:
 +
Log in as System Administrator. Select "Application Dictionary" -> "Window, Tab & Field" -> Name = Product
 +
 
 +
Click on "Tab".
 +
Go to the end of the list and add a new row. Zoom in and set Table to "M_Storage_M_Storage", Name to "Located at", Description to "Where are my units located?", Tab Level to "2" and check "read only".
 +
Now save and click on "Create Fields". Thats it. Now you can see where your units are when zooming into a product.
 +
 
 +
==== Security ====
 +
Submitted By: Armen (armenrz)
 +
 
 +
Summary: Security
 +
 
 +
sf.net tracker: [https://sourceforge.net/forum/message.php?msg_id=4451508 here]
 +
 
 +
 
 +
1) ADempiere support role based security - Role window.
 +
2) Role Data Access. You can also play around with SQLWhere in Window, Tab & Field.
 +
 
 +
Example:
 +
(instr('@#User_Level@','C')<>0 OR C_BPartner.CreatedBy=@#AD_user_ID@ OR C_BPartner.SalesRep_ID=@#AD_User_ID@)
 +
 
 +
For pricelist, there's one place you can't hide price from user, which is  Product Info. You need to modify some codes to do this. What I did is add IsCanViewPrice option in Role so now each role can be set either they can view price or not.
 +
 
 +
 
 +
==== Bank Transfer tips ====
 +
Submitted By: usman88
 +
 
 +
Summary: Bank Transfer tips
 +
 
 +
sf.net tracker: [https://sourceforge.net/forum/message.php?msg_id=4467580 here]
 +
 
 +
* [http://www.adempiere.com/wiki/index.php/Bank_to_Bank_Transfer_Transaction_tips Bank to Bank Transfer Transaction tips]
 +
 
 +
Small tips to handle 1 source Bank to 1 recipient Bank transfer transaction.
 +
 
 +
1. Create new cash journal.
 +
 
 +
2. Select appropriate cash book ( in my case i use dummy cash book to serve this transaction)
 +
 
 +
3. Next go to cash line and create a new line and select cash type as bank transfer.
 +
 
 +
4. Then select source bank account and type in transfer amount
 +
 
 +
5. Create 2nd line as in step 3.
 +
 
 +
6. This time select recipient bank account and type in transfer amount but in negative sign.
 +
 
 +
7. Back to cash journal tab, complete and post it.
 +
 
 +
8. To finalize it create, complete and post Bank statement for each bank account.
 +
 
 +
 
 +
PS. Above tips can be use for more complex scenario such as transfer from 2 bank to 1 recipient.
 +
 
 +
==== Listing a BOM within a BOM ====
 +
Submitted By: stingreye
 +
 
 +
Summary: Listing a BOM within a BOM
 +
 
 +
sf.net tracker: [https://sourceforge.net/forum/message.php?msg_id=4369782 here]
 +
 
 +
Here is the view in Oracle... Because we have so many parts we ended up doing
 +
a materialized view that we update with a process in Compiere everytime we
 +
change
 +
a BOM.  We did that so we could report off of this view faster.
 +
 
 +
I am sure someone out here could write a much better query than this but here
 +
is what I did.  Basically, created a view on top of itself so that the parent
 +
records would null.  Then used the connect by clause to generate the hierarchy.
 +
You will also notice the use of connect_by_root = Top level of bill.
 +
Connect_by_ISLEAF = bottom level of bill.  Level = what level of the hierarchy.
 +
 
 +
<pre>
 +
CREATE OR REPLACE VIEW BOM_INDENTED
 +
(TOPLEVELID, TOPLEVEL, TOPLEVEL_DESC, PRODUCTNUM, PRODDEC,
 +
M_PRODUCTBOM_ID, BOM_LEVEL, BOMQTY, DESCRIPTION, AD_CLIENT_ID,
 +
AD_ORG_ID, ROWNUMBER, BOM_LEVEL_NUM, BOTTOMCOMPONENT)
 +
AS
 +
 
 +
SELECT  CONNECT_BY_ROOT M_ProductBom_ID AS TOPLEVELID,CONNECT_BY_ROOT Value
 +
AS TOPLEVEL,CONNECT_BY_ROOT b.DESCRIPTION AS TOPLEVEL_DESC, Value AS
 +
ProductNum,
 +
b.DESCRIPTION AS ProdDesc, M_PRODUCTBOM_ID,LPAD(' ',2*(LEVEL-1)) ||
 +
TO_CHAR(LEVEL)
 +
BOM_Level, BOMQTY, a.DESCRIPTION,a.AD_CLIENT_ID, a.AD_ORG_ID, ROWNUM, LEVEL,
 +
Connect_By_ISLEAF
 +
  FROM
 +
 
 +
-- part 2 subquerry combining top level and bom to create null to start from
 +
( SELECT
 +
"M_PRODUCT_BOM_ID","AD_CLIENT_ID","AD_ORG_ID","ISACTIVE",--"CREATED","C
 +
REATEDBY","UPDATED","UPDATEDBY",  (remove becuase unnnecessarry)
 +
"LINE","M_PRODUCT_ID","M_PRODUCTBOM_ID","BOMQTY","DESCRIPTION","BOMTYPE"
 +
FROM M_PRODUCT_BOM
 +
 
 +
UNION
 +
-- part 1 the tope level querry creating the nulls that is combined in part 2
 +
SELECT M_PRODUCT_BOM_1.M_PRODUCT_BOM_ID, M_PRODUCT_BOM.AD_CLIENT_ID,
 +
M_PRODUCT_BOM.AD_ORG_ID, M_PRODUCT_BOM_1.ISACTIVE,-- M_PRODUCT_BOM_1.CREATED,
 +
M_PRODUCT_BOM_1.CREATEDBY, M_PRODUCT_BOM_1.UPDATED, M_PRODUCT_BOM_1.UPDATEDBY,
 +
(removed unnecessary)
 +
M_PRODUCT_BOM_1.LINE,M_PRODUCT_BOM_1.M_PRODUCTBOM_ID AS M_PRODUCT_ID,
 +
M_PRODUCT_BOM.M_PRODUCT_ID AS M_PRODUCTBOM_ID,  M_PRODUCT_BOM_1.BOMQTY,
 +
M_PRODUCT_BOM_1.DESCRIPTION, M_PRODUCT_BOM_1.BOMTYPE
 +
FROM M_PRODUCT_BOM LEFT JOIN M_PRODUCT_BOM  M_PRODUCT_BOM_1 ON
 +
M_PRODUCT_BOM.M_PRODUCT_ID = M_PRODUCT_BOM_1.M_PRODUCTBOM_ID
 +
GROUP BY M_PRODUCT_BOM_1.M_PRODUCT_BOM_ID, M_PRODUCT_BOM.AD_CLIENT_ID,
 +
M_PRODUCT_BOM.AD_ORG_ID, M_PRODUCT_BOM_1.ISACTIVE, M_PRODUCT_BOM_1.CREATED,
 +
M_PRODUCT_BOM_1.CREATEDBY, M_PRODUCT_BOM_1.UPDATED, M_PRODUCT_BOM_1.UPDATEDBY,
 +
M_PRODUCT_BOM_1.LINE, M_PRODUCT_BOM.M_PRODUCT_ID,
 +
M_PRODUCT_BOM_1.M_PRODUCTBOM_ID,
 +
M_PRODUCT_BOM_1.BOMQTY, M_PRODUCT_BOM_1.DESCRIPTION, M_PRODUCT_BOM_1.BOMTYPE
 +
HAVING (((M_PRODUCT_BOM_1.M_PRODUCTBOM_ID) IS NULL))) a
 +
-- part 3 continued
 +
  INNER JOIN M_PRODUCT b
 +
  ON a.M_PRODUCTBOM_ID = b.M_PRODUCT_ID
 +
  START WITH a.M_PRODUCT_ID IS NULL
 +
  CONNECT BY PRIOR  M_PRODUCTBOM_ID = a.M_PRODUCT_ID
 +
  ORDER SIBLINGS BY b.Value
 +
/
 +
 
 +
</pre>
 +
 
 +
If you want to use materialized views... we did it the following way (I really
 +
know very little about them, so if someone has a better idea of how to use them
 +
for this, it would be appreciated)
 +
The materialized view would be
 +
 
 +
<pre>
 +
CREATE MATERIALIZED VIEW BOM_INDENTED_MV
 +
(PTX_Path,TOPLEVELID, TOPLEVEL, TOPLEVEL_DESC, PRODUCTNUM, PRODDEC,
 +
M_PRODUCTBOM_ID, BOM_LEVEL, BOMQTY, DESCRIPTION, AD_CLIENT_ID,
 +
AD_ORG_ID, BOM_LEVEL_NUM, BOTTOMCOMPONENT,TOPLEVEL_ISACTIVE, COMP_ISACTIVE,
 +
TOP_Client)
 +
 +
Build IMMEDIATE
 +
REFRESH ON DEMAND
 +
DISABLE QUERY REWRITE
 +
 +
AS
 +
SELECT Path, TOPLEVELID,TOPLEVEL,TOPLEVEL_DESC, ProductNum, ProdDesc,
 +
M_PRODUCTBOM_ID, BOM_Level, BOMQTY, f1.DESCRIPTION,mp2.AD_CLIENT_ID,
 +
mp2.AD_ORG_ID,
 +
BomLevelNum, BottomComponent, MP.ISACTIVE AS TOPLEV_ISACTIVE, MP2.ISACTIVE AS
 +
COMP_ISACTIVE, mp.AD_CLIENT_ID AS TOPLEVEL_Client
 +
  FROM (
 +
SELECT DISTINCT SYS_CONNECT_BY_PATH (M_PRODUCTBOM_ID,'/') AS Path,
 +
CONNECT_BY_ROOT
 +
M_ProductBom_ID AS TOPLEVELID,CONNECT_BY_ROOT Value AS TOPLEVEL,CONNECT_BY_ROOT
 +
b.DESCRIPTION AS TOPLEVEL_DESC, Value AS ProductNum, b.DESCRIPTION AS ProdDesc,
 +
M_PRODUCTBOM_ID,LPAD(' ',2*(LEVEL-1)) || TO_CHAR(LEVEL) BOM_Level, BOMQTY,
 +
a.DESCRIPTION,a.AD_CLIENT_ID, a.AD_ORG_ID, LEVEL AS BomLevelNum,
 +
Connect_By_ISLEAF
 +
AS BottomComponent
 +
  FROM
 +
 
 +
-- part 2 subquerry combining top level and bom to create null to start from
 +
( SELECT
 +
"M_PRODUCT_BOM_ID","AD_CLIENT_ID","AD_ORG_ID","ISACTIVE",--"CREATED","C
 +
REATEDBY","UPDATED","UPDATEDBY",  (remove becuase unnnecessarry)
 +
"LINE","M_PRODUCT_ID","M_PRODUCTBOM_ID","BOMQTY","DESCRIPTION","BOMTYPE"
 +
FROM M_PRODUCT_BOM
 +
 
 +
UNION
 +
-- part 1 the tope level querry creating the nulls that is combined in part 2
 +
SELECT M_PRODUCT_BOM_1.M_PRODUCT_BOM_ID, M_PRODUCT_BOM.AD_CLIENT_ID,
 +
M_PRODUCT_BOM.AD_ORG_ID, M_PRODUCT_BOM_1.ISACTIVE,-- M_PRODUCT_BOM_1.CREATED,
 +
M_PRODUCT_BOM_1.CREATEDBY, M_PRODUCT_BOM_1.UPDATED, M_PRODUCT_BOM_1.UPDATEDBY,
 +
(removed unnecessary)
 +
M_PRODUCT_BOM_1.LINE,M_PRODUCT_BOM_1.M_PRODUCTBOM_ID AS M_PRODUCT_ID,
 +
M_PRODUCT_BOM.M_PRODUCT_ID AS M_PRODUCTBOM_ID,  M_PRODUCT_BOM_1.BOMQTY,
 +
M_PRODUCT_BOM_1.DESCRIPTION, M_PRODUCT_BOM_1.BOMTYPE
 +
FROM M_PRODUCT_BOM LEFT JOIN M_PRODUCT_BOM  M_PRODUCT_BOM_1 ON
 +
M_PRODUCT_BOM.M_PRODUCT_ID = M_PRODUCT_BOM_1.M_PRODUCTBOM_ID
 +
GROUP BY M_PRODUCT_BOM_1.M_PRODUCT_BOM_ID, M_PRODUCT_BOM.AD_CLIENT_ID,
 +
M_PRODUCT_BOM.AD_ORG_ID, M_PRODUCT_BOM_1.ISACTIVE, M_PRODUCT_BOM_1.CREATED,
 +
M_PRODUCT_BOM_1.CREATEDBY, M_PRODUCT_BOM_1.UPDATED, M_PRODUCT_BOM_1.UPDATEDBY,
 +
M_PRODUCT_BOM_1.LINE, M_PRODUCT_BOM.M_PRODUCT_ID,
 +
M_PRODUCT_BOM_1.M_PRODUCTBOM_ID,
 +
M_PRODUCT_BOM_1.BOMQTY, M_PRODUCT_BOM_1.DESCRIPTION, M_PRODUCT_BOM_1.BOMTYPE
 +
HAVING (((M_PRODUCT_BOM_1.M_PRODUCTBOM_ID) IS NULL))) a
 +
-- part 3 continued
 +
  INNER JOIN M_PRODUCT b
 +
  ON a.M_PRODUCTBOM_ID = b.M_PRODUCT_ID
 +
  START WITH a.M_PRODUCT_ID IS NULL
 +
  CONNECT BY PRIOR  M_PRODUCTBOM_ID = a.M_PRODUCT_ID
 +
  ORDER SIBLINGS BY b.Value
 +
) f1
 +
INNER JOIN M_PRODUCT mp ON TOPLEVELID=mp.M_PRODUCT_ID
 +
INNER JOIN M_PRODUCT mp2 ON M_PRODUCTBOM_ID = mp2.M_PRODUCT_ID
 +
ORDER BY Path
 +
/
 +
 
 +
</pre>
 +
 
 +
Then to refresh the materialize view we used the following database procedure
 +
where we used a parameter in the "report process" window to identify which MV
 +
to refresh:
 +
 
 +
<pre>
 +
CREATE OR REPLACE PROCEDURE Indented_Bom_Mv_Refresh
 +
(
 +
PInstance_ID    IN NUMBER
 +
)
 +
AS
 +
-- Logistice
 +
ResultStr VARCHAR2(2000);
 +
Message VARCHAR2(2000);
 +
Record_ID NUMBER;
 +
-- Parameter
 +
CURSOR Cur_Parameter (PInstance NUMBER) IS
 +
SELECT i.Record_ID, p.ParameterName, p.P_String, p.P_Number, p.P_Date
 +
FROM AD_PINSTANCE i, AD_PINSTANCE_PARA p
 +
WHERE i.AD_PInstance_ID=PInstance
 +
AND i.AD_PInstance_ID=p.AD_PInstance_ID(+)
 +
ORDER BY p.SeqNo;
 +
-- Parameter Variables
 +
p_MVIEW VARCHAR2(2000);
 +
 
 +
 
 +
BEGIN
 +
DBMS_OUTPUT.PUT_LINE('Updating PInstance - Processing ' || PInstance_ID);
 +
    ResultStr := 'PInstanceNotFound';
 +
    UPDATE AD_PINSTANCE
 +
    SET Created = SYSDATE,
 +
        IsProcessing = 'Y'
 +
    WHERE AD_PInstance_ID=PInstance_ID;
 +
    COMMIT;
 +
-- Get Parameters
 +
ResultStr := 'ReadingParameters';
 +
FOR p IN Cur_Parameter (PInstance_ID) LOOP
 +
Record_ID := p.Record_ID;
 +
IF (p.ParameterName = 'MVIEW') THEN
 +
P_PTX_MVIEW := p.P_String;
 +
DBMS_OUTPUT.PUT_LINE('  MVIEW=' || p_MVIEW);
 +
ELSE
 +
DBMS_OUTPUT.PUT_LINE('*** Unknown Parameter=' || p.ParameterName);
 +
END IF;
 +
END LOOP; -- Get Parameter
 +
DBMS_OUTPUT.PUT_LINE('  Record_ID=' || Record_ID);
 +
 
 +
 +
DBMS_MVIEW.REFRESH (p_PTX_MVIEW, 'c');
 +
 
 +
 
 +
<<FINISH_PROCESS>>
 +
--  Update AD_PInstance
 +
DBMS_OUTPUT.PUT_LINE('Updating PInstance - Finished ' || Message);
 +
    UPDATE  AD_PINSTANCE
 +
    SET Updated = SYSDATE,
 +
        IsProcessing = 'N',
 +
        Result = 1,                -- success
 +
        ErrorMsg = Message
 +
    WHERE  AD_PInstance_ID=PInstance_ID;
 +
    COMMIT;
 +
    RETURN;
 +
 
 +
EXCEPTION
 +
    WHEN  OTHERS THEN
 +
ResultStr := ResultStr || ': ' || SQLERRM || ' - ' || Message;
 +
DBMS_OUTPUT.PUT_LINE(ResultStr);
 +
        UPDATE  AD_PINSTANCE
 +
        SET Updated = SYSDATE,
 +
            IsProcessing = 'N',
 +
            Result = 0,            -- failure
 +
            ErrorMsg = ResultStr
 +
        WHERE  AD_PInstance_ID=PInstance_ID;
 +
        COMMIT;
 +
        RETURN;
 +
END ;
 +
/
 +
 
 +
</pre>
 +
 
 +
 
 +
==== User authentication in Adempiere using LDAP ====
 +
Submitted By: gemmiti
 +
 
 +
Summary: User authentication in Adempiere using LDAP
 +
 
 +
sf.net tracker: [https://sourceforge.net/forum/message.php?msg_id=3959888 here]
 +
 
 +
Enabling LDAP Functionality:
 +
 
 +
1.  Log in as SysAdmin
 +
 
 +
2.  Go to Menu > System Admin > System
 +
 
 +
3.  In Field "Ldap URL" fill in your LDAP URL, i.e. "LDAP://YourLdapServer.com"
 +
 
 +
4.  In field "LDAP Domain" Your Domain, i.e., "YourLdapServer.com"
 +
 
 +
5.  Log Out as SysAdmin
 +
 
 +
6.  Log In as SuperUser/Admin
 +
 
 +
7.  GoTo Menu > General Rules > Security>User
 +
 
 +
8.  In tab "User Contact" and "Internal" you will find a field for LDAP User
 +
Name -- Here (for a particular user) fill in the LDAP use name.
 +
 
 +
Upon logging in -- the user can enter his/her LDAP user name and password and
 +
it will associate the correct credentials to the user you have set up in
 +
Compiere.
 +
 
 +
==== Add OnHandQty In Product window ====
 +
Submitted By: stingreye
 +
 
 +
Summary: Add OnHandQty In Product window
 +
 
 +
sf.net tracker: [https://sourceforge.net/forum/message.php?msg_id=3984175 here]
 +
 
 +
<pre>
 +
First the SQL
 +
1) You want On Hand Qty -  Product can be stored in multiple locators in M_Storage table. I assume you want total of all locators
 +
2) So SQL = SELECT SUM (QTYONHAND) FROM M_STORAGE s
 +
3) Now you want to sync with product table,  so  we add WHERE s.M_PRODUCT_ID = M_PRODUCT.M_PRODUCT_ID
 +
4) So the final SQL we need is (SELECT SUM(QTYONHAND) FROM M_STORAGE s WHERE s.M_PRODUCT_ID = M_PRODUCT.M_PRODUCT_ID)
 +
 
 +
Now lets add it to compiere:
 +
1) Log in as SuperUser or System
 +
2) Role = System Administrator
 +
3) Open Table window
 +
4) Select Column tab
 +
5) Create new record
 +
6) Insert a  name for DB Column Name
 +
7) Choose a system element in this case most likely Qty_OnHand
 +
8) Reference = String
 +
9) Length = 20 should be plenty
 +
10) Click Save
 +
11) Click synchronize column, cross fingers
 +
12) Look on bottom left of window for alter table M_PRODUCTADD name of the field you just made
 +
 
 +
Lets add it to the M_Product window.
 +
 
 +
1) Go to Window Tab Field
 +
2) Choose Product Table
 +
3) Goto Tab
 +
4) Choose the “tab” we want which is Product (it is for the M_PRODUCT table)
 +
5) Choose Field Tab
 +
6) New Record
 +
7) Name your Field (Qty on Hand)
 +
8) Column – Choose the new column you created.
 +
9) Save
 +
 
 +
Now open the Product window and it should work!
 +
 
 +
</pre>
 +
 
 +
==== Workflow Simple approval ====
 +
* [http://www.adempiere.com/wiki/index.php/How_to_Activate_Document_Approval_Workflow Workflow Simple approval]
 +
 
 +
==== Workflow Dynamic approval ====
 +
* [http://www.adempiere.com/wiki/index.php/How_to_Configure_Dynamic_Approval_Workflow Workflow Dynamic Approval]
 +
 
 +
==== Changelog functionality ====
 +
changelog functionality consists of two parts: who & what.
 +
 
 +
* Via tables user can identify "what" wish to log.
 +
* Via roles "who".
 +
 
 +
By this way is possible to finely control the auditing.
 +
This means more tables to be flagged if user wish to log all tables.
 +
 
 +
 
 +
==== SECURE SCENARIO to use Adempiere ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4506970 sf.net post] by Carlos
 +
 
 +
Possible SECURE SCENARIO to use Adempiere (applicable Compiere installations also)
 +
 
 +
CLIENTS
 +
* 1 - Don't install clients
 +
 
 +
* 2 - Install two servers - one for NX (call it NXServer), and the other for oracle and JBoss (call it ADServer)
 +
 
 +
* 3 - Allow clients just run through NX connection (you'll have total control of the ADempiere.properties in a linux box)
 +
 
 +
* 4 - Configure the ADServer to only accept connections from NXServer
 +
 
 +
* 5 - Configure the Oracle in ADServer to only accept connections from the same ADServer and from NXServer
 +
 
 +
SERVICES ON WEB
 +
* 1 - Don't expose web services from jboss directly
 +
 
 +
* 2 - Install an apache server to expose in a controlled way just the needed services and pages from jboss adempiere
 +
 
 +
 
 +
In this scenario NX can be replaced with any terminal server software  (Microsoft TS, Citrix, Sun Global Secure Desktop, etc).
 +
And you must incur in costs of terminal server software licensing - but  security is not free.
 +
And you must ensure all those servers - ensure NX, ensure oracle, ensure jboss, ensure apache, ensure linux, etc.
 +
 
 +
 
 +
==== Product Attribute Instance - Color/Size/Serial number ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4547817 Color/Size in Product Attribute per Instance] Very good explanation from Colin
 +
 
 +
 
 +
==== Material transaction between two organizations ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4548319 sf.net post] another good description from Colin
 +
 
 +
 
 +
==== Maintain multiple environments(Postgre multiple schema managing) ====
 +
* [http://www.adempiere.com/wiki/index.php/Mantain_multiple_environments wiki page]Good description from Fernando
 +
 
 +
 
 +
==== Report sales figures by product ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4602421 sf.net post]
 +
 
 +
1. Create a Report Line Set called All Products.
 +
2. Create a Report Line under it called Product with a Line Type of Segment Value (leave Posting and Amount Types blank)
 +
3. Create a Report Source under it with Type=Product and leave the Product field blank
 +
4. Create a Report Column Set called Current Period and YTD
 +
5. Create 2 report columns under it, one for Current Period and YTD. The first one should have Posting Type=Actual, Amount Type=Period Balance, Column Type=Relative Period, Relative Period=0. The second one should be the same except Amount Type=Year Balance.
 +
6. Then create a Financial report using these Report Line and Columns Sets. Make sure to check List Sources when you run to see all the products. Warning, If there are more than 1000 products it won't work (we're obviously aware of this limitation and working on removing it).
 +
 
 +
You can easily produce a similar report for Sales by Business Partner by just
 +
substituting Type=Business Parter in Step 3.
 +
 
 +
 
 +
==== How to monitor Oracle sessions? ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4623204 sf.net post]
 +
 
 +
SELECT SID, SERIAL#, STATUS, SERVER
 +
  FROM V$SESSION
 +
  WHERE USERNAME = 'ADEMPIERE';
 +
 
 +
 
 +
==== How to change document numbers? ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4669455 sf.net post]
 +
 
 +
Go to Performance
 +
<pre>
 +
Analysis -> Accounting Rules -> Document Type
 +
</pre>
 +
Here you can see all existing document types like Purchase Order etc. If the 'Document is Number Controlled' checkbox is checked then you will have a Document Sequence field (a drop down). Right click and zoom to the Document Sequence window
 +
<pre>
 +
Performance Analysis -> Accounting Rules -> Document Sequence
 +
</pre>
 +
Here you can change the current next value, the increment and you can add prefix and or suffix for your order/invoice numbers.
 +
 
 +
 
 +
==== Where to place JasperReport files? ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4726526 sf.net post]
 +
 
 +
JasperReport can be defined as:
 +
 
 +
<pre>
 +
http://
 +
https://
 +
attachment:
 +
file:/
 +
or a direct file_directory path
 +
</pre>
 +
 
 +
An easier way to deploy jasper reports could be putting the .jasper in the customization.jar
 +
 
 +
For that we could add a new prefix like:
 +
<pre>
 +
resource:org/adempiere/jasper/MyReport.jasper
 +
</pre>
 +
 
 +
 
 +
==== How to handle imprests? ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4725517 sf.net post]
 +
 
 +
 
 +
==== How to process credit card payments from Java GUI? ====
 +
 
 +
How a user could create a payment in the client (not the webstore) that will get passed to the payment processor?
 +
 
 +
 
 +
Window 'Invoice (Customer)'.
 +
 
 +
Complete 'Invoice (Customer)'.
 +
 
 +
Set Payment Type - Press Button which by default has value 'On Credit'.
 +
 
 +
A new window open and user can change payment Type from 'On Credit' to 'Credit Card'.
 +
 
 +
Enter Credit Card data.
 +
 
 +
==== BOM price explained. ====
 +
https://sourceforge.net/forum/message.php?msg_id=4740301
 +
 
 +
BOM Product price is depend of the price of the products which built it.
 +
For example Product A consist of 1 product B and 1 product C. Product B and C are being priced at USD 5 and USD 6 respectively. The price of Product A would be USD 11. You cannot change it.
 +
 +
Meanwhile we often find a case where the price of Product A IS NOT the price of product B or C combined. It can be higher or lower. I try to add price to product A, which not the combined price but it doesn't work. This is what happen.
 +
 +
I put price of USD 15 for product A. When I created Sales Order, and I chose product A the price was still USD 15. Everything felt right. And then the disaster came. When I click Complete button suddenly the price change to USD 11!
 +
 
 +
 
 +
If the BOM is not stocked it is considered a 'basket; and will compute the price based on the component prices.
 +
 
 +
If you want to assign a price change it to 'stocked'
 +
 
 +
=== Developer hints ===
 +
* class dbPort/org.compiere.process.DocActionTemplate shows a template for DocAction, i think that it must be updated.
 +
 
 +
* [http://www.youtube.com/watch?v=tRHyFODLlUE Video created by Tim; part 1]
 +
* [http://www.youtube.com/watch?v=tRHyFODLlUE Video created by Tim; part 2]
 +
* [http://www.adempiere.com/wiki/index.php/Open_Window_and_Tab Open Window and Tab programmatically], [https://sourceforge.net/forum/message.php?msg_id=4137884 sf.net post]
 +
 
 +
 
 +
==== Hint-1; UPDATE columns which must have default value or have checked constraint ====
 +
When developer add new column which is NOT NULL or which has checked constraint, please do not forget to execute proper UPDATE TABLE sql statements.
 +
 
 +
Example:
 +
<pre>
 +
ALTER TABLE EXP_FormatLine
 +
ADD IsPartUniqueIndex CHAR(1) CHECK(IsPartUniqueIndex IN ('Y', 'N'));
 +
 
 +
UPDATE EXP_FormatLine
 +
SET IsPartUniqueIndex = 'N'
 +
WHERE IsPartUniqueIndex IS NULL;
 +
</pre>
 +
 
 +
==== Hint-2; Be carefull when creating VIEWS ====
 +
Use LEFT/RIGHT OUTER JOINS, because in many cases fields do not have values and INNER JOIN will not show all records.
 +
In this example C_Invoice.C_Order_ID is not manadatory so view will not show records which do not have Order associated with Invoice!
 +
 
 +
<pre>
 +
FROM C_Invoice i
 +
    INNER JOIN C_DocType d ON (i.C_DocType_ID=d.C_DocType_ID)
 +
    LEFT OUTER JOIN C_Order o ON (i.C_Order_ID=o.C_Order_ID)
 +
</pre>
 +
 
 +
==== Hint-3; Java on Ubuntu ====
 +
Ubuntu came with default version of java 1.4.2 and installing 1.5.0 didn't change that. So developer have to change it. Exporting the path to your newer java to the .bashrc config file of your environment is a standadrd decision but is not system wide and in some cases is not enough.
 +
The decision is. When you type at the prompt:
 +
<pre>
 +
  $ sudo update-java-alternatives -l
 +
</pre>
 +
will see the versions of all javas installed into your system. In order to make the latest one default for the whole system type:
 +
<pre>
 +
  $ sudo update-java-alternatives -s java-newer-ver
 +
</pre>
 +
 
 +
 
 +
==== Hint-4; How to truncate timestamp ====
 +
<pre>
 +
Timestamp today = TimeUtil.trunc(new Timestamp (System.currentTimeMillis() ), TimeUtil.TRUNC_DAY);
 +
</pre>
 +
 
 +
 
 +
==== Hint-5; How to use MTable.get(..) and MTable.getPO(..) ====
 +
Class: base/src/org/compiere/model/MProduct.java
 +
 
 +
<pre>
 +
public MAttributeInstance getAttributeInstance(String name, String trxName)
 +
{
 +
MAttributeInstance instance = null;
 +
 +
MTable table = MTable.get(Env.getCtx(), MAttribute.Table_ID);
 +
MAttribute attribute = (MAttribute)table.getPO("Name = ?", new Object[]{name}, trxName);
 +
if ( attribute == null ) return null;
 +
table = MTable.get(Env.getCtx(), MAttributeInstance.Table_ID);
 +
instance = (MAttributeInstance)table.getPO(
 +
MAttributeInstance.COLUMNNAME_M_AttributeSetInstance_ID + "=?"
 +
+ " and " + MAttributeInstance.COLUMNNAME_M_Attribute_ID + "=?" ,
 +
new Object[]{getM_AttributeSetInstance_ID(), attribute.getM_Attribute_ID()},
 +
trxName);
 +
return instance;
 +
}
 +
</pre>
 +
 
 +
==== Subversion Access ====
 +
Subversion Plugin for Eclipse [http://www.polarion.org/index.php?page=download&project=subversive Subversive]
 +
 
 +
Adempiere project's SourceForge.net Subversion repository can be checked out through SVN with the following instruction set:
 +
svn co https://adempiere.svn.sourceforge.net/svnroot/adempiere adempiere
 +
 
 +
* SVN Browse: [http://adempiere.svn.sourceforge.net/viewvc/adempiere/ here]
 +
 
 +
==== MFG ====
 +
[http://sourceforge.net/forum/message.php?msg_id=4440920 sf.net forum post]
 +
 
 +
Important Steps:
 +
<pre>
 +
1. Apply the following patches:
 +
 +
buildbase.patch.tim
 +
buildclient.patch.tim
 +
buildutils_dev.patch.tim
 +
X_AD_WF_Node.patch
 +
X_C_DocType.patch
 +
X_S_Resource.patch
 +
X_AD_Workflow.patch
 +
X_M_Cost.patch
 +
X_M_Transaction.patch
 +
X_M_Product.patch
 +
 +
2. I copied adempiere/libero/build.xml.tim to adempiere/libero/build.xml
 +
 +
Build your Adempiere and run it. 
 +
 
 +
3. Create a new client and import accounting etc...
 +
(If you don't do this you won't see all the menus, you can't just login under GardenAdmin/GardenAdmin that is not enough)
 +
It looks that 2pack file do not contains proper access records.
 +
Must research!!!
 +
 
 +
4. Login with your new client Admin login you created in step3 and Libero away!!!
 +
</pre>
 +
 
 +
 
 +
===== Compiling adempiere + libero from SVN head =====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4648987 sf.net post]
 +
 
 +
<pre>
 +
1. Check out the head version of both libero and adempiere
 +
2. Build adempiere
 +
3. Build libero
 +
4. Rebuild adempiere (to get the libero.jar into the install)
 +
5. Set up the database. (Create database, run the pljava deployer, drop the
 +
sqlj schema, import the dump file)
 +
6. Run the 330-trunk database migrations
 +
7. Copy EE01.zip into the packages directory
 +
8. Run silent setup and start the app server.
 +
9. Launch the Adempiere client
 +
10. Add the EE01 entity type
 +
11. Pack in the EE01.zip
 +
12. Copy libero.jar into the packages/packages/EE01/lib directory.
 +
13. Re-run silentsetup and start the server.
 +
</pre>
 +
 
 +
==== Template Process and steps to create a process ====
 +
1)create a java class extends org.compiere.process.SvrProcess
 +
 
 +
2)Implements two methods
 +
void doIt()
 +
String prepare()
 +
 
 +
In Prepare method you can get different parameters
 +
ProcessInfoParameter[] para = getParameter();
 +
for (int i = 0; i < para.length; i++)
 +
{
 +
String name = para[i].getParameterName();
 +
if (para[i].getParameter() == null)
 +
;
 +
else
 +
System.out.println(name);
 +
}
 +
and in doIt method you try to insert this parameters into your table
 +
after you create this class
 +
Login with system administrator role
 +
 
 +
3) 'Report and Process' window define your process with parameter
 +
4) 'Table and Column' window choose your table and create a column with Button Reference
 +
 
 +
5) Choose your process for this Button
 +
 
 +
<pre>
 +
package org.adempiere.process;
 +
 
 +
import java.sql.PreparedStatement;
 +
import java.sql.ResultSet;
 +
import java.sql.SQLException;
 +
import java.util.logging.Level;
 +
 
 +
import org.compiere.model.MClient;
 +
import org.compiere.model.MDocType;
 +
import org.compiere.model.X_C_BPartner_EDI;
 +
import org.compiere.model.X_C_EDIFormat;
 +
import org.compiere.model.X_C_EDIProcessor;
 +
import org.compiere.process.ProcessInfoParameter;
 +
import org.compiere.process.SvrProcess;
 +
import org.compiere.util.DB;
 +
import org.compiere.util.Env;
 +
import org.compiere.util.Msg;
 +
 
 +
/**
 +
*  @author Trifon Trifonov
 +
*  @version $Id:$
 +
*/
 +
public class ModelImporter extends SvrProcess
 +
{
 +
/** Client Parameter */
 +
protected int p_AD_Client_ID = 0;
 +
 +
/** Business Partner Parameter */
 +
protected int p_C_BPartner_ID = 0;
 +
 +
/** Document Type Parameter */
 +
protected int p_C_DocType_ID = 0;
 +
 +
/** Record ID */
 +
protected int p_Record_ID = 0;
 +
 +
/** Table ID */
 +
int AD_Table_ID = 0;
 +
 +
/**
 +
* Get Parameters
 +
*/
 +
protected void prepare ()
 +
{
 +
 +
p_Record_ID = getRecord_ID();
 +
if (p_AD_Client_ID == 0)
 +
p_AD_Client_ID = Env.getAD_Client_ID(getCtx());
 +
AD_Table_ID = getTable_ID();
 +
 +
StringBuffer sb = new StringBuffer ("AD_Table_ID=").append(AD_Table_ID);
 +
sb.append("; Record_ID=").append(getRecord_ID());
 +
// Parameter
 +
ProcessInfoParameter[] para = getParameter();
 +
for (int i = 0; i < para.length; i++)
 +
{
 +
String name = para[i].getParameterName();
 +
if (para[i].getParameter() == null)
 +
;
 +
else if (name.equals("C_BPartner_ID"))
 +
p_C_BPartner_ID = para[i].getParameterAsInt();
 +
else
 +
log.log(Level.SEVERE, "Unknown Parameter: " + name);
 +
}
 +
 +
log.info(sb.toString());
 +
}
 +
 
 +
/**
 +
* Process
 +
* @return info
 +
*/
 +
protected String doIt () throws Exception
 +
{
 +
StringBuffer result = new StringBuffer("");
 +
 +
MClient client = MClient.get (getCtx(), p_AD_Client_ID);
 +
log.info(client.toString());
 +
// get proper EDI Format from Document Type
 +
MDocType docType = MDocType.get(getCtx(), p_C_DocType_ID);
 +
 +
int C_EDIFormat_ID = 0;
 +
int C_EDIProcessor_ID = 0;
 +
String sql1 = "SELECT C_EDIFormat_ID, C_EDIProcessor_ID "
 +
  + "FROM " + X_C_BPartner_EDI.Table_Name + " "
 +
  + "WHERE AD_Client_ID = ? "
 +
  + " AND C_BPartner_ID = ? "
 +
  + " AND C_DocType_ID = ? "
 +
  + " AND Inbound = 'N' "
 +
;
 +
ResultSet rs1 = null;
 +
PreparedStatement pstmt1 = null;
 +
try
 +
{
 +
pstmt1 = DB.prepareStatement(sql1, get_TrxName());
 +
pstmt1.setInt(1, p_AD_Client_ID);
 +
pstmt1.setInt(2, p_C_BPartner_ID);
 +
pstmt1.setInt(3, p_C_DocType_ID);
 +
rs1 = pstmt1.executeQuery();
 +
if (rs1.next())
 +
{
 +
// Found specific C_EDIFormat for given BPartner and C_DocType_ID
 +
C_EDIFormat_ID = rs1.getInt(X_C_EDIFormat.COLUMNNAME_C_EDIFormat_ID);
 +
C_EDIProcessor_ID = rs1.getInt(X_C_EDIProcessor.COLUMNNAME_C_EDIProcessor_ID);
 +
} else {
 +
// Get C_EDIFormat_ID from Document Type
 +
C_EDIFormat_ID = docType.getC_EDIFormat_ID();
 +
}
 +
 +
} finally {
 +
try {
 +
if (rs1 != null) rs1.close();
 +
if (pstmt1 != null) pstmt1.close();
 +
} catch (SQLException ex) {/*ignored*/}
 +
rs1 = null;
 +
pstmt1 = null;
 +
}
 +
if (C_EDIFormat_ID == 0) {
 +
throw new Exception("EDI Format is not set for C_DocType_ID = [" + p_C_DocType_ID + "]");
 +
}
 +
if (C_EDIProcessor_ID == 0) {
 +
throw new Exception("EDI Processor is not set for C_DocType_ID = [" + p_C_DocType_ID + "]");
 +
}
 +
 +
addLog(0, null, null, Msg.getMsg (getCtx(), "EDISubmitProcessResult") + "\n" + result.toString());
 +
return result.toString();
 +
}
 +
}
 +
</pre>
 +
 
 +
==== Migration with SQL statements - Oracle - AD_Element ====
 +
<pre>
 +
INSERT INTO AD_Element
 +
(AD_Element_ID, AD_Client_ID, AD_Org_ID, IsActive,
 +
Created, CreatedBy,
 +
Cpdated, UpdatedBy,
 +
ColumnName, EntityType, Name,
 +
PrintName
 +
)
 +
VALUES (500XX, 0, 0, 'Y',
 +
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
'[ColumnNameHere]', 'D', '[NameHere]',
 +
'[PrintNameHere]'
 +
);
 +
COMMIT;
 +
UPDATE AD_Sequence
 +
SET CurrentNextSys = (SELECT MAX (AD_Element_ID) + 1
 +
FROM AD_Element
 +
WHERE AD_Element_ID < 1000000)
 +
WHERE NAME = 'AD_Element';
 +
</pre>
 +
 
 +
 
 +
==== Migration with SQL statements - Oracle - AD_Table ====
 +
<pre>
 +
INSERT INTO AD_Table
 +
(AD_Table_ID, AD_Client_ID, AD_Org_ID, IsActive,
 +
Created, CreatedBy,
 +
Updated, UpdatedBy,
 +
Name, Description, Help, TableName,
 +
IsView, AccessLevel, EntityType, AD_Window_ID,
 +
AD_Val_Rule_ID, LoadSeq, IsSecurityEnabled, IsDeleteable,
 +
IsHighVolume, ImportTable, IsChangelog, ReplicationType,
 +
PO_Window_ID, CopyColumnsFromTable
 +
)
 +
VALUES
 +
(53014, 0, 0, 'Y',
 +
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
'[NameHere]', '[DescriptionHere]', '[HelpHere]', '[TableNameHere]',
 +
'N', '4', 'D', null,
 +
null, 0, 'N', 'Y',
 +
'N', 'N', 'N', 'L',
 +
null, 'N'
 +
);
 +
 
 +
COMMIT;
 +
UPDATE AD_Sequence
 +
SET CurrentNextSys = (SELECT MAX (AD_Table_ID) + 1
 +
FROM AD_Table
 +
WHERE AD_Table_ID < 1000000)
 +
WHERE NAME = 'AD_Table';
 +
</pre>
 +
 
 +
==== Migration with SQL statements - Oracle - AD_Column ====
 +
<pre>
 +
INSERT INTO AD_Column
 +
(AD_Column_ID, AD_Client_ID, AD_Org_ID, IsActive,
 +
Created,
 +
Updated, CreatedBy,
 +
UpdatedBy, Name, Description, Version,
 +
EntityType, ColumnName, AD_Table_ID, AD_Reference_ID,
 +
FieldLength, IsKey, IsParent, IsMandatory, IsUpdateable,
 +
IsIdentifier, SeqNo, IsTranslated, IsEncrypted,
 +
IsSelectionColumn, AD_Element_ID, Callout, IsSyncDatabase,
 +
IsAlwaysUpdateable
 +
)
 +
VALUES (502XX, 0, 0, 'Y',
 +
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'),
 +
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
100, '[NameHere]', '[DescriptionHere]', 1,
 +
'D', '[ColumnNameHere]', AD_Table_IDHERE, AD_Reference_IDHere,
 +
1, 'N', 'N', 'Y', 'Y',
 +
'N', 0, 'N', 'N',
 +
'N', 50071, '[CalloutHere]', 'N',
 +
'N'
 +
);
 +
COMMIT;
 +
UPDATE AD_Sequence
 +
SET CurrentNextSys = (SELECT MAX (AD_Column_ID) + 1
 +
FROM AD_Column
 +
WHERE AD_Column_ID < 1000000)
 +
WHERE NAME = 'AD_Column';
 +
</pre>
 +
 
 +
==== Migration with SQL statements - Oracle - AD_Window ====
 +
<pre>
 +
INSERT INTO AD_Window
 +
(AD_Window_ID,AD_Client_ID, AD_Org_ID, IsActive,
 +
Created, CreatedBy,
 +
Updated, UpdatedBy,
 +
Name, Description, Help, WindowType,
 +
IsSoTrx, EntityType, Processing, AD_Image_ID,
 +
AD_Color_ID, IsDefault, WinHeight, WinWidth,
 +
IsBetaFunctionality
 +
)
 +
VALUES (53003, 0, 0, 'Y',
 +
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
'[NameHere]', null, null, 'M',
 +
'N', 'D', 'N', null,
 +
null, 'N', 0, 0,
 +
'N'
 +
);
 +
 
 +
COMMIT;
 +
UPDATE AD_Sequence
 +
SET CurrentNextSys = (SELECT MAX (AD_Window_ID) + 1
 +
  FROM AD_Window
 +
  WHERE AD_Window_ID < 1000000)
 +
WHERE Name = 'AD_Window';
 +
</pre>
 +
 
 +
 
 +
==== Migration with SQL statements - Oracle - AD_Tab ====
 +
<pre>
 +
INSERT INTO AD_Tab
 +
(AD_Tab_ID, AD_Client_ID, AD_Org_ID, IsActive,
 +
Created, CreatedBy,
 +
Updated, UpdatedBy,
 +
Name, Description, Help, AD_Table_ID,
 +
AD_Window_ID, SeqNo, TabLevel, IsSingleRow,
 +
IsInfoTab, IsTranslationTab, IsReadOnly, AD_Column_ID,
 +
HasTree, WhereClause, OrderByClause, CommitWarning,
 +
AD_Process_ID, Processing, AD_Image_ID, ImportFields,
 +
AD_ColumnSortOrder_ID, AD_ColumnSortYesNo_ID, IsSortTab, EntityType,
 +
Included_Tab_ID, ReadOnlyLogic, DisplayLogic, IsInsertRecord,
 +
IsAdvancedTab
 +
)
 +
VALUES (53014, 0, 0, 'Y',
 +
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
'[NameHere]', null, null, [AD_TableIDHERE],
 +
[AD_Window_IDHERE], [SeqNoHERE], 0, 'N',
 +
'N', 'N', 'N', null,
 +
'N', null, null, null,
 +
null, 'N', null, 'N',
 +
null, null, 'N', 'D',
 +
null, null, null, 'Y',
 +
'N'
 +
);
 +
 
 +
COMMIT;
 +
UPDATE AD_Sequence
 +
SET CurrentNextSys = (SELECT MAX (AD_Tab_ID) + 1
 +
  FROM AD_Tab
 +
  WHERE AD_Tab_ID < 1000000)
 +
WHERE Name = 'AD_Tab';
 +
</pre>
 +
 
 +
 
 +
==== Migration with SQL statements - Oracle - AD_Field ====
 +
<pre>
 +
INSERT INTO AD_Field
 +
(AD_Field_ID, AD_Client_ID, AD_Org_ID, IsActive,
 +
Created, CreatedBy,
 +
Updated, UpdatedBy,
 +
Name, Description, IsCentrallyMaintained, SeqNo, AD_Tab_ID,
 +
AD_Column_ID, IsDisplayed, DisplayLength, IsReadonly,
 +
IsSameLine, IsHeading, IsFieldOnly, IsEncrypted, EntityType
 +
)
 +
VALUES (50184, 0, 0, 'Y',
 +
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
'Store Archive On File System', 'Store Archive On File System', 'Y', 250, 145,
 +
50214, 'Y', 1, 'N',
 +
'N', 'N', 'N', 'N', 'D'
 +
);
 +
COMMIT;
 +
UPDATE AD_Sequence
 +
SET CurrentNextSys = (SELECT MAX (AD_Field_ID) + 1
 +
  FROM AD_Field
 +
  WHERE AD_Field_ID < 1000000)
 +
WHERE Name = 'AD_Field';
 +
</pre>
 +
 
 +
 
 +
==== Migration with SQL statements - Oracle - AD_Menu ====
 +
<pre>
 +
INSERT INTO AD_Menu
 +
(AD_Menu_ID, AD_Client_ID, AD_Org_ID, IsActive,
 +
Created, CreatedBy,
 +
Updated, UpdatedBy,
 +
Name, Description, IsSummary, IsSoTrx,
 +
IsReadOnly, Action, AD_Window_ID, AD_Workflow_ID,
 +
AD_Task_ID, AD_Process_ID, AD_Form_ID, AD_Workbench_ID,
 +
EntityType
 +
)
 +
VALUES( 53012, 0, 0, 'Y',
 +
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
'[NameHERE]', NULL, 'N', 'N',
 +
'N', 'W', [AD_Window_IDHERE], NULL,
 +
NULL, NULL, NULL, NULL,
 +
'D'
 +
);
 +
COMMIT;
 +
UPDATE AD_Sequence
 +
SET CurrentNextSys = (SELECT MAX (AD_Menu_ID) + 1
 +
  FROM AD_Menu
 +
  WHERE AD_Menu_ID < 1000000)
 +
WHERE Name = 'AD_Menu';
 +
</pre>
 +
 
 +
 
 +
==== Migration with SQL statements - Oracle - AD_TreeNodeMM ====
 +
<pre>
 +
INSERT INTO AD_TreeNodeMM
 +
(AD_Tree_ID, Node_ID, AD_Client_ID, AD_Org_ID, IsActive,
 +
Created, Createdby,
 +
Updated, UpdatedBy, Parent_ID, SeqNo
 +
)
 +
VALUES (10, [Node_IDHERE], 0, 0, 'Y',
 +
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 0,
 +
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 0, [Parent_IDHERE], [SeqNoHERE]
 +
);
 +
COMMIT;
 +
UPDATE AD_Sequence
 +
SET CurrentNextSys = (SELECT MAX (AD_Menu_ID) + 1
 +
  FROM AD_Menu
 +
  WHERE AD_Menu_ID < 1000000)
 +
WHERE Name = 'AD_Menu';
 +
</pre>
 +
 
 +
==== Migration with SQL statements - AD_Message ====
 +
<pre>
 +
INSERT INTO AD_Message
 +
(AD_Message_ID, AD_Client_ID, AD_Org_ID, IsActive,
 +
Created, CreatedBy,
 +
Updated, UpdatedBy,
 +
Value, MsgText, MsgType
 +
)
 +
VALUES (500XX, 0, 0, 'Y',
 +
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
 +
'[VaueHere]','[MSG Text Here]','I'
 +
);
 +
COMMIT;
 +
UPDATE AD_Sequence
 +
SET CurrentNextSys = (SELECT MAX (AD_Message_ID) + 1
 +
FROM AD_Message
 +
WHERE AD_message_ID < 1000000)
 +
WHERE NAME = 'AD_Message';
 +
</pre>
 +
 
 +
==== Migration with SQL statements - AD_Process_Para ====
 +
<pre>
 +
INSERT INTO AD_Process_Para
 +
(AD_Process_Para_ID, AD_Client_ID, AD_Org_ID, IsActive, Created,
 +
CreatedBy, Updated, UpdatedBy, Name,
 +
Description,
 +
Help,
 +
AD_Process_ID, SeqNo, AD_Reference_ID, AD_Reference_Value_ID,
 +
AD_Val_Rule_ID, ColumnName, IsCentrallyMaintained, FieldLength,
 +
IsMandatory, IsRange, AD_Element_ID, EntityType
 +
)
 +
VALUES (50019, 0, 0, 'Y', TO_DATE ('2007-03-03', 'YYYY-MM-DD'),
 +
100, TO_DATE ('2007-03-03', 'YYYY-MM-DD'), 100, 'Shipment Date',
 +
'Date printed on shipment',
 +
'The Shipment Date indicates the date printed on the shipment.',
 +
118, 15, 15, NULL,
 +
NULL, 'MovementDate', 'N', 0,
 +
'Y', 'N', 1037, 'D'
 +
);
 +
COMMIT;
 +
UPDATE AD_SEQUENCE
 +
SET currentnextsys = (SELECT MAX (ad_process_para_id) + 1
 +
FROM AD_Process_Para
 +
WHERE AD_Process_Para_ID < 1000000)
 +
WHERE NAME = 'AD_Process_Para';
 +
</pre>
 +
 
 +
 
 +
==== Migration with SQL statements - AD_Ref_List - Postgre ====
 +
<pre>
 +
INSERT INTO AD_Ref_List (
 +
Created, CreatedBy, Updated, UpdatedBy,
 +
AD_Org_ID, AD_Ref_List_ID, AD_Reference_ID,
 +
Value, Name, IsActive, AD_Client_ID, EntityType
 +
) VALUES (
 +
TO_TIMESTAMP('2008-01-19 22:45:00','YYYY-MM-DD HH24:MI:SS'), 0, TO_TIMESTAMP('2008-01-19 22:45:00','YYYY-MM-DD HH24:MI:SS'), 0,
 +
0, 53287, 329,
 +
'DOO', 'Distribution Order', 'Y',0,'EE01'
 +
);
 +
</pre>
 +
 
 +
==== Session_IsChangeLog, AD_Table.IsChangeLog, AD_Column.IsChangeLog combination ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4561355 sf.net post]
 +
<pre>
 +
1. Session_IsChangeLog=no,  AD_Table.IsChangeLog=no,  AD_Column.IsChangeLog=no
 +
    =>is column logged: no
 +
2. Session_IsChangeLog=no,  AD_Table.IsChangeLog=no,  AD_Column.IsChangeLog=yes
 +
    =>is column logged: no
 +
3. Session_IsChangeLog=no,  AD_Table.IsChangeLog=yes, AD_Column.IsChangeLog=no
 +
    =>is column logged: no
 +
4. Session_IsChangeLog=no,  AD_Table.IsChangeLog=yes, AD_Column.IsChangeLog=yes
 +
    =>is column logged: yes
 +
5. Session_IsChangeLog=yes, AD_Table.IsChangeLog=no,  AD_Column.IsChangeLog=no
 +
    =>is column logged: no
 +
6. Session_IsChangeLog=yes, AD_Table.IsChangeLog=no,  AD_Column.IsChangeLog=yes
 +
    =>is column logged: yes
 +
7. Session_IsChangeLog=yes, AD_Table.IsChangeLog=yes, AD_Column.IsChangeLog=no
 +
    =>is column logged: no
 +
8. Session_IsChangeLog=yes, AD_Table.IsChangeLog=yes, AD_Column.IsChangeLog=yes
 +
    =>is column logged: yes
 +
 
 +
Note: Session_IsChangeLog means: AD_Role.IsChangeLog or is a webstore session.
 +
 
 +
Observation1: as you see, AD_Column.IsChangeLog=Y means inherit policy from
 +
parent (AD_Table) and AD_Column.IsChangeLog=N means never log this record.
 +
 
 +
PS: in future, i think we can move from IsChangeLog flag to some
 +
ChangeLogPolicy=(Always, Never, Inherit from parent).
 +
</pre>
 +
 
 +
 
 +
==== How to use Transactions and Save points in Adempiere ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4584671 sf.net post]
 +
 
 +
<pre>
 +
String trxName = Trx.createTrxName("test");
 +
Trx trx = Trx.get(trxName, true);
 +
Savepoint save1 = trx.setSavepoint("save1");
 +
 
 +
location = new MLocation(m_Ctx, 0, trxName);
 +
 
 +
...
 +
 
 +
trx.rollback(save1);
 +
 
 +
trx.commit();
 +
trx.close();
 +
</pre>
 +
 
 +
 
 +
==== How to build Adempiere customization.jar ====
 +
Customization.jar is in the lib directory of trunk. (ie /trunk/lib )
 +
Go to that directory and execute following commands:
 +
 
 +
jar uvf customization.jar -C ../libero/build/ ./org/compiere/model/
 +
jar uvf customization.jar -C ../libero/build/ ./org/compiere/acct/
 +
jar uvf customization.jar -C ../libero/build/ ./org/compiere/process/
 +
 
 +
Then goto utils_dev directory and ./RUN_build.sh
 +
 
 +
After the build has completed the new customized.jar will be in $ADEMPIERE_HOME/lib
 +
Adempiere should now use the customized classes.
 +
 
 +
 
 +
==== How to Open Window from source code? ====
 +
 
 +
<pre>
 +
MQuery aQuery = new  MQuery ("C_Invoice");
 +
aQuery.setRecordCount(1);
 +
aQuery.addRestriction("C_Invoice_ID", "=", C_Invoice_ID );
 +
 
 +
AWindow frame = new AWindow();
 +
frame.initWindow(183, aQuery); // 183=window "Invoice (Vendor)"
 +
 
 +
frame.validate();
 +
AEnv.showCenterScreen(frame);
 +
</pre>
 +
 
 +
 
 +
==== How to keep parameter window open after view report? ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4688709 sf.net post]
 +
 
 +
 
 +
==== How to create confirmation for inventory move? ====
 +
* [https://sourceforge.net/tracker/?func=detail&atid=879334&aid=1875267&group_id=176962 sf.net post]
 +
 
 +
 
 +
==== How to make Adempiere LDAP username registration compatible with OpenLDAP ====
 +
* [http://adempiere.svn.sourceforge.net/adempiere/?rev=4301&view=rev sf.net link]
 +
<pre>
 +
- StringBuffer principal = new StringBuffer (userName).append("@").append(domain);
 +
+ // For OpenLDAP uncomment the next line 
 +
+ // StringBuffer principal = new StringBuffer("uid=").append(userName).append(",").append(domain);
 +
+ StringBuffer principal = new StringBuffer(userName).append("@").append(domain);
 +
  env.put(Context.SECURITY_PRINCIPAL, principal.toString());
 +
  env.put(Context.SECURITY_CREDENTIALS, password);
 +
</pre>
 +
 
 +
 
 +
==== How to use JSR 223: Scripting callouts in Adempiere? ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4740486 sf.net forum post]
 +
* [[Script Callout]]
 +
 
 +
==== How to get Compiere Home from java class? ====
 +
 
 +
<pre>
 +
org.compiere.util.Ini.findAdempiereHome()
 +
</pre>
 +
 
 +
=== License to use for new classes ===
 +
<pre>
 +
/**********************************************************************
 +
* This file is part of Adempiere ERP Bazaar                          *
 +
* http://www.adempiere.org                                            *
 +
*                                                                    *
 +
* Copyright (C) Trifon Trifonov.                                      *
 +
* Copyright (C) Contributors                                          *
 +
*                                                                    *
 +
* This program is free software; you can redistribute it and/or      *
 +
* modify it under the terms of the GNU General Public License        *
 +
* as published by the Free Software Foundation; either version 2      *
 +
* of the License, or (at your option) any later version.              *
 +
*                                                                    *
 +
* 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., 51 Franklin Street, Fifth Floor, Boston,          *
 +
* MA 02110-1301, USA.                                                *
 +
*                                                                    *
 +
* Contributors:                                                      *
 +
* - Trifon Trifonov (trifonnt@users.sourceforge.net)                  *
 +
*                                                                    *
 +
* Sponsors:                                                          *
 +
* - Company (http://www.site.com)                                    *
 +
***********************************************************************/
 +
...
 +
...
 +
/**
 +
* @author Trifon Trifonov
 +
* @version $Id$
 +
*/
 +
</pre>
 +
 
 +
=== Adempiere Export/Import Tools ===
 +
* ADCK can be used in two modes.
 +
** As Development tool. To model DB design and create/modify tables.
 +
As Development tool ADCK uses Druid which allows developer to generate CREATE TABLE and ALTER table SQL statement for various DBs: Oracle, Postgres, MySQL, ...
 +
As Development tool ADCK can generate xml files for various tools and frameworks like: [http://www.hibernate.org/ hibernate], [http://db.apache.org/torque/ torque].
 +
 
 +
** As transfer tool for only migrating AD changes from Adempiere instance to instance or from version to version.
 +
As transfer tool ADCK require initial just setting of proper settings in properties files.
 +
 
 +
==== 2Pack vs. ADCK comparison table. ====
 +
 
 +
This table is made with the sole purpose to help me to organize information regarding import/export tools in Adempiere.
 +
I do not have any idea to push any of the tools mentiod here.
 +
It is user's choice to use or not to use any of them and also users choice to have headache after thier usage.
 +
 
 +
WARNING: !!!MAKE A BACKUP BEFORE ANY USAGE OF ANY OF THE TOOLS!!!
 +
 
 +
<table>
 +
<tr><td>2Pack</td><td>ADCK</td></tr>
 +
<tr><td>menu</td><td>[[ADCK menu|menu]]</td></tr>
 +
<tr><td>window</td><td>[[ADCK window|window]]</td></tr>
 +
<tr><td>tab</td><td>[[ADCK tab|tab]]</td></tr>
 +
<tr><td>field</td><td>[[ADCK field|field]]</td></tr>
 +
<tr><td>process</td><td>[[ADCK process|process]]</td></tr>
 +
<tr><td>processpara</td><td>[[ADCK processpara|processpara]]</td></tr>
 +
<tr><td>table</td><td>[[ADCK table|table]]</td></tr>
 +
<tr><td>column</td><td>[[ADCK column|column]]</td></tr>
 +
<tr><td>impformat</td><td>[[ADCK AD_ImpFormat|AD_ImpFormat]]</td></tr>
 +
<tr><td>impformatrow</td><td>[[ADCK AD_ImpFormat|AD_ImpFormat_Row]]</td></tr>
 +
<tr><td>printformat</td><td>[[ADCK AD_PrintFormat|AD_PrintFormat]]</td></tr>
 +
<tr><td>printformatitem</td><td>[[ADCK AD_PrintFormat|AD_PrintFormatItem]]</td></tr>
 +
<tr><td>reference</td><td>[[ADCK |]]</td></tr>
 +
<tr><td>referencelist</td><td>[[ADCK |]]</td></tr>
 +
<tr><td>referencetable</td><td>[[ADCK |]]</td></tr>
 +
<tr><td>reportview</td><td>[[ADCK |]]</td></tr>
 +
<tr><td>reportviewcol</td><td>[[ADCK |]]</td></tr>
 +
<tr><td>task</td><td>[[ADCK |]]</td></tr>
 +
<tr><td>form</td><td>[[ADCK |]]</td></tr>
 +
<tr><td>workbench</td><td>[[ADCK |]]</td></tr>
 +
<tr><td>preference</td><td>[[ADCK |]]</td></tr>
 +
<tr><td>role</td><td>[[ADCK AD_Role|AD_Role]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK AD_User|AD_User]]</td></tr>
 +
<tr><td>userrole</td><td>[[ADCK AD_User_Roles|AD_User_Roles]]</td></tr>
 +
<tr><td>orgrole</td><td>[[ADCK AD_Role_OrgAccess|AD_Role_OrgAccess]]</td></tr>
 +
<tr><td>windowaccess</td><td>[[ADCK AD_Window_Access|AD_Window_Access]]</td></tr>
 +
<tr><td>processaccess</td><td>[[ADCK AD_Process_Access|AD_Process_Access]]</td></tr>
 +
<tr><td>formaccess</td><td>[[ADCK AD_Form_Access|AD_Form_Access]]</td></tr>
 +
<tr><td>workflowaccess</td><td>[[ADCK AD_Workflow_Access|AD_Workflow_Access]]</td></tr>
 +
<tr><td>taskaccess</td><td>[[ADCK |]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK AD_Column_Access|AD_Column_Access]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK AD_Language|AD_Language]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK AD_Message|AD_Message]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK AD_PrintTableFormat|AD_PrintTableFormat]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK AD_Scheduler|AD_Scheduler]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK C_BP_Group|C_BP_Group]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK M_Product_Category|M_Product_Category]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK PA_ReportColumnSet|PA_ReportColumnSet]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK PA_ReportColumnSet|PA_ReportColumn]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK PA_Report|PA_Report]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK PA_ReportLineSet|PA_ReportLineSet]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK PA_ReportLineSet|PA_ReportLine]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK PA_ReportLineSet|PA_ReportSource]]</td></tr>
 +
<tr><td>???</td><td>[[ADCK AD_Client|AD_Client]]</td></tr>
 +
<tr><td>[[2Pack Any Table| 2Pack Any Table]]</td><td>[[ADCK Any Table|ADCK Any Table]]</td></tr>
 +
 
 +
<tr><td>???</td><td>[[ADCK |TEMPLATE]]</td></tr>
 +
</table>
 +
 
 +
==== Weak sides of 2pack according me ====
 +
* Require integration at source code level with Adempiere, which means that if i need to customize any import functionality i must rebuild whole application or patch it.
 +
** Carlos pointed that 2Pack can import records into any table, even customized.
 +
** My comment is regarding main xml elements like: menu, window, tab, field, process, ... First time when i understood that i need to modify main xml elements was for JasperReports integration when i had to add new column into AD_Process table.
 +
** I think that GenericPO which is responsible to import records into Any Table had one issue (I have to remember the exact reason. It was regarding Sequences or something related. ).
 +
** Format of general imports is complicated.
 +
<pre>
 +
 
 +
</pre>
 +
 
 +
* Main class(org.adempiere.pipo.PackInHandler) which handle import is very big(3800 lines) and complex, which require lot of time for developer to study it and makes modifications hard task.
 +
** Since version 3.3.0 Low Heng Sin refactored org.adempiere.pipo.PackInHandler and now it is split into multiple classes.
 +
 
 +
* 2Pack uses SAX Parser which makes developer job harder as developer can't look forward or backward in XML tree.
 +
 
 +
==== Weak sides of ADCK according me ====
 +
* It is external program, so user do not have such detailed control over security.
 +
* It is harder for developer to work with it as do not have automatic changes extraction like 2Pack.
 +
 
 +
=== Ideas for extensions  ===
 +
 
 +
==== Computerized Maintenance Management System ====
 +
[https://sourceforge.net/forum/message.php?msg_id=4465723 sf.net post]
 +
CMMS is Computerized Maintenance Management System that designed specially for preventive maintenance for assets such as light vehicle, heavy equipment etc. so that company can create budgeting for repair and maintenance for their assets. Technicaly the module give alert to user when an asset have to get action such as replace fuel filter, oil filter or other item spareparts. Therefore these module related with inventory (internal use). Inventory will decrease its stock when user CMMS request for repair and maintenance their an asset.
 +
 
 +
 
 +
==== Additional fields in I_Xxx tables ====
 +
[https://sourceforge.net/forum/message.php?msg_id=4441215 sf.net forum post]
 +
 
 +
By: Carlos (globalqss)
 +
 
 +
Hi, every time I customize tables for a customer (almost all projects) I need
 +
to change the importers and/or make some tricks with not used fields on import.
 +
[Struggling today with this case]
 +
 
 +
Idea!
 +
 
 +
Not tested, but I think I could make a ModelValidator on udpate of I_ table
 +
(i.e. I_BPartner) and process the corresponding fields.
 +
 
 +
The other thing we could do is to add some free fields to every I_ table as
 +
wildcards to save customized or non considered fields and process them properly
 +
with the ModelValidator.
 +
Maybe just adding i.e. 10 fields FreeField01 through FreeField10 on the tables
 +
can make the trick.
 +
 
 +
=== Recent Adempiere changes ===
 +
==== Avoid usage of clearing accounts ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4647051 sf.net post]
 +
 
 +
Tracker also contains a .doc file which show the effect of the change and he scripts to test it with GardenWorld.
 +
 
 +
 
 +
==== Add more query method to MTable ====
 +
* [https://sourceforge.net/tracker/?func=detail&atid=879335&aid=1777787&group_id=176962 Feature Requests-1777787 Add more query method to MTable]
 +
 
 +
Date: 2007-08-21
 +
 
 +
MTable has new method:
 +
<pre>
 +
public Query createQuery(String whereClause, String trxName)
 +
{
 +
return new Query(this, whereClause, trxName);
 +
}
 +
</pre>
 +
 
 +
==== Jar file in 2pack/lib will be packed into Adempiere.jar  ====
 +
Starting from revision 3261 of trunk, any jar file that is pack of the lib folder of a 2pack package will be packed into the Adempiere.jar by the run_setup process. What this mean is, you just need to compile all libero specific code, pack it in a jar file and place it under the lib folder of the libero 2pack archive. Please look at the latest FAPack006.zip in the svn packages folder for an example.
 +
 
 +
 
 +
=== Reorganization of Adempiere menu ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4555658 sf.net post]
 +
 
 +
<pre>
 +
<menu name="" >
 +
  <menu name="Export Format" >
 +
    <window name="Export Format" />
 +
  </menu>
 +
</menu>
 +
 
 +
</pre>
 +
 
 +
 
 +
Suggested menu:
 +
<pre>
 +
<menu name="Quote-to-Invoice" >
 +
  <menu name="Sales Orders" >
 +
    <menu name="Rules" >
 +
      <window name="" />
 +
      ...
 +
    </menu>
 +
    <menu name="Transact" >
 +
      <window name="" />
 +
      ...
 +
    </menu>
 +
    <menu name="Report and Inquire" >
 +
      <window name="" />
 +
      ...
 +
    </menu>
 +
    <menu name="Processes" >
 +
      <window name="" />
 +
      ...
 +
    </menu>
 +
  </menu>
 +
 
 +
  <menu name="Shipments" >
 +
    <menu name="Rules" >
 +
      <window name="" />
 +
      ...
 +
    </menu>
 +
    <menu name="Transact" >
 +
      <window name="" />
 +
      ...
 +
    </menu>
 +
    <menu name="Report and Inquire" >
 +
      <window name="" />
 +
      ...
 +
    </menu>
 +
    <menu name="Processes" >
 +
      <window name="" />
 +
      ...
 +
    </menu>
 +
  </menu>
 +
</menu>
 +
 
 +
</pre>
 +
 
 +
= CRM systems =
 +
* [http://xrms.sourceforge.net/pagebuilder.php?s1=18 XRMS]
 +
** [http://gleez.com/articles/it-systems/xrms-vs-sugarcrm XRMS vs. SugarCRM]
 +
* [http://www.vtiger.com vTiger]
 +
** [http://www.crm-now.de/ online]
 +
** [http://www.vtigerserver.com/ online]
 +
 
 +
* [http://www.freecrm.com Free CRM; provides free and paid subsription]
 +
* [http://yucrm.opencrx.com.cn/crm/ new GUI based on OpenCRX]
 +
* [http://www.codeproject.com/useritems/Excel_Leads_into_MS_CRM.asp Import Leads from Excel via Email into Microsoft CRM] Interesting. Adempiere has the same two phase approach. Temporary tale and after that process which import into real table.
 +
 
 +
== Comparison of CRM systems ==
 +
* [http://www.pc101.com/showthread.php?t=3555 interesting post regarding different offers of CRM packages]
 +
 
 +
 
 +
== Localized in Bulgarian ==
 +
* [http://dl.sugarforge.org/bgcrm/bgcrm/bg_bgdocuments/README_bg_bg.txt SugarCRM]
 +
 
 +
 
 +
== Interesting news/Forum post regarding CRM systems ==
 +
* [http://www.sugarcrm.com/forums/showthread.php?p=81242#post81242 SOAP Performance Issue Loading Accounts] Strange advice "database to database conversion"! But for CRM system probably it is OK!
 +
* [http://www.sugarcrm.com/forums/showthread.php?p=80835#post80835 SugarCRM for blind man's (disabled people)] Very interesting requirements!
 +
* [http://sourceforge.net/forum/forum.php?forum_id=728923 Dimdim Sugar CRM Integration Pack Release]
 +
* [http://www.sugarcrm.com/forums/showthread.php?p=83961#post83961 SugarCRM osCommerce Integration] It is very strange for me too see how developers make integration at DB level. It looks that for CRM system it is completely OK.
 +
* [http://wiki.apexdevnet.com/index.php/Apex_Email_Services Apex Email Services] www.salesforce.com
 +
 
 +
 
 +
= Wiki =
 +
 
 +
== XWiki ==
 +
* [http://www.xwiki.org/xwiki/bin/view/Main/WebHome XWiki site]
 +
* [http://www.theserverside.com/tt/articles/article.tss?l=XWiki XWiki: A Platform for Collaborative Platform Apps]
 +
 
 +
= ERP Systems =
 +
* [http://www.baanusers.co.uk/docs/total_cost_of_erp_ownership.pd.pdf Average price of ERP] Good article. Shows TCO.
 +
* [http://tinyerp.org/wiki/index.php/DevelopperBook/TechSpecArchProgram TinyERP design]
 +
* [http://sourceforge.net/projects/postbooks PostBook] Server part build with Postgre SQL procedures.
 +
* [http://www.openbluelab.org OpenBlueLab] Model Driven Desing
 +
* [http://www.openjades.com/ OpenJades]
 +
* [http://sourceforge.net/projects/gardenia/ Gardenia]Source code is older than binary release.
 +
* [http://seekingalpha.com/article/48112-sap-bets-the-future-on-business-by-design SAP Bets the Future on Business By Design]Quite expensive solution - min 25 user x 125 / month = 3125 / month x 12 = 37 500 USD year.
 +
* [http://www.salmon.ca/pricing.htm Price comparison]
 +
 
 +
 
 +
== ERP Requirements ==
 +
Features that a composite of UK government bodies classified as Mandatory, Highly Desirable and nice-to-have in financial systems.  Chapter 9 sets out their requirements on fixed assets. List they came up seems to have general application.
 +
* [http://www.cio.gov.uk/documents/pdf/sharedservices/technology/D1401.pdf Core Accounting Systems Specification. Core Statement of Requirements]
 +
 
 +
* Historic Data
 +
** [http://tinyerp.org/wiki/index.php/Main/GermanNeedsEn TinyERP Historic Data]
 +
 
 +
 
 +
=== Seats/tables in a restaurant (or plane or cinema) ===
 +
 
 +
In my opinion the seat/table numbering problematic could be solved with the help of the entities AccommodationClass, AccommodationMap  described in the book vol2. I will give you a short description of these entities and example of the "numbering issue" solution.
 +
 
 +
AccommodationClass - description:
 +
It is designed to store classes information (these could be plane, bus classes, table types, chair types, room types etc)
 +
 
 +
AccommodationClass - definition (based on the book but modified a little)
 +
fields: accClassId, parentAccClassId, description
 +
 
 +
 
 +
AccommodationMap - description:
 +
Its idea is to provide information of the number of spaces offered by a fa/accClass. Here we can extend it to provide overbooking information and seat numbering information(the last two fields in the definition below)
 +
fields: mapId, accClassId, faId, nrOfSpaces, overBooked, number
 +
 
 +
Example:
 +
Define two tables.
 +
- Table number 5 has 3 chairs. Chair with number 1 is baby_chair. The other two chairs with number 2 and 3 are high_chairs.
 +
- Table number 9 has 2 chairs. Chairs number 1 and 2 are normal_chairs.
 +
 
 +
In FixedAsset relate the tables to the chairs.
 +
<pre>
 +
FixedAsset:fixedAssetId=table1,  parentFixedAssetId=NULL
 +
FixedAsset:fixedAssetId=table2,  parentFixedAssetId=NULL
 +
FixedAsset:fixedAssetId=chair11, parentFixedAssetId=table1 //chair11 belongs to table1
 +
FixedAsset:fixedAssetId=chair12, parentFixedAssetId=table1 //chair12 belongs to table1
 +
FixedAsset:fixedAssetId=chair13, parentFixedAssetId=table1 //chair13 belongs to table1
 +
FixedAsset:fixedAssetId=chair14, parentFixedAssetId=table2 //chair14 belongs to table2
 +
FixedAsset:fixedAssetId=chair15, parentFixedAssetId=table2 //chair15 belongs to table2
 +
</pre>
 +
 
 +
In Accommodationclass define the table/chair classes.
 +
<pre>
 +
AccommodationClass: accClassId=tables,        parentAccClassId=NULL
 +
AccommodationClass: accClassId=chairs,        parentAccClassId=NULL
 +
AccommodationClass: accClassId=plane_classes, parentAccClassId=NULL
 +
AccommodationClass: accClassId=baby_chair,    parentAccClassId=chairs;
 +
AccommodationClass: accClassId=high_chair,    parentAccClassId=chairs;
 +
AccommodationClass: accClassId=normal_chair,  parentAccClassId=chairs;
 +
</pre>
 +
 
 +
 
 +
In AccommodationMap define how many places each table or chair has and which is its number.
 +
<pre>
 +
AccommodationMap: accClassId=tables,        fixedAssetId=table1,  nrOfSpaces=3, number=5 //table number 5 has 3 chairs(faId=table1)
 +
AccommodationMap: accClassId=baby_chair,    fixedAssetId=chair11, nrOfSpaces=1, number=1 //chair number 1 has one place(faId=chair11)
 +
AccommodationMap: accClassId=high_chair,    fixedAssetId=chair12, nrOfSpaces=1, number=2 //chair number 2 has one place(faId=chair12)
 +
AccommodationMap: accClassId=high_chair,    fixedAssetId=chair13, nrOfSpaces=1, number=3 //chair number 3 has one place(faId=chair13)
 +
AccommodationMap: accClassId=tables,        fixedAssetId=table2,  nrOfSpaces=2, number=9 //table number 9 has two places(faId=table2)
 +
AccommodationMap: accClassId=normal_chair,  fixedAssetId=chair14, nrOfSpaces=1, number=1 //chair number 1 has one place(faId=chair14)
 +
AccommodationMap: accClassId=normal_chair,  fixedAssetId=chair15, nrOfSpaces=1, number=2 //chair number 2 has one place(faId=chair15)
 +
</pre>
 +
 
 +
In similar fashion you can define theaters, planes etc.
 +
Also overbooking data could be kept in the AccommodationMap entity which could be used for hotel reservations. Hourly reservations could be enabled as well with the introduction of the AccommodationSpot entity.
 +
 
 +
== ERP articles ==
 +
 
 +
* [http://www.revenue.ie/index.htm?/leaflets/warehouse.htm Customs Warehouse]
 +
* [http://fscavo.blogspot.com/2007/08/total-cost-study-for-open-source-erp.html Total cost study for an open source ERP project]
 +
 
 +
 
 +
== Comparison of Open Source ERP Systems ==
 +
* [http://www.big.tuwien.ac.at/research/publications/diplomatheses/herzog.pdf A Comparison of Open Source ERP Systems]
 +
 
 +
 
 +
== SAP ==
 +
* [http://www.camagazine.com/2/2/1/6/6/index1.shtml Shattering the SAP myth]Lists SAP Business One features
 +
* [http://sap.ittoolbox.com/documents/popular-q-and-a/sap-business-one-proscons-3200 SAP Business One Pros/Cons]
 +
 
 +
 
 +
== Compiere ==
 +
My opinion is that this is very outdated information, but who knows...
 +
* [http://www.sybase.com/aseex_resources Compiere on Sybase]
 +
* [http://sourceforge.net/tracker/index.php?func=detail&aid=1058112&group_id=29057&atid=410218 The Achilles-heel of most ERP solutions]
 +
 
 +
 
 +
* Interesting posts from Compiere forums
 +
** [https://sourceforge.net/forum/message.php?msg_id=4741205 sf.net forum post]Albert totally killed Compiere Inc.
 +
 
 +
Take over Compiere you need Albert
 +
 
 +
== OpenBravo ==
 +
* [http://wiki.openbravo.com/wiki/index.php/Web_Services_Introduction Web Services]
 +
* [http://jordimash.blogspot.com/2007/12/openbravo-and-ez-publish.html Openbravo and eZ Publish interoperability]
 +
 
 +
== Open Compiere ==
 +
* [http://opencompiere.sourceforge.net/releasenotes/ReleaseNotes-r261-build20070723.xhtml list with bug fixes transfered from Adempiere] Amazing - EDI is part of it :) - Thank you!
 +
 
 +
= Tina POS =
 +
* [http://wiki.openbravo.com/wiki/index.php/TinaPOS_Integration TinaPOS Integration]
 +
 
 +
 
 +
== Weak sides ==
 +
* [https://sourceforge.net/forum/message.php?msg_id=4441167 Bill Of Materials]
 +
 
 +
 
 +
== Questions and Answers ==
 +
* [https://sourceforge.net/forum/message.php?msg_id=4732820 How to add Dual currency?]
 +
 
 +
= HTML/CSS =
 +
* [http://alistapart.com/articles/multicolumnlists CSS Swag: Multi-Column Lists]
 +
* [http://www.dhtmlgoodies.com A library of DHTML and Ajax scripts]
 +
 
 +
 
 +
* Drag and Drop
 +
** [http://tool-man.org/examples/sorting.html Drag & Drop Sortable Lists with JavaScript and CSS]
 +
** [http://www.walterzorn.com/dragdrop/dragdrop_e.htm JavaScript: DHTML API, Drag & Drop for Images and Layers]
 +
 
 +
 
 +
== Tips for Ste design ==
 +
* [http://www.snap2objects.com/2007/12/13/11-images-you-might-want-to-avoid-in-your-designs/ 11 Images you might want to avoid in your designs.]
 +
 
 +
= J2EE =
 +
* [http://www.onjava.com/lpt/a/7214 Using XML and Jar Utility API to Build a Rule-Based Java EE Auto-Deployer]
 +
 
 +
 
 +
= Java related =
 +
* [[Dynamic Proxy]]
 +
* [[Example Adempiere JPA persistance]]
 +
* [http://download-east.oracle.com/docs/cd/B31017_01/web.1013/b28221/cmp30cfg016.htm Configuring Inheritance for a JPA Entity; Explanation why Teo likes DiscriminatorColumn]
 +
* [http://thought-bytes.blogspot.com/2007/04/hello-world-with-standalone-java.html Hello world with standalone java persistence]
 +
* [http://www.javaperformancetuning.com/resources.shtml#ProfilingToolsFree Java Performance Tuning]
 +
 
 +
 
 +
* [http://blog.spaceprogram.com/search/label/linux  Downloading JDK to your Linux Server via SSH]
 +
 
 +
 
 +
* Java Properties
 +
** [http://www.javaworld.com/javaworld/javatips/jw-javatip135.html Java Tip 135: Layer and compare property files]A utility for comparing and combining property files eases multilayer property file organization
 +
** [http://www.baclace.net/java/prop_diff/index.html PropDiff]
 +
 
 +
 
 +
* [http://s3browse.com/explore/static.springframework.org Amazon S3Browse site]
 +
* [http://blog.interface21.com/main/2007/04/25/uploading-to-amazon-s3-using-a-custom-ant-task/ Uploading to Amazon S3 using a custom ANT task]
 +
* [http://www.onjava.com/pub/a/onjava/2007/11/07/introduction-to-amazon-s3-with-java-and-rest.html Introduction to Amazon S3 with Java and REST]
 +
 
 +
 
 +
* [http://entips.sharmavishal.com/2007/09/what-are-common-methods-used-for.html What are the common methods used for session tracking]
 +
* [http://www.rgagnon.com/howto.html Reall Java How To]
 +
* [http://chaoticjava.com/posts/how-to-write-iterators-really-really-fast/ How to write Iterators really REALLY fast]
 +
* [http://www.terracotta.org/ Terracotta: JVM-level clustering technology]
 +
** [http://javathink.blogspot.com/2007/08/extreme-hibernate-performance-delivered.html Extreme Hibernate Performance - Delivered]
 +
** [http://coderoshi.blogspot.com/2007/08/terracotta-jetty-awesome.html  Terracotta + Jetty = Awesome]
 +
* [http://www.artima.com/articles Good list with articles]
 +
* [http://www.codeproject.com/useritems/DBGrid.asp Data Grid for JSP]
 +
* [http://jdevelopment.nl/java/java-best-practices/ Java bad practices]
 +
* [http://www.javalobby.org/articles/ibatis-introduction/ Introduction to iBatis]
 +
* [http://www.bedework.org Bedework: Open Source Calendar for the Enterprise]
 +
* [http://blog.elevenworks.com/?p=18 TreeTable example (with source code)]
 +
* [http://articles.lightdev.com/gantt/gantt_article.pdf Article: Gantt Charts With JXTreeTable ]
 +
* [http://enigmastation.com/rsslibj/ RSS lib]
 +
* [http://www.mvnforum.com MVN forum] Java based forum
 +
* [http://www.javaworld.com/javaworld/jw-09-2007/jw-09-checkboxtree.html?fsrc=rss-index Swing-based tree layouts with CheckboxTree]A configurable tree component with checkable nodes
 +
* [http://blog.taragana.com/index.php/archive/how-to-simulate-telnet-session-in-java/ How To Simulate Telnet Session in Java]
 +
* [http://publicobject.com/glazedlists/ Glazed Lists]
 +
** [http://www.javaworld.com/javaworld/jw-10-2004/jw-1025-glazed.html JTable filtering with Glazed Lists]Use list transformations to add text filtering to your application
 +
** [http://www.ibm.com/developerworks/java/library/j-filters/ Swing model filtering]Using filter objects to reinterpret data and state models
 +
* Java and email clients
 +
** [http://www.firstpr.com.au/web-mail/ Links to emails clients]not only in java
 +
** [http://java-source.net/open-source/mail-clients mail clients in java]
 +
** [http://jwma.sourceforge.net/index.html JWMA]Web email client written in java.
 +
** [http://java-source.net/open-source/mail-clients/columba Columba]Good one, but not active since.
 +
 
 +
 
 +
== Hibernate ==
 +
* [http://hibernatesynch.sourceforge.net/ Hibernate Synchronizer] Eclipse plig-in which automatically generate java code when your hibernate mapping files are modified.
 +
 
 +
 
 +
== JPA ==
 +
* [http://java.sun.com/developer/technicalArticles/J2EE/jpa/ The Java Persistence API - A Simpler Programming Model for Entity Persistence]
 +
* [http://www.theserverside.com/tt/articles/article.tss?l=JPAObjectModel Defining your Object model with JPA] Good article
 +
* [http://www.avaje.org/occ.html Optimistic Concurrency Checking]
 +
* [http://www.avaje.org Object Relational Mapping Persistence Layer] Very interesting. It has features which are good and do not exist in JPA. Like getting access to java.sql.Connection.
 +
* [http://www.winstonprakash.com/articles/articles.html Binding Database Table to a Table Component Using JPA]
 +
 
 +
== Dynamic model; Adding columns runtime ==
 +
* Hibernate
 +
** [http://www.infoq.com/articles/hibernate-custom-fields Using Hibernate to Support Custom Domain Object Fields]Dynamic/Runtime column addition.
 +
** [http://www.hibernate.org/171.html Hibernate and dynamic models]
 +
 
 +
** [http://forums.java.net/jive/thread.jspa?messageID=219628&tstart=0  Can JPA cope with a dynamic schema?]
 +
 
 +
 
 +
* [http://en.wikipedia.org/wiki/Entity-Attribute-Value_model EAV / Entity Attribute Value model]
 +
 
 +
== Data/Properties Binding ==
 +
* [http://jcp.org/en/jsr/detail?id=295 JSR 295: Beans Binding]
 +
* [http://beansbinding.dev.java.net/ Home page at dev.java.net]
 +
* [http://jgoodies.com/downloads/libraries.html JGoodies Binding]
 +
* [http://weblogs.java.net/blog/shan_man/archive/2007/09/beans_binding_1.html Beans Binding 1.0 Released]
 +
* [http://www.javalobby.org/java/forums/t102115.html Bean-dependent or Bean-independent Properties? Lets Battle it Out!]It looks that JSR-295 (Beans Binding) is going to start good discussion regarding type of Ben Properties.
 +
 
 +
 
 +
== Bean Validation ==
 +
* [http://jcp.org/en/jsr/detail?id=303 JSR 303: Bean Validation]
 +
 
 +
* [http://wiki.opensymphony.com/display/XW/Validation+Framework XWork Validation Framework]
 +
 
 +
* [http://jakarta.apache.org/commons/validator/ Commons-Validator]
 +
 
 +
* [http://www.hibernate.org/hib_docs/annotations/reference/en/html/validator.html Hibernate Validator]
 +
 
 +
== Java Tips ==
 +
* [http://www.elluminate.com/support/faqs/jws_show_console.jsp How to show web start console]
 +
* [http://lopica.sourceforge.net/faq.html#awt-class-loading Unofficial Java Web Start/JNLP FAQ]
 +
* [http://www.myloadtest.com/java-thread-dump/ Java Thread Dump] Ctrl+Break
 +
* [http://java.sun.com/developer/technicalArticles/Programming/Stacktrace/ An Introduction to Java Stack Traces]
 +
* [http://www.theserverside.com/news/thread.tss?thread_id=47032 JSON visualization plugin for Eclipse]
 +
* Java Expression Languages
 +
** [http://mvel.codehaus.org/ MVEL]
 +
 
 +
* Iterating through entries of Map or EntrySet
 +
<pre>
 +
// Assuming map = Map<String, String>
 +
for (Iterator iter = map.entrySet().iterator(); iter.hasNext();)
 +
{
 +
    Map.Entry entry = (Map.Entry)iter.next();
 +
    String key = (String)entry.getKey();
 +
    String value = (String)entry.getValue();
 +
}
 +
</pre>
 +
 
 +
 
 +
== Frameworks ==
 +
* [http://www.c1-setcon.com/widgetserver/index.html WidgetServer]
 +
WidgetServer is a component based, server-side, Java/XML rich-client-framework which enables an application to run as either
 +
<pre>
 +
- an application with a rich Web client based on AJAX (HTML, XML, CSS, Javascript)
 +
- an application with a simple Web client based on HTML and CSS
 +
- a standalone application with a Swing GUI,
 +
- a client/server application with a thin Swing client,
 +
- or a mobile application on different devices like PDAs or Smartphones
 +
</pre>
 +
 
 +
* [http://osbl.wilken.de/wiki/index.php/OSBL osbl - OS Business Library]
 +
 
 +
 
 +
=== Struts ===
 +
* [http://www.javaworld.com/javaworld/jw-03-2006/jw-0306-hiberstruts.html Bridge the gap between Struts and Hibernate]Extend Struts for a more object-oriented relationship with Hibernate
 +
 
 +
 
 +
== Design Patterns, Design metrics ==
 +
* [http://www.clarkware.com/software/JDepend.html JDepend] JDepend traverses Java class file directories and generates design quality metrics for each Java package. JDepend allows you to automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to manage package dependencies effectively.
 +
 
 +
== Java and IM ==
 +
* [http://jymsg9.sourceforge.net/ Yahoo Instant Messenger Support for Java]
 +
** [http://www.devx.com/Java/Article/22546/1954?pf=true Build Your Own Messaging Application in Java with jYMSG]
 +
* [http://code.google.com/p/yowl/ yowl]Centralised notification system for use in web applications
 +
 
 +
 
 +
=== IRC ===
 +
* [http://sourceforge.net/projects/moepii IRClib IRC library]
 +
* [http://martyr.sourceforge.net/ Martyr - A Java IRC Library]
 +
* [http://www.jibble.org/pircbot.php PircBot Java IRC Bot]Very nice! SpeechBot, LogBot and other based on PircBot.
 +
 
 +
 
 +
==== IRC Articles ====
 +
* [http://www.onjava.com/pub/a/onjava/2004/09/08/IRCinJava.html IRC Text to Speech with Java]
 +
* [http://www.ibm.com/developerworks/library/j-javabot/index.html IRC bot dreams]
 +
 
 +
== Java Content Repository API ==
 +
* [http://www.ibm.com/developerworks/java/library/j-jcr/ Introducing the Java Content Repository API]
 +
* [http://www.onjava.com/pub/a/onjava/2006/10/04/what-is-java-content-repository.html What is Java Content Repository]
 +
* [http://www.artima.com/lejava/articles/contentrepository.html Catch Jackrabbit and the Java Content Repository API]
 +
 
 +
 
 +
== Autocompletion ==
 +
* [http://www.orbital-computer.de/JComboBox/ Inside JComboBox: adding automatic completion]
 +
* [http://sourceforge.net/tracker/index.php?func=detail&aid=1730452&group_id=176962&atid=879335 Autocompletion in Adempiere by Paul Bowden]
 +
 
 +
 
 +
== CI - Continuous Integration ==
 +
* [http://www.infoq.com/news/2007/12/ci-hudson.html Continuous Integration and Code Inspection with Hudson and FindBugs]
 +
 
 +
 
 +
== Dependency Injection ==
 +
* [http://www.javalobby.org/articles/swing-fuse/ Easier Custom Components with Swing Fuse]
 +
 
 +
 
 +
== Java Graph/Report packages ==
 +
* [http://sourceforge.net/projects/linguinemaps/ Linguine Maps]Provides clean object-oriented diagramming API for graph visualization. It visualizes Apache Ant files, Hibernate and Apache Object Relational Bridge mapping files, DTD's for XML and more.
 +
 
 +
** [http://www.softwaresecretweapons.com/jspwiki/linguinemaps Linguine Maps Examples]
 +
** [http://www.softwaresecretweapons.com/jspwiki/howtouselinguinemapsjavaapi How To Use Linguine Maps Java API]
 +
 
 +
* [http://www.graphviz.org/ Graphviz] - Graph Visualization Software
 +
 
 +
* [http://www.javaworld.com/javaworld/jw-12-2006/jw-1209-swing.html Export Swing components to PDF]Use JFreeChart and iText to draw charts
 +
 
 +
== Java GUI ==
 +
 
 +
* [http://www.software4java.com/ JAdaptiveMenu]JPopupMenu like in Microsoft Office
 +
 
 +
* [http://jroller.com/santhosh/entry/personalized_menus_in_swing Personalized Menus in Swing]Open Source
 +
* [https://myswing.dev.java.net/ MySwing Project]
 +
* [https://myswing.dev.java.net/MyBlog/MySwingTree.html Cool Swing Stuff]
 +
 
 +
 
 +
=== Java GUI Libraries ===
 +
 
 +
 
 +
==== UFace ====
 +
* [http://code.google.com/p/uface/ UFace]
 +
 
 +
 
 +
==== SWT ====
 +
* [http://www.eclipse.org/swt/snippets/ SWT Snippets]Snippets are minimal stand-alone programs that demonstrate specific techniques or functionality
 +
 
 +
= DMS - Document Management Systems =
 +
* [http://jlibrary.sourceforge.net/ jLibrary]
 +
* [http://dev.alfresco.com/ Alfresco]
 +
** [http://ecmarchitect.com Jeff Potts on ECM, portals, search, collaboration, and a bunch of personal stuff]
 +
** [http://www.ecmarchitect.com/images/articles/alfresco-actions/actions-article.pdf Developing Custom Actions]
 +
** [http://wiki.alfresco.com/wiki/Introducing_the_Alfresco_Java_Content_Repository_API Introducing the Alfresco Java Content Repository API]
 +
 
 +
= CMS - Content Management Systems =
 +
* [http://www.magnolia.info Magnolia]
 +
* [https://atleap.dev.java.net/ atLeap]
 +
 
 +
= Eclipse IDE and Application build on Eclipse =
 +
* [http://wiki.eclipse.org/Using_Sourceforge_with_Mylyn Using Sourceforge.net with Mylyn]
 +
* Design Pattern Plugins
 +
** [http://eclipse-plugins.2y.net/eclipse/plugins.jsp;jsessionid=28CE9D6D999526684ACDFDCBBF1C3464?category=Patterns Eclipse Plugins - Patterns category]
 +
** [http://www.patternbox.com Pattern Box] Very good plugin. Design pattern editor for Eclipse
 +
** [http://home.icslab.agh.edu.pl/~shogun/iosr/site/maven/index.html Design Patterns Plugin]
 +
 
 +
 
 +
== Eclipse Easy Shell plugin ==
 +
* [http://pluginbox.sourceforge.net/plugins.html Easy Shell plugin]
 +
* Settings for Linux in order to open proper terminal
 +
<pre>
 +
gnome-terminal --working-directory {1}
 +
</pre>
 +
* Seetings for windows
 +
<pre>
 +
cmd.exe /C start /D{1} cmd.exe /K "rxvt.exe -fn "Console" -vb +sb -sl 1000 -e bash -I"
 +
</pre>
 +
 
 +
= Script Languages =
 +
* [http://www.beanshell.org/examples/actionhandler.html Neanshell, example how to invoke scriped ActionListener Interface]
 +
* [http://www.cs.put.poznan.pl/dweiss/xml/projects/bsh-binding/index.xml?lang=en Dynamic BeanShell binding and ANT tasks]
 +
* [http://www.javaworld.com/javaworld/jw-10-2003/jw-1003-beanshell.html Discover new dimensions of scripted Java]
 +
* [http://today.java.net/pub/a/today/2007/09/20/scripting-balance-design-performance.html Scripting with Balance in Design and Performance]
 +
* [http://jvm-languages.com/wiki/Main_Page JVM Languages]Book
 +
 
 +
 
 +
== Eclipse plugin ==
 +
* [http://eclipse-shell.sourceforge.net/index.html Eclipse Shell]
 +
* [http://maven.apache.org/eclipse-plugin.html Eclipse Maven plug-in]
 +
 
 +
= Java FTP Libraries and Articles =
 +
* [http://sourceforge.net/projects/ftp4che ftp4che] Features: Implicit SSL / Implicit TLS / AUTH SSL / AUTH TLS / FXP support / PRET support / SSCN support / event model / bandwidth control / unlimited file size support / ...
 +
* [http://www.javaworld.com/javaworld/jw-04-2003/jw-0404-ftp.html Java FTP client libraries reviewed]
 +
* [http://www.javaworld.com/javaworld/jw-03-2006/jw-0306-ftp.html Update: Java FTP libraries benchmarked]
 +
* [http://www.amoebacode.com/ftp/ amoebacode FTP Library]
 +
* [http://www.nsftools.com/tips/RawFTP.htm List of raw FTP commands]
 +
 
 +
 
 +
== Posts regarding FTP and SSL ==
 +
* [http://forum.java.sun.com/thread.jspa?threadID=649454&tstart=225 FTPS and JSSE - plaintext exception]
 +
 
 +
 
 +
== Commercial which support FTPS (FTP Over SSL)==
 +
* [http://www.example-code.com/java/javaftp.asp Chilkat]
 +
* [http://www.jscape.com/articles/secure_ftp_using_java_ssl.html Secure FTP Factory]
 +
* [http://www.enterprisedt.com/products/edtftpj/overview.html edtFTPj - LGPL for standard FTP.]
 +
 
 +
= OpenXava hints =
 +
 
 +
* Naming convention
 +
 
 +
** Utility classes are in org.openxava.util package.
 +
 
 +
** An utility class must be in plural and its methods have to be static.
 +
 
 +
** Example utility class: For dates called Dates.
 +
 
 +
 
 +
== OpenXava User hints ==
 +
 
 +
=== Hint.1 How do to search in detail mode? ===
 +
Click on 'new', fill the fields, and click on 'Search'.
 +
 
 +
 
 +
== OpenXava Developer hints ==
 +
 
 +
==== Hint.1 Always use different properties names ====
 +
Let's have component Organization
 +
<pre>
 +
<component name="Organization">
 +
<entity>
 +
<property name="orgId" type="String" key="true" hidden="true" >
 +
<default-value-calculator class="org.openxava.calculators.UUIDCalculator" on-create="true" />
 +
</property>
 +
<property name="orgName" type="String" size="30" required="false"/>
 +
...
 +
</component>
 +
</pre>
 +
 
 +
and component Warehouse
 +
 
 +
<pre>
 +
<component name="Warehouse">
 +
<entity>
 +
<property name="warehouseId" type="String" key="true" hidden="true" >
 +
<default-value-calculator class="org.openxava.calculators.UUIDCalculator" on-create="true" />
 +
</property>
 +
<property name="warehouseName" type="String" size="30" required="false"/>
 +
...
 +
</component>
 +
</pre>
 +
 
 +
by this way in Application_en.properties developer can define different names for properties:
 +
<pre>
 +
organizationId=Organization ID
 +
orgName=Organization Name
 +
warehouseId=Warehouse ID
 +
warehouseName=Warehouse Name
 +
</pre>
 +
 
 +
also it helps developer to understand well which exactly property he uses/modify.
 +
 
 +
==== Hint.2 Always create by hand DB migration scripts. ====
 +
ORM(Hibernate) tools do not create proper DB migration scripts.
 +
 
 +
=== OpenXava Links & Info ===
 +
* [http://openxava.wiki.sourceforge.net/ OpenXava Wiki page]
 +
* [http://sourceforge.net/projects/qamanager/ qaProjectManager] Web based application used for keeping track of engineering and customer releases, Resource allocations and related information effectively in QA Projects. Powered by openXava.
 +
 
 +
* Nice to have OpenXava features:
 +
** Icon in header of each column indicating that column can be sorted.
 +
** When hook over header of column to show more information for column. Information to be configured in OpenXava xml files.
 +
** Ability to align labels in forums.
 +
 
 +
 
 +
* [https://sourceforge.net/forum/message.php?msg_id=4563535 Interesting proposal regarding Actions]
 +
 
 +
<pre>
 +
==========================================================================================
 +
                                                                  +----------------------+
 +
                                                          Actions:|1.- Pick              |
 +
                                                                  |2.- Edit              |
 +
                                                                  |3.- Copy              |
 +
                                                                  |4.- Delete            |
 +
                                                                  |5.- See (Detail mode) |
 +
                                                                  +----------------------+
 +
                                                                  |A.- Detail of Subjects|
 +
    +--------+-----+------------------------+----------------+  |B.- Send e-mail      |
 +
    | ACTION |  ID | Pupil                  | Comments      |  |C.- Print curriculum  |
 +
    +--------+-----+------------------------+----------------+  |D.- etc...            |
 +
    |  A    |  1  | Eduard Escrihuela      | Firt pupil    |  +----------------------+
 +
    +--------+-----+------------------------+----------------+
 +
    |  C    |  2  | Enric Selfa            | Second pupil  |
 +
    +--------+-----+------------------------+----------------+
 +
    |  ..    | ..  | ..                    | ...            |
 +
                                                                      +-----------------+
 +
                                                                      | EXECUTE ACTIONS |
 +
                                                                      +-----------------+
 +
==========================================================================================
 +
</pre>
 +
 
 +
You can see to the left a grid whith the LIST mode of the PUPILS and the FIRST field is the ACTION to apply to the records. The A action (Detail of subjects of this pupil) is selected for the first pupil and the B action (Printing of his curriculum) is selected for the second pupil.
 +
 +
The actions possible are detailed in the combo on the TOP RIGHT of the window. Options 1 to 5 are standard (always available by default). The rest of actions are specific to the model . 
 +
 
 +
Finally there is a button for executing ALL the actions at the same time.
 +
 
 +
The default actions are:
 +
 
 +
1.-Pick: For instance to select a Customer for a invoice. By using this action you choose your customer and return to previous model (invoice)
 +
 
 +
2.- Edit: To modifiy the record
 +
 
 +
3.- Copy: To create a new record but previously copying the information of an existing record that is very similar to the new one
 +
 
 +
4.- Delete: to delete the record
 +
 
 +
5.- See: To see the record in detail mode and READ ONLY
 +
 
 +
== OpenXava Q & A ==
 +
Created an entity ticketClass with a method GenerateTickets. Implemented the calculator using an IModelCalculator class.
 +
 +
Want to create a button/link when ticketClass is displayed so that user click on it the method gets executed.
 +
 
 +
 
 +
=== Q.1 How do I set this up? ===
 +
* A1. Have to create an action and include it in the controller of your module.
 +
In this action, you can obtain the object and call to you method, something like this:
 +
<pre>
 +
public void execute() throws Exception {
 +
  ...
 +
  TicketClass ticketClass = (TicketClass) MapFacade.findEntity(getModelName(), getView().getKeyValues());
 +
  ticketClass.generateTickets();
 +
  getView().findObject(); // This refresh the view (Q2)
 +
  ...
 +
}
 +
</pre>
 +
 
 +
 
 +
=== Q.2 How can I get the view of the entity refreshed after the method is executed. ===
 +
* A2. See the above code
 +
 
 +
 
 +
=== Q.3 How can i reload other modules to reflect the changes made by an action that was performed in one module? ===
 +
An action in one module (module A) that changes the value of the data
 +
contained in another module (module B), when i execute an action button (in
 +
module A), it executes successfully and updates the data in the other entity
 +
(entity B) in the database, but when i view module B, the module list view (of
 +
module B) is still showing the old data!
 +
 
 +
* A3. In a Liferay 2.1.3 with OX2.2 it works fine, that is, I modify data in a portlet, I move to another and the data
 +
is refreshed without touch filter nor any other action.
 +
Look at your web/WEB-INF/portlet.xml, have you <expiration-cache>0</expiration-cache> for your portlets?
 +
Since OX2.1 expiration-cache is 0 in the portlet.xml generated by OpenXava.
 +
Hence, if you are using OX2.1 or better you only need to execute the ant target 'redeployPortlets' in order to fix your portlet.xml file.
 +
 
 +
 
 +
=== Q.4 How to avoid warnings that messages are not translated ===
 +
* A4.
 +
This messages warn you about the labels that you need to put in your i18n/YourProyectName-labels_en.properties.
 +
Developer can avoid this messages putting the next line:
 +
<pre>
 +
i18nWarnings=false
 +
</pre>
 +
in the file properties/xava.properties of your project.
 +
 
 +
 
 +
=== Q.5 Example TestCase ===
 +
<pre>
 +
public class ExampleTest extends ModuleTestBase {
 +
 +
  public DepartmentsTest(String testName) {
 +
 
 +
  super(testName,"ExampleManager", "ExampleModlue");
 +
  }
 +
 
 +
  public void testCreateReadUpdateDelete() throws Exception {
 +
 
 +
    //Test Create
 +
    execute("CRUD.new");
 +
    setValue("id", "ENG");
 +
    setValue("name", "Example Name");
 +
    setValue("description", "Example description");
 +
    assertNoErrors();
 +
  }
 +
}
 +
</pre>
 +
 
 +
 
 +
=== Q.6 How to provide a web API for accessing the OpenXava application? ===
 +
Just use Web Services.
 +
The OpenXava applications are standard Java Web applications, therefore you can use any Java API from your OpenXava application.
 +
 
 +
In this case you can create a simple Java class, with the services of you application that you want to expose.
 +
And use from it MapFacade or the model objects generated by OpenXava, or whatever code of your application you want.
 +
Something like this:
 +
 
 +
<pre>
 +
public class MyService {
 +
 
 +
  public Address getCustomerAddress(String customerId) throws Exception {
 +
    // Here you use the POJOs generated by OpenXava
 +
    Customer customer = (Customer) Customer.findById(customerId);
 +
    return customer.getAddress();
 +
  }
 +
}
 +
</pre>
 +
 
 +
Now you can create a Web Service from MyService class using AXIS, or the wizard included in Eclipse WTP.
 +
But, remember, all this is a Java issue, not an OpenXava one.
 +
 
 +
 
 +
=== Q.7 Magic numbers ===
 +
It is possible to define some magic numbers in OX?
 +
The Environment Variables are not enough. I want to use the magic numbers in components.
 +
* A7. Use standard techniques for Java and XML.
 +
In Java you can use "public final static" variables:
 +
<pre>
 +
public class MyMagicNumbers {
 +
  public final static int MY_MAGIC = 24324;
 +
}
 +
</pre>
 +
 
 +
In XML you can use XML ENTITIES:
 +
<pre>
 +
<!ENTITY mymagic "24324">
 +
</pre>
 +
 
 +
and then use &mymagic; instead of 34324.
 +
 
 +
These techniques are not from OpenXava but from Java and XML.
 +
 
 +
In XML you can use @mymagic@, and the filter of OpenXava ant build
 +
changes it from a value of your properties file. This allows you
 +
to have a different value of @mymagic@ for each customer or configuration.
 +
This is a technique from OpenXava.
 +
 
 +
 
 +
=== Q.8 How to access EJB from OpenXava ===
 +
* Reference Guide section 3.14.
 +
 
 +
* There is a example of using a EJB inside validator.
 +
 
 +
* Developer can access EJB code in any part of OpenXava applications, for example:
 +
<pre>
 +
Delivery delivery = DeliveryUtil.getHome().findByNumber(33);
 +
delivery.generateInvoice();
 +
</pre>
 +
 
 +
 
 +
=== Q.9 Access rights depending on the user profile ===
 +
* [http://sourceforge.net/forum/message.php?msg_id=3973596 sf.net thread]
 +
* User should only see fields or to execute actions depending on his user profile (or role).
 +
* Certain users to be able to update certain fields while others may only read them.
 +
 
 +
 
 +
==== 1. Option - provided by the container portal ====
 +
*Create two groups of users:
 +
** First with create-delete-edit rights.
 +
** Second only with read rights.
 +
 
 +
* Define two modules(portlets):
 +
** First  with CRUD controller.
 +
** Second with Print controller.
 +
The admin may assign First or Second module (portlet) for each group of users with the portal administrative tools.
 +
 
 +
==== 2. Option ====
 +
Not completly implemented in OpenXava, but there are some useful tools in OX that can help:
 +
* Users.getCurrent() return the current user if application is started in portal. This value may be used in any point of the code.
 +
 +
* Filters: filters the data displayed in the mode list according to the current user.
 +
 +
A full management of users in OX project implies creation of several modules for storing the info about users, interfaces for change rights and create new users, roles and rights, overwrite standard controllers, to write new actions (typically "save" action, frequently "new" action too), to write specific validator, to write filters for tabs in list mode, and more... 
 +
 +
Javier's opinion: I think that part of this stuff can be moved to a new project, instead of be included in OX core. This new project would manage access rights and user profiles, and will be reusable for other projects.
 +
 
 +
==== Links ====
 +
* [http://wiki.liferay.com/index.php/Acegi_Security_for_Liferay Acegi Security for Liferay]
 +
* [http://wiki.liferay.com/index.php/Custom_redirect_after_login Custom redirect after login]
 +
 
 +
 
 +
=== Q.10 Property displayed as Radio button ===
 +
* Existing test case: CustomerWithRadioButtons
 +
* Section 4.7 of reference guide shows how editors are full configurable in OpenXava.
 +
* /components/SomeComponent.xml file
 +
<pre>
 +
<entity>
 +
  <property name="gender" >
 +
<valid-values>
 +
<valid-value value="Male"/>
 +
<valid-value value="Female"/>
 +
</valid-values>
 +
  </property>
 +
</entity>
 +
<view>
 +
  <property-view property="gender" editor="ValidValuesRadioButton"></property-view>
 +
  <members >
 +
    name;
 +
    gender;
 +
  </members >
 +
<view>
 +
</pre>
 +
 
 +
* OpenXava/xava/default-editors.xml contains definition of:
 +
** ValidValuesRadioButton
 +
<pre>
 +
<editor name="ValidValuesRadioButton" url="radioButtonEditor.jsp">
 +
<property name="horizontal" value="true" />
 +
</editor>
 +
</pre>
 +
 
 +
** ValidValuesVerticalRadioButton
 +
<pre>
 +
<editor name="ValidValuesVerticalRadioButton"
 +
url="radioButtonEditor.jsp">
 +
<property name="horizontal" value="true" />
 +
</editor>
 +
</pre>
 +
 
 +
** ValidValuesHorizontalRadioButton
 +
<pre>
 +
<editor name="ValidValuesHorizontalRadioButton"
 +
url="radioButtonEditor.jsp">
 +
<property name="horizontal" value="true" />
 +
</editor>
 +
</pre>
 +
 
 +
It looks both last have the same value for horizontal request parameter <property name="horizontal" value="true" />.
 +
Probably this is a mistake.
 +
 
 +
 
 +
=== Q.11 OpenXava design ===
 +
* All model classes implement org.openxava.model.IModel interface:
 +
<pre>
 +
/**
 +
* Interface to be implemented by all model classes. <p>
 +
*
 +
* The model classes may be EntityBeans EJB 2 or POJOs (for JDO, EJB3 or Hibernate).
 +
*
 +
* @author Javier Paniza
 +
*/
 +
public interface IModel {
 +
 +
/**
 +
* Returns metadata about object. <p>
 +
*
 +
* @return  Not null.
 +
* @exception XavaException  Any problem related to OpenXava.
 +
* @exception RemoteException  System problem.
 +
*/
 +
MetaModel getMetaModel() throws XavaException, RemoteException;
 +
 
 +
}
 +
</pre>
 +
 
 +
 
 +
=== Q.12 How to get logger ===
 +
OpenXava uses [http://commons.apache.org/logging/ Apache Commons Loggin]
 +
 
 +
<pre>
 +
private static Log log = LogFactory.getLog(Users.class);
 +
</pre>
 +
 
 +
 
 +
=== Q.13 Using the <transient> tag ===
 +
Section 4.10 of Reference guide says:
 +
 
 +
"put <transient/> at the end of the component definition (1), just in the part for the mappings"
 +
 
 +
Make sure you write the following:
 +
<pre>
 +
 
 +
<?xml version="1.0" encoding="ISO-8859-1"?>
 +
<!DOCTYPE component SYSTEM "dtds/component.dtd">
 +
<component name="YourComponent">
 +
    <entity>
 +
        ...
 +
    </entity>
 +
    ...
 +
    <transient/>  <!--If you put it anywhere else you will see error in the
 +
document-->
 +
</component>
 +
</pre>
 +
 
 +
 
 +
=== Q.14 Search criteria customization in List mode ===
 +
Requirement: The user writes his search criteria (Type employee salary for example) and then presses the search button.
 +
 
 +
Create a module that start in detail mode.
 +
Use a view that show just the data for filtering.
 +
 
 +
Define a controller with your "Search" actions, and in this action change to list mode.
 +
 
 +
In this way you can achieve your goal.
 +
 
 +
Read the chapters 7 and 8 of Reference Guide.
 +
 
 +
 
 +
=== Q.15 How to change Action view from link to button? ===
 +
* [http://sourceforge.net/forum/forum.php?thread_id=1807009&forum_id=419690 link to sf.net post] sf.net thread contains explanation and initial modifications.
 +
 
 +
1. Create a new property called 'buttonsForNoImageActions' (or so), for use in xava.properties.
 +
 
 +
2. Add the property in the class [http://www.gestion400.com/OpenXavaDoc/apidocs/org/openxava/util/XavaPreferences.html XavaPreferences].
 +
 
 +
3. Modify the class [http://www.gestion400.com/OpenXavaDoc/apidocs/org/openxava/web/taglib/ActionTag.html ActionTag].
 +
 
 +
By default, buttonsForNoImageActions must be 'false', in order to not change the current OX behavior (by default).
 +
 
 +
 
 +
Temporary solution.
 +
Change actionEditor.jsp
 +
<pre>
 +
- <xava:link action="<%=p.getAction()%>"/>
 +
+ <xava:button action="<%=p.getAction()%>"/>
 +
</pre>
 +
 
 +
 
 +
=== Q.16 How to open/goto custom jsp? ===
 +
DECLARATIVE jsp navigation, as following:
 +
 
 +
<pre>
 +
<action name="goToMyJSP" class="org.openxava.actions.NavigationAction">
 +
  <set property="customView" value="mypage.jsp"/>
 +
  <set property="nextController" value="MyController"/>
 +
</action>
 +
 
 +
</pre>
 +
 
 +
In general, action classes can be made reusable, and can be configured in controllers.xml. In this way  can do more configuration and less programming.
 +
 
 +
 
 +
=== Q.17 How to make a property as a NOT persistent or view only field in the entity element? ===
 +
Yes, it's possible.
 +
 
 +
Two options:
 +
 
 +
==== Option 1. Calculated properties (section 3.8.4 of reference guide) ====
 +
It is possible to use qualified properties!
 +
<pre>
 +
<component name="Engagement">
 +
<entity>
 +
...
 +
<property name="cmpContactName" type="String" size="60" >
 +
<calculator class="org.openxava.calculators.StringCalculator" >
 +
<set property="string" from="cmpContact.compName.custCompName"/>
 +
</calculator>
 +
</property>
 +
...
 +
</component>
 +
</pre>
 +
 
 +
No need to create special Calculator!
 +
<pre>
 +
<component name="Engagement">
 +
<entity>
 +
...
 +
<property name="cmpContactName" type="String" size="60" >
 +
<calculator class="bg.d3soft.openxava.calculators.CompanyContactNameCalculator" >
 +
</calculator>
 +
</property-->
 +
...
 +
</component>
 +
</pre>
 +
 
 +
 
 +
==== Option 2. View properties (section 4.5 of reference guide) ====
 +
View properties are used for the case that you want to have something editable in the view, but you do not want to save it in DB.
 +
View properties do not have same functionality as properties. That's why this behavior is normal.
 +
For some reason view property do not show the same result:
 +
<pre>
 +
<component>
 +
...
 +
<view>
 +
<property name="cmpContactName" type="String" size="60" >
 +
<calculator class="org.openxava.calculators.StringCalculator" >
 +
<set property="string" from="cmpContact.compName.custCompName"/>
 +
</calculator>
 +
</property>
 +
...
 +
</view>
 +
</component>
 +
</pre>
 +
 
 +
 
 +
=== Q.18 How to implement Wizard form ===
 +
First consider seriously to use a single view with several sections. This is more flexible in most cases and easy to implement with OpenXava.
 +
 
 +
Steps:
 +
Your action for navigate must implements IChangeControllersAction, this allows you to change the actions to show in each page, and using
 +
 
 +
<pre>
 +
getView().setViewName( ... );
 +
 
 +
</pre>
 +
 
 +
inside execute() of your action,  you can change the view in each step.
 +
 
 +
Look at the Reference Guide and OpenXavaTest for IChangeControllersAction, and also for INavigationAction.
 +
 
 +
 
 +
=== Q.19 How to forward to a JSP ===
 +
Action obtains two values which are important for the JSP.
 +
 
 +
Create a IForwardAction with a code like:
 +
 
 +
<pre>
 +
public String getForwardURI() {
 +
    return "/mypage.jsp?a=" + getA() + "&b=" + getB();
 +
}
 +
</pre>
 +
 
 +
And put mypage.jsp in the 'web' folder of your project.
 +
 
 +
 
 +
=== Q.20 How to change order of error messages? ===
 +
 
 +
Method 'validate' of MapFacadeBean:
 +
 
 +
<pre>
 +
private void validate(Messages errors, MetaModel metaModel, Map values, Map
 +
keyValues, Object containerKey, boolean creating)
 +
throws XavaException, RemoteException {
 +
Iterator it = values.entrySet().iterator();
 +
while (it.hasNext()) {
 +
Map.Entry en = (Map.Entry) it.next();
 +
String name = (String) en.getKey();
 +
Object value = en.getValue();
 +
validate(errors, metaModel, name, value, creating);
 +
}
 +
if (metaModel.containsValidadors()) {
 +
validateWithModelValidator(errors, metaModel, values, keyValues,
 +
containerKey,
 +
creating);
 +
}
 +
}
 +
</pre>
 +
 
 +
In this case the loop is over entrySet of a Map, hence the order is unknown. You can modify this method in order to work by the correct order, some method of MetaModel returns the member names
 +
in order of declaration.
 +
 
 +
=== Q.21 How to disable the icon in the corner most column in column arrangement view? ===
 +
 
 +
Modify list.jsp.
 +
 
 +
 
 +
=== Q.22 How to open custom JSP view in a pop up window? ===
 +
Is it possible to open custom JSP view in a pop up window?
 +
 
 +
No. The custom JSP must be inside the module.
 +
Use IForwardAction that has a method (inNewWindow()) for create a pop up windows.
 +
You can put your JSP in a public folder, and send the parameters for this jsp using OX session objects.
 +
 
 +
=== Q.23 How to hide/show view section depending on user rights? ===
 +
Some users must be able to see given section from the view while other users must NOT be able to see this section.
 +
 
 +
At the moment developer can hide (using View.setHidden) members and groups, but not sections.
 +
 +
There are 4 (at least) options:
 +
* Use OpenXava/src/org.openxava.view.View.setSectionEditable.
 +
* Put your sensible data in a group, and hide/show it.
 +
* Create 2 views (one with the critical section, another without it).
 +
* Modify OpenXava to allow to hide programatically sections.
 +
 
 +
 
 +
* Which class should change view or hide section?
 +
 
 +
** SEARCH_ACTION and 'new' Action are good places.
 +
** Other options as in an on-each-request action, or an on-init action.
 +
 +
 
 +
* Guide how to develop option 4?
 +
** Look at OpenXava/src/org.openxava.view.View.setHidden method.
 +
 
 +
=== Q.24 How to display only label in view? ===
 +
Use a property of the view with stereotype LABEL.
 +
 
 +
<pre>
 +
<view>
 +
  <property name="selectLabel" stereotype="LABEL" type="String" >
 +
  </property>
 +
  <members>
 +
    selectLabel;
 +
    a;
 +
    b;
 +
  </members>
 +
</view>
 +
</pre>
 +
 
 +
File Application_en.properties must contain translation of property:
 +
<pre>
 +
selectLabel=Select at least one:
 +
</pre>
 +
 
 +
 
 +
Another option may be to have a property with no content and 'Select at least one:' as label.
 +
 
 +
File: xava/editors.xml
 +
<pre>
 +
<?xml version = "1.0" encoding = "ISO-8859-1"?>
 +
<!DOCTYPE editors SYSTEM "dtds/editors.dtd">
 +
<editors>
 +
<editor url="void.jsp">
 +
<for-stereotype stereotype="VOID" />
 +
</editor>
 +
</editors>
 +
</pre>
 +
 
 +
Create empty file: web/xava/editors/void.jsp
 +
<pre>
 +
</pre>
 +
 
 +
Difference is only in stereotype:
 +
<pre>
 +
<view>
 +
  <property name="selectLabel" stereotype="VOID" type="String">
 +
  </property>
 +
  <members>
 +
    selectLabel;
 +
    a;
 +
    b;
 +
  </members>
 +
</view>
 +
</pre>
 +
 
 +
 
 +
=== Q.25 How to make property required from Action? ===
 +
Make a property 'X' required depending on the value of other property 'A'.
 +
If property 'A' has value 111 than property 'X' must became required.
 +
 
 +
<pre>
 +
<property-view property="A">
 +
    <on-change class="bg.d3soft.openxava.actions.OnChangeA"/>
 +
</property-view>
 +
</pre>
 +
 
 +
* Use a validator for property X (reference guide 3.8.6), and inject in the validator the property A (using <set />).
 +
 
 +
* Use a model level validator (section 3.16).
 +
 +
You cannot change the state of a property from 'required' to 'not required' at runtime (well, you can, but you shouldn't), because required is a feature of the model, not of a view.
 +
You can access to the MetaModel at runtime and change the value of required, but if you do it in this way the value will be change for all modules, and all users at the same time, because you are modifying the meta data of the model.
 +
 
 +
 
 +
=== Q.26 How to display property of a reference? ===
 +
View properties are used for the case that you want to have something editable in the view, but you do not want to save it in DB.
 +
 
 +
* If property must be read only than use a calculated property.
 +
 
 +
* If property must be editable than:
 +
Use a property of the view, populate it in the code in SEARCH_ACTION, and save its content in your own Save action.
 +
 
 +
 
 +
=== Q.27 How to add EMAIL stereotype and validation class ===
 +
Will be part of OpenXava 2.2.3! [https://sourceforge.net/forum/message.php?msg_id=4506845 sf.net post]
 +
 
 +
1) Add to Application/xava/default-size.xml
 +
<pre>
 +
<for-stereotype name="EMAIL" size="50"/>
 +
</pre>
 +
 
 +
 
 +
2) Add to Application/xava/editors.xml
 +
<pre>
 +
<editor url="textEditor.jsp">
 +
  <for-stereotype stereotype="EMAIL"/>
 +
</editor>
 +
</pre>
 +
 
 +
 
 +
3) Add to Application/xava/stereotype-type-default.xml
 +
<pre>
 +
<for stereotype="EMAIL" type="String"/>
 +
</pre>
 +
 
 +
 
 +
4) Add to Application/i18n/messages_en.properties file
 +
<pre>
 +
email_validation_error={0} must be a valid email address
 +
</pre>
 +
 
 +
 
 +
5) Validation class
 +
<pre>
 +
package org.openxava.validators;
 +
 
 +
import org.openxava.util.*;
 +
import org.openxava.validators.IPropertyValidator;
 +
import java.util.regex.Pattern;
 +
import java.util.regex.Matcher;
 +
 
 +
public class EmailValidator implements IPropertyValidator {
 +
 
 +
    Pattern pat=Pattern.compile(".+@.+\\.[a-z]+");
 +
 
 +
    public void validate(Messages errors, Object value, String propertyName,
 +
String modelName) throws Exception {
 +
 
 +
        if (value == null || value.toString().length() ==0 ) return;
 +
        Matcher matcher = pat.matcher(value.toString());
 +
        if (! matcher.find()) {
 +
          errors.add("email_validation_error", propertyName);
 +
          return;
 +
        }
 +
    }
 +
}
 +
</pre>
 +
 
 +
 
 +
5.1) Second version of Validator class using Apache Commons validator
 +
<pre>
 +
import org.apache.commons.validator.GenericValidator;
 +
import org.openxava.util.Messages;
 +
import org.openxava.validators.IPropertyValidator;
 +
 
 +
/**
 +
* @author Janesh Kodikara
 +
*/
 +
public class EmailValidator implements IPropertyValidator {
 +
 
 +
    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {
 +
 
 +
        if (value == null || value.toString().length() == 0)
 +
          return;
 +
 
 +
        if (! GenericValidator.isEmail(value.toString())) {
 +
            errors.add("email_validation_error", propertyName);
 +
            return;
 +
        }
 +
    }
 +
}
 +
</pre>
 +
 
 +
 
 +
=== Q.28 How to translate OpenXava ===
 +
For example to Bulgarian (bg).
 +
 
 +
* Copy OpenXava/i18n/Labels_en.properties to OpenXava/i18n/Labels_bg.properties.
 +
* Copy OpenXava/i18n/Messages_en.properties to OpenXava/i18n/Messages_bg.properties.
 +
 
 +
Translate Labels_bg.properties and Messages_bg.properties!
 +
 
 +
Thread which can be useful:
 +
[http://sourceforge.net/forum/forum.php?thread_id=1804922&forum_id=419690 here]
 +
 
 +
 
 +
=== Q.29 How to translate application based on OpenXava ===
 +
For example to Bulgarian (bg).
 +
 
 +
* Copy <ApplictionName>/i18n/Labels_en.properties to <ApplictionName>/i18n/Labels_bg.properties.
 +
* Copy <ApplictionName>/i18n/Messages_en.properties to <ApplictionName>/i18n/Messages_bg.properties.
 +
 
 +
Translate Labels_bg.properties and Messages_bg.properties!
 +
 
 +
Thread which can be useful:
 +
[http://sourceforge.net/forum/forum.php?thread_id=1804922&forum_id=419690 here]
 +
 
 +
 
 +
=== Q.30 How to add PASSWORD stereotype ===
 +
1) Create new file in Application/web/xava/editors/passwordEditor.jsp
 +
<pre>
 +
<%@ page import="org.openxava.model.meta.MetaProperty" %>
 +
<%@ page import="org.openxava.util.Strings" %>
 +
<%@ page import="org.openxava.util.Align" %>
 +
 
 +
<jsp:useBean id="style" class="org.openxava.web.style.Style" scope="request"/>
 +
 
 +
<%
 +
String propertyKey = request.getParameter("propertyKey");
 +
MetaProperty p = (MetaProperty) request.getAttribute(propertyKey);
 +
String fvalue = (String) request.getAttribute(propertyKey + ".fvalue");
 +
String align = p.isNumber()?"style='text-align:right'":"";
 +
boolean editable="true".equals(request.getParameter("editable"));
 +
String disabled=editable?"":"disabled";
 +
String script = request.getParameter("script");
 +
boolean label = org.openxava.util.XavaPreferences.getInstance().isReadOnlyAsLabel();
 +
String smaxSize = request.getParameter("maxSize");
 +
int maxSize = 0;
 +
if (!org.openxava.util.Is.emptyString(smaxSize)) {
 +
maxSize = Integer.parseInt(smaxSize);
 +
}
 +
else {
 +
maxSize = org.openxava.util.XavaPreferences.getInstance().getMaxSizeForTextEditor();
 +
}
 +
int size = p.getSize() > maxSize ? maxSize : p.getSize();
 +
 
 +
/*
 +
boolean fillWithZeros = "true".equals(request.getParameter("fillWithZeros"));
 +
if (fillWithZeros && fvalue.length() > 0) {
 +
fvalue = Strings.fix(fvalue, size, Align.RIGHT, '0');
 +
}
 +
*/
 +
 
 +
if (editable || !label) {
 +
%>
 +
<input name="<%=propertyKey%>" class=<%=style.getEditor()%>
 +
type="password"
 +
title="<%=p.getDescription(request)%>"
 +
<%=align%>
 +
maxlength="<%=p.getSize()%>"
 +
size="<%=size%>"
 +
value="<%=Strings.change(fvalue, "\"", "&quot;")%>"
 +
<%=disabled%>
 +
<%=script%>
 +
/>
 +
<%
 +
} else {
 +
%>
 +
<%=fvalue%>&nbsp;
 +
<%
 +
}
 +
%>
 +
<% if (!editable) { %>
 +
<input type="password" name="<%=propertyKey%>" value="<%=fvalue%>">
 +
<% } %>
 +
 
 +
</pre>
 +
 
 +
 
 +
2) Add to Application/xava/editors.xml
 +
<pre>
 +
<editor url="passwordEditor.jsp">
 +
  <for-stereotype stereotype="PASSWORD"/>
 +
</editor>
 +
</pre>
 +
 
 +
 
 +
3) Add to Application/xava/Stereotype-type-default.xml
 +
<pre>
 +
<for stereotype="PASSWORD" type="String"/>
 +
</pre>
 +
 
 +
 
 +
4) Example usage Application/components/Employee.xml
 +
<pre>
 +
<component name="Employee">
 +
  <entity>
 +
...
 +
    <property name="empPassword" stereotype="PASSWORD" size="20" required="true"/>
 +
...
 +
</pre>
 +
 
 +
 
 +
=== Q.31 How to develop import functionality ===
 +
1) Create new file in Application/web/xava/editors/loadCSVFile.jsp
 +
<pre>
 +
<%@ include file="../imports.jsp"%>
 +
 
 +
<jsp:useBean id="style" class="org.openxava.web.style.Style" scope="request"/>
 +
 
 +
<table>
 +
<th align='left' class="<%=style.getLabel()%>">
 +
<xava:message key="enter_new_csv_file"/>
 +
</th>
 +
<td>
 +
<input name = "newCsvFile" class=<%=style.getEditor()%> type="file" size='60'/>
 +
</td>
 +
</table>
 +
 
 +
</pre>
 +
 
 +
 
 +
2) Add new class to Application/src/bg/d3soft/openxava/actions/LoadCSVFileAction.java
 +
<pre>
 +
package bg.d3soft.openxava.actions;
 +
 
 +
import org.openxava.actions.BaseAction;
 +
import org.openxava.actions.ILoadFileAction;
 +
 
 +
public class LoadCSVFileAction extends BaseAction implements ILoadFileAction {
 +
 +
private String newCsvFileProperty;
 +
 +
 +
public void execute() throws Exception {
 +
 +
}
 +
 +
public String[] getNextControllers() {
 +
return new String [] { "ImportCSVFile" };
 +
}
 +
 
 +
public String getCustomView() {
 +
return "xava/editors/loadCSVFile";
 +
}
 +
 
 +
public boolean isLoadFile() {
 +
return true;
 +
}
 +
 
 +
public String getNewCsvFileProperty() {
 +
return newCsvFileProperty;
 +
}
 +
 
 +
public void setewCsvFileProperty(String string) {
 +
newCsvFileProperty = string;
 +
}
 +
}
 +
</pre>
 +
 
 +
 
 +
3) Add new class to Application/src/bg/d3soft/openxava/actions/ImportCsvFileAction.java
 +
<pre>
 +
package bg.d3soft.openxava.actions;
 +
 
 +
public class ImportCsvFileAction extends BaseAction implements INavigationAction, IProcessLoadedFileAction {
 +
 +
private static Log log = LogFactory.getLog(ImportCsvFileAction.class);
 +
 +
private List fileItems;
 +
 +
private View view;
 +
 +
private String newCsvFileProperty;
 +
 +
public void execute() throws Exception {
 +
Iterator i = getFileItems().iterator();
 +
while (i.hasNext()) {
 +
FileItem fi = (FileItem)i.next();
 +
String fileName = fi.getName();
 +
log.info("fileName = [" + fileName + "]");
 +
 +
if (!Is.emptyString(fileName)) {
 +
//getView().setValue(getNewCsvFileProperty(), fi.get());
 +
log.info("getNewCsvFileProperty = [" + getNewCsvFileProperty() + "]");
 +
log.info("fi.getSize() = [" + fi.getSize() + "]");
 +
 +
ImportUtil impUtil = new ImportUtil();
 +
impUtil.importCustomerCompanyFromCSV(fi);
 +
}
 +
}
 +
}
 +
 
 +
public String[] getNextControllers() {
 +
return DEFAULT_CONTROLLERS;
 +
}
 +
public String getCustomView() {
 +
return DEFAULT_VIEW;
 +
}
 +
public View getView() {
 +
return view;
 +
}
 +
public void setView(View view) {
 +
this.view = view;
 +
}
 +
public String getNewCsvFileProperty() {
 +
return newCsvFileProperty;
 +
}
 +
public void setNewCsvFileProperty(String string) {
 +
newCsvFileProperty = string;
 +
}
 +
public List getFileItems() {
 +
return fileItems;
 +
}
 +
public void setFileItems(List fileItems) {
 +
this.fileItems = fileItems;
 +
}
 +
}
 +
</pre>
 +
 
 +
 
 +
4) Add to Application/i18n/Application-labels_en.properties
 +
<pre>
 +
loadCSVFile=Import CSV File
 +
importCSVFile=Import CSV File
 +
</pre>
 +
 
 +
 
 +
5) Add to Application/i18n/Application-messages_en.properties
 +
<pre>
 +
enter_new_csv_file=Enter CSV File
 +
</pre>
 +
 
 +
 
 +
6) Add new class to Application/src/bg/d3soft/openxava/actions/LoadCSVFileAction.java
 +
<pre>
 +
 
 +
</pre>
 +
 
 +
 
 +
7) Add to Application/xava/controllers.xml
 +
<pre>
 +
<?xml version = "1.0" encoding = "ISO-8859-1"?>
 +
<!DOCTYPE controllers SYSTEM "dtds/controllers.dtd">
 +
<controllers>
 +
...
 +
<object name="xava_newCsvFileProperty" class="java.lang.String"/>
 +
...
 +
<controller name="LoadCSVFile">
 +
<action name="loadCSVFile"
 +
class="bg.d3soft.openxava.actions.LoadCSVFileAction"
 +
hidden="false"
 +
mode="detail"
 +
image="images/db_update.png"
 +
>
 +
<!-- set value="" property=""/-->
 +
<!-- use-object name="xava_newCsvFileProperty"/-->
 +
</action>
 +
 +
</controller>
 +
 +
<controller name="ImportCSVFile">
 +
<action name="importCSVFile"
 +
class="bg.d3soft.openxava.actions.ImportCsvFileAction"
 +
hidden="false"
 +
mode="detail"
 +
>
 +
<use-object name="xava_view"/>
 +
<use-object name="xava_newCsvFileProperty"/>
 +
</action>
 +
 +
<action name="cancel"
 +
class="org.openxava.actions.CancelAction">
 +
</action>
 +
</controller>
 +
...
 +
</controllers>
 +
</pre>
 +
 
 +
 
 +
 
 +
8) Add to Application/web/xava/images/db_update.png
 +
 
 +
 
 +
9) Example usage Application/xava/application.xml
 +
<pre>
 +
...
 +
<module name="CustomerCompanies">
 +
<model name="CustomerCompany" />
 +
<controller name="TypicalNotResetOnSave" />
 +
<controller name="LoadCSVFile" />
 +
</module>
 +
...
 +
</pre>
 +
 
 +
 
 +
10) Example csv file
 +
<pre>
 +
"Date Created","Name","Web Address","Corp Location"
 +
"ERROR","CustCompName-5","www.web005.com","Corp. location-5"
 +
"ERROR","CustCompName-6","www.web006.com","Corp. location-6"
 +
"ERROR","CustCompName-7","www.web007.com","Corp. Location-7"
 +
</pre>
 +
 
 +
 
 +
=== Q.32 How to create formatter for java.util.Date ===
 +
==== Option A - Create your own formatter (IFormatter) =====
 +
Create your own formatter (IFormatter) and assign it to the java.util.Date type in editors.xml of your project.
 +
 
 +
OpenXava version 2.2.2
 +
OpenXavaTest/xava/editors
 +
<pre>
 +
<editor name="DateCalendar" url="dateCalendarEditor.jsp">
 +
  <formatter class="org.openxava.formatters.DateFormatter" />
 +
  <for-type type="java.util.Date" />
 +
</editor>
 +
</pre>
 +
 
 +
 
 +
==== Option B - Modify DateFormatter (and DateTimeFormatter) of OpenXava ====
 +
Look at DateFormatter (and DateTimeFormatter) of OpenXava.
 +
They are tuned for work better for Spanish and Polish.
 +
 
 +
Changes in the DateFormatter and in the DateTimeFormatter.
 +
 
 +
In DateFormater added:
 +
<pre>
 +
private static DateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); // modified
 +
private static DateFormat spanishDateFormat = new SimpleDateFormat("dd/MM/yyyy");
 +
 +
private static DateFormat [] spanishDateFormats = {
 +
spanishDateFormat,
 +
germanDateFormat, // modified
 +
new SimpleDateFormat("ddMMyyyy"),
 +
new SimpleDateFormat("dd.MM.yyyy"),
 +
};
 +
</pre>
 +
 
 +
In method getDateFormat(HttpServletRequest request)
 +
<pre>
 +
if ("de".equals(request.getLocale().getLanguage())) return germanDateFormat; // modified
 +
</pre>
 +
 
 +
In DateTimeFormatter added:
 +
<pre>
 +
private static DateFormat germanDateFormat = new  SimpleDateFormat("dd.MM.yyyy"); //modified
 +
</pre>
 +
 
 +
In the method getDateFormat(HttpServletRequest request)
 +
<pre>
 +
if ("de".equals(request.getLocale().getLanguage())) return germanDateFormat; // modified
 +
</pre>
 +
 
 +
 
 +
full source code of Formatter:
 +
<pre>
 +
import java.text.*;
 +
 
 +
import javax.servlet.http.*;
 +
 
 +
import org.openxava.util.*;
 +
import org.openxava.formatters.*;
 +
 
 +
public class GermanDateFormatter implements IFormatter {
 +
 +
private static DateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
 +
private static DateFormat spanishDateFormat = new SimpleDateFormat("dd/MM/yyyy");
 +
 +
private static DateFormat [] spanishDateFormats = {
 +
spanishDateFormat,
 +
germanDateFormat, 
 +
new SimpleDateFormat("ddMMyyyy"),
 +
new SimpleDateFormat("dd.MM.yyyy"),
 +
};
 +
 +
public String format(HttpServletRequest request, Object date) {
 +
if (date == null) return "";
 +
if (Dates.getYear((java.util.Date)date) < 2) return "";
 +
return getDateFormat(request).format(date);
 +
}
 +
 +
public Object parse(HttpServletRequest request, String string) throws ParseException
 +
{
 +
if (Is.emptyString(string)) return null;
 +
if (string.indexOf('-') >= 0) { // SimpleDateFormat does not work well with -
 +
string = Strings.change(string, "-", "/");
 +
}
 +
DateFormat [] dateFormats = getDateFormats(request);
 +
for (int i=0; i<dateFormats.length; i++) {
 +
try {
 +
return dateFormats[i].parseObject(string);
 +
}
 +
catch (ParseException ex) {
 +
}
 +
}
 +
throw new ParseException(XavaResources.getString("bad_date_format",string),-1);
 +
}
 +
 +
private DateFormat getDateFormat(HttpServletRequest request) {
 +
if ("de".equals(request.getLocale().getLanguage()))
 +
                  return germanDateFormat;
 +
if ("es".equals(request.getLocale().getLanguage()) ||
 +
    "pl".equals(request.getLocale().getLanguage())
 +
                )
 +
                  return spanishDateFormat;
 +
return DateFormat.getDateInstance(DateFormat.SHORT, request.getLocale());
 +
}
 +
 +
private DateFormat[] getDateFormats(HttpServletRequest request) {
 +
if ("es".equals(request.getLocale().getLanguage()) ||
 +
                    "de".equals(request.getLocale().getLanguage()) ||
 +
    "pl".equals(request.getLocale().getLanguage())
 +
                )
 +
                  return spanishDateFormats;
 +
return new DateFormat [] { getDateFormat(request) };
 +
}
 +
}
 +
</pre>
 +
 
 +
 
 +
=== Q.33 Possible properties in Application/properties/xava.properties ===
 +
Java class responsible for loading xava.properties: org.openxava.util.XavaPreferences
 +
 
 +
Since version > 2.2.2.
 +
 
 +
User can hide/show the filter part on init in list and collections.
 +
<pre>
 +
showFilterByDefaultInList=true
 +
showFilterByDefaultInCollections=true
 +
</pre>
 +
 
 +
 
 +
Since version 2.2.1.
 +
 
 +
Users.getCurrent() returns the user email instead of the user id inside a portal.
 +
<pre>
 +
emailAsUserNameInPortal=true|false(false)
 +
</pre>
 +
 
 +
<pre>
 +
readOnlyAsLabel=true|false(false)
 +
tabAsEJB=true|false(false)
 +
showCountInList=true|false(true)  - avoid the initial select count(*) in the model list. It takes time when number of rows is big.
 +
formLineSpacing=integer(1)
 +
csvSeparator=character(;)
 +
persistenceProviderClass=String(org.openxava.model.impl.HibernatePersistenceProvider)org.openxava.model.impl.EJBPersistenceProvider
 +
mapFacadeAsEJB=true|false(false)
 +
detailOnBottomInCollections=true|false(false)
 +
jpaCodeInPOJOs=
 +
i18nWarnings=true|false(true)
 +
duplicateComponentWarnings=true|false(true)
 +
failOnAnnotationMisuse=true|false(true)
 +
maxSizeForTextEditorinteger(100)
 +
javaLoggingLevel=String(INFO);FINEST|INFO
 +
hibernateJavaLoggingLevel=String(INFO);FINEST|INFO
 +
</pre>
 +
 
 +
==== How to access Xava Properties from jsp file? ====
 +
<pre>
 +
<%
 +
boolean label = org.openxava.util.XavaPreferences.getInstance().isReadOnlyAsLabel();
 +
%>
 +
</pre>
 +
 
 +
 
 +
=== Q.34 How to add WEBURL stereotype and validation class ===
 +
Will be part of OpenXava 2.2.3! [https://sourceforge.net/forum/message.php?msg_id=4506845 sf.net post]
 +
 
 +
1) Add to Application/xava/default-size.xml
 +
<pre>
 +
<for-stereotype name="WEBURL" size="50"/>
 +
</pre>
 +
 
 +
2) Add to Application/xava/editors.xml
 +
<pre>
 +
<editor url="textEditor.jsp">
 +
  <for-stereotype stereotype="WEBURL"/>
 +
</editor>
 +
</pre>
 +
 
 +
3) Add to Application/xava/stereotype-type-default.xml
 +
<pre>
 +
<for stereotype="WEBURL" type="String"/>
 +
</pre>
 +
 
 +
4) Add to Application/i18n/messages_en.properties file
 +
<pre>
 +
url_validation_error={0} must be a valid url
 +
</pre>
 +
 
 +
5) Validation class
 +
<pre>
 +
import org.openxava.util.*;
 +
import org.openxava.validators.IPropertyValidator;
 +
import org.apache.commons.validator.UrlValidator;
 +
 
 +
/**
 +
* @author Janesh Kodikara
 +
*/
 +
public class URLValidator implements IPropertyValidator {
 +
 
 +
    UrlValidator urlValidator = new UrlValidator();
 +
 
 +
    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {
 +
 
 +
        if (value == null || value.toString().length() == 0 )
 +
          return;
 +
 
 +
        if ( !urlValidator.isValid(value.toString()) ) {
 +
          errors.add("url_validation_error", propertyName);
 +
        }
 +
    }
 +
}
 +
</pre>
 +
 
 +
6) Add following jar files
 +
 
 +
A) jakarta-oro-2.0.8.jar
 +
http://jakarta.apache.org/site/downloads/downloads_oro.cgi?Preferred=http%3A%2F%2Fgovernment-grants.org%2Fmirrors%2Fapache.org
 +
 
 +
B) commons-validator-1.3.1.jar
 +
http://commons.apache.org/downloads/download_validator.cgi
 +
 
 +
 
 +
=== Q.35 How to add TELEPHONE stereotype and validation class ===
 +
Will be part of OpenXava 2.2.3! [https://sourceforge.net/forum/message.php?msg_id=4506845 sf.net post]
 +
 
 +
1) Add to Application/xava/default-size.xml
 +
<pre>
 +
<for-stereotype name="TELEPHONE" size="15"/>
 +
</pre>
 +
 
 +
2) Add to Application/xava/editors.xml
 +
<pre>
 +
<editor url="textEditor.jsp">
 +
  <for-stereotype stereotype="TELEPHONE"/>
 +
</editor>
 +
</pre>
 +
 
 +
3) Add to Application/xava/stereotype-type-default.xml
 +
<pre>
 +
<for stereotype="TELEPHONE" type="String"/>
 +
</pre>
 +
 
 +
4) Add to Application/i18n/messages_en.properties file
 +
<pre>
 +
phone_valid_number_error= {0} must be a valid number
 +
phone_minimum_size_error= {0} must be at least  {2} {1} long
 +
</pre>
 +
 
 +
5) Validation class
 +
<pre>
 +
package org.openxava.validators;
 +
 
 +
import org.openxava.util.*;
 +
import org.openxava.validators.IPropertyValidator;
 +
 
 +
/**
 +
* @author Janesh Kodikara
 +
*/
 +
public class PhoneNumberValidator implements IPropertyValidator {
 +
    private long minSize = 8;
 +
    private Long phoneNumber;
 +
 
 +
    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {
 +
 
 +
        if (value == null || value.toString().length() ==0 )
 +
          return;
 +
 
 +
        //Check if input is a number
 +
        try {
 +
          phoneNumber = new  Long(value.toString());
 +
        } catch(NumberFormatException ex){
 +
          errors.add("phone_valid_number_error", propertyName);
 +
          return;
 +
        }
 +
 
 +
        //Check if input length is at least greater than specified minimum length
 +
        if ( phoneNumber.toString().length() < minSize) {
 +
            errors.add("phone_minimum_size_error", propertyName, "digits", new Long(minSize));
 +
            return;
 +
        }
 +
    }
 +
    public long getMinSize() {
 +
        return minSize;
 +
    }
 +
    public void setMinSize(long minSize) {
 +
        this.minSize= minSize;
 +
    }
 +
}
 +
</pre>
 +
 
 +
 
 +
=== Q.36 How to hide field/property ===
 +
Section 3.8 of Reference Guide:
 +
<pre>
 +
A hidden property has a meaning for the developer but not for the user.
 +
The hidden properties are excluded when the automatic user interface is generated.
 +
However at Java code level they are present and fully functional.
 +
Even if you put it explicitly into a view the property will be shown in the user interface.
 +
</pre>
 +
 +
Hidden property is used mainly for hidden keys, but if you put the property in the view, the property will be show.
 +
 
 +
Example code:
 +
 
 +
When the user click 'Others' from languages combo box, the Others text field should be displayed.
 +
Entity part:
 +
<pre>
 +
<!-- The Combo box -->
 +
<property name="languages">
 +
  <valid-values>
 +
    ....
 +
    <valid-value value="English"/>
 +
    <valid-value value="Others"/>
 +
  </valid-values>
 +
</property>
 +
</pre>
 +
 
 +
The Others property:
 +
<pre>
 +
<property name="otherLanguages" hidden="true" type="String" size="20"/>
 +
</pre>
 +
 
 +
View part:
 +
<pre>
 +
<property-view property="languages">
 +
  <on-change class="com.sami.actions.OnLanguagesChange"/>
 +
</property-view>
 +
</pre>
 +
 
 +
'OnLanguagesChange' action:
 +
<pre>
 +
...
 +
getView().setHidden("otherLanguages", false);
 +
...
 +
</pre>
 +
 
 +
The action is perfect, when user choose the Others from the combo box, the Others text field displayed, but the problem is, that Others text field displayed when user request the form always (On the initial view).
 +
 +
Can not hide properties in the initial view, when user click any action the hidden properties disappear?!
 +
 
 +
The solution in this case is to refine the 'new' action and the 'search' action to hide the 'otherLanguage' property.
 +
But, before, try to define your module in this way:
 +
<pre>
 +
<module name="YourModule">
 +
  <env-var name="XAVA_SEARCH_ACTION" value="CRUD.searchExecutingOnChange"/>
 +
...
 +
</module>
 +
</pre>
 +
 
 +
Look at section 7.6 of reference guide !
 +
 
 +
 
 +
=== Q.37 How to set rows count in tab ===
 +
* [http://sourceforge.net/forum/forum.php?thread_id=1640350&forum_id=419690 sf.net post]
 +
 
 +
 
 +
=== Q.38 How to separate translations for each portlet ===
 +
* [https://sourceforge.net/forum/forum.php?thread_id=1609526&forum_id=419690 sf.net post]
 +
Source file which handle this: org.openxava.util.Labels
 +
 
 +
For properties in tabs, in i18n file (assuming there are ComponentFoo and ComponentBar, both with references to Example Component)
 +
<pre>
 +
ComponentFoo.tab.properties.example.description=Example foo
 +
ComponentBar.tab.properties.example.description=Example bar
 +
</pre>
 +
 
 +
For properties in detail mode:
 +
<pre>
 +
ComnponentFoo.view.level=Level Foo
 +
ComnponentBar.view.level=Level Bar
 +
</pre>
 +
 
 +
For properties which are part of view:
 +
<pre>
 +
# CustomerContact tab inside Engagement
 +
CustomerContact.views.CustomerContact.custName=Customer Name
 +
CustomerContact.views.CustomerContact.custName[description]=Customer Name
 +
CustomerContact.views.<View Name Here>.custName[description]=Customer Name
 +
 
 +
CustomerContact.tab.properties.custName=Customer Name
 +
CustomerContact.tab.properties.custName[description]=Customer Name
 +
</pre>
 +
 
 +
 
 +
=== Q.39 How to create custom JasperReport which uses JDBC connection to DB ===
 +
* [http://sourceforge.net/forum/message.php?msg_id=3715755 sf.net forum post]
 +
 
 +
Need returning null in the method getDataSource() of your JasperReport action (derived from JasperReportBaseAction).
 +
 
 +
<pre>
 +
public class EngagementReportAction extends JasperReportBaseAction {
 +
...
 +
protected JRDataSource getDataSource() throws Exception {
 +
  return null;
 +
}
 +
...
 +
}
 +
</pre>
 +
 
 +
 
 +
=== Q.40 Since version 2.2.1 Calendar overlaps with Main Horizontal line of Portal ===
 +
* [https://sourceforge.net/forum/forum.php?thread_id=1832154&forum_id=419690 sf.net post]
 +
 
 +
In order to change this behavior modify file OpenXava/web/script.jsp
 +
Old line:
 +
<pre>
 +
97:  _dynarch_popupCalendar.showAtElement(el.nextSibling, "Br");        // show the calendar
 +
</pre>
 +
 
 +
New line
 +
<pre>
 +
97:  _dynarch_popupCalendar.showAtElement(el.nextSibling, "tr");        // show the calendar
 +
</pre>
 +
 
 +
"tr" is need for IE6, for working fine when date fields are at the bottom of the page.
 +
Will be available in OX2.2.3
 +
Correct one is:
 +
<pre>
 +
  <%
 +
  // Date fields at end of the windows is not shown correctly in IE6,
 +
  // hence, we align at top in IE6, and at botton in other browsers.
 +
  String browser = request.getHeader("user-agent");
 +
  String calendarAlign = browser != null && browser.indexOf("MSIE 6") >= 0 ? "tr" : "Br"; 
 +
  %>
 +
  _dynarch_popupCalendar.showAtElement(el.nextSibling, "<%=calendarAlign%>"); // show the calendar
 +
</pre>
 +
 
 +
 
 +
=== Q.41 How to filter by property of Reference? ===
 +
All fields by which developer wants to make filtering MUST be described in 'properties' tag!
 +
 
 +
Example code:
 +
 
 +
<pre>
 +
<tab>
 +
<filter class="bg.d3soft.openxava.filters.UserFilter"/>
 +
<properties>custCrtdBy, engDealMkr.empLogonID, rptProMng.empLogonID</properties>
 +
<base-condition>${custCrtdBy} = ? or ${engDealMkr.empLogonID} = ? or ${rptProMng.empLogonID} = ?</base-condition>
 +
...
 +
</tab>
 +
</pre>
 +
 
 +
 
 +
=== Q.42 How to display confirmation message? ===
 +
Confirmation message can be shown using the 'confirm' attribute of <action /> element in controllers.xml.
 +
Section 7.3 of reference guide.
 +
 
 +
This is a generic feature that can be applied to any action that show a JavaScript dialog to confirm the action.
 +
Given that it's generic (not only for list mode), it cannot revise if some item is selected (or any other condition).
 +
It simply ask before action to be execute.
 +
 
 +
A solution can be to define your list action using confirm=false, and then create your logic that move to other controller for confirmation before execute your definitive action, in this way you can control exactly your logic, but you will lost the agility of using a JavaScript dialog.
 +
 
 +
 
 +
=== Q.43 Openxava and Cross Site Scripting (XSS)? ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4583744]
 +
 
 +
 
 +
=== Q.44 How to use Identity Column? ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4584145 sf.net post]
 +
 
 +
Identity must be declared in DB as an auto increment column.
 +
 
 +
Hibernate will create proper DB script.
 +
When updateSchema Ant target is executed( on OpenXava project which uses hibernate), it will generates the correct SQL script. For example, if you are using AS/400 dialect, hibernate
 +
will generate a line like:
 +
<pre>
 +
ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY
 +
</pre>
 +
 
 +
If in your OX componentes you write:
 +
<pre>
 +
<property name="number" type="Integer" key="true" size="5" required="false">
 +
<default-value-calculator class="org.openxava.calculators.IdentityCalculator"
 +
on-create="true"/>
 +
</property>
 +
</pre>
 +
 
 +
OpenXava generates a .hbm.xml with the next content:
 +
<pre>
 +
<id name="number" column="NUMBER" access="field" type='java.lang.Integer'
 +
length='5'>
 +
<generator class='identity'/>
 +
</id>
 +
</pre>
 +
 
 +
 
 +
=== Q.45 How to add IP stereotype and validation class ===
 +
Will be part of OpenXava 2.2.4!
 +
 
 +
[https://sourceforge.net/forum/message.php?msg_id=4506845 sf.net post]
 +
 
 +
1) Add to Application/xava/default-size.xml
 +
<pre>
 +
<for-stereotype name="IP" size="15"/>
 +
</pre>
 +
 
 +
2) Add to Application/xava/editors.xml
 +
<pre>
 +
<editor url="textEditor.jsp">
 +
  <for-stereotype stereotype="IP"/>
 +
</editor>
 +
</pre>
 +
 
 +
3) Add to Application/xava/stereotype-type-default.xml
 +
<pre>
 +
<for stereotype="IP" type="String"/>
 +
</pre>
 +
 
 +
4) Add to Application/i18n/messages_en.properties file
 +
<pre>
 +
ip_validation_error={0} must be a valid IP address
 +
</pre>
 +
 
 +
5) Validation class
 +
<pre>
 +
package org.openxava.validators;
 +
 
 +
import org.openxava.validators.IPropertyValidator;
 +
import org.openxava.util.Messages;
 +
import org.apache.commons.validator.GenericValidator;
 +
 
 +
/**
 +
* @author Janesh Kodikara
 +
*/
 +
public class IPValidator implements IPropertyValidator {
 +
 
 +
    public void validate(Messages errors, Object value, String propertyName,
 +
String modelName) throws Exception
 +
{
 +
 
 +
        String numberRegExp = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
 +
        String ipRegExp = "\\b" + numberRegExp + "\\." + numberRegExp + "\\." +  numberRegExp +"\\." + numberRegExp + "\\b";
 +
 
 +
        if (value == null || value.toString().length() == 0) return;
 +
 
 +
        if (! GenericValidator.matchRegexp(value.toString(), ipRegExp)) {
 +
            errors.add("invalid_ip_error", propertyName);
 +
        }
 +
    }
 +
}
 +
</pre>
 +
 
 +
 
 +
=== Q.46 How to add Reachable IP stereotype and validation class ===
 +
Will be part of OpenXava 2.2.4 and 3.0beta5!
 +
 
 +
[https://sourceforge.net/forum/message.php?msg_id=4506845 sf.net post]
 +
 
 +
1) Add to Application/xava/default-size.xml
 +
<pre>
 +
<for-stereotype name="IP" size="15"/>
 +
</pre>
 +
 
 +
2) Add to Application/xava/editors.xml
 +
<pre>
 +
<editor url="textEditor.jsp">
 +
  <for-stereotype stereotype="IP"/>
 +
</editor>
 +
</pre>
 +
 
 +
3) Add to Application/xava/stereotype-type-default.xml
 +
<pre>
 +
<for stereotype="IP" type="String"/>
 +
</pre>
 +
 
 +
4) Add to Application/i18n/messages_en.properties file
 +
<pre>
 +
ip_not_reachable={0} is Not Reachable
 +
</pre>
 +
 
 +
5) Validation class
 +
<pre>
 +
package org.openxava.validators;
 +
 
 +
import org.openxava.validators.IPropertyValidator;
 +
import org.openxava.util.Messages;
 +
import org.apache.commons.validator.GenericValidator;
 +
 
 +
/**
 +
* @author Janesh Kodikara
 +
*/
 +
public class IPValidator implements IPropertyValidator {
 +
 
 +
    public void validate(Messages errors, Object value, String propertyName,
 +
String modelName) throws Exception
 +
{
 +
 
 +
        if (value == null || value.toString().length() == 0) return;
 +
 
 +
        /*String address = "192.168.0.60";
 +
        InetAddress addr = InetAddress.getByName( value );
 +
        boolean isValidAddress = addr.isReachable(myTimeout);
 +
        System.out.println(" Reachable " + isValidAddress);*/
 +
        if (! GenericValidator.matchRegexp(value.toString(), ipRegExp)) {
 +
            errors.add("ip_not_reachable", propertyName);
 +
        }
 +
    }
 +
}
 +
</pre>
 +
 
 +
=== Q.47 How to avoid Warnings during Generate Portlet ant task? ===
 +
Will be included in OX2.2.4!
 +
 
 +
Go to OpenXava/build.xml, and examine the target "generatePortletXml" ant task.
 +
It looks like:
 +
 
 +
<pre>
 +
<classpath>
 +
<pathelement path="../OpenXava/bin"/>
 +
<fileset dir="../OpenXava/web/WEB-INF/lib">
 +
<include name="**/*.jar"/>
 +
</fileset>
 +
<fileset dir="web/WEB-INF/lib">
 +
<include name="**/*.jar"/>
 +
</fileset>
 +
...
 +
</classpath>
 +
</pre>
 +
 
 +
Because we include ../OpenXava/bin and web/WEB-INF/lib that contains openxava.jar, the default-controllers.xml is duplicated in the path, then you get the warning.
 +
 
 +
Solution is just to exclude the openxava.jar from the classpath.
 +
Modify the build.xml of your OpenXava project.
 +
 
 +
<pre>
 +
<classpath>
 +
<pathelement path="../OpenXava/bin"/>
 +
<fileset dir="../OpenXava/web/WEB-INF/lib">
 +
<include name="**/*.jar"/>
 +
</fileset>
 +
<fileset dir="web/WEB-INF/lib">
 +
<include name="**/*.jar"/>
 +
<exclude name="openxava.jar"/>
 +
</fileset>
 +
...
 +
</classpath>
 +
</pre>
 +
 
 +
 
 +
=== Q.48 How to add ISBN stereotype and validation class ===
 +
Will be part of OpenXava 2.2.4 and 3.0beta5!
 +
 
 +
[https://sourceforge.net/forum/message.php?msg_id=4633525 sf.net post]
 +
 
 +
1) Add to Application/xava/default-size.xml
 +
<pre>
 +
<for-stereotype name="ISBN" size="13"/>
 +
</pre>
 +
 
 +
2) Add to Application/xava/editors.xml
 +
<pre>
 +
<editor url="textEditor.jsp">
 +
  <for-stereotype stereotype="ISBN"/>
 +
</editor>
 +
</pre>
 +
 
 +
3) Add to Application/xava/stereotype-type-default.xml
 +
<pre>
 +
<for stereotype="ISBN" type="String"/>
 +
</pre>
 +
 
 +
4) Add to Application/i18n/messages_en.properties file
 +
<pre>
 +
isbn_validation_error={0} must be a valid ISBN address
 +
</pre>
 +
 
 +
5) Validation class
 +
<pre>
 +
package org.openxava.validators;
 +
 +
import org.openxava.validators.IPropertyValidator;
 +
import org.openxava.util.Messages;
 +
/**
 +
*
 +
* @author Janesh Kodikara
 +
*/
 +
 
 +
public class ISBNValidator implements IPropertyValidator {
 +
 
 +
    private  org.apache.commons.validator.ISBNValidator validator = new org.apache.commons.validator.ISBNValidator();
 +
 
 +
    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {
 +
 
 +
        if (value == null || value.toString().length() ==0 ) return;
 +
 
 +
        if (! validator.isValid(value.toString())) {
 +
          errors.add("isbn_validation_error", propertyName);
 +
        }
 +
    }
 +
 
 +
}
 +
</pre>
 +
 
 +
=== Q.49 How to add Credit Card stereotype and validation class ===
 +
Will be part of OpenXava 2.2.4 and 3.0beta5!
 +
 
 +
[https://sourceforge.net/forum/message.php?msg_id=4644874 sf.net post]
 +
 
 +
1) Add to Application/xava/default-size.xml
 +
<pre>
 +
<for-stereotype name="CREDIT_CARD" size="19"/>
 +
</pre>
 +
 
 +
2) Add to Application/xava/editors.xml
 +
<pre>
 +
<editor url="textEditor.jsp">
 +
  <for-stereotype stereotype="CREDIT_CARD"/>
 +
</editor>
 +
</pre>
 +
 
 +
3) Add to Application/xava/stereotype-type-default.xml
 +
<pre>
 +
<for stereotype="CREDIT_CARD" type="String"/>
 +
</pre>
 +
 
 +
4) Add to Application/i18n/messages_en.properties file
 +
<pre>
 +
creditcard_validation_error={0} must be a valid Credit card number
 +
</pre>
 +
 
 +
5) Validation class
 +
<pre>
 +
package org.openxava.validators;
 +
 
 +
import org.openxava.validators.IPropertyValidator;
 +
import org.openxava.util.Messages;
 +
import org.apache.commons.validator.GenericValidator;
 +
 
 +
/**
 +
* @author Janesh Kodikara
 +
*/
 +
public class CreditCardValidator implements IPropertyValidator {
 +
 
 +
 
 +
    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {
 +
 
 +
        if (value == null || value.toString().length() == 0) return;
 +
 
 +
        if (! GenericValidator.isCreditCard(value.toString())) {
 +
            errors.add("creditcard_validation_error", propertyName);
 +
        }
 +
 
 +
    }
 +
 
 +
}
 +
</pre>
 +
 
 +
=== Q.50 How to add EMAIL_LIST stereotype and validation class? ===
 +
Will be part of OpenXava 2.2.4 and 3.0beta5!
 +
 
 +
[https://sourceforge.net/forum/message.php?msg_id=4661604 sf.net post]
 +
 
 +
1) Add to Application/xava/default-size.xml
 +
<pre>
 +
<for-stereotype name="EMAIL_LIST" size="200"/>
 +
</pre>
 +
 
 +
2) Add to Application/xava/editors.xml
 +
<pre>
 +
<editor url="textEditor.jsp">
 +
  <for-stereotype stereotype="EMAIL_LIST"/>
 +
</editor>
 +
</pre>
 +
 
 +
3) Add to Application/xava/stereotype-type-default.xml
 +
<pre>
 +
<for stereotype="EMAIL_LIST" type="String"/>
 +
</pre>
 +
 
 +
4) Add to Application/i18n/messages_en.properties file
 +
<pre>
 +
email_list_validation_error=Email list should contain valid emails separated by commas
 +
</pre>
 +
 
 +
5) Validation class
 +
<pre>
 +
package org.openxava.validators;
 +
 
 +
import org.openxava.validators.IPropertyValidator;
 +
import org.openxava.util.Messages;
 +
 
 +
import org.apache.commons.validator.GenericValidator;
 +
import java.util.StringTokenizer;
 +
 
 +
/**
 +
* @author Janesh Kodikara
 +
*/
 +
 
 +
public class EmailListValidator implements IPropertyValidator {
 +
 
 +
    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {
 +
 
 +
 
 +
        if (value == null || value.toString().length() == 0)
 +
            return;
 +
 
 +
        StringTokenizer emailAddresses = new StringTokenizer(value.toString(), ",");
 +
        while(emailAddresses.hasMoreTokens()) {
 +
            if (! GenericValidator.isEmail(emailAddresses.nextToken())) {
 +
                errors.add("email_list_validation_error", propertyName);
 +
            }
 +
        }
 +
    }
 +
 
 +
}
 +
</pre>
 +
 
 +
=== Q.51 How to save model details when a action is called? ===
 +
* [http://sourceforge.net/forum/message.php?msg_id=4673734 sf.net post]
 +
 
 +
Is it possible to save model details when a action is called?
 +
 
 +
Yes.
 +
 
 +
An option is to make your action a child of SaveAction, and put the property resetAfter to false. Then you only need to:
 +
 
 +
<pre>
 +
public void execute() throws Exception {
 +
  super.execute();
 +
  // Here the code of you action.
 +
}
 +
</pre>
 +
 
 +
Or you can save the data from the view directly using MapFacade.
 +
 
 +
Look at the code of SaveAction in order to learn how to use MapFacade.
 +
 
 +
 
 +
=== Q.52 Converter for TIME stereotype. ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4691679 sf.net post]
 +
 
 +
Will be part of OpenXava 2.2.5.
 +
 
 +
 
 +
* By default, when you use "TIME" stereotype you want to work with String for manage time data, both at Java level and DB level. This case is:
 +
<pre>
 +
  <property name="mytime" stereotype="TIME"/>
 +
</pre>
 +
 
 +
 
 +
* If you want to work with java.sql.Time usually you use the Java type directly, and you don't use TIME stereotype. In this way you use java.sql.Time for Java and DB. Code is:
 +
<pre>
 +
  <property name=mytime" type="java.sql.Time"/>
 +
</pre>
 +
 
 +
 
 +
* New converter is only for the case that you want to work with String at Java level and with java.sql.Time at DB level:
 +
 
 +
<pre>
 +
  <property name="mytime" stereotype="TIME"/>
 +
  ...
 +
  <property-mapping ... >
 +
    <converter class="org.openxava.converters.StringTimeConverter"/>
 +
  </property-mapping>
 +
  ...
 +
</pre>
 +
 
 +
* New converter:
 +
 
 +
<pre>
 +
package org.openxava.converters;
 +
 
 +
import org.openxava.converters.IConverter;
 +
import org.openxava.converters.ConversionException;
 +
 
 +
import java.sql.Time;
 +
 
 +
/**
 +
* In java a <tt>String</tt> and in database a
 +
* <tt>java.sql.Time</tt>. <p>
 +
*
 +
* @author Janesh Kodikara
 +
*/
 +
public class StringTimeConverter implements IConverter {
 +
 
 +
    private Time time;
 +
    private String timeStamp;
 +
 
 +
    public Object toDB(Object o) throws ConversionException {
 +
 
 +
 
 +
        if (o == null) return null;
 +
        if (!(o instanceof String)) {
 +
            throw new ConversionException("conversion_db_string_expected");
 +
        }
 +
 
 +
        timeStamp = o.toString() + ":00";
 +
        time = Time.valueOf(timeStamp);
 +
        return time;
 +
    }
 +
 
 +
    public Object toJava(Object o) throws ConversionException {
 +
        if (o == null) return null;
 +
        if (!(o instanceof java.sql.Time)) {
 +
            throw new ConversionException("conversion_java_sqltime_expected");
 +
        }
 +
 
 +
        time = (Time) o;
 +
        timeStamp = time.toString();
 +
        timeStamp = timeStamp.substring(0, 5);
 +
 
 +
        return timeStamp;
 +
    }
 +
}
 +
</pre>
 +
 
 +
 
 +
=== Q.53 How to add a string to description list? ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4696866 sf.net post]
 +
 
 +
Section 4.3.6 of Reference guide.
 +
 
 +
Is it possible to add text to a description list?
 +
 
 +
Need to display book title along with Author and separate the variable with  a string (e.g ":" or "by")
 +
 
 +
<pre>
 +
<reference-view reference="book">
 +
  <descriptions-list description-properties="title, author.firstName, author.secondName"/>
 +
</reference-view>
 +
</pre>
 +
 
 +
or
 +
 
 +
<pre>
 +
<reference-view reference="subfamily" create="false">
 +
 
 +
<!-- In this case description-property can be omited -->
 +
<descriptions-list 
 +
description-property="description"
 +
depends="family"
 +
condition="${family.number} = ?"/>
 +
 
 +
</reference-view>
 +
</pre>
 +
 
 +
 
 +
==== First suggestion: Use Calculated property ====
 +
<pre>
 +
<component name="Book">
 +
  <entity>
 +
    ...
 +
    <property name="authorFullName" type="String" size="25">
 +
<calculator class="org.openxava.calculators.ConcatCalculator">
 +
<set property="string1" from="author.firstName"/>
 +
<set property="separator" value=" "/>
 +
<set property="string2" from="author.secondName"/>
 +
</calculator>
 +
    </property>
 +
 
 +
    <property name="fullTitle" type="String" size="60">
 +
<calculator class="org.openxava.calculators.ConcatCalculator">
 +
<set property="string1" from="title"/>
 +
<set property="separator" value=" by "/>
 +
<set property="string2" from="authorFullName"/>
 +
</calculator>
 +
    </property>
 +
 
 +
  </entity>
 +
...
 +
</component>
 +
 
 +
<component ... >
 +
  <view>
 +
    <reference-view reference="book">
 +
      <descriptions-list description-properties="fullTitle"/>
 +
    </reference-view>
 +
  </view>
 +
</component>
 +
</pre>
 +
 
 +
 
 +
==== Second suggestion: Develop new functionality ====
 +
 
 +
> Way to distinguish properties from strings.
 +
 
 +
Your way is good, and I think that natural for an OX developer.
 +
Use other attribute, 'description-message-id'.
 +
 
 +
 
 +
> Guide how to develop new functionality?
 +
 
 +
The code for concatenating the description of description list is in the class.
 +
<pre>
 +
org.openxava.calculators.DescriptionsCalculator
 +
</pre>
 +
 
 +
After this works, we can consider using 'description-message-id', this will involve to modify the dtd and parser.
 +
 
 +
==== Third suggestion: New functionality with i18n ====
 +
<pre>
 +
<descriptions-list description-properties="title, author.firstName, author.secondName" pattern-id="descriptions_list_book_title"
 +
/>
 +
</pre>
 +
 
 +
 +
And in YourApplication-messages_en.properties you have:
 +
<pre>
 +
descriptions_list_book_title={0} by {1} {2}
 +
</pre>
 +
 
 +
=== Q.54 How to remove image? ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4700916 sf.net post]
 +
 
 +
Edit imageEditor.jsp, and add a new action to reset the image, inside the below block.
 +
<pre>
 +
<% if (editable) { %>
 +
</pre>
 +
 
 +
Add the action in ImageEditor controller of default-controllers.xml.
 +
 
 +
Have a look to the code of LoadImageAction.
 +
 
 +
 
 +
=== Q.55 How to modify OpenXava DTD? ===
 +
 
 +
Add new XML element or xml attribute to below class.
 +
Java class which holds all dtd element and attribute names is:
 +
<pre>
 +
OpenXava/src/org/openxava/util/xmlparse/XmlElementsNames.java
 +
</pre>
 +
 
 +
 
 +
=== Q.56 How to add new property to xava.properties file? ===
 +
 
 +
Edit file:
 +
<pre>
 +
OpenXava/src/org/openxava/util/XavaPreferences.java
 +
</pre>
 +
 
 +
Added new method which returns value of new property:
 +
<pre>
 +
public boolean isMapFacadeAutoCommit()
 +
{
 +
    return "true".equalsIgnoreCase(getProperties().getProperty("mapFacadeAutoCommit", "false").trim());
 +
}
 +
</pre>
 +
 
 +
 
 +
=== Q.57 How to sort reference list with condition? ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4722363 sf.net post]
 +
 
 +
Error is thrown if column in condition is not included in the FROM part.
 +
 
 +
Because OX uses description-properties to determine which tables must be included in FROM part.
 +
 +
A simple workaround is to add your property to description properties, in this way:
 +
<pre>
 +
<reference-view reference="releasebyQA" frame="false">
 +
  <descriptions-list description-property="name, designation.department.id"
 +
                    condition="${designation.department.id} ='QA'"/>
 +
</reference-view>
 +
</pre>
 +
 
 +
 
 +
=== Q.58 How to create Date Validation class? ===
 +
* [https://sourceforge.net/forum/message.php?msg_id=4726771 sf.net post]
 +
 
 +
<pre>
 +
package org.openxava.validators;
 +
 
 +
import org.apache.commons.validator.routines.DateValidator;
 +
import org.openxava.util.Messages;
 +
import java.util.Date;
 +
 
 +
 
 +
/**
 +
* @author Janesh Kodikara
 +
*/
 +
 
 +
public class XavaDateValidator {
 +
 
 +
    DateValidator validator;
 +
 
 +
    public XavaDateValidator() {
 +
        validator = new DateValidator();
 +
    }
 +
 
 +
    public boolean isSameDate(Date startDate, Date endDate) {
 +
        boolean isSame = false;
 +
 
 +
        if (validator.compareDates(startDate, endDate, null) == 0) {
 +
            isSame = true;
 +
        }
 +
        return isSame;
 +
    }
 +
 
 +
    public void isSameDate(Messages errors, String startFieldName, Date startDate, String endFieldName, Date endDate) {
 +
 
 +
        if (startDate == null || endDate == null) return;
 +
 
 +
        if (validator.compareDates(startDate, endDate, null) == 0) {
 +
            errors.add("same_dates_error", endFieldName, startFieldName);
 +
        }
 +
    }
 +
 
 +
    public boolean isFutureDate(Date value) {
 +
        boolean isSame = false;
 +
        Date today = new Date();
 +
        if (validator.compareDates(value, today, null) > 0) {
 +
            isSame = true;
 +
        }
 +
        return isSame;
 +
    }
 +
 
 +
    public void isFutureDate(Messages errors, String fieldName, Date value) {
 +
        Date today = new Date();
 +
 
 +
        if (value == null) return;
 +
 
 +
        if (validator.compareDates(value, today, null) > 0) {
 +
            errors.add("date_in_future_error", fieldName);
 +
        }
 +
    }
 +
 
 +
    public boolean isPastDate(Date value) {
 +
        boolean isSame = false;
 +
        Date today = new Date();
 +
        if (validator.compareDates(value, today, null) < 0) {
 +
            isSame = true;
 +
        }
 +
        return isSame;
 +
    }
 +
    public void isPastDate(Messages errors, String fieldName, Date value) {
 +
        Date today = new Date();
 +
 
 +
        if (value == null) return;
 +
 
 +
        if (validator.compareDates(value, today, null) > 0) {
 +
            errors.add("past_date_error", fieldName);
 +
        }
 +
    }
 +
 
 +
 
 +
    public void isStartDateAfter(Messages errors, String startFieldName, Date startDate, String endFieldName, Date endDate) {
 +
        if (startDate == null || endDate == null) return;
 +
 
 +
        if (validator.compareDates(startDate, endDate, null) > 0) {
 +
            errors.add("start_date_greater_error", endFieldName, startFieldName);
 +
        }
 +
    }
 +
}
 +
</pre>
 +
 
 +
= Liquibase =
 +
* [http://www.liquibase.org/ http://www.liquibase.org]
 +
 
 +
* Articles
 +
 
 +
== Liquibase Questions and Hints ==
 +
 
 +
=== Hint.1 How to update data? ===
 +
Is there any way to update a row that already exists in a table (besides using <sql>)?
 +
 
 +
Currently there is not.
 +
I have considered creating an update tag but have not yet.
 +
The main reason I did not create it originally is that it seemed to not add a lot of value over the standard <sql> update statement and created a lot of typing.
 +
 
 +
For example:
 +
<pre>
 +
<update table="person">
 +
<column name="username" value="newUsername">
 +
<where>username = 'oldUsername'</where>
 +
</update>
 +
</pre>
 +
 
 +
seems like a lot of work compared to
 +
 
 +
<pre>
 +
<sql>UPDATE person SET username='newUsername' WHERE username='oldUsername'</sql>
 +
</pre>
 +
 
 +
Now that there is support for standardizing dates, Boolean values, etc. it may be worth creating however.
 +
 
 +
 
 +
 
 +
= Web Services =
 +
* [http://www.artima.com/lejava/articles/threeminutes.html Three Minutes to a Web Service]
 +
* [http://www.devshed.com/index2.php?option=content&task=view&id=1164&pop=1&hide_ads=1&page=0&hide_js=1 Developing SOAP Clients using PHP]
 +
* [http://ws.apache.org/axis/java/user-guide.html Axis User's Guide]
 +
* [http://www.onjava.com/lpt/a/1025 Java and Web Services Primer]
 +
* [http://www.allesta.com/products/overview.html Open source Web services management (WSM)]
 +
* [http://wso2.org/projects/wsas/java WSO2 Web Services Application Server (WSAS)]
 +
** [http://www.xml.com/pub/a/2007/05/02/sure-reliable-web-services-with-apache.html Secure, Reliable Web Services with Apache]
 +
 
 +
 
 +
== Web Service Providers ==
 +
* [http://dev.bulport.com/ws/ BG to USD exchange rate]
 +
* [http://www.swift.com/biconline/index.cfm?fuseaction=display_freesearch Search by BIC]
 +
 
 +
= Ajax =
 +
* [http://www.devarticles.com/c/a/JavaScript/Learning-AJAX/ Learning AJAX ]
 +
* [http://www.devarticles.com/c/a/JavaScript/JSP-Libraries-and-AJAX/ JSP Libraries and AJAX ]
 +
* [http://www.codeproject.com/jscript/AutoSuggestControl.asp Auto-suggest control] Auto-complete control.
 +
* [http://www.smartclient.com/ Smart Client] Commercial but looks good.
 +
 
 +
 
 +
== Ajax Frameworks ==
 +
* [http://developer.tibco.com/gi TIBCO General Interface]
 +
** [http://www.theserverside.com/tt/articles/article.tss?l=UsingDWRwithTIBCO Using DWR with TIBCO General Interface]
 +
 
 +
= Mashups =
 +
* [http://www.eaipatterns.com/ramblings/59_mashupeai.html Mashups == EAI 2.0?] very good article with example.
 +
* [http://www.readwriteweb.com/archives/yahoo_pipes_web_database.php Yahoo! Pipes and The Web As Database]
 +
* [http://apatarforge.org/wiki/display/INT/Salesforce.com+SMS+Mashup+using+StrikeIron+SMS+Web+Service Salesforce.com SMS Mashup using StrikeIron SMS Web Service]
 +
* [http://www.stephenpasco.com/content/view/24/28/ Broadcasting Google map events to an Enterprise Service Bus tutorial - a multi-part tutorial] Interesting idea.
 +
 
 +
 
 +
= Portlets =
 +
* [http://www.devx.com/Java/Article/35332/1954?pf=true Building a Web Service Powered JSR 168 Financial Portlet]
 +
* [http://www.ibm.com/developerworks/web/library/wa-aj-dwr/ Develop an Ajax-based file upload portlet using DWR]Display a convenient progress bar during the file upload process
 +
 
 +
 
 +
= GWT - Google Web Toolkit =
 +
* [http://code.google.com/webtoolkit/ Google Web Toolkit - Google Code]
 +
 
 +
* [http://mygwt.net/ MyGWT]Open source Java library for the Google Web Toolkit.
 +
* [http://www.infoq.com/news/2008/01/gwt-frameworks Numerous Open Source GWT Framework Projects]
 +
* [http://gears.google.com/ Google Gears]
 +
** [http://www.gwtsite.com/getting-started-with-gwt-and-google-gears/ Getting started with GWT and Google Gears]Google Gears -library that enables web applications to work offline.
 +
** [http://wiki.apexdevnet.com/index.php/Building_Offline_Salesforce_Applications_with_Google_Gears_and_Google_Web_Toolkit Building Offline Salesforce Applications with Google Gears and Google Web Toolkit]
 +
 
 +
* [http://sourceforge.net/projects/googlipse/ Googlipse (Gwt-Eclipse Plugin)]
 +
** [http://www.gwtsite.com/eclipse-plugin-for-gwt-released/ Eclipse plugin for GWT released]
 +
** [http://www.gwtsite.com/googlipse-quickstart/ Googlipse quickstart Part 2]
 +
 
 +
* [http://www.javaworld.com/javaworld/jw-04-2007/jw-04-gwt.html Some Recipes to Improve Your Google Web Toolkit Development]
 +
 
 +
= Portals, JCR, ECM, Groupware =
 +
* [http://www.theserverside.com/tt/articles/article.tss?l=eXoPlatform2 eXo Platform 2]
 +
 
 +
* User information which Portal must provide according to Portlet Specification.
 +
** [http://portals.apache.org/pluto/pluto-container/apidocs/constant-values.html Apache Pluto Constant Field Values]
 +
** [http://lutece.paris.fr/fr/attributes.html User Information Attribute Names]
 +
** [http://mail-archives.apache.org/mod_mbox/portals-jetspeed-dev/200501.mbox/%3C20050114130407.3704.qmail@minotaur.apache.org%3E User Attributes Usage documentation] Apache Jetspeed allows mapping of custom attributes to Portlet API attributes
 +
 
 +
* Portal comparison
 +
** [http://meera-subbarao.blogspot.com/2008/01/which-one-do-you-prefer-liferay-or.html Which one do you prefer; Liferay or JBoss Portal?]
 +
** [http://www.infoworld.com/article/06/05/05/77788_19TCportals_1.html InfoWorld - Comparision of Liferay and JBoss portal]
 +
** [http://www.javalobby.org/eps/jboss-portal/ JBoss Portal Presentation]
 +
** [http://tomasvarsavsky.com/2007/09/21/evaluating-opencms-alfresco-and-liferay/ Evaluating OpenCms, Alfresco and Liferay] Interesting and well written review! Developer works for ThoughtWorks... so i'm not surprised that it is well written.
 +
 
 +
 
 +
 
 +
== Liferay Portal ==
 +
* [http://wiki.liferay.com/index.php/Main_Page WIKI GUIDE FOR LIFERAY 4]
 +
* [http://wiki.liferay.com/index.php/Portlet_DataHandlers Portlet Data Handlers]How to export/import data from Liferay Portlets using Liferay API.
 +
 
 +
* [http://freeanalysis.wordpress.com/2008/01/17/next-level-freedashboard-embeded-into-liferay/ FreeDashboard Embeded into LifeRay] Dashboard portlets and BI.
 +
* [http://wiki.liferay.com/index.php/How_to_use_the_sitemap_protocol_with_Liferay How to use the sitemap protocol with Liferay]
 +
* [http://wiki.liferay.com/index.php/Exposing_Microformats_in_Liferay Exposing Microformats in Liferay]
 +
* [http://wiki.liferay.com/index.php/Community_Roles Community Roles]
 +
* [http://www.liferay.com/web/guest/devzone/forums?p_p_id=19&p_p_action=0&p_p_state=maximized&p_p_mode=view&p_p_col_id=null&p_p_col_pos=0&p_p_col_count=3&_19_struts_action=%2Fmessage_boards%2Fview_message&_19_messageId=39008 600.000 users] Good number of users!
 +
* [http://wiki.liferay.com/index.php/Mail_%28JavaMail%29_Setup_For_External_.WAR_Portlets Mail (JavaMail) Setup For External .WAR Portlets]
 +
* [http://www.liferay.com/web/guest/devzone/forums/message_boards/message/29306 How to get Liferay user name in a servlet]
 +
* [http://www.javalobby.org/articles/liferay/ How to create new Themes in Liferay]
 +
* [http://www.liferay.com/web/guest/devzone/forums/message_boards/message/27790 How to create user?]
 +
* [http://www.liferay.com/web/guest/devzone/forums/message_boards/message/24992 How to Authenticate using email address instead of user id?]
 +
* [http://www.liferay.com/web/guest/devzone/forums/message_boards/message/37323 How to programatically manage community / users]
 +
* [http://wiki.liferay.com/index.php/Accessing_the_Document_Library_with_WebDAV How to access the Document Library with WebDAV]
 +
* [http://www.liferay.com/web/guest/devzone/forums/message_boards/message/34311 How to manage users programatically?]
 +
* [http://www.liferay.com/web/guest/devzone/forums/message_boards/message/34992 How to hide Liferay portlet's tab?]
 +
* [http://www.liferay.com/web/guest/community/forums/message_boards/message/106870 ModelListener for listening to user changes]
 +
* [http://www.liferay.com/web/guest/devzone/forums?p_p_id=19&p_p_action=0&p_p_state=maximized&p_p_mode=view&p_p_col_id=null&p_p_col_pos=0&p_p_col_count=0&_19_struts_action=%2Fmessage_boards%2Fview_message&_19_messageId=39474 Liferay OpenID tutorial]
 +
 
 +
* [http://www.liferay.com/web/guest/devzone/forums/message_boards/message/32361 How to get user attributes]
 +
<pre>
 +
I am trying to get user atributes using the JSR-186 specified way.
 +
Here is the extract from portlet.xml:
 +
<user-attribute>
 +
  <name>user.name.given</name>
 +
</user-attribute>
 +
<user-attribute>
 +
  <name>user.name.family</name>
 +
</user-attribute>
 +
<user-attribute>
 +
  <name>user.business-info.postal.street</name>
 +
</user-attribute>
 +
<user-attribute>
 +
  <name>user.business-info.postal.city</name>
 +
</user-attribute>
 +
<user-attribute>
 +
  <name>user.business-info.postal.country</name>
 +
</user-attribute>
 +
<user-attribute>
 +
  <name>user.business-info.postal.organization</name>
 +
</user-attribute>
 +
<user-attribute>
 +
  <name>user.business-info.telecom.telephone.number</name>
 +
</user-attribute>
 +
 
 +
Here is the code to get user attributes:
 +
 
 +
HashMap hmUserInfo = (HashMap)request.getAttribute(PortletRequest.USER_INFO);'
 +
log.debug((String)hmUserInfo.get(UserAttributes.USER_NAME_GIVEN));
 +
log.debug(((String)hmUserInfo.get(UserAttributes.USER_NAME_FAMILY));
 +
log.debug((String)hmUserInfo.get(UserAttributes.USER_BUSINESS_INFO_POSTAL_CITY));
 +
log.debug((String)hmUserInfo.get(UserAttributes.USER_BUSINESS_INFO_POSTAL_COUNTRY));
 +
log.debug((String)hmUserInfo.get(UserAttributes.USER_BUSINESS_INFO_POSTAL_ORGANIZATION));
 +
log.debug((String)hmUserInfo.get(UserAttributes.USER_BUSINESS_INFO_POSTAL_STREET));
 +
log.debug((String)hmUserInfo.get(UserAttributes.USER_BUSINESS_INFO_TELECOM_TELEPHONE_NUMBER));
 +
 
 +
Liferay return first/last names ONLY in spite of the fact that all other information is presented for this user.
 +
I entered it using Organization Admin portlet.
 +
</pre>
 +
 
 +
 
 +
=== Liferay Web Services ===
 +
* [http://www.liferay.com/web/guest/devzone/forums?p_p_id=19&p_p_action=0&p_p_state=maximized&p_p_mode=view&p_p_col_id=null&p_p_col_pos=0&p_p_col_count=0&_19_struts_action=%2Fmessage_boards%2Fview_message&_19_messageId=38896 Existing folders via SOAP]
 +
 
 +
 
 +
=== Liferay Hints ===
 +
 
 +
==== Hint.1 Multiple Instances of Portlet ====
 +
* [http://liferaylearnings.blogspot.com link]
 +
 
 +
Portlets which allowed multiple instances to be instantieted in portal.
 +
Add this tag to the portlet configuration in liferay-portlet-ext.xml
 +
<pre>
 +
<instanceable>true</instanceable>
 +
</pre>
 +
 
 +
 
 +
==== Hint.2 How to add new layout ====
 +
* [http://wiki.liferay.com/index.php?title=Themes_and_Layouts&redirect=no Liferay Themes and Layouts]
 +
 
 +
Edit file: portal\webapps\ROOT\WEB-INF\liferay-layout-templates-ext.xml
 +
<pre>
 +
<?xml version="1.0"?>
 +
<!DOCTYPE layout-templates PUBLIC "-//Liferay//DTD Layout Templates 4.0.0//EN" "http://www.liferay.com/dtd/liferay-layout-templates_4_0_0.dtd">
 +
 
 +
<layout-templates>
 +
<custom>
 +
 +
<layout-template id="2_columns_iv" name="2 Columns (20/80)">
 +
<template-path>/html/layouttpl/custom/2_columns_iv.tpl</template-path>
 +
</layout-template>
 +
 +
</custom>
 +
</layout-templates>
 +
</pre>
 +
 
 +
Add new file: portal\webapps\ROOT\html\layouttpl\custom\2_columns_iv.tpl
 +
<pre>
 +
<div id="layout-content-outer-decoration">
 +
<div id="layout-content-inner-decoration">
 +
<div id="layout-content-container">
 +
<table border="0" cellpadding="0" cellspacing="0" width="100%">
 +
<tr>
 +
<td valign="top" width="19%">
 +
$processor.processColumn("column-1")
 +
</td>
 +
<td class="layout-column-spacer" width="1%">
 +
<div>&nbsp;</div>
 +
</td>
 +
<td valign="top" width="80%">
 +
$processor.processColumn("column-2")
 +
</td>
 +
</tr>
 +
</table>
 +
</div>
 +
</div>
 +
</div>
 +
</pre>
 +
 
 +
Enjoy new layout!
 +
 
 +
= XML =
 +
* [http://www.devarticles.com/c/a/JavaScript/More-on-JavaScript-and-XML/ More on JavaScript and XML ]
 +
 
 +
* [http://www.zvon.org/index.php?nav_id=tutorials Good XML/xPath/CSS/... Tutorials ]
 +
 
 +
* [http://dtddoc.sourceforge.net/ DTD Doc]
 +
 
 +
* [http://servingxml.sourceforge.net/ ServingXML]Open source, Apache 2.0 licensed, framework for flat/XML data transformations.
 +
 
 +
* [http://www.javaworld.com/javaworld/jw-07-2007/jw-07-xmlmerge.html XML merging made easy]Manipulate XML files using XPath declarations
 +
 
 +
* [http://www.xfront.com/index.html www.xfront.com]Good tutorials and articles
 +
 
 +
 
 +
* EntityResolver
 +
** [http://www.sagehill.net/docbookxsl/WriteCatalog.html How to write an XML catalog file]
 +
** [http://articles.techrepublic.com.com/5100-22_11-5075716.html Resolve custom XML entities with SAX and Java]
 +
** [http://www.ibm.com/developerworks/library/x-tipent.html Using an entity resolver]
 +
** [http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/parsers/DocumentBuilder.html DOM entity Resolver]
 +
 
 +
 
 +
* How to include one XML file in another?
 +
** [http://xml.silmaril.ie/authors/includes/ How do I include one XML file in another?]
 +
** [http://www.xml.com/pub/a/98/08/xmlqna1.html#EXTENT EXTENT]
 +
** [http://www.xml.com/pub/a/98/08/xmlqna2.html#ENTDECL Entity Declarations, Attributes and Expansion]
 +
** [http://axlrosen.net/stuff/complex-entity-example.html Example of shared entities in external file]
 +
 
 +
 
 +
* XML Catalogs
 +
** [http://www.oasis-open.org/committees/entity/spec.html XML catalog DTD defined by OASIS]
 +
** [http://www.sagehill.net/docbookxsl/WriteCatalog.html How to write an XML catalog file]
 +
 
 +
 
 +
== XForms ==
 +
* [http://code.google.com/p/x2o/ X2O] XForm server; Create a system to use XML schemas to generate XForms and related XML-based GUIs
 +
** [http://www.xml.com/pub/a/2007/08/16/xforms-xml-schema-and-rox.html XForms, XML Schema, and ROX]
 +
 
 +
* [http://www.ibm.com/developerworks/xml/library/x-xformstipjava/ Accepting XForms data in Java]
 +
 
 +
* [http://www.ibm.com/developerworks/library/x-xformsgwt1/]Integrate XForms with the Google Web Toolkit, Part 1: Creating an artist and album management form
 +
 
 +
* [http://www.ibm.com/developerworks/java/library/x-xformsgwt2/index.html] Integrate XForms with the Google Web Toolkit, Part 2: Creating an artist and album management form
 +
 
 +
* [http://www.xml.com/pub/a/2001/09/05/xforms.html?page=2 What Are XForms]
 +
 
 +
* [http://en.wikibooks.org/wiki/XForms XForms Tutorial and Cookbook]
 +
 
 +
* [http://sitec.design-freestyle.com/Dynamic-user-interfaces-and-XForms-performance/ Dynamic user interfaces and XForms performance]
 +
 
 +
* [http://blogs.ittoolbox.com/pm/minimalit/archives/xforms-what-you-need-to-know-21295?rss=1 XForms - what you need to know]
 +
 
 +
* [http://www.ibm.com/developerworks/xml/library/x-xformsroi/index.html The ROI of XForms]
 +
 
 +
* [http://nunojob.wordpress.com/2008/01/05/creating-a-user-interface-for-xml-schema-using-xforms/ Creating a User Interface for XML Schema using xForms]
 +
 
 +
* [http://www.idealliance.org/papers/dx_xml03/index/author/a709805de74ae699bfebc5aca2.html Generating User Interfaces from Composite Schemas]
 +
 
 +
* [http://dret.net/netdret/docs/mt-ws2006-michel.pdf ]
 +
 
 +
 
 +
=== XForms Server-side Transformation Engines ===
 +
* [http://www.orbeon.com/ Orbeon]
 +
* [http://chiba.sourceforge.net/ Chiba]
 +
 
 +
 
 +
=== XForms Browser extensions ===
 +
* [http://www.mozilla.org/projects/xforms/ Mozilla XForms]
 +
* [http://www.formsplayer.com formsPlayer] a full-featured XForms processor that provides a complete implementation of the W3C's XForms specification. Workis with IE only.
 +
 
 +
 
 +
=== XForms Browser-based scripts ===
 +
* [http://www.formfaces.com/ FormFaces] perform the required XForms processing, also without installing extensions on the browser.
 +
 
 +
 
 +
=== XForms for Mobile devices ===
 +
* [http://www.picoforms.com/ PicoForms]
 +
* [http://www.ctr.kcl.ac.uk/mwcn2005/Paper/C200556.pdf MoviForms]
 +
 
 +
== XSLT ==
 +
* [http://www17.homepage.villanova.edu/william.pohlhaus/xsl/java/ Using Java in XSL]
 +
 
 +
 
 +
* Identity Transform
 +
<pre>
 +
<!-- identity transform -->
 +
<xsl:template match="*|@*|node()">
 +
  <xsl:copy>
 +
    <xsl:apply-templates select="*|@*|node()"/>
 +
  </xsl:copy>
 +
</xsl:template>
 +
</pre>
 +
 
 +
== XML databases ==
 +
* [http://exist.sourceforge.net/ eXist]
 +
 
 +
= REST =
 +
* [http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm REST architecture style]Dissertation by Roy Fielding
 +
* [http://en.wikipedia.org/wiki/Representational_State_Transfer REST page in Wikipedia]
 +
* [http://jcp.org/en/jsr/detail?id=311 JCR-311]JAX-RS: The JavaTM API for RESTful Web Services
 +
 
 +
 
 +
== REST Articles ==
 +
* [http://www.xml.com/pub/a/2004/12/01/restful-web.html How to Create a REST Protocol]
 +
* [http://www.infoq.com/articles/rest-introduction A Brief Introduction to REST]
 +
* [http://www.javaworld.com/javaworld/jw-10-2007/jw-10-resteasy.html?fsrc=rss-index REST easy with the JavaBeans Activation Framework]
 +
* [http://www.ddj.com/web-development/199902676 SOA, Web Services, and RESTful Systems]A framework for building RESTful systems
 +
* [http://www.prescod.net/rest/mistakes/ Common REST Mistakes]
 +
* [http://blog.exoplatform.org/2008/01/23/exo-rest-framework-use-case/ eXo REST framework use case]
 +
 
 +
 
 +
== REST Frameworks ==
 +
* [https://cetia4.dev.java.net/ Cetia4]Java Servlet-based REST Framework
 +
 
 +
 
 +
=== Restlet REST Framewrok ===
 +
* [http://www.restlet.org/ Restlet, a REST framework for Java]Good one. Organized
 +
* [http://www.theserverside.com/news/thread.tss?thread_id=38290 The Server Side post] with very good discussion
 +
 
 +
 
 +
=== Jersey REST framework ===
 +
* [https://jersey.dev.java.net/ Jersey]JAX-RS (JSR 311) Reference Implementation for building RESTful Web services.
 +
* [http://objectif-naiade.blogspot.com/2007/11/java-rest-framework-jersey.html A java REST framework : Jersey]
 +
* [http://objectif-naiade.blogspot.com/2007/11/integrating-jersey-with-guice-and.html Integrating Jersey with GUICE and freemarker]
 +
* [http://weblogs.java.net/blog/mhadley/archive/2007/09/integrating_jer.html Integrating Jersey and Spring]
 +
 
 +
 
 +
=== Project Zero REST framework ===
 +
* [http://www.projectzero.org/wiki/bin/view/ Project Zero]IBM REST framework
 +
 
 +
 
 +
== Mattress REST framework ==
 +
* [http://www.mattressframework.org/ Mattress]
 +
* [http://sourceforge.net/projects/mattress/ sf.net page]
 +
 
 +
= BPM =
 +
* [http://bpms.intalio.com/content/view/18/59/ Intalio]
 +
 
 +
 
 +
== BPM Articles ==
 +
* [http://www.infoq.com/articles/seven-fallacies-of-bpm The Seven Fallacies of Business Process Execution]
 +
* [http://wiki.jboss.org/wiki/Wiki.jsp?page=JbpmAndDrools How to invoke rules from a jBPM ActionHandler]
 +
 
 +
= Rule Engines =
 +
* [http://jcp.org/en/jsr/detail?id=94 JSR 94]
 +
* [http://java.sun.com/developer/technicalArticles/J2SE/JavaRule.html Getting Started With the Java Rule Engine API (JSR 94): Toward Rule-Based Applications]
 +
* [http://javaboutique.internet.com/tutorials/rules_engine/ A Closer Look at the Java Rules Engine API (JSR 94)]
 +
* [http://www.onjava.com/pub/a/onjava/2005/08/03/drools.html Give Your Business Logic a Framework with Drools]
 +
* [http://www-128.ibm.com/developerworks/java/library/j-drools/ Implement business logic with the Drools rules engine]
 +
* [http://docs.codehaus.org/display/DROOLS/JSR-94+TCK+Tutorial JSR-94 Technology Compatibility Kit (TCK) Tutorial]
 +
 
 +
= ESB - Enterprise Service Bus and JBI - Java Business Integration=
 +
* [http://servicemix.apache.org/home.html ServiceMix]
 +
* [http://www.jcp.org/en/jsr/detail?id=208 JCR-208]Java Business Integration
 +
 
 +
 
 +
== ESB/JBI Articles ==
 +
* [http://www.javaworld.com/cgi-bin/mailto/x_java.cgi ServiceMix as an enterprise service bus]
 +
 
 +
= Linux =
 +
* [http://www.desktoplinux.com/articles/AT3304051309.html 13 reasons why Linux won't make it to a desktop near you]
 +
* [http://www.desktoplinux.com/news/NS3014149484.html Why the Linux Desktop will succeed despite itself]
 +
* User Firendly Linux Distros
 +
** [http://www.mepis.org/ MEPIS] Fedora based
 +
 
 +
* [http://www.clamav.net/ Clam AntiVirus]Open source (GPL) anti-virus toolkit for UNIX, designed especially for e-mail scanning on mail gateways.
 +
 
 +
* how to download xampp from command line:
 +
<pre>
 +
wget http://www.apachefriends.org/download.php?xampp-linux-1.6.4.tar.gz
 +
</pre>
 +
 
 +
 
 +
= Virtual Machines =
 +
 
 +
* [http://openqrm.com/ Open QRM]
 +
** [http://mattinaction.blogspot.com/2008/01/cios-and-it-managers-are-you-willing-to.html CIOs and IT Managers: Are you willing to adopt virtualization now?]
 +
** [http://wiki.linuxfellaz.net/doku.php?id=openqrm:webfarm Building a virtualized web-farm with openQRM]
 +
** [http://www.onlamp.com/pub/a/onlamp/2007/02/08/managing-virtualization.html An Introduction to openQRM]
 +
 
 +
 
 +
== Applications based on VM ==
 +
* SVN
 +
** [http://www.vmware.com/appliances/directory/328 Helix Agile Development Virtual Appliance]Subversion and Trac. Small size - 85 MB.
 +
** [http://buildix.thoughtworks.com/ Buildix]Continuous Integration, Source Control, Wikis and Bug-Trackers
 +
** [http://www.young-technologies.com/Software/Subversion-Virtual-Machine/ Subversion Virtual Machine] Subversion server, fully configured WebSVN front end and Webmin.
 +
** [http://www.jumpbox.com/jumpbox-for-tracsubversion-software-project-management JumpBox for Trac/Subversion Software Project Management]Trac and Subversion
 +
 
 +
= Live CDs =
 +
 
 +
== Linux based ==
 +
* [http://sourceforge.net/projects/vixta/ Vixta]
 +
* [http://www.nycbug.org/index.php?NAV=Library;SUBM=10101 Postgre DB Live CD]
 +
** [http://blogs.ittoolbox.com/unix/bsd/archives/postgresql-livecd-14866 Description what is on CD]
 +
** [http://sourceforge.net/projects/netepi netepi] Has a shell script in the latest tarball release for NetEpi Collection which takes the Ubuntu LiveCD distribution and strips out unnecessary stuff, installs PostgreSQL and NetEpi and various screencast demo movies and the manuals etc, and then creates an ISO for burning.
 +
 
 +
 
 +
== Windows based ==
 +
* [http://nu2.nu/pebuilder/ Bart's Preinstalled Environment (BartPE) bootable live windows CD/DVD]
 +
 
 +
= Ant related =
 +
* [http://www.javalobby.org/articles/ant-preprocessor/ Using Ant as a Text Substitution Preprocessor]
 +
* [http://kcbaltz.blogspot.com/2005/04/someone-on-this-javalobby-post-asked.html Ant and copy filtering as a build configuration mechanism]
 +
* [http://blog.seba3y.com/2007/05/using-apache-ant-for-text-manipulation.html Using Apache Ant for Text Manipulation]
 +
 
 +
 
 +
= HTML, CSS, RSS =
 +
* [http://yura.thinkweb2.com/scripting/contextMenu/ Context menu functionality on your page]
 +
* [http://www.smashingmagazine.com/2007/08/25/20-free-and-fresh-icon-sets/ 20+ Free And Fresh Icon Sets]
 +
* [http://www.java2s.com/Code/JavaScript/GUI-Components/Calendarwithdifferenttheme.htm Calendar with different theme] Very good calendar component! JavaScrip based, date and time can be set with keyboard or mouse only.
 +
* [http://emmaalvarez.blogspot.com/2007/09/top-best-50-free-tools-for-your-website.html  Top best 50 free tools for your website]
 +
* [http://www.dezinerfolio.com/?p=775&cp=all  Creating Liquid CSS Tabs for Menus]Interesting post how to create menu with CSS.
 +
 
 +
 
 +
== How to add URL to My Yahoo RSS Reader ==
 +
<pre>
 +
http://add.my.yahoo.com/rss?url=http://www.someSite.com/rss/press_release_todays_newsfeed.xml
 +
</pre>
 +
 
 +
 
 +
= DB Related =
 +
* [http://schemaspy.sourceforge.net/ Schema Spy] Good tool which can create graphical representation of DB Schema
 +
** [http://www.joachim-uhl.de/projekte/schemaspygui/ Schema Spy GUI]
 +
** Install Debian package "gsfonts" in order to solve the issue with 'dot'.
 +
 
 +
* [http://jdbclogger.sourceforge.net/installation.html JDBC Logger ] show you the SQL statements
 +
 
 +
* [http://www.liquibase.org/ Database Refactoring With LiquiBase; DBMS-independent library for tracking, managing and applying database changes; Similar to DDLUtils]
 +
** [http://blog.liquibase.org/2007/06/problem-with-database-diffs.html The Problem With Database Diffs] Interesting post regarding automatic diff of DBs; I would say that the same problem applies for ERP system. You can't understand what is semantic of change only from Change Log. For example: Changes regarding Documents (Invoice, Orders, ... ) must be sent only when document status is changed (from Prepared to Completed for example), becaese lines are added after main record is created, that's why upon Document creation his children(Order Lines or Invoice Lines) are empty...
 +
 
 +
* [http://jopinblog.wordpress.com/2007/04/24/oracle-plsql-equivalents-for-ms-sql-server-t-sql-constructs/ Oracle (PL/SQL) Equivalents for MS SQL Server (T-SQL) Constructs] List of the top 10 things Developer should known about Oracle - PL/SQL coming from an MS SQL Server - T-SQL background.
 +
 
 +
* [http://www.oreilly.com/news/sqlnut_1200.html Executing Common SQL Coding Tasks Using Function Calls] Function implementations in Microsoft SQL Server, MySQL, Oracle, and PostgreSQL.
 +
 
 +
* [http://www.dba-oracle.com/oracle_news/2005_12_16_sql_syntax_differences.htm SQL Syntax differences between Oracle and MS-SQL]
 +
* [http://download.oracle.com/docs/cd/E10405_01/doc/appdev.120/e10379/ss_oracle_compared.htm Microsoft SQL Server and Oracle Compared]
 +
 
 +
* [http://images.omniti.net/omniti.com/talks/BBPostgres.pdf Moving a large, complicated and mission-critical data datawarehouse from Oracle to PostgreSQL]
 +
 
 +
* [http://quantum.sourceforge.net/update-site/ Quantum]Plug-in for Eclipse
 +
 
 +
* [https://sourceforge.net/projects/dbsql2xml/ DBsql2XML]Java tool (class) for transformation (export, convert) relational database into hierarchical XML.
 +
 
 +
* Useful scripts related to Tables/Indexes in Oracle.
 +
** [http://vsbabu.org/oracle/sect16.html]
 +
** [http://www.orafaq.com/scripts/sql/tabinfo.txt]
 +
 
 +
* [http://publib.boulder.ibm.com/infocenter/ledoc/v6r11/index.jsp?topic=/com.ibm.rcp.tools.doc.db2e/dbsap_b8.html Microsoft SQL Server 2 DB2 data type mappings]
 +
 
 +
* [http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html Using MAX data types in SQL Server]MAX allows up to 2 GB text or image to be stored.
 +
 
 +
 
 +
Query to look Sessions of users in Postgre:
 +
<pre>
 +
select pg_class.relname, pg_locks.transaction, pg_locks.mode,
 +
pg_locks.granted as "g",
 +
      pg_stat_activity.query_start,
 +
  age(now(),pg_stat_activity.query_start) as "age",
 +
pg_stat_activity.procpid,
 +
  pg_database.datname , pg_stat_activity.client_addr,
 +
  pg_locks.page, pg_locks.tuple, pg_locks.relation,
 +
rpad(pg_stat_activity.current_query, 200)
 +
  from pg_stat_activity,pg_database , pg_locks
 +
  left outer join pg_class on
 +
  (pg_locks.relation = pg_class.oid)
 +
  where pg_locks.pid=pg_stat_activity.procpid
 +
    and pg_locks.database = pg_database.oid
 +
    and pg_locks.mode      like '%ExclusiveLock'
 +
  order by query_start;
 +
 
 +
usie  pg_cancel_backend(pid) function to cancel
 +
</pre>
 +
 
 +
Following query lists all open sessions and the relevant PIDs.
 +
<pre>
 +
SELECT Activity.datname, Activity.procpid, Shadow.usename,
 +
Activity.current_query
 +
FROM pg_stat_activity Activity
 +
INNER JOIN pg_shadow Shadow
 +
ON (Activity.usesysid=Shadow.usesysid);
 +
</pre>
 +
 
 +
 
 +
* Table oriented frameworks
 +
 
 +
** [http://sourceforge.net/projects/butler/ Butler framework]Table-oriented java object model on top of JDBC that makes database programming easier. It also has a set of database aware swing components and a JSP tag library.
 +
** [http://www.javaworld.com/javaworld/jw-10-2004/jw-1018-butler.html The power of table-oriented programming]An introduction to Butler
 +
 
 +
 
 +
== DB Replication ==
 +
* [http://symmetricds.org/ SymmetricDS]
 +
 
 +
 
 +
== LDAP ==
 +
* [http://www.samse.fr/GPL/ldap_pg/HOWTO/ OpenLDAP-POSTGRESQL HOWTO]With real example
 +
 
 +
== DB Structure and Data comparison ==
 +
* [http://snippets.dzone.com/posts/show/949#related pg_diff - compare two PostgreSQL database schemas]Ruby
 +
* [http://pgdiff.sourceforge.net/ Pg Diff]
 +
* [http://www.adamspiers.org/computing/mysqldiff/ MySQL Diff]
 +
* [http://www.sqlmanager.net/en/products/postgresql/datacomparer EMS Data Comparer for PostgreSQL]Good price.
 +
 
 +
== Security, SQL Injection ==
 +
* [http://www.imperva.com/application_defense_center/white_papers/blind_sql_server_injection.html Blind SQL Injection]
 +
 
 +
 
 +
== Oracle to/from Postgre porting/conversion ==
 +
* [http://www.fop.unicamp.br/informatica/index.php?option=com_docman&task=doc_view&gid=94 Porting from Oracle to PostgreSQL] good document
 +
* [http://www.postgresql.org/docs/8.0/interactive/datatype.html Postgre 8.0 data types]
 +
* [http://omniti.com/talks/OracleToPostgres.pdf Oracle to Posgre conversion]
 +
* [http://www.download3k.com/Business-Finance/Database-Management/Download-Oracle-PostgreSQL-Import-Export-Convert-Software.html Oracle to PostgreSQL Import/Export/Convert Software]
 +
* [http://www.sqlmanager.net/products/postgresql/datapump EMS Data Pump for PostgreSQL]Very good price.
 +
 
 +
== ER Diagrams ==
 +
* [http://www.azzurri.jp/en/software/clay/index.jsp Clay] Eclipse based
 +
* [http://mogwai.sourceforge.net/erdesigner/erdesigner.html Mogwai ER-Designer]Supports import from torgue xml files.
 +
 
 +
 
 +
== Druid ==
 +
* [http://druid.sourceforge.net/ sf.net site]
 +
 
 +
 
 +
=== Changes which i made to Druid ===
 +
 
 +
 
 +
==== Show class name in modules dialog ====
 +
Menu "Config" -> "Modules..." now shows class name of loaded module. This allows developer to find responsible class and modify it if necessary.
 +
 
 +
[[Image:LoadedModules.JPG|300px|thumb|Loaded modules window]]
 +
 
 +
 
 +
<pre>
 +
package druid.dialogs.modules;
 +
 
 +
import java.awt.Color;
 +
 
 +
import javax.swing.JTextField;
 +
 
 +
import org.dlib.gui.FlexLayout;
 +
import org.dlib.gui.TLabel;
 +
import org.dlib.gui.TPanel;
 +
import org.dlib.gui.TTextArea;
 +
import org.dlib.gui.TTextField;
 +
 
 +
import druid.interfaces.BasicModule;
 +
 
 +
public class GeneralPanel extends TPanel
 +
{
 +
private JTextField txtId      = new TTextField();
 +
private JTextField txtVersion = new TTextField();
 +
private JTextField txtAuthor  = new TTextField();
 +
private TTextArea  txaDescr  = new TTextArea(6, 40);
 +
private JTextField txtClass   = new TTextField();  // @Trifon
 +
 
 +
public GeneralPanel()
 +
{
 +
super("General");
 +
 
 +
FlexLayout flexL = new FlexLayout(2,5,4,4);  // @Trifon
 +
flexL.setColProp(1, FlexLayout.EXPAND);
 +
setLayout(flexL);
 +
 
 +
//--- setup textfields
 +
 
 +
txtId.setEditable(false);
 +
txtVersion.setEditable(false);
 +
txtAuthor.setEditable(false);
 +
txaDescr.setEditable(false);
 +
txtClass.setEditable(false);  // @Trifon
 +
 
 +
txtId.setBackground(Color.white);
 +
txtVersion.setBackground(Color.white);
 +
txtAuthor.setBackground(Color.white);
 +
txtClass.setBackground(Color.white);  // @Trifon
 +
 
 +
//--- setup panel
 +
 
 +
add("0,0",    new TLabel("Id"));
 +
add("0,1",    new TLabel("Version"));
 +
add("0,2",    new TLabel("Author"));
 +
add("0,3,l,t", new TLabel("Descr"));
 +
add("0,4",    new TLabel("Class"));  // @Trifon
 +
 
 +
add("1,0,x", txtId);
 +
add("1,1,x", txtVersion);
 +
add("1,2,x", txtAuthor);
 +
add("1,3,x", txaDescr);
 +
add("1,4,x", txtClass);  // @Trifon
 +
}
 +
 
 +
public void setCurrentModule(BasicModule mod)
 +
{
 +
txtId.setText(mod.getId());
 +
txtVersion.setText(mod.getVersion());
 +
txtAuthor.setText(mod.getAuthor());
 +
txaDescr.setText(mod.getDescription());
 +
txtClass.setText(mod.getClass().getCanonicalName());  // @Trifon
 +
}
 +
}
 +
</pre>
 +
 
 +
 
 +
==== TODO SQL constant remapping ====
 +
class: factory.sql.AbstractSqlGenModule
 +
 
 +
<pre>
 +
protected String genFieldAttrib(FieldNode node, AttribSet asAttrib, Object obj)
 +
{
 +
StringBuffer sb = new StringBuffer();
 +
 
 +
String faSqlName = asAttrib.getString("sqlName");
 +
 
 +
if (obj instanceof Boolean)
 +
{
 +
boolean b = ((Boolean)obj).booleanValue();
 +
 
 +
if (b)
 +
sb.append(faSqlName);
 +
}
 +
 
 +
else if (obj instanceof String || obj instanceof Integer)
 +
{
 +
String value = obj.toString().trim();
 +
 
 +
if (!value.equals("")) {
 +
// TODO - Trifon
 +
// Here we can make SQL constant remapping!
 +
// SYSDATE -> NOW()
 +
BasicDatabaseSettings sett = new BasicDatabaseSettings(node.getDatabase().modsConfig, this);
 +
 
 +
AttribList alSqlMapping = sett.getSqlMapping();
 +
if (alSqlMapping.size() > 0) {
 +
sb.append(faSqlName + " " + remapSqlType(value, alSqlMapping));
 +
} else {
 +
sb.append(faSqlName + " " + value);
 +
}
 +
}
 +
 +
}
 +
 
 +
else
 +
throw new DruidException(DruidException.INC_STR, "Unknown type of object", obj);
 +
 
 +
return sb.toString();
 +
}
 +
</pre>
 +
 
 +
=== Druid Hints ===
 +
 
 +
==== Hint.1 Remapping of DB Types ====
 +
Druid fully supports remapping of database types.
 +
This feature allows developer to build his initial DB model against specific DB(Oracle for example) and generate SQL scripts for any DB (Postgre for example). Or developer can define abstract DB types and create appropriate mapping for each DB!
 +
 
 +
Field "Sql Type" can contain any [http://en.wikipedia.org/wiki/Regular_expression Regular expression].
 +
 
 +
Java Pattern class : [http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html java.util.regex.Pattern]
 +
 
 +
 
 +
Example remapping from Oracle to Postgre.
 +
 
 +
Sql Type:
 +
<pre>
 +
NUMBER\(10,0\)
 +
</pre>
 +
 
 +
Mappend type:
 +
<pre>
 +
NUMERIC(10)
 +
</pre>
 +
 
 +
= BI - Business Intelligence =
 +
 
 +
* [http://www.freeanalysis.org/ FreeAnalysis] Quite strange for Open Source project, but company provide sources only after sending email to them. Will check how open they are!
 +
** [http://freeanalysis.wordpress.com/2007/11/26/freeanalysis-embeded-into-liferay/ FreeAnalysis embeded into Liferay]
 +
** [http://freeanalysis.wordpress.com/2008/01/17/next-level-freedashboard-embeded-into-liferay/ FreeDashboard Embeded into LifeRay]
 +
 
 +
= SEO - Search Engine Optimization =
 +
* [http://www.kaldata.com/forums/index.php?showtopic=58362 Good Article in Bulgarian]
 +
 
 +
 
 +
= Open Source Report Engines/Frameworks =
 +
 
 +
== JDOReports ==
 +
* [http://jooreports.sourceforge.net/ JOOReports]
 +
 
 +
 
 +
=== JDOReports Developer Tips ===
 +
 
 +
==== Hint.1 How to open template document which is password protected ====
 +
* [https://sourceforge.net/forum/message.php?msg_id=4683858 sf.net post]
 +
 
 +
Templates to be protected against unauthorised changes to at least some extent.
 +
 
 +
Opening a password protected template is not supported. If what you want is to protect the output document (rather than the template) then you can post-process the document through JODConverter and OpenOffice.org and specify a password at that stage (optionally also converting the document to PDF or another format).
 +
 
 +
Could use JODConverter to unprotect the template before processing it through JOOReports. Convert the document from ODT to ODT (!) passing the password as an import option. Need OpenOffice.org installed and running on the server for JODConverter to work though.
 +
 
 +
<pre>
 +
DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
 +
 
 +
DocumentFormat inFormat = new DocumentFormat("OpenDocument Text", DocumentFamily.TEXT, "application/vnd.oasis.opendocument.text", "odt");
 +
inFormat.setImportOption("Password", "testpwd");
 +
 
 +
DocumentFormat outFormat = new DocumentFormat("OpenDocument Text", DocumentFamily.TEXT, "application/vnd.oasis.opendocument.text", "odt");
 +
outFormat.setExportFilter(DocumentFamily.TEXT, "writer8");
 +
 
 +
File inFile = new File(getDocumentsPath() + "\\" + templateName);
 +
File outFile = new File(getDocumentsPath() + "\\temp.odt");
 +
converter.convert(inFile, inFormat, outFile, outFormat);
 +
</pre>
 +
 
 +
or
 +
 
 +
Alternatively could use the registry to get the default ODT format:
 +
 
 +
<pre>
 +
DocumentFormatRegistry registry = new DefaultDocumentFormatRegistry();
 +
DocumentConverter converter = new OpenOfficeDocumentConverter(connection, registry);
 +
 
 +
DocumentFormat odt = registry.getFormatByFileExtension("odt");
 +
       
 +
DocumentFormat odtWithPassword = new DocumentFormat(odt.getName(), odt.getFamily(), odt.getMimeType(), odt.getFileExtension());
 +
odtWithPassword.setImportOption("Password", "secret");
 +
 
 +
converter.convert(inputFile, odtWithPassword, outputFile, odt);
 +
</pre>
 +
 
 +
== Open Reports ==
 +
* [http://oreports.com/ Open Reports] I like it very much. It has report scheduling, dashboard in professional edition with AJAX interface. Works with multiple report engines like: JasperReports, Eclipse BIRT, JXLS.
 +
* [http://www.linux.com/feature/56650 www.linux.com article]
 +
 
 +
 
 +
== Jasper Reports ==
 +
* [http://www.jasperforge.org/sf/wiki/do/viewPage/projects.ireport/wiki/IReportAndGroovy iReport and Groovy]
 +
* [http://dev2dev.bea.com.cn/bbs/servlet/D2DServlet/download/124-20790-120385-1202/The+JasperReports+Ultimate+Guide.pdf The JasperReports Ultimate Guide]
 +
* [https://sourceforge.net/forum/message.php?msg_id=4651164 Drill-down Jasper report for Adempiere]
 +
 
 +
 
 +
=== Jasper Reports Tips ===
 +
 
 +
==== Hint.1 How to convert field from Boolean to String ====
 +
Field RptSgnEngLtr is defined as java.lang.Boolean.
 +
 
 +
<pre>
 +
( $F{RptSgnEngLtr}.equals(new Boolean (true)) ? "YES" : "NO" )
 +
</pre>
 +
 
 +
or shorter
 +
 
 +
<pre>
 +
$F{RptSgnEngLtr}.booleanValue() ? "YES" : "NO"
 +
</pre>
 +
 
 +
 
 +
==== Hint.2 How to sum two double fields ====
 +
<pre>
 +
new Double($F{f1}.doubleValue() + $F{f2}.doubleValue())
 +
</pre>
 +
 
 +
 
 +
==== Hint.3 How to compare numbers ====
 +
<pre>
 +
new Boolean($F{f}.intValue() == 1)
 +
</pre>
 +
 
 +
 
 +
==== Hint.4 How to compare strings ====
 +
<pre>
 +
new Boolean($F{f} != null && $F{f}.equals("test"))
 +
</pre>
 +
 
 +
 
 +
==== Hint.5 How to Highlight odd or even rows ====
 +
* [http://www.brianburridge.com/2006/06/19/highlighting-odd-even-rows-jasperreports/ Highlighting Odd and Even Rows in JasperReports]
 +
 
 +
 
 +
==== Hint.6 How to Build Dynamic JasperReports ====
 +
* [http://www-128.ibm.com/developerworks/websphere/library/techarticles/0505_olivieri/0505_olivieri.html Generating XML templates for JasperReports using Rational Application Developer]
 +
 
 +
= JBoss =
 +
* [http://www.fusioncube.net/?p=41 Hosting Multiple Domains With JBoss]
 +
 
 +
 
 +
= Open Source Integration Projects =
 +
* [http://www.xaware.com/ XAware]
 +
* [http://www.apatar.com Apatar]
 +
 
 +
 
 +
== CSV/Ini/Excel Readers/Parsers/Writers ==
 +
 
 +
 
 +
=== Super CSV ===
 +
* [https://sourceforge.net/projects/supercsv/ sf.net project page]
 +
 
 +
* [https://sourceforge.net/forum/message.php?msg_id=4731844 Generic Cell Processors that convert Strings to enums]
 +
 
 +
 
 +
== Ini4J ==
 +
* [http://ini4j.sourceforge.net/ Ini4J]
 +
 
 +
= OSGi =
 +
* [http://www.eclipsezone.com/eclipse/forums/t99588.rhtml Using Log4J in Eclipse Equinox/OSGi]
 +
 
 +
 
 +
= Security =
 +
* [http://www.acegisecurity.org/ Acegi Security]
 +
* [http://www.ja-sig.org/products/cas/index.html JA-SIG Central Authentication Service]
 +
 
 +
 
 +
== OpenID ==
 +
* [http://openid.net/ OpenID site]
 +
* [http://blog.spaceprogram.com/search/label/Single%20Sign%20On  How to Add OpenID Support to your Java Application]
 +
* [http://developers.sun.com/learning/javaoneonline/2007/pdf/TS-6536.pdf? Enabling Identity 2.0 in Java Technology]
 +
* [http://www.theserverside.com/tt/articles/article.tss?l=OpenID Using OpenID]
 +
* [http://www.javameblog.com/2007/08/openid-bootcamp-tutorial.html OpenID Bootcamp Tutorial]very good presentation.
 +
 
 +
 
 +
=== Projects ===
 +
* [http://code.google.com/p/openid4j/ openID4j]
 +
* [http://code.google.com/p/joid/ JOID]lets you create both OpenID 2.0 relying parties and identity providers.
 +
* [http://code.google.com/p/openid4java/ OpenID4Java]
 +
 
 +
* [http://www.siege.org/projects/phpMyID/ phpMyID]
 +
 
 +
= kTable =
 +
 
 +
== Move Table Header ==
 +
* [https://sourceforge.net/forum/message.php?msg_id=4581708 sf.net post]
 +
 
 +
Create following Header Listener
 +
<pre>
 +
public class HeaderListener implements Listener, ControlListener {
 +
 +
KTable table_ = null;
 +
 +
Point initPoint = null;
 +
 +
Tracker tracker = null;
 +
 +
public HeaderListener(KTable table) {
 +
table_ = table;
 +
}
 +
 +
public void mouseDoubleClick(MouseEvent e) { 
 +
}
 +
 +
public void mouseUp(int x , int y ) {
 +
Point p = table_.getCellForCoordinates(x, y);
 +
 +
System.out.println("Up " + p);
 +
 +
if (
 +
(p.y < table_.getModel().getFixedHeaderRowCount()) && 
 +
(p.x >= table_.getModel().getFixedHeaderColumnCount()) &&
 +
(p.x != initPoint.x) &&
 +
(p.y == initPoint.y)
 +
){
 +
 +
//if (p.y == initPoint.y) {
 +
System.out.println("Move " + initPoint + " to " + p);
 +
((SpanModel)table_.getModel()).switchColumn(p.x, initPoint.x);
 +
}
 +
initPoint = null;
 +
//tracker.close();
 +
}
 +
 +
public void mouseDown(Event e) {
 +
 +
Point p = table_.getCellForCoordinates(e.x, e.y);
 +
if (
 +
(p.y < table_.getModel().getFixedHeaderRowCount()) && 
 +
(p.x >= table_.getModel().getFixedHeaderColumnCount())
 +
)
 +
initPoint = p;
 +
 +
System.out.println("Down " + p);
 +
 
 +
}
 +
 +
public void mouseMove(Event event) { 
 +
int JITTER = 8;
 +
Display display = event.display;
 +
Shell shell = display.getActiveShell();
 +
 +
Rectangle tableLocation = display.map(table_, null, shell.getClientArea ());
 +
System.out.println("table location " + tableLocation); 
 +
 +
Point p = table_.getCellForCoordinates(event.x, event.y); 
 +
Rectangle rect = table_.getCellRect(p.x, p.y);
 +
 +
 +
int deltaX = initPoint.x - event.x, deltaY = initPoint.y - event.y;
 +
if (Math.abs (deltaX) < JITTER && Math.abs (deltaY) < JITTER) {
 +
return;
 +
}
 +
 +
tracker = new Tracker (table_, SWT.LEFT | SWT.RIGHT);
 +
 +
tracker.setRectangles (new Rectangle [] {rect});
 +
tracker.open ();
 +
//FALL THROUGH
 +
 +
Rectangle finalPosition = tracker.getRectangles()[0]; 
 +
System.out.println(finalPosition);
 +
 +
int posX = finalPosition.x + finalPosition.width / 2 ;//- tableLocation.x;
 +
int posY = finalPosition.y + finalPosition.height / 2 ;//- tableLocation.y;
 +
mouseUp (posX,posY);
 +
 +
}
 +
 +
public void handleEvent(Event event) {
 +
switch (event.type) {
 +
case SWT.MouseDown:
 +
mouseDown((event));
 +
break;
 +
case SWT.MouseMove:
 +
if (initPoint == null) return;
 +
mouseMove(event);
 +
 +
case SWT.MouseUp:
 +
break;
 +
 +
}
 +
 +
public void controlMoved(ControlEvent e) {
 +
}
 +
 +
public void controlResized(ControlEvent e) {
 +
// TODO Auto-generated method stub 
 +
}
 +
</pre>
 +
 
 +
= Security Frameworks and Articles =
 +
* [http://www.ibm.com/developerworks/java/library/j-acegi1/index.html Securing Java applications with Acegi, Part 1: Architectural overview and security]
 +
* [http://www.ibm.com/developerworks/java/library/j-acegi2/ Securing Java applications with Acegi, Part 2: Working with an LDAP directory server]
 +
* [http://www.ibm.com/developerworks/java/library/j-acegi3/ Securing Java applications with Acegi, Part 3: Access control for Java objects]
 +
 
 +
= VoIP, IPTV =
 +
* [http://www.videolan.org/vlc/ VideoLan]
 +
* Ip Tvs
 +
** [http://iptv.bg/ http://www.iptv.bg]
 +
 
 +
 
 +
= Fun =
 +
* [http://robocode.sourceforge.net/ Robocode] I love this kind of games where user can develop his own creature with AI.
 +
* [http://sourceforge.net/projects/farcolony/ Far Colony] Game of exploration and space colonization being held with 23th century.
 +
* [http://www.addictinggames.com Online games]
 +
* [http://www.gsudokr.com/ Sudoko]built with google gwt and google gears
 +
* [http://bjorn.jottit.com/Things_to_do_when_you%27re_a_bored_developer. Things to do when you're a bored developer]
 +
 
 +
 
 +
== [http://www.travian.bg/?uc=bg1_27916 Travian] ==
 +
 
 +
* [http://travian.ws http://travian.ws]Travian World Analyzer
 +
* [http://userscripts.org/users/21460;scripts Travian user scripts]
 +
** [http://userscripts.org/scripts/show/17866 Travian: Extended map with window v2.2.0]
 +
 
 +
* [http://www.travianmap.nl/index.php?ln=en http://www.travianmap.nl]
 +
* [http://travmap.shishnet.org/ http://travmap.shishnet.org/]
 +
* [http://travilog.org.ua/bg/ Battle report archive for online web based strategy Travian]
 +
 
 +
== Fork developers work in their free time! Excuse Me??? ==
 +
What Compiere defenders think.
 +
 
 +
Can you belive? I work for free? Please do not tell it to my wife... This is top secret.
 +
 
 +
 
 +
* [https://sourceforge.net/forum/message.php?msg_id=4468154 sf.net post] It looks that this post was deleted from Compiere forums. Compiere Inc. do not like what friends of Compiere think??? Just to prove that such post exist i posted whole post [https://sourceforge.net/forum/message.php?msg_id=4496149 here]
 +
 
 +
''Having been in the ERP game for a very long time, I just find the bazaar a bit too risky for real life scenario and most of the clever developers involved are doing out of free time. I honestly dont even have free time to write this email, but I guess some people have more free time than others. So what people do in their free times is entirely up to them? The product is becoming massive yes, and to expect the couple of clever developers to maintain it within their "free" time would be EXTREMELY risky for any  enterprise to put reliance on. Yes it may be more clever and even more transparrent and yes many more extremely clever things will be released out of it. Question  though is who is going to maintain it in their free time over the next couple of years and who actually needs to get paid to support it.''
 +
 
 +
= Site Meter =
 +
<!-- Site Meter -->
 +
* [http://sm9.sitemeter.com/stats.asp?site=sm9trifon http://sm9.sitemeter.com/meter.asp?site=sm9trifon&i=t.gif] Site Meter
 +
<!-- Copyright (c)2006 Site Meter -->
 +
 
 +
* [http://www.alexa.com/data/details/traffic_details/adempiere.com www.alexa.com]www.adempiere.com

Revision as of 23:55, 24 January 2008

Name This user real name is : Trifon Nikolaev Trifonov
Sourceforge logo.png This user has a Sourceforge account.
Wikipedia logo.png This user has a Wikipedia account.


Contents

About Me

I started my own company last year providing Adempiere and Compiere consultancy and development. I like developing business systems. This makes me headache from time to time, but also makes me very happy when i see system working.

  • I'm SUN Certified Programmer 1.4.
  • Graduated High School of Economics and Computer Science
  • Bachelor degree in Mathematics

As a member of ADempiere Council i like to review patches and SVN commits in order to be sure that code remains stable and system functional.

My Blogs

Trifon's Paid Services

Adempiere customized with client's own brand

  • Client must send two images.
  • Price 200 EURO.
  • Services created for small and mid-sized implementation companies which do not have own java developers and find modifying of source code impossible task.

Adempiere Virtual Appliance

  • Fully setup and ready to use Adempiere!
  • Standard users: Garden Admin and Garden Users can send emails!
  • VMWare with Linux - Fedora Core - 5/7
  • Adempiere
  • Sun JDK
  • Database - Oracle or Postgres
  • Jakarta James email server
  • Price 45 EURO

On demand Adempiere build

  • Build of Adempiere upon user request.
  • Price - 125 EUR
  • 17 EUR will be donated to Adempiere.

Users can donate smaller amount and when 125 EUR is reached a build will be made.

  • Build can include additional functionality like Fixed Asset or other not included in trunk.

Adempiere DVD by Trifon

  • DVD with complete Adempiere sources, Eclipse IDE and Sun JDK. Developer need to copy one directory to his local hard drive and can start customizing Adempiere.
  • Available version for Linux and Windows.
  • Price is: 30 EURO + shipping cost to your place or only 30 EUR and download from FTP Server.
  • Jakarta James email server.
  • Please contact me if you would like to have it.

  • Need urgent advice for your Adempiere implementation or need to talk with experienced Adempiere developer - call now to get friendly help. Ask for Trifon.
  • Price is 0.80 EUR per minute

Use Skype Prime service to call now. More info about Skype Prime


  • Ether Another pay per call service

  • 1500 EUR per week + ticket + hotel
  • Example training plan
1) General overview of Adempiere ERP-CRM system.
2) Introduction to user interface.
3) How to setup new Company in Adempiere.
4) How to setup new Organization in Adempiere.
5) How to create and import Chart of Accounts.
6) How to create new Product and set Product Price and Price List.
7) How to import Products from external sources/systems.
8) How to create Discount Schema and Price List and apply specific discount/overcharge for specific Group/Product, e.t.c.
9) How to create create new Business Partner(Client, Vendor and Employee).
10) How to import Business Partners from external sources/systems.
11) How to create Purchase Order.
12) How to Create Material Receipt.
13) How to create Invoice (Vendor)
14) how to create Sales Order.
15) How to create Shipment (Customer)
16) How to create Shipment Confirmation.
17) How to create Invoice (Customer).
18) How to create Payment.
19) How to match Purchase Order - Material Receipt - Invoice (Vendor).
20) How to match Sales Order - Shipment - Invoice (Customer).
21) How to create Cash Payment and Cash Receipt.
22) How to create Bank Account and Bank transaction.
23) How to modify Print Format of documents.
24) How to setup emails of Adempiere users and send emails with attached document(Purchase Order, Invoice, e.t.c) to clients.
25) How to create Users and assign User permissions.
26) How to setup Window, Tab and Field permissions for specific Roles and Users.
27) How to share data between Organizations and users.
28) How to setup records to be readable only by their creators.

  • If you need training or support for EDI in Adempiere, please do not hesitate to contact me.
  • Prices start from 30 EUR per hour.

  • Leading Open Source Enterprise Portal
  • JSR-168 compliant
  • Business Friendly Open Source License: MIT License


  • Suitable for:
    • Small applications which need to be developed from scratch
    • Development of applications which must be part of a Web Portal.
    • Applications based on OpenXava can run on any DB which is supported by Hibernate.
    • Licensed under LGPL. You can develop commercial application using OpenXava.
    • Applications based on OpenXava can run on any application server (Tomcat, JBoss, WebSphere, etc).
    • Applications based on Openxava have easy integration of reports made with JasperReports.

Trifon's contributions to OpenXava

  • Please contact me for quotation.

  • Development of java applications.
  • Please contact me for quotation.

Trifon's projects based on Compiere/Adempiere

Project 0 (area: Supply Chain Management)


Migrated from Microsoft Access based application to Compiere ERP-CRM
Company is the biggest distributor of newspapers in Bulgaria.
Huge migration effort.
Imported definitions of:
Vendors, Customers, Sales Agents, Products, Price Lists, Accounts, Purchase Orders, Sales Orders, Billing addresses, Warehouses.
Imported ~  20 000 Product definitions.
Imported ~ 100 000 Purchase Orders.
Imported ~ 100 000 Sales Orders.
Developed new module in Compiere ERP-CRM in order to fit company needs in Product Distribution area.
Developed mobile application and data synchronization module for real time tracking of products.
Implemented:
Product Attributes, Purchase Orders, Material Receipts, Invoices (Vendor), Sales Orders, Shipments, Invoices (Customer), Warehouse management, Price Lists, Accounting, Discount Schema.


Project 1 (area: ERP)

Migrated from 20 years old application to Compiere ERP-CRM.
Huge effort in import of data from legacy system.
Imported definitions of:
Vednors, Customers, Sales Agents, Products, Price Lists, Accounts, Purchase Orders, Sales Orders, Shippers, Billing addresses, Discount Schema.
Developed import functionality in Compiere ERP-CRM.
Developed Slading Scale Commissions in Compiere ERP-CRM.
Developed Bill of Ladding in Compiere ERP-CRM.

Implemented:
Purchase Orders, Material Receipts, Invoices (Vendor), Sales Orders, Shipments, Invoices (Customer), Warehouse management, Price Lists, Accounting.


Project 2 (area: ERP)

Migrated from Microsoft Solomon to Compiere ERP-CRM.
Fast migration path.
Imported definitions of:
Vendors, Customers, Products, Accounts.
Developed better user interface to fit needs of users used to work with Microsoft Solomon.
Developed export from Compiere ERP-CRM to People Soft system.
Improved traceability of Orders to fit needs of purchasing agency.

Implemented:
Purchase Orders, Material Receipts, Invoices (Vendor), Sales Orders, Shipments, Invoices (Customer), Warehouse management, Price Lists, Accounting.


Project 3 (area: Supply Chain Management)

Extension for Compiere MFG-SCM project.
Developed java application for java enabled mobile phones.
Developed web application.
Developed connection module that enables data scanned with bluetooth enabled barcode scanner to be transferred to mobile phone and after that to web application.
Application allows factory to track in real time product/part availability.
Used Java, JSP, Servlet, AJAX and J2ME technologies.

Trifon's Recent thoughts

Open Source’s Missed Opportunity

Trifonnt 03:07, 18 January 2008 (EST)


Requirements of very small companies

  • sf.netInteresting post from OpenBravo forums.

How customers should approach Open source vendor

Very good post from Matt Asay


Yes, I get quite a few requests to have Alfresco integrate with JBoss and Liferay, and I've done business with both. But I didn't need a committee to tell me that. Customers did. Customers have yet to request integration with Compiere, for example, so we haven't done it. Someday we probably will. But when customers vote with dollars.


Interesting requirement: Map Your Contacts By Region


Select a group of accounts based on geography...let's say all accounts in Texas. Then be able to map those accounts on an interactive map that will show the locations of each of those accounts as push pins. When you roll over each push pin, it pops up the name of the account and any specified modules like opportunities, calendar etc. Another cool feature would be select any two accounts to calculate the distance/drive time and even download directions.

Trifonnt 02:07, 11 December 2007 (EST)


Number of Adempiere developers

11 December 2007.

Adempiere has 56 registered developers in sf.net.

Trifonnt 02:07, 11 December 2007 (EST)

Risk to be Open Source developer

Here i will try to identify some of the negative sides of being Open Source developer. This are real examples which happen to me and make me sad.

  • Help a user and after few days/weeks/months receive a spam message from the company where user work or from him personally.
    • NEVER help a user in private emails. Private emails are for paid support only! RULE NUMBER ONE.
  • Many times colleagues or other people tell me that i must increase my prices. It sounds quite good as advice, but the bad side is when they start working with you they are not so happy to pay you recommended by them price. ALWAYS RESPECT YOUR PRICE! RULE NUMBER TWO. It is your price which is good for you and under your conditions.

Trifonnt 14:43, 1 November 2007 (EDT)

Idea for additional meta data: AD_Table NamedQuery

JPA has very nice feature 'Named Query'. It would make Application Dictionary more reach if Adempiere has such feature. This idea is very near to Finders, but it allows more wide range of queries. Trifonnt 19:17, 26 October 2007 (EDT)


Idea for additional java interface: DocumentConversion

Adempiere ERP-CRM has processes which generate new document from existing document. For example Generate Invoice from Sales Order. This are quite useful processes, but currently they are not designed with the idea for extendability's. For example if user define new fields in Sales Order and would like to see values of this fields transfered to Invoice and Shipment later then he must modify source code of GenerateInvoice and GenerateShipment processes. This is not easy and i think that design can be improved. Possible improvements:

  • Define new java interface and invoke classes which implement this interface. This require changes in existing GenerateXxx classes.
  • Define new structure in Application Dictionary which will describe which fields must be transfered during Document Generation process.

Trifonnt 17:59, 26 October 2007 (EDT)


Data Services

Rob Cardwell has very interesting article: Data Services: A Fundamental Building Block of SOA.

In middle of this article i found that Adempiere has this beautiful functionality.

This approach requires tools that can capture existing data structures from reverse-engineered relational database schema's, and can map these existing structures into more business-oriented data views.

Adempiere AD(Application dictionary) on which all tables and windows are based provides meta data for all data structures in the system and even for all graphical components! But with Adempiere user do not need to reverse-engineer database system, all data structures have business oriented view by design.

Trifonnt 22:51, 28 September 2007 (EDT)


Why fights in Open Source projects are bad?

Link to Adempiere post: here

What an ERP system MUST NOT allow user to do?

Recently i read a urgent post in OpenBravo forum.

i have deleted "big bazzar and System", the default clients and i can't enter to OpenBravo now what is the solution?

Interesting? This sounds like:

i have deleted "Local Disk C and D" and i can't enter my windows system what is the solution?

One of the most valuable ideas in Compiere is IsActive column and restriction to delete records in most of the tables. It is good if user can delete some Client, but System records must never be deletable! This makes another question to me. Is ERP for every user? My answer at this moment is NO. User who implement ERP must be very careful, conscious and most importantly must always make backup of data.

Trifonnt 17:01, 4 September 2007 (EDT)


OpenBravo Green?

Recently OpenBravo Green came into my mind(Jordi Mash told me about OpenBravo Green at Adempiere conference in Belrin) and i decided to review it and to check status.

First of all they have good document with intentions and requirements. Good number of frameworks and technologies are listed at this page: Design principles for Openbravo Green

They have a prototype and online demo, but i failed to login into demo page. OpenBravo Green demo

Source code of prototye was more interesting for me and it was the reason that made me write this post.

  • I expected to see more commnents and more TODOs. It is prototype and important is to see what developer intend to do than what has been done. Visibility of ideas and intentions is more important than actual work finished. This is not a minus it is just a note and wish from my side.
  • Source code dissapointed me, because:
    • I saw one regular web based application. No trace from the idea of Model Driven Architecture or Application dictionary. Probably model classes were generated by some tool, but no evidence or comment in the code or in the wiki pages.
    • Only one author, no participataion from community.
    • Author is Adrian Romero, who is very good POS developer(Tina POS), but i doubt about his experience in ERP systems and Application Driven systems. It looks that he is the only active visible OpenBravo developer.


Adempiere: Which is first Data or Code?

Recently i modified very deeply core of Adempiere in order to simplify development and to speed it up. I wasn't sure that such modification is possible and i was very happy when it happened and when at the end it even worked. After some tests i decided to revert to old version of persistent classes (X_xxx) and i deleted newly generated classes and started well known old GenerateModel, but... It failed because GenerateModel needs persistent classes in order to connect to Database. But developer can't generate persistent classes because GenerateModel can't connect to DB. So we got cycle... And here comes my question: Which is first Data or Code? I think that design of GenerateModel can be improved:


Trifonnt 12:55, 19 August 2007 (EDT)

Does Community Open Source project need roadmap?

  • What does Roadmap means for a project?
  • Goolge define:Roadmap says few things, but i like mostly one of them:
A program for future development indicating what will be developed and when.

My opinion is that it must be more like:

A program for future development indicating what will be developed, by who will be developed and when.
  • Three very important conditions in order to have Roadmap:
    • Functionality

This is easy to be done. All we need functionality and all we with pleasure advice what to be done. So i think that here ANY project can produce good number of items.

    • Who will develop it?

UPS, here the problems come. In order to develop something WE need knowledge, so from the big list of ALL only developers can participate in development. All this means that in Roadmap, Open Source project must identify developers or companies that will create new functionality. Ok, let's say that i would like to build this new functionality and i write my name against the feature.

    • When functionality will be developed?

Who knows? Who can answer? Who is responsible? It looks that WHEN brings more question than it answers. In Open Source project if no one commit his time to develop given functionality no one can answer the questions. Moreover if someone commit his free time does anyone has rights to push him for specific date? I do not think so... It is developers free will to participate and create functionality. And as you guess in most of the time it is hard to find free time for building big functionality.

My personal opinion is that spending time to create Roadmap without committed developers/companies against specific functionality is just good wast of time. Even worst it is confusing for the end user who read Roadmap and wait for new version and new functionality.

My big excuse to the users who will be frustrated from ssch Roadmaps. Trifonnt 19:31, 8 August 2007 (EDT)

To be Adempiere Developer or Adempiere Businessman(Seller)

I work with Adempiere/Compiere since more than 3 years. I must say that i like the product and area very much. I like to develop extensions for Adempiere and i do it everyday for 10-12 hours a day and sometimes more. I know it is not healthy, but... But last weeks i started to feel tired from all the rules for Developers and all fights in forums and in email lists. Also i realized that Business people around Adempiere do not have such limitations as Developers. For example:

  • On www.adempierebusiness.com there are 30 registered Implementation Partners. Good number.
    • What does this Implementation Partners give to Adempiere project?

Some of them nothing. Well business people say that if we limit and ask for money then this will stop add option of Adempiere. But may i ask how developers can survive?

    • What they get?

FREE Advertisement. Perfect... I think that Adempiere is the only project that allows such thing. Most of other Open Source projects take money for advertisement and put money back into the project.

  • I have read that some of Adempiere Implementation Partners do not work for less than 50 000 USD. Amount which i as developer do not had chance to see till now. Who knows someday Clients may find that contracting developer is much faster and cheaper...
  • User expect developers to provide FREE help in Adempiere forums, which gives additional workload to developers.
  • Developers are expected to be open and expose all their information to community.

So:

  • I found that i had made mistake.

It looks that to be Businessman and make money around Adempiere is much easy and painless than to be Adempiere developer. :(

  • I think to reconsider my role in Adempiere project. Role of Implementation Partner looks much safer and giving more incomes.
  • I should start making advertisements from now... So here it is: I can provide Adempiere on Site Implementation for 1500 EURO / week + expenses(hotel + ticket) in case i need to move to other location.

Adempiere trackers

Submitted by Trifon and Assigned to Trifon

Assigned to Trifon

Adempiere contributions

Functionality Contributions

EDI @ Adempiere - Sponsored Development: EDI Import/Export

Replication @ Adempiere - Sponsored Development: Replication

  • HermesJMSA console that helps you interact with JMS providers making it easy to browse or seach queues and topics, copy messages around and delete them.


JMS @ Salesforce.com:


Swing POS @ Adempiere - Sponsored Development: Swing POS

Simplify and Speedup Adempiere development

SF.NET forum post here

Feature Requests:

This enhancement allows Adempiere developers to:

  • Speedup thier day to day work and to have more Object friendly code.
  • Work with Java Interfaces instead of Java Classes.

For example:

    • Adempiere - Old code
Trx trx = Trx.get(Trx.createTrxName("Test"), true);
trx.start();

MAlert alertOldWay = new MAlert(Env.getCtx(), 100, trx.getTrxName());
log.info(alertOldWay.toString());
		
X_AD_AlertProcessor alertProcessorOldWay = new X_AD_AlertProcessor(Env.getCtx(), alertOldWay.getAD_AlertProcessor_ID(), trx.getTrxName());
log.info("alertProcessorOldWay.getAD_AlertProcessor_ID = " + alertProcessorOldWay.getAD_AlertProcessor_ID());

alertOldWay.setDescription("Trifon test");
//--- Save; 
resultSave = alertOldWay.save();
log.info("resultSave = " + resultSave);
		
System.out.println("New value of Description = " + alertOldWay.getDescription());

trx.commit();
trx.close();
    • Adempiere - New code
Trx trx = Trx.get(Trx.createTrxName("Test"), true);
trx.start();

I_AD_Alert alert = new MAlert(Env.getCtx(), 100, trx.getTrxName());
log.info(alert.toString());

I_AD_AlertProcessor alertProcessor = alert.getI_AD_AlertProcessor();
log.info("I_AD_AlertProcessor.getAD_AlertProcessor_ID = " + alertProcessor.getAD_AlertProcessor_ID());

alert.setDescription("Trifon Description modified!");
//--- Save; PO.save(PO) must be static method!!! Two way of usage: PO.save(Object) or PO.save(PO)
//resultSave = PO.save((PO)alert); 
resultSave = PO.save(alert);  // Overloaded save method; For simple usage!
log.info("resultSave = " + resultSave);
				
System.out.println("New value of Description = " + alert.getDescription());

trx.commit();
trx.close();

This modificationas make Adempiere code closer to Hibernate

    • Hibernate code. Example code from here.
Session session = HibernateUtil.getSessionFactory().getCurrentSession();

session.beginTransaction();

Event theEvent = new Event();
theEvent.setTitle(title);
theEvent.setDate(theDate);

session.save(theEvent);

session.getTransaction().commit();

Proposed by Hengsin modification:

Add second interface I_Persistent with one method save()

public interface I_Persistent {
	public boolean save();
}


  • Using the coding pattern below instead of the old new MAlert(Env.getCtx(), 100, trx.getTrxName()) approach would ensure your code always using the correct model class.

How to load:

// to load existing record
int AD_Alert_ID = 100;
MTable table = MTable.get(Env.getCtx(), I_AD_Alert.Table_ID);
I_AD_Alert alert = (I_AD_Alert)table.getPO(AD_Alert_ID, trxName);

How to create new record:

// to create new record
MTable table = MTable.get(Env.getCtx(), I_AD_Alert.Table_ID);
I_AD_Alert alert = (I_AD_Alert)table.getPO(0, trxName);
...


  • Classes which override save() method:
org.compiere.process.DocActionTemplate
org.compiere.model.MClient
org.compiere.model.MClientInfo
org.compiere.model.MSystem

Generated Model class must implement both interfaces and extend PO.

Weak sides that need to be improved:

  • Hard coded Document Engine
  • Hard coded lookup of model class
  • Hard coded list of document type for new client
  • Incomplete Security Implementation
  • No plugin/module support. Both ADCK and 2Pack support dynamic deployment of AD changes but doesn't address the need to deploy java code extension ( especially problematic/messy if your extension needs to use additional third party library).
  • Incomplete web client port
  • Incomplete workflow engine implementation
  • Various swing client bug and limitation
Links

Planned Contributions and Tasks

  • Restrict form "Generate Invoices (manual)" to show only public records (hide locked records) BUG - 1713337
  • Restrict form "Generate Shipments (manual)" to show only public records (hide locked records) BUG - 1713317

Interesting bugs/patches/Feature Requests

Feature Requests

My favorite readings

General


  • OpenQA - Selenium a test tool for web applications. Selenium tests run directly in a browser, just as real users do.


Interesting


Pivot Tables


Mozilla - Firefox Extensions

Project/Time management

  • Project Dune Web-based issue tracker. Integration with subversion or cvs, code inspections in the browser, SCRUM project management.
  • Open Proj - free, open source desktop alternative to Microsoft Project.
  • Open Workbench - Open source project similar to Microsoft Project.
  • workeffort Businesses perform work efforts within their organizations to accomplish tasks such as producing products, developing software, mantaining assets etc. This system helps in managing these kind of tasks. It also includes a time tracking system.
  • eHourTimesheet Management
  • OpenTimeEclipse, SWT/JFace, Hibernate, embedded relational databases, XML.

Communication

"I guess I should warn you, if I turn out to be particularly clear, you've probably misunderstood what I've said."


Software Engineers Salaries

Open Source articles

We tried once to create an open-source developer out of a normal developer, but it completely failed.
We never tried it again. Truth be told, I had an aversion to it.
An open source developer is a self-starter. 
He's competitive - this is someone that wants to prove that they can do something better than you can. 
As such, it's a great recruitment/qualification vehicle, because you can see their work before you ever think of hiring them. 
You can see if they'll work out for the company. 
We definitely took that approach to hiring.
, but don't beg for help, the guys who work owe you nothing.

OSS Etiquette & Culture


Open Source Models


Giving It Away

My wish list - Books

Ordered by my desire!!!


Online books

with the J2EETM Platform, Second Edition]

Engine 6.20 - Administration Manual] Something which i have been part of!!!

Articles and posts from Martin Fowler

Financial based

Read and respond to this message at: https://sourceforge.net/forum/message.php?msg_id=4366156 By: drhayderaziz

I think that Adempiere would get a lot of kudos if Adempiere went the XBRL route www.xbrl.org for financial reporting. For listed companies (and even for unlisted) XBRL will be the way to go especially for any international company that has to consolidate accounts from multiple legal entities in multiple countries in a standardized manner. This would be an essential component of an ERP system in the 2008-2009 time frame. If Adempiere would have its COA structured the XBRL way and have XBRL compliant financial statements at company/consolidated level it would be an AMAZING value proposition to so many organizations.


CS and ROT explained

In UK two methods of trading are popular with manufactures and wholesalers - Consignment Stocking(CS) and Retention of Title (ROT). The question is does ERP handle these types correctly?

CS is where stock is supplied and title transferred on sale to the end user.

ROT is where title is transferred on payment by the wholesaler.

This means that some goods held in the wholesalers warehouse will not belong to him and should not be counted as assets until title is transferred in the case of ROT and not at all in the case of CS unless the wholesaler uses ROT himself.

Non IT Technology

Social networks

 Call me now http://www.bitwine.com/presence/1/25850.gif


Developer oriented social network


The Semantic Web - Information sharing - machine-readable way

  • The Friend of a Friend (FOAF) projectThe Friend of a Friend (FOAF) project is creating a Web of machine-readable pages describing people, the links between them and the things they create and do.

Adempiere



http://adempiere.globalqss.com/cgi-bin/get_ID?
USER=user
&PASSWORD=pass
&TABLE=AD_Column
&ALTKEY=
&COMMENT=SomeCommentHere
    • Show log
http://adempiere.globalqss.com/cgi-bin/showlog?AD_Column


Adempiere Brazil Localization effort people that are cooperating with Adempiere LBR (LBR = Localization Brazil). Those are their names, followed by their sourceforge username.

Eduardo Montenegro (emontenegro) Alvaro Montenegro (amontenegro) Mario Grigioni (mgrigioni)


Adempiere commit schema

  • Mentor/Commiter approach approved with 11/11 votes, according to this thread.

VERY IMPORTANT

Incoming events

Time: xx:xx GMT Day: Tuesday June 26 Venue: IRC channel #adempiere-team (on irc.freenode.net)

1 - Xxx

2 - Xxx

Possible integrations with external systems

  • Hospital Information System
    • care2x Care2x is a hospital information system which has lots of feature but no accounting at all.
    • NetEpi Open Source, network-enabled tools for epidemiology and public health practice.
    • OpenMRS


Adempiere Application dictionary vs. Axapta Data dictionary

Performance tests & results made by me

This are slower than on my laptop. On laptop result was around 17 products / second.

Processors..........: 2 x Pentium2 800MHz
RAM.................: 2 GB
OS..................: Linux, Fedora Core 5
DB..................: Oracle XE
JDK.................: Sun JDK 1.5.0_11
Adempiere version...: 3.3.0
Note................: Adempiere client on the same machine as DB.

Tables where records are inserted: 
AD_TREENODEPR     1095095
M_PRODUCT         1095095
M_PRODUCT_ACCT    1095095
M_PRODUCT_TRL     1095095

Performance table

Start Time      = Thu Aug 09 04:57:01 EEST 2007
End Time        = Thu Aug 09 05:13:54 EEST 2007
Duration(ms)    = 1012585
Duration(sec.)  = 1012
Duration(min.)  = 16
Products        = 5000
Time(seconds)   = 1012
Produsts/Second = 4.9407115

Start Time      = Thu Aug 09 05:17:04 EEST 2007
End Time        = Thu Aug 09 09:14:23 EEST 2007
Duration(ms)    = 14239657
Duration(sec.)  = 14239
Duration(min.)  = 237
Products        = 144000
Time(seconds)   = 14239
Produsts/Second = 10.11307 


Start Time       = Fri Aug 10 03:43:13 EEST 2007
End Time         = Fri Aug 10 07:42:25 EEST 2007
Duration(ms)     = 14351454
Duration(sec.)   = 14351
Duration(min.)   = 239
Duration(hours.) = 3
Products         = 144000
Time(seconds)    = 239
Produsts/Second  = 10.03
 
Start Time       = Fri Aug 10 13:00:23 EEST 2007
End Time         = Fri Aug 10 16:58:42 EEST 2007
Duration(ms)     = 14298664
Duration(sec.)   = 14298
Duration(min.)   = 238
Duration(hours.) = 3
Products         = 144000
Time(seconds)    = 14298
Produsts/Second  = 10.071339

Start Time       = Fri Aug 10 19:59:38 EEST 2007
End Time         = Sat Aug 11 03:59:55 EEST 2007
Duration(ms)     = 28817002
Duration(sec.)   = 28817
Duration(min.)   = 480
Duration(hours.) = 8
Products         = 288000
Time(seconds)    = 28817
Produsts/Second  = 9.994101

Start Time       = Sat Aug 11 17:53:38 EEST 2007
End Time         = Sun Aug 12 02:18:17 EEST 2007
Duration(ms)     = 30278812
Duration(sec.)   = 30278
Duration(min.)   = 504
Duration(hours.) = 8
Products         = 288000
Time(seconds)    = 30278
Produsts/Second  = 9.511857

Postal Code Web Service


Interesting Proposal for Web services

1. Products - When entering a new product, call an UPC/EAN webservice (http://www.gepir.org/) that validates a product UPC/EAN and populates the item description and trade info (size, weight, etc).

2. Business Partners - When entering a new Business Partner, call a Company Registrar to validate (and populate) company registration / vat numbers and registered address, directors, etc.

3. Credit Checking - When entering a new Business Partner, call a webservice to perform a credit vetting / check after which the report can be populated into a credit check table or attached to the record.


Comparison of Posterita Web UI and Robert Klein Ajax Web UI

  • Robert Klein Ajax is more usable than Posterita WebUI
    • Attachment works in Robert Klein but not in Posterita.
    • Grid of Posterita is mess up.
    • Scrolling and navigation are mess up in Posterita.
    • Decimal point of numeric has many zeros in Posterita.
    • Robert Klein Web UI runs fast than Posterita.

Adempiere Frequently Asked Question

Practical Use of Document Type & Sequence

  • What is its real purpose of Document Sequence

The purpose is to have different sequence (Document No) for each document type. For example: Imagine you want to difference the PO depending on what you buy. You could have the document type "Purchase Order-A" and the "Purchase Order-B".

"Purchase Order-A" --> Sequence (Document no):A00001 "Purchase Order-B" --> Sequence (Document no):B00001

So for the same transaction (Purchase order) you can difference distinct sequence numbers.


How to create new user and restricted access rights?

Define Role for User Create Role:

Click on the General Setup -> Security -> Role
Click on the New button(ex: MyRole).
Select the Organization from drop down.
Enter the Name for role.
Select the User Level from User Level drop down.
Tick on the Manual Checkbox.
Click on the Save button.
Click on the Grant Access button (eg:Access to All for Sale Module).
Select the Module from drop down that you have to include.
Select the Access To from drop down that you have to include.
Click on the OK button.
Click on the Save button.

Click on the Org Access tab.
Select the Organization for newely defined role.
Click on the Save button.

Create User:

Click on the General Setup -> Security -> User.
Select the Organization from organization drop down.
(Note: user organization and define role organization must be same.)
Enter the Name for user(ex: ABC). 
Set the Password for user.
Click on the Save button.

Assign Role to User:

-     Click on the User Roles tab. 
Select Role from drop down(ex:MyRole).
Click on the Save button.

Click on the User tab. Select the Default Role from drop down(ex:MyRole). Select Default Client from drop down. Select the Default Organization from drop down. Click on the Save button. Login as ABC user.


How to modify Invoice Posting?

Default Adempiere Account posting:

----------------------------------------------------------------
Account                     Debit               Credit
----------------------------------------------------------------
Account Receivable         55.000.000         
   A tax                                        5.000.000
   Service Revenue                             50.000.000
----------------------------------------------------------------


Desired Adempiere Account posting:

----------------------------------------------------------------
Account                     Debit               Credit
----------------------------------------------------------------
Account Receivable         52.750.000                           
An Account                  2.250.000 - which is 4.5%x50.000.000
   A tax                                        5.000.000        
   Service Revenue                             50.000.000
----------------------------------------------------------------
<pre>

Desired functionality can be achieved with Account splitting.
Rule must be defined in the system which will split posting into Account Receivable on two account entries.

=== Implementor hints ===

==== Show where products are located ====
Submitted By: Jan Kantert (jab_doa)

Summary: Show where products are located

sf.net tracker: [https://sourceforge.net/tracker/?func=detail&atid=879335&aid=1768749&group_id=176962 here]


Initial Comment:
Log in as System Administrator. Select "Application Dictionary" -> "Window, Tab & Field" -> Name = Product

Click on "Tab". 
Go to the end of the list and add a new row. Zoom in and set Table to "M_Storage_M_Storage", Name to "Located at", Description to "Where are my units located?", Tab Level to "2" and check "read only". 
Now save and click on "Create Fields". Thats it. Now you can see where your units are when zooming into a product.

==== Security ====
Submitted By: Armen (armenrz)

Summary: Security

sf.net tracker: [https://sourceforge.net/forum/message.php?msg_id=4451508 here]


1) ADempiere support role based security - Role window.
2) Role Data Access. You can also play around with SQLWhere in Window, Tab & Field.

Example:
(instr('@#User_Level@','C')<>0 OR C_BPartner.CreatedBy=@#AD_user_ID@ OR C_BPartner.SalesRep_ID=@#AD_User_ID@)

For pricelist, there's one place you can't hide price from user, which is  Product Info. You need to modify some codes to do this. What I did is add IsCanViewPrice option in Role so now each role can be set either they can view price or not.


==== Bank Transfer tips ====
Submitted By: usman88

Summary: Bank Transfer tips

sf.net tracker: [https://sourceforge.net/forum/message.php?msg_id=4467580 here]

* [http://www.adempiere.com/wiki/index.php/Bank_to_Bank_Transfer_Transaction_tips Bank to Bank Transfer Transaction tips]

Small tips to handle 1 source Bank to 1 recipient Bank transfer transaction. 

1. Create new cash journal.

2. Select appropriate cash book ( in my case i use dummy cash book to serve this transaction)

3. Next go to cash line and create a new line and select cash type as bank transfer.

4. Then select source bank account and type in transfer amount

5. Create 2nd line as in step 3. 

6. This time select recipient bank account and type in transfer amount but in negative sign.

7. Back to cash journal tab, complete and post it.

8. To finalize it create, complete and post Bank statement for each bank account.


PS. Above tips can be use for more complex scenario such as transfer from 2 bank to 1 recipient.

==== Listing a BOM within a BOM ====
Submitted By: stingreye

Summary: Listing a BOM within a BOM

sf.net tracker: [https://sourceforge.net/forum/message.php?msg_id=4369782 here]

Here is the view in Oracle... Because we have so many parts we ended up doing
a materialized view that we update with a process in Compiere everytime we
 change
a BOM.  We did that so we could report off of this view faster.

I am sure someone out here could write a much better query than this but here
is what I did.  Basically, created a view on top of itself so that the parent
records would null.  Then used the connect by clause to generate the hierarchy.
You will also notice the use of connect_by_root = Top level of bill.
Connect_by_ISLEAF = bottom level of bill.  Level = what level of the hierarchy.

<pre>
CREATE OR REPLACE VIEW BOM_INDENTED
(TOPLEVELID, TOPLEVEL, TOPLEVEL_DESC, PRODUCTNUM, PRODDEC, 
 M_PRODUCTBOM_ID, BOM_LEVEL, BOMQTY, DESCRIPTION, AD_CLIENT_ID, 
 AD_ORG_ID, ROWNUMBER, BOM_LEVEL_NUM, BOTTOMCOMPONENT)
AS 

SELECT   CONNECT_BY_ROOT M_ProductBom_ID AS TOPLEVELID,CONNECT_BY_ROOT Value
AS TOPLEVEL,CONNECT_BY_ROOT b.DESCRIPTION AS TOPLEVEL_DESC, Value AS
 ProductNum,
b.DESCRIPTION AS ProdDesc, M_PRODUCTBOM_ID,LPAD(' ',2*(LEVEL-1)) ||
 TO_CHAR(LEVEL)
BOM_Level, BOMQTY, a.DESCRIPTION,a.AD_CLIENT_ID, a.AD_ORG_ID, ROWNUM, LEVEL,
Connect_By_ISLEAF
  FROM 
  
-- part 2 subquerry combining top level and bom to create null to start from
( SELECT
 "M_PRODUCT_BOM_ID","AD_CLIENT_ID","AD_ORG_ID","ISACTIVE",--"CREATED","C
REATEDBY","UPDATED","UPDATEDBY",  (remove becuase unnnecessarry)
"LINE","M_PRODUCT_ID","M_PRODUCTBOM_ID","BOMQTY","DESCRIPTION","BOMTYPE"
FROM M_PRODUCT_BOM

UNION
-- part 1 the tope level querry creating the nulls that is combined in part 2
SELECT M_PRODUCT_BOM_1.M_PRODUCT_BOM_ID, M_PRODUCT_BOM.AD_CLIENT_ID,
M_PRODUCT_BOM.AD_ORG_ID, M_PRODUCT_BOM_1.ISACTIVE,-- M_PRODUCT_BOM_1.CREATED,
M_PRODUCT_BOM_1.CREATEDBY, M_PRODUCT_BOM_1.UPDATED, M_PRODUCT_BOM_1.UPDATEDBY,
(removed unnecessary)
 M_PRODUCT_BOM_1.LINE,M_PRODUCT_BOM_1.M_PRODUCTBOM_ID AS M_PRODUCT_ID,
M_PRODUCT_BOM.M_PRODUCT_ID AS M_PRODUCTBOM_ID,  M_PRODUCT_BOM_1.BOMQTY,
M_PRODUCT_BOM_1.DESCRIPTION, M_PRODUCT_BOM_1.BOMTYPE
FROM M_PRODUCT_BOM LEFT JOIN M_PRODUCT_BOM  M_PRODUCT_BOM_1 ON
M_PRODUCT_BOM.M_PRODUCT_ID = M_PRODUCT_BOM_1.M_PRODUCTBOM_ID
GROUP BY M_PRODUCT_BOM_1.M_PRODUCT_BOM_ID, M_PRODUCT_BOM.AD_CLIENT_ID,
M_PRODUCT_BOM.AD_ORG_ID, M_PRODUCT_BOM_1.ISACTIVE, M_PRODUCT_BOM_1.CREATED,
M_PRODUCT_BOM_1.CREATEDBY, M_PRODUCT_BOM_1.UPDATED, M_PRODUCT_BOM_1.UPDATEDBY,
M_PRODUCT_BOM_1.LINE, M_PRODUCT_BOM.M_PRODUCT_ID,
 M_PRODUCT_BOM_1.M_PRODUCTBOM_ID,
M_PRODUCT_BOM_1.BOMQTY, M_PRODUCT_BOM_1.DESCRIPTION, M_PRODUCT_BOM_1.BOMTYPE
HAVING (((M_PRODUCT_BOM_1.M_PRODUCTBOM_ID) IS NULL))) a
-- part 3 continued
   INNER JOIN M_PRODUCT b
   ON a.M_PRODUCTBOM_ID = b.M_PRODUCT_ID
  START WITH a.M_PRODUCT_ID IS NULL
  CONNECT BY PRIOR  M_PRODUCTBOM_ID = a.M_PRODUCT_ID
  ORDER SIBLINGS BY b.Value
/

If you want to use materialized views... we did it the following way (I really know very little about them, so if someone has a better idea of how to use them for this, it would be appreciated) The materialized view would be

CREATE MATERIALIZED VIEW BOM_INDENTED_MV
(PTX_Path,TOPLEVELID, TOPLEVEL, TOPLEVEL_DESC, PRODUCTNUM, PRODDEC, 
 M_PRODUCTBOM_ID, BOM_LEVEL, BOMQTY, DESCRIPTION, AD_CLIENT_ID, 
 AD_ORG_ID, BOM_LEVEL_NUM, BOTTOMCOMPONENT,TOPLEVEL_ISACTIVE, COMP_ISACTIVE,
TOP_Client)
 
 Build IMMEDIATE
 REFRESH ON DEMAND 
 DISABLE QUERY REWRITE
 
AS 
SELECT Path, TOPLEVELID,TOPLEVEL,TOPLEVEL_DESC, ProductNum, ProdDesc,
M_PRODUCTBOM_ID, BOM_Level, BOMQTY, f1.DESCRIPTION,mp2.AD_CLIENT_ID,
 mp2.AD_ORG_ID,
BomLevelNum, BottomComponent, MP.ISACTIVE AS TOPLEV_ISACTIVE, MP2.ISACTIVE AS
COMP_ISACTIVE, mp.AD_CLIENT_ID AS TOPLEVEL_Client
  FROM (
SELECT DISTINCT SYS_CONNECT_BY_PATH (M_PRODUCTBOM_ID,'/') AS Path,
 CONNECT_BY_ROOT
M_ProductBom_ID AS TOPLEVELID,CONNECT_BY_ROOT Value AS TOPLEVEL,CONNECT_BY_ROOT
b.DESCRIPTION AS TOPLEVEL_DESC, Value AS ProductNum, b.DESCRIPTION AS ProdDesc,
M_PRODUCTBOM_ID,LPAD(' ',2*(LEVEL-1)) || TO_CHAR(LEVEL) BOM_Level, BOMQTY,
a.DESCRIPTION,a.AD_CLIENT_ID, a.AD_ORG_ID, LEVEL AS BomLevelNum,
 Connect_By_ISLEAF
AS BottomComponent
  FROM 
  
-- part 2 subquerry combining top level and bom to create null to start from
( SELECT
 "M_PRODUCT_BOM_ID","AD_CLIENT_ID","AD_ORG_ID","ISACTIVE",--"CREATED","C
REATEDBY","UPDATED","UPDATEDBY",  (remove becuase unnnecessarry)
"LINE","M_PRODUCT_ID","M_PRODUCTBOM_ID","BOMQTY","DESCRIPTION","BOMTYPE"
FROM M_PRODUCT_BOM

UNION
-- part 1 the tope level querry creating the nulls that is combined in part 2
SELECT M_PRODUCT_BOM_1.M_PRODUCT_BOM_ID, M_PRODUCT_BOM.AD_CLIENT_ID,
M_PRODUCT_BOM.AD_ORG_ID, M_PRODUCT_BOM_1.ISACTIVE,-- M_PRODUCT_BOM_1.CREATED,
M_PRODUCT_BOM_1.CREATEDBY, M_PRODUCT_BOM_1.UPDATED, M_PRODUCT_BOM_1.UPDATEDBY,
(removed unnecessary)
 M_PRODUCT_BOM_1.LINE,M_PRODUCT_BOM_1.M_PRODUCTBOM_ID AS M_PRODUCT_ID,
M_PRODUCT_BOM.M_PRODUCT_ID AS M_PRODUCTBOM_ID,  M_PRODUCT_BOM_1.BOMQTY,
M_PRODUCT_BOM_1.DESCRIPTION, M_PRODUCT_BOM_1.BOMTYPE
FROM M_PRODUCT_BOM LEFT JOIN M_PRODUCT_BOM  M_PRODUCT_BOM_1 ON
M_PRODUCT_BOM.M_PRODUCT_ID = M_PRODUCT_BOM_1.M_PRODUCTBOM_ID
GROUP BY M_PRODUCT_BOM_1.M_PRODUCT_BOM_ID, M_PRODUCT_BOM.AD_CLIENT_ID,
M_PRODUCT_BOM.AD_ORG_ID, M_PRODUCT_BOM_1.ISACTIVE, M_PRODUCT_BOM_1.CREATED,
M_PRODUCT_BOM_1.CREATEDBY, M_PRODUCT_BOM_1.UPDATED, M_PRODUCT_BOM_1.UPDATEDBY,
M_PRODUCT_BOM_1.LINE, M_PRODUCT_BOM.M_PRODUCT_ID,
 M_PRODUCT_BOM_1.M_PRODUCTBOM_ID,
M_PRODUCT_BOM_1.BOMQTY, M_PRODUCT_BOM_1.DESCRIPTION, M_PRODUCT_BOM_1.BOMTYPE
HAVING (((M_PRODUCT_BOM_1.M_PRODUCTBOM_ID) IS NULL))) a
-- part 3 continued
   INNER JOIN M_PRODUCT b
   ON a.M_PRODUCTBOM_ID = b.M_PRODUCT_ID
  START WITH a.M_PRODUCT_ID IS NULL
  CONNECT BY PRIOR  M_PRODUCTBOM_ID = a.M_PRODUCT_ID
  ORDER SIBLINGS BY b.Value
) f1
INNER JOIN M_PRODUCT mp ON TOPLEVELID=mp.M_PRODUCT_ID
INNER JOIN M_PRODUCT mp2 ON M_PRODUCTBOM_ID = mp2.M_PRODUCT_ID
ORDER BY Path
/

Then to refresh the materialize view we used the following database procedure where we used a parameter in the "report process" window to identify which MV to refresh:

CREATE OR REPLACE PROCEDURE Indented_Bom_Mv_Refresh
(
	PInstance_ID    		IN NUMBER	
)
AS
--	Logistice
	ResultStr						VARCHAR2(2000);
	Message							VARCHAR2(2000);
	Record_ID						NUMBER;
	--	Parameter
	CURSOR Cur_Parameter (PInstance NUMBER) IS
		SELECT i.Record_ID, p.ParameterName, p.P_String, p.P_Number, p.P_Date
		FROM AD_PINSTANCE i, AD_PINSTANCE_PARA p
		WHERE i.AD_PInstance_ID=PInstance
		AND i.AD_PInstance_ID=p.AD_PInstance_ID(+)
		ORDER BY p.SeqNo;
	--	Parameter Variables
	p_MVIEW						VARCHAR2(2000);


BEGIN
	DBMS_OUTPUT.PUT_LINE('Updating PInstance - Processing ' || PInstance_ID);
    ResultStr := 'PInstanceNotFound';
    UPDATE AD_PINSTANCE
    SET Created = SYSDATE,
        IsProcessing = 'Y'
    WHERE AD_PInstance_ID=PInstance_ID;
    COMMIT;
--	Get Parameters
	ResultStr := 'ReadingParameters';
	FOR p IN Cur_Parameter (PInstance_ID) LOOP
		Record_ID := p.Record_ID;
		IF (p.ParameterName = 'MVIEW') THEN
 			P_PTX_MVIEW := p.P_String;
			DBMS_OUTPUT.PUT_LINE('  MVIEW=' || p_MVIEW);
		ELSE
			DBMS_OUTPUT.PUT_LINE('*** Unknown Parameter=' || p.ParameterName);
	 	END IF;
	END LOOP;	--	Get Parameter
	DBMS_OUTPUT.PUT_LINE('  Record_ID=' || Record_ID);

		
DBMS_MVIEW.REFRESH (p_PTX_MVIEW, 'c');


<<FINISH_PROCESS>>
	--  Update AD_PInstance
	DBMS_OUTPUT.PUT_LINE('Updating PInstance - Finished ' || Message);
    UPDATE  AD_PINSTANCE
    SET Updated = SYSDATE,
        IsProcessing = 'N',
        Result = 1,                 -- success
        ErrorMsg = Message
    WHERE   AD_PInstance_ID=PInstance_ID;
    COMMIT;
    RETURN;

EXCEPTION
    WHEN  OTHERS THEN
		ResultStr := ResultStr || ': ' || SQLERRM || ' - ' || Message;
		DBMS_OUTPUT.PUT_LINE(ResultStr);
        UPDATE  AD_PINSTANCE
        SET Updated = SYSDATE,
            IsProcessing = 'N',
            Result = 0,             -- failure
            ErrorMsg = ResultStr
        WHERE   AD_PInstance_ID=PInstance_ID;
        COMMIT;
        RETURN;
END ;
/


User authentication in Adempiere using LDAP

Submitted By: gemmiti

Summary: User authentication in Adempiere using LDAP

sf.net tracker: here

Enabling LDAP Functionality:

1. Log in as SysAdmin

2. Go to Menu > System Admin > System

3. In Field "Ldap URL" fill in your LDAP URL, i.e. "LDAP://YourLdapServer.com"

4. In field "LDAP Domain" Your Domain, i.e., "YourLdapServer.com"

5. Log Out as SysAdmin

6. Log In as SuperUser/Admin

7. GoTo Menu > General Rules > Security>User

8. In tab "User Contact" and "Internal" you will find a field for LDAP User Name -- Here (for a particular user) fill in the LDAP use name.

Upon logging in -- the user can enter his/her LDAP user name and password and it will associate the correct credentials to the user you have set up in Compiere.

Add OnHandQty In Product window

Submitted By: stingreye

Summary: Add OnHandQty In Product window

sf.net tracker: here

First the SQL 
1)	You want On Hand Qty -  Product can be stored in multiple locators in M_Storage table. I assume you want total of all locators
2)	So SQL = SELECT SUM (QTYONHAND) FROM M_STORAGE s
3)	Now you want to sync with product table,  so  we add WHERE s.M_PRODUCT_ID = M_PRODUCT.M_PRODUCT_ID
4)	So the final SQL we need is (SELECT SUM(QTYONHAND) FROM M_STORAGE s WHERE s.M_PRODUCT_ID = M_PRODUCT.M_PRODUCT_ID)

Now lets add it to compiere:
1)	Log in as SuperUser or System
2)	Role = System Administrator
3)	Open Table window
4)	Select Column tab
5)	Create new record
6)	Insert a  name for DB Column Name 
7)	Choose a system element in this case most likely Qty_OnHand
8)	Reference = String
9)	Length = 20 should be plenty
10)	Click Save
11)	Click synchronize column, cross fingers
12)	Look on bottom left of window for alter table M_PRODUCTADD name of the field you just made

Lets add it to the M_Product window.

1)	Go to Window Tab Field
2)	Choose Product Table
3)	Goto Tab 
4)	Choose the “tab” we want which is Product (it is for the M_PRODUCT table)
5)	Choose Field Tab
6)	New Record
7)	Name your Field (Qty on Hand)
8)	Column – Choose the new column you created.
9)	Save

Now open the Product window and it should work!

Workflow Simple approval

Workflow Dynamic approval

Changelog functionality

changelog functionality consists of two parts: who & what.

  • Via tables user can identify "what" wish to log.
  • Via roles "who".

By this way is possible to finely control the auditing. This means more tables to be flagged if user wish to log all tables.


SECURE SCENARIO to use Adempiere

Possible SECURE SCENARIO to use Adempiere (applicable Compiere installations also)

CLIENTS

  • 1 - Don't install clients
  • 2 - Install two servers - one for NX (call it NXServer), and the other for oracle and JBoss (call it ADServer)
  • 3 - Allow clients just run through NX connection (you'll have total control of the ADempiere.properties in a linux box)
  • 4 - Configure the ADServer to only accept connections from NXServer
  • 5 - Configure the Oracle in ADServer to only accept connections from the same ADServer and from NXServer

SERVICES ON WEB

  • 1 - Don't expose web services from jboss directly
  • 2 - Install an apache server to expose in a controlled way just the needed services and pages from jboss adempiere


In this scenario NX can be replaced with any terminal server software (Microsoft TS, Citrix, Sun Global Secure Desktop, etc). And you must incur in costs of terminal server software licensing - but security is not free. And you must ensure all those servers - ensure NX, ensure oracle, ensure jboss, ensure apache, ensure linux, etc.


Product Attribute Instance - Color/Size/Serial number


Material transaction between two organizations


Maintain multiple environments(Postgre multiple schema managing)


Report sales figures by product

1. Create a Report Line Set called All Products. 2. Create a Report Line under it called Product with a Line Type of Segment Value (leave Posting and Amount Types blank) 3. Create a Report Source under it with Type=Product and leave the Product field blank 4. Create a Report Column Set called Current Period and YTD 5. Create 2 report columns under it, one for Current Period and YTD. The first one should have Posting Type=Actual, Amount Type=Period Balance, Column Type=Relative Period, Relative Period=0. The second one should be the same except Amount Type=Year Balance. 6. Then create a Financial report using these Report Line and Columns Sets. Make sure to check List Sources when you run to see all the products. Warning, If there are more than 1000 products it won't work (we're obviously aware of this limitation and working on removing it).

You can easily produce a similar report for Sales by Business Partner by just substituting Type=Business Parter in Step 3.


How to monitor Oracle sessions?

SELECT SID, SERIAL#, STATUS, SERVER

 FROM V$SESSION
 WHERE USERNAME = 'ADEMPIERE';


How to change document numbers?

Go to Performance

Analysis -> Accounting Rules -> Document Type

Here you can see all existing document types like Purchase Order etc. If the 'Document is Number Controlled' checkbox is checked then you will have a Document Sequence field (a drop down). Right click and zoom to the Document Sequence window

Performance Analysis -> Accounting Rules -> Document Sequence

Here you can change the current next value, the increment and you can add prefix and or suffix for your order/invoice numbers.


Where to place JasperReport files?

JasperReport can be defined as:

http://
https://
attachment:
file:/ 
or a direct file_directory path 

An easier way to deploy jasper reports could be putting the .jasper in the customization.jar

For that we could add a new prefix like:

resource:org/adempiere/jasper/MyReport.jasper


How to handle imprests?


How to process credit card payments from Java GUI?

How a user could create a payment in the client (not the webstore) that will get passed to the payment processor?


Window 'Invoice (Customer)'.

Complete 'Invoice (Customer)'.
Set Payment Type - Press Button which by default has value 'On Credit'.
A new window open and user can change payment Type from 'On Credit' to 'Credit Card'.
Enter Credit Card data.

BOM price explained.

https://sourceforge.net/forum/message.php?msg_id=4740301
BOM Product price is depend of the price of the products which built it. 

For example Product A consist of 1 product B and 1 product C. Product B and C are being priced at USD 5 and USD 6 respectively. The price of Product A would be USD 11. You cannot change it.

Meanwhile we often find a case where the price of Product A IS NOT the price of product B or C combined. It can be higher or lower. I try to add price to product A, which not the combined price but it doesn't work. This is what happen.

I put price of USD 15 for product A. When I created Sales Order, and I chose product A the price was still USD 15. Everything felt right. And then the disaster came. When I click Complete button suddenly the price change to USD 11!


If the BOM is not stocked it is considered a 'basket; and will compute the price based on the component prices.
If you want to assign a price change it to 'stocked'

Developer hints

  • class dbPort/org.compiere.process.DocActionTemplate shows a template for DocAction, i think that it must be updated.


Hint-1; UPDATE columns which must have default value or have checked constraint

When developer add new column which is NOT NULL or which has checked constraint, please do not forget to execute proper UPDATE TABLE sql statements.

Example:

ALTER TABLE EXP_FormatLine
ADD IsPartUniqueIndex CHAR(1) CHECK(IsPartUniqueIndex IN ('Y', 'N'));

UPDATE EXP_FormatLine
SET IsPartUniqueIndex = 'N' 
WHERE IsPartUniqueIndex IS NULL;

Hint-2; Be carefull when creating VIEWS

Use LEFT/RIGHT OUTER JOINS, because in many cases fields do not have values and INNER JOIN will not show all records. In this example C_Invoice.C_Order_ID is not manadatory so view will not show records which do not have Order associated with Invoice!

FROM C_Invoice i 
    INNER JOIN C_DocType d ON (i.C_DocType_ID=d.C_DocType_ID) 
    LEFT OUTER JOIN C_Order o ON (i.C_Order_ID=o.C_Order_ID) 

Hint-3; Java on Ubuntu

Ubuntu came with default version of java 1.4.2 and installing 1.5.0 didn't change that. So developer have to change it. Exporting the path to your newer java to the .bashrc config file of your environment is a standadrd decision but is not system wide and in some cases is not enough. The decision is. When you type at the prompt:

  $ sudo update-java-alternatives -l

will see the versions of all javas installed into your system. In order to make the latest one default for the whole system type:

  $ sudo update-java-alternatives -s java-newer-ver 


Hint-4; How to truncate timestamp

Timestamp today = TimeUtil.trunc(new Timestamp (System.currentTimeMillis() ), TimeUtil.TRUNC_DAY);


Hint-5; How to use MTable.get(..) and MTable.getPO(..)

Class: base/src/org/compiere/model/MProduct.java

public MAttributeInstance getAttributeInstance(String name, String trxName) 
{
	MAttributeInstance instance = null;
	
	MTable table = MTable.get(Env.getCtx(), MAttribute.Table_ID);
	MAttribute attribute = (MAttribute)table.getPO("Name = ?", new Object[]{name}, trxName);
	if ( attribute == null ) return null;
	table = MTable.get(Env.getCtx(), MAttributeInstance.Table_ID);
	instance = (MAttributeInstance)table.getPO(
			MAttributeInstance.COLUMNNAME_M_AttributeSetInstance_ID + "=?" 
			+ " and " + MAttributeInstance.COLUMNNAME_M_Attribute_ID + "=?" ,
			new Object[]{getM_AttributeSetInstance_ID(), attribute.getM_Attribute_ID()},
			trxName);
	return instance;
}

Subversion Access

Subversion Plugin for Eclipse Subversive

Adempiere project's SourceForge.net Subversion repository can be checked out through SVN with the following instruction set: svn co https://adempiere.svn.sourceforge.net/svnroot/adempiere adempiere

MFG

sf.net forum post

Important Steps:

1. Apply the following patches: 
 
buildbase.patch.tim 
buildclient.patch.tim 
buildutils_dev.patch.tim 
X_AD_WF_Node.patch 
X_C_DocType.patch 
X_S_Resource.patch 
X_AD_Workflow.patch 
X_M_Cost.patch 
X_M_Transaction.patch 
X_M_Product.patch 
 
2. I copied adempiere/libero/build.xml.tim to adempiere/libero/build.xml 
 
Build your Adempiere and run it.  

3. Create a new client and import accounting etc... 
(If you don't do this you won't see all the menus, you can't just login under GardenAdmin/GardenAdmin that is not enough) 
It looks that 2pack file do not contains proper access records.
Must research!!!

4. Login with your new client Admin login you created in step3 and Libero away!!!


Compiling adempiere + libero from SVN head
1. Check out the head version of both libero and adempiere 
2. Build adempiere 
3. Build libero 
4. Rebuild adempiere (to get the libero.jar into the install) 
5. Set up the database. (Create database, run the pljava deployer, drop the
sqlj schema, import the dump file)
6. Run the 330-trunk database migrations 
7. Copy EE01.zip into the packages directory 
8. Run silent setup and start the app server.
9. Launch the Adempiere client
10. Add the EE01 entity type
11. Pack in the EE01.zip
12. Copy libero.jar into the packages/packages/EE01/lib directory.
13. Re-run silentsetup and start the server.

Template Process and steps to create a process

1)create a java class extends org.compiere.process.SvrProcess

2)Implements two methods void doIt() String prepare()

In Prepare method you can get different parameters ProcessInfoParameter[] para = getParameter(); for (int i = 0; i < para.length; i++) { String name = para[i].getParameterName(); if (para[i].getParameter() == null)

else System.out.println(name); } and in doIt method you try to insert this parameters into your table after you create this class Login with system administrator role

3) 'Report and Process' window define your process with parameter 4) 'Table and Column' window choose your table and create a column with Button Reference

5) Choose your process for this Button

package org.adempiere.process;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;

import org.compiere.model.MClient;
import org.compiere.model.MDocType;
import org.compiere.model.X_C_BPartner_EDI;
import org.compiere.model.X_C_EDIFormat;
import org.compiere.model.X_C_EDIProcessor;
import org.compiere.process.ProcessInfoParameter;
import org.compiere.process.SvrProcess;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;

/**
 *  @author Trifon Trifonov
 *  @version $Id:$
 */
public class ModelImporter extends SvrProcess
{
	/** Client Parameter			*/
	protected int	p_AD_Client_ID = 0;
	
	/** Business Partner Parameter */
	protected int p_C_BPartner_ID = 0;
	
	/** Document Type Parameter */
	protected int p_C_DocType_ID = 0;
	
	/** Record ID */
	protected int p_Record_ID = 0;
	
	/** Table ID */
	int AD_Table_ID = 0;
	
	/**
	 * 	Get Parameters
	 */
	protected void prepare ()
	{
		
		p_Record_ID = getRecord_ID();
		if (p_AD_Client_ID == 0)
			p_AD_Client_ID = Env.getAD_Client_ID(getCtx());
		AD_Table_ID = getTable_ID();
		
		StringBuffer sb = new StringBuffer ("AD_Table_ID=").append(AD_Table_ID);
		sb.append("; Record_ID=").append(getRecord_ID());
		//	Parameter
		ProcessInfoParameter[] para = getParameter();
		for (int i = 0; i < para.length; i++)
		{
			String name = para[i].getParameterName();
			if (para[i].getParameter() == null)
				;
			else if (name.equals("C_BPartner_ID"))
				p_C_BPartner_ID = para[i].getParameterAsInt();
			else
				log.log(Level.SEVERE, "Unknown Parameter: " + name);
		}
		
		log.info(sb.toString());
	}

	/**
	 * 	Process 
	 *	@return info
	 */
	protected String doIt () throws Exception
	{
		StringBuffer result = new StringBuffer("");
		
		MClient client = MClient.get (getCtx(), p_AD_Client_ID);
		log.info(client.toString());
		// get proper EDI Format from Document Type
		MDocType docType = MDocType.get(getCtx(), p_C_DocType_ID);
		
		int C_EDIFormat_ID = 0;
		int C_EDIProcessor_ID = 0;
		String sql1 = "SELECT C_EDIFormat_ID, C_EDIProcessor_ID "
			   + "FROM " + X_C_BPartner_EDI.Table_Name + " "
			   + "WHERE AD_Client_ID = ? "
			   + " AND C_BPartner_ID = ? "
			   + " AND C_DocType_ID = ? "
			   + " AND Inbound = 'N' " 
		;
		ResultSet rs1 = null;
		PreparedStatement pstmt1 = null;
		try
		{
			pstmt1 = DB.prepareStatement(sql1, get_TrxName());
			pstmt1.setInt(1, p_AD_Client_ID);
			pstmt1.setInt(2, p_C_BPartner_ID);
			pstmt1.setInt(3, p_C_DocType_ID);
			rs1 = pstmt1.executeQuery();
			if (rs1.next())
			{
				// Found specific C_EDIFormat for given BPartner and C_DocType_ID
				C_EDIFormat_ID = rs1.getInt(X_C_EDIFormat.COLUMNNAME_C_EDIFormat_ID);
				C_EDIProcessor_ID = rs1.getInt(X_C_EDIProcessor.COLUMNNAME_C_EDIProcessor_ID);
			} else {
				// Get C_EDIFormat_ID from Document Type
				C_EDIFormat_ID = docType.getC_EDIFormat_ID();
			}
			
		} finally {
			try {
				if (rs1 != null) rs1.close();
				if (pstmt1 != null) pstmt1.close();
			} catch (SQLException ex) {/*ignored*/}
			rs1 = null;
			pstmt1 = null;
		}
		if (C_EDIFormat_ID == 0) {
			throw new Exception("EDI Format is not set for C_DocType_ID = [" + p_C_DocType_ID + "]");
		}
		if (C_EDIProcessor_ID == 0) {
			throw new Exception("EDI Processor is not set for C_DocType_ID = [" + p_C_DocType_ID + "]");
		}
		
		addLog(0, null, null, Msg.getMsg (getCtx(), "EDISubmitProcessResult") + "\n" + result.toString());
		return result.toString();
	}
}

Migration with SQL statements - Oracle - AD_Element

INSERT INTO AD_Element
(AD_Element_ID, AD_Client_ID, AD_Org_ID, IsActive,
Created, CreatedBy,
Cpdated, UpdatedBy,
ColumnName, EntityType, Name,
PrintName
)
VALUES (500XX, 0, 0, 'Y',
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
'[ColumnNameHere]', 'D', '[NameHere]',
'[PrintNameHere]'
);
COMMIT;
UPDATE AD_Sequence
SET CurrentNextSys = (SELECT MAX (AD_Element_ID) + 1
FROM AD_Element
WHERE AD_Element_ID < 1000000)
WHERE NAME = 'AD_Element';


Migration with SQL statements - Oracle - AD_Table

INSERT INTO AD_Table 
(AD_Table_ID, AD_Client_ID, AD_Org_ID, IsActive,
Created, CreatedBy,
Updated, UpdatedBy, 
Name, Description, Help, TableName, 
IsView, AccessLevel, EntityType, AD_Window_ID, 
AD_Val_Rule_ID, LoadSeq, IsSecurityEnabled, IsDeleteable, 
IsHighVolume, ImportTable, IsChangelog, ReplicationType, 
PO_Window_ID, CopyColumnsFromTable
) 
VALUES 
(53014, 0, 0, 'Y', 
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100, 
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
'[NameHere]', '[DescriptionHere]', '[HelpHere]', '[TableNameHere]', 
'N', '4', 'D', null, 
null, 0, 'N', 'Y', 
'N', 'N', 'N', 'L', 
null, 'N'
);

COMMIT;
UPDATE AD_Sequence
SET CurrentNextSys = (SELECT MAX (AD_Table_ID) + 1
FROM AD_Table
WHERE AD_Table_ID < 1000000)
WHERE NAME = 'AD_Table';

Migration with SQL statements - Oracle - AD_Column

INSERT INTO AD_Column
(AD_Column_ID, AD_Client_ID, AD_Org_ID, IsActive,
Created,
Updated, CreatedBy,
UpdatedBy, Name, Description, Version,
EntityType, ColumnName, AD_Table_ID, AD_Reference_ID, 
FieldLength, IsKey, IsParent, IsMandatory, IsUpdateable,
IsIdentifier, SeqNo, IsTranslated, IsEncrypted,
IsSelectionColumn, AD_Element_ID, Callout, IsSyncDatabase,
IsAlwaysUpdateable
)
VALUES (502XX, 0, 0, 'Y',
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'),
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
100, '[NameHere]', '[DescriptionHere]', 1,
'D', '[ColumnNameHere]', AD_Table_IDHERE, AD_Reference_IDHere,
1, 'N', 'N', 'Y', 'Y',
'N', 0, 'N', 'N',
'N', 50071, '[CalloutHere]', 'N',
'N'
);
COMMIT;
UPDATE AD_Sequence
SET CurrentNextSys = (SELECT MAX (AD_Column_ID) + 1
FROM AD_Column
WHERE AD_Column_ID < 1000000)
WHERE NAME = 'AD_Column';

Migration with SQL statements - Oracle - AD_Window

INSERT INTO AD_Window
(AD_Window_ID,AD_Client_ID, AD_Org_ID, IsActive,
Created, CreatedBy,
Updated, UpdatedBy, 
Name, Description, Help, WindowType, 
IsSoTrx, EntityType, Processing, AD_Image_ID, 
AD_Color_ID, IsDefault, WinHeight, WinWidth, 
IsBetaFunctionality
) 
VALUES (53003, 0, 0, 'Y', 
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100, 
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100, 
'[NameHere]', null, null, 'M', 
'N', 'D', 'N', null, 
null, 'N', 0, 0, 
'N'
);

COMMIT;
UPDATE AD_Sequence
SET CurrentNextSys = (SELECT MAX (AD_Window_ID) + 1
  FROM AD_Window
  WHERE AD_Window_ID < 1000000)
WHERE Name = 'AD_Window';


Migration with SQL statements - Oracle - AD_Tab

INSERT INTO AD_Tab 
(AD_Tab_ID, AD_Client_ID, AD_Org_ID, IsActive,
Created, CreatedBy,
Updated, UpdatedBy,
Name, Description, Help, AD_Table_ID, 
AD_Window_ID, SeqNo, TabLevel, IsSingleRow, 
IsInfoTab, IsTranslationTab, IsReadOnly, AD_Column_ID, 
HasTree, WhereClause, OrderByClause, CommitWarning, 
AD_Process_ID, Processing, AD_Image_ID, ImportFields, 
AD_ColumnSortOrder_ID, AD_ColumnSortYesNo_ID, IsSortTab, EntityType, 
Included_Tab_ID, ReadOnlyLogic, DisplayLogic, IsInsertRecord, 
IsAdvancedTab
) 
VALUES (53014, 0, 0, 'Y', 
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100, 
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100, 
'[NameHere]', null, null, [AD_TableIDHERE], 
[AD_Window_IDHERE], [SeqNoHERE], 0, 'N', 
'N', 'N', 'N', null, 
'N', null, null, null, 
null, 'N', null, 'N', 
null, null, 'N', 'D', 
null, null, null, 'Y', 
'N'
);

COMMIT;
UPDATE AD_Sequence
SET CurrentNextSys = (SELECT MAX (AD_Tab_ID) + 1
  FROM AD_Tab
  WHERE AD_Tab_ID < 1000000)
WHERE Name = 'AD_Tab';


Migration with SQL statements - Oracle - AD_Field

INSERT INTO AD_Field
(AD_Field_ID, AD_Client_ID, AD_Org_ID, IsActive,
Created, CreatedBy,
Updated, UpdatedBy,
Name, Description, IsCentrallyMaintained, SeqNo, AD_Tab_ID,
AD_Column_ID, IsDisplayed, DisplayLength, IsReadonly,
IsSameLine, IsHeading, IsFieldOnly, IsEncrypted, EntityType
)
VALUES (50184, 0, 0, 'Y',
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
'Store Archive On File System', 'Store Archive On File System', 'Y', 250, 145,
50214, 'Y', 1, 'N',
'N', 'N', 'N', 'N', 'D'
);
COMMIT;
UPDATE AD_Sequence
SET CurrentNextSys = (SELECT MAX (AD_Field_ID) + 1
  FROM AD_Field
  WHERE AD_Field_ID < 1000000)
WHERE Name = 'AD_Field';


Migration with SQL statements - Oracle - AD_Menu

INSERT INTO AD_Menu
(AD_Menu_ID, AD_Client_ID, AD_Org_ID, IsActive,
Created, CreatedBy,
Updated, UpdatedBy,
Name, Description, IsSummary, IsSoTrx, 
IsReadOnly, Action, AD_Window_ID, AD_Workflow_ID, 
AD_Task_ID, AD_Process_ID, AD_Form_ID, AD_Workbench_ID, 
EntityType
)
 VALUES( 53012, 0, 0, 'Y',
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100, 
'[NameHERE]', NULL, 'N', 'N', 
'N', 'W', [AD_Window_IDHERE], NULL, 
NULL, NULL, NULL, NULL, 
'D'
);
COMMIT;
UPDATE AD_Sequence
SET CurrentNextSys = (SELECT MAX (AD_Menu_ID) + 1
  FROM AD_Menu
  WHERE AD_Menu_ID < 1000000)
WHERE Name = 'AD_Menu';


Migration with SQL statements - Oracle - AD_TreeNodeMM

INSERT INTO AD_TreeNodeMM 
(AD_Tree_ID, Node_ID, AD_Client_ID, AD_Org_ID, IsActive, 
Created, Createdby, 
Updated, UpdatedBy, Parent_ID, SeqNo
)
VALUES (10, [Node_IDHERE], 0, 0, 'Y', 
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 0, 
TO_DATE ('10/22/2007 09:30:00', 'MM/DD/YYYY HH24:MI:SS'), 0, [Parent_IDHERE], [SeqNoHERE]
);
COMMIT;
UPDATE AD_Sequence
SET CurrentNextSys = (SELECT MAX (AD_Menu_ID) + 1
  FROM AD_Menu
  WHERE AD_Menu_ID < 1000000)
WHERE Name = 'AD_Menu';

Migration with SQL statements - AD_Message

INSERT INTO AD_Message
(AD_Message_ID, AD_Client_ID, AD_Org_ID, IsActive,
Created, CreatedBy,
Updated, UpdatedBy,
Value, MsgText, MsgType
)
VALUES (500XX, 0, 0, 'Y',
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
TO_DATE ('02/26/2007 12:30:00', 'MM/DD/YYYY HH24:MI:SS'), 100,
'[VaueHere]','[MSG Text Here]','I'
);
COMMIT;
UPDATE AD_Sequence
SET CurrentNextSys = (SELECT MAX (AD_Message_ID) + 1
FROM AD_Message
WHERE AD_message_ID < 1000000)
WHERE NAME = 'AD_Message';

Migration with SQL statements - AD_Process_Para

INSERT INTO AD_Process_Para
(AD_Process_Para_ID, AD_Client_ID, AD_Org_ID, IsActive, Created,
CreatedBy, Updated, UpdatedBy, Name,
Description,
Help,
AD_Process_ID, SeqNo, AD_Reference_ID, AD_Reference_Value_ID,
AD_Val_Rule_ID, ColumnName, IsCentrallyMaintained, FieldLength,
IsMandatory, IsRange, AD_Element_ID, EntityType
)
VALUES (50019, 0, 0, 'Y', TO_DATE ('2007-03-03', 'YYYY-MM-DD'),
100, TO_DATE ('2007-03-03', 'YYYY-MM-DD'), 100, 'Shipment Date',
'Date printed on shipment',
'The Shipment Date indicates the date printed on the shipment.',
118, 15, 15, NULL,
NULL, 'MovementDate', 'N', 0,
'Y', 'N', 1037, 'D'
);
COMMIT;
UPDATE AD_SEQUENCE
SET currentnextsys = (SELECT MAX (ad_process_para_id) + 1
FROM AD_Process_Para
WHERE AD_Process_Para_ID < 1000000)
WHERE NAME = 'AD_Process_Para';


Migration with SQL statements - AD_Ref_List - Postgre

INSERT INTO AD_Ref_List (
Created, CreatedBy, Updated, UpdatedBy, 
AD_Org_ID, AD_Ref_List_ID, AD_Reference_ID, 
Value, Name, IsActive, AD_Client_ID, EntityType
) VALUES (
TO_TIMESTAMP('2008-01-19 22:45:00','YYYY-MM-DD HH24:MI:SS'), 0, TO_TIMESTAMP('2008-01-19 22:45:00','YYYY-MM-DD HH24:MI:SS'), 0, 
0, 53287, 329, 
'DOO', 'Distribution Order', 'Y',0,'EE01'
);

Session_IsChangeLog, AD_Table.IsChangeLog, AD_Column.IsChangeLog combination

1. Session_IsChangeLog=no,  AD_Table.IsChangeLog=no,  AD_Column.IsChangeLog=no
     =>is column logged: no
2. Session_IsChangeLog=no,  AD_Table.IsChangeLog=no,  AD_Column.IsChangeLog=yes
     =>is column logged: no
3. Session_IsChangeLog=no,  AD_Table.IsChangeLog=yes, AD_Column.IsChangeLog=no
     =>is column logged: no
4. Session_IsChangeLog=no,  AD_Table.IsChangeLog=yes, AD_Column.IsChangeLog=yes
     =>is column logged: yes
5. Session_IsChangeLog=yes, AD_Table.IsChangeLog=no,  AD_Column.IsChangeLog=no
     =>is column logged: no
6. Session_IsChangeLog=yes, AD_Table.IsChangeLog=no,  AD_Column.IsChangeLog=yes
     =>is column logged: yes
7. Session_IsChangeLog=yes, AD_Table.IsChangeLog=yes, AD_Column.IsChangeLog=no
     =>is column logged: no
8. Session_IsChangeLog=yes, AD_Table.IsChangeLog=yes, AD_Column.IsChangeLog=yes
     =>is column logged: yes

Note: Session_IsChangeLog means: AD_Role.IsChangeLog or is a webstore session.

Observation1: as you see, AD_Column.IsChangeLog=Y means inherit policy from
parent (AD_Table) and AD_Column.IsChangeLog=N means never log this record.

PS: in future, i think we can move from IsChangeLog flag to some
ChangeLogPolicy=(Always, Never, Inherit from parent).


How to use Transactions and Save points in Adempiere

String trxName = Trx.createTrxName("test");
Trx trx = Trx.get(trxName, true);
Savepoint save1 = trx.setSavepoint("save1");

location = new MLocation(m_Ctx, 0, trxName);

... 

trx.rollback(save1);

trx.commit();
trx.close();


How to build Adempiere customization.jar

Customization.jar is in the lib directory of trunk. (ie /trunk/lib ) Go to that directory and execute following commands:

jar uvf customization.jar -C ../libero/build/ ./org/compiere/model/ jar uvf customization.jar -C ../libero/build/ ./org/compiere/acct/ jar uvf customization.jar -C ../libero/build/ ./org/compiere/process/

Then goto utils_dev directory and ./RUN_build.sh

After the build has completed the new customized.jar will be in $ADEMPIERE_HOME/lib Adempiere should now use the customized classes.


How to Open Window from source code?

MQuery aQuery = new  MQuery ("C_Invoice");
aQuery.setRecordCount(1);
aQuery.addRestriction("C_Invoice_ID", "=", C_Invoice_ID );

AWindow frame = new AWindow();
frame.initWindow(183, aQuery); // 183=window "Invoice (Vendor)"

frame.validate();
AEnv.showCenterScreen(frame);


How to keep parameter window open after view report?


How to create confirmation for inventory move?


How to make Adempiere LDAP username registration compatible with OpenLDAP

- StringBuffer principal = new StringBuffer (userName).append("@").append(domain);
+ // For OpenLDAP uncomment the next line  
+ // StringBuffer principal = new StringBuffer("uid=").append(userName).append(",").append(domain);
+ StringBuffer principal = new StringBuffer(userName).append("@").append(domain);
  env.put(Context.SECURITY_PRINCIPAL, principal.toString());
  env.put(Context.SECURITY_CREDENTIALS, password);


How to use JSR 223: Scripting callouts in Adempiere?

How to get Compiere Home from java class?

org.compiere.util.Ini.findAdempiereHome()

License to use for new classes

/**********************************************************************
* This file is part of Adempiere ERP Bazaar                           *
* http://www.adempiere.org                                            *
*                                                                     *
* Copyright (C) Trifon Trifonov.                                      *
* Copyright (C) Contributors                                          *
*                                                                     *
* This program is free software; you can redistribute it and/or       *
* modify it under the terms of the GNU General Public License         *
* as published by the Free Software Foundation; either version 2      *
* of the License, or (at your option) any later version.              *
*                                                                     *
* 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., 51 Franklin Street, Fifth Floor, Boston,          *
* MA 02110-1301, USA.                                                 *
*                                                                     *
* Contributors:                                                       *
* - Trifon Trifonov (trifonnt@users.sourceforge.net)                  *
*                                                                     *
* Sponsors:                                                           *
* - Company (http://www.site.com)                                     *
***********************************************************************/
...
...
/**
 *	@author Trifon Trifonov
 *	@version $Id$
 */

Adempiere Export/Import Tools

  • ADCK can be used in two modes.
    • As Development tool. To model DB design and create/modify tables.

As Development tool ADCK uses Druid which allows developer to generate CREATE TABLE and ALTER table SQL statement for various DBs: Oracle, Postgres, MySQL, ... As Development tool ADCK can generate xml files for various tools and frameworks like: hibernate, torque.

    • As transfer tool for only migrating AD changes from Adempiere instance to instance or from version to version.

As transfer tool ADCK require initial just setting of proper settings in properties files.

2Pack vs. ADCK comparison table.

This table is made with the sole purpose to help me to organize information regarding import/export tools in Adempiere. I do not have any idea to push any of the tools mentiod here. It is user's choice to use or not to use any of them and also users choice to have headache after thier usage.

WARNING: !!!MAKE A BACKUP BEFORE ANY USAGE OF ANY OF THE TOOLS!!!

2PackADCK
menumenu
windowwindow
tabtab
fieldfield
processprocess
processparaprocesspara
tabletable
columncolumn
impformatAD_ImpFormat
impformatrowAD_ImpFormat_Row
printformatAD_PrintFormat
printformatitemAD_PrintFormatItem
reference[[ADCK |]]
referencelist[[ADCK |]]
referencetable[[ADCK |]]
reportview[[ADCK |]]
reportviewcol[[ADCK |]]
task[[ADCK |]]
form[[ADCK |]]
workbench[[ADCK |]]
preference[[ADCK |]]
roleAD_Role
???AD_User
userroleAD_User_Roles
orgroleAD_Role_OrgAccess
windowaccessAD_Window_Access
processaccessAD_Process_Access
formaccessAD_Form_Access
workflowaccessAD_Workflow_Access
taskaccess[[ADCK |]]
???AD_Column_Access
???AD_Language
???AD_Message
???AD_PrintTableFormat
???AD_Scheduler
???C_BP_Group
???M_Product_Category
???PA_ReportColumnSet
???PA_ReportColumn
???PA_Report
???PA_ReportLineSet
???PA_ReportLine
???PA_ReportSource
???AD_Client
2Pack Any TableADCK Any Table
???TEMPLATE

Weak sides of 2pack according me

  • Require integration at source code level with Adempiere, which means that if i need to customize any import functionality i must rebuild whole application or patch it.
    • Carlos pointed that 2Pack can import records into any table, even customized.
    • My comment is regarding main xml elements like: menu, window, tab, field, process, ... First time when i understood that i need to modify main xml elements was for JasperReports integration when i had to add new column into AD_Process table.
    • I think that GenericPO which is responsible to import records into Any Table had one issue (I have to remember the exact reason. It was regarding Sequences or something related. ).
    • Format of general imports is complicated.

  • Main class(org.adempiere.pipo.PackInHandler) which handle import is very big(3800 lines) and complex, which require lot of time for developer to study it and makes modifications hard task.
    • Since version 3.3.0 Low Heng Sin refactored org.adempiere.pipo.PackInHandler and now it is split into multiple classes.
  • 2Pack uses SAX Parser which makes developer job harder as developer can't look forward or backward in XML tree.

Weak sides of ADCK according me

  • It is external program, so user do not have such detailed control over security.
  • It is harder for developer to work with it as do not have automatic changes extraction like 2Pack.

Ideas for extensions

Computerized Maintenance Management System

sf.net post CMMS is Computerized Maintenance Management System that designed specially for preventive maintenance for assets such as light vehicle, heavy equipment etc. so that company can create budgeting for repair and maintenance for their assets. Technicaly the module give alert to user when an asset have to get action such as replace fuel filter, oil filter or other item spareparts. Therefore these module related with inventory (internal use). Inventory will decrease its stock when user CMMS request for repair and maintenance their an asset.


Additional fields in I_Xxx tables

sf.net forum post

By: Carlos (globalqss)

Hi, every time I customize tables for a customer (almost all projects) I need to change the importers and/or make some tricks with not used fields on import. [Struggling today with this case]

Idea!

Not tested, but I think I could make a ModelValidator on udpate of I_ table (i.e. I_BPartner) and process the corresponding fields.

The other thing we could do is to add some free fields to every I_ table as wildcards to save customized or non considered fields and process them properly with the ModelValidator. Maybe just adding i.e. 10 fields FreeField01 through FreeField10 on the tables can make the trick.

Recent Adempiere changes

Avoid usage of clearing accounts

Tracker also contains a .doc file which show the effect of the change and he scripts to test it with GardenWorld.


Add more query method to MTable

Date: 2007-08-21

MTable has new method:

	public Query createQuery(String whereClause, String trxName) 
	{
		return new Query(this, whereClause, trxName);
	}

Jar file in 2pack/lib will be packed into Adempiere.jar

Starting from revision 3261 of trunk, any jar file that is pack of the lib folder of a 2pack package will be packed into the Adempiere.jar by the run_setup process. What this mean is, you just need to compile all libero specific code, pack it in a jar file and place it under the lib folder of the libero 2pack archive. Please look at the latest FAPack006.zip in the svn packages folder for an example.


Reorganization of Adempiere menu

<menu name="" >
  <menu name="Export Format" >
    <window name="Export Format" />
  </menu>
</menu>


Suggested menu:

<menu name="Quote-to-Invoice" >
  <menu name="Sales Orders" >
    <menu name="Rules" >
      <window name="" />
      ...
    </menu>
    <menu name="Transact" >
      <window name="" />
      ...
    </menu>
    <menu name="Report and Inquire" >
      <window name="" />
      ...
    </menu>
    <menu name="Processes" >
      <window name="" />
      ...
    </menu>
  </menu>

  <menu name="Shipments" >
    <menu name="Rules" >
      <window name="" />
      ...
    </menu>
    <menu name="Transact" >
      <window name="" />
      ...
    </menu>
    <menu name="Report and Inquire" >
      <window name="" />
      ...
    </menu>
    <menu name="Processes" >
      <window name="" />
      ...
    </menu>
  </menu>
</menu>

CRM systems

Comparison of CRM systems


Localized in Bulgarian


Interesting news/Forum post regarding CRM systems


Wiki

XWiki

ERP Systems


ERP Requirements

Features that a composite of UK government bodies classified as Mandatory, Highly Desirable and nice-to-have in financial systems. Chapter 9 sets out their requirements on fixed assets. List they came up seems to have general application.


Seats/tables in a restaurant (or plane or cinema)

In my opinion the seat/table numbering problematic could be solved with the help of the entities AccommodationClass, AccommodationMap described in the book vol2. I will give you a short description of these entities and example of the "numbering issue" solution.

AccommodationClass - description: It is designed to store classes information (these could be plane, bus classes, table types, chair types, room types etc)

AccommodationClass - definition (based on the book but modified a little) fields: accClassId, parentAccClassId, description


AccommodationMap - description: Its idea is to provide information of the number of spaces offered by a fa/accClass. Here we can extend it to provide overbooking information and seat numbering information(the last two fields in the definition below) fields: mapId, accClassId, faId, nrOfSpaces, overBooked, number

Example: Define two tables.

- Table number 5 has 3 chairs. Chair with number 1 is baby_chair. The other two chairs with number 2 and 3 are high_chairs.
- Table number 9 has 2 chairs. Chairs number 1 and 2 are normal_chairs.

In FixedAsset relate the tables to the chairs.

FixedAsset:fixedAssetId=table1,  parentFixedAssetId=NULL
FixedAsset:fixedAssetId=table2,  parentFixedAssetId=NULL
FixedAsset:fixedAssetId=chair11, parentFixedAssetId=table1 //chair11 belongs to table1
FixedAsset:fixedAssetId=chair12, parentFixedAssetId=table1 //chair12 belongs to table1
FixedAsset:fixedAssetId=chair13, parentFixedAssetId=table1 //chair13 belongs to table1
FixedAsset:fixedAssetId=chair14, parentFixedAssetId=table2 //chair14 belongs to table2
FixedAsset:fixedAssetId=chair15, parentFixedAssetId=table2 //chair15 belongs to table2

In Accommodationclass define the table/chair classes.

AccommodationClass: accClassId=tables,        parentAccClassId=NULL
AccommodationClass: accClassId=chairs,        parentAccClassId=NULL
AccommodationClass: accClassId=plane_classes, parentAccClassId=NULL
AccommodationClass: accClassId=baby_chair,    parentAccClassId=chairs;
AccommodationClass: accClassId=high_chair,    parentAccClassId=chairs;
AccommodationClass: accClassId=normal_chair,  parentAccClassId=chairs;


In AccommodationMap define how many places each table or chair has and which is its number.

AccommodationMap: accClassId=tables,        fixedAssetId=table1,  nrOfSpaces=3, number=5 //table number 5 has 3 chairs(faId=table1)
AccommodationMap: accClassId=baby_chair,    fixedAssetId=chair11, nrOfSpaces=1, number=1 //chair number 1 has one place(faId=chair11)
AccommodationMap: accClassId=high_chair,    fixedAssetId=chair12, nrOfSpaces=1, number=2 //chair number 2 has one place(faId=chair12)
AccommodationMap: accClassId=high_chair,    fixedAssetId=chair13, nrOfSpaces=1, number=3 //chair number 3 has one place(faId=chair13)
AccommodationMap: accClassId=tables,        fixedAssetId=table2,  nrOfSpaces=2, number=9 //table number 9 has two places(faId=table2)
AccommodationMap: accClassId=normal_chair,  fixedAssetId=chair14, nrOfSpaces=1, number=1 //chair number 1 has one place(faId=chair14)
AccommodationMap: accClassId=normal_chair,  fixedAssetId=chair15, nrOfSpaces=1, number=2 //chair number 2 has one place(faId=chair15)

In similar fashion you can define theaters, planes etc. Also overbooking data could be kept in the AccommodationMap entity which could be used for hotel reservations. Hourly reservations could be enabled as well with the introduction of the AccommodationSpot entity.

ERP articles


Comparison of Open Source ERP Systems


SAP


Compiere

My opinion is that this is very outdated information, but who knows...


  • Interesting posts from Compiere forums
Take over Compiere you need Albert

OpenBravo

Open Compiere

Tina POS


Weak sides


Questions and Answers

HTML/CSS



Tips for Ste design

J2EE


Java related






Hibernate

  • Hibernate Synchronizer Eclipse plig-in which automatically generate java code when your hibernate mapping files are modified.


JPA

Dynamic model; Adding columns runtime


Data/Properties Binding


Bean Validation

Java Tips

  • Iterating through entries of Map or EntrySet
// Assuming map = Map<String, String>
for (Iterator iter = map.entrySet().iterator(); iter.hasNext();)
{ 
    Map.Entry entry = (Map.Entry)iter.next();
    String key = (String)entry.getKey();
    String value = (String)entry.getValue();
}


Frameworks

WidgetServer is a component based, server-side, Java/XML rich-client-framework which enables an application to run as either

- an application with a rich Web client based on AJAX (HTML, XML, CSS, Javascript)
- an application with a simple Web client based on HTML and CSS
- a standalone application with a Swing GUI,
- a client/server application with a thin Swing client,
- or a mobile application on different devices like PDAs or Smartphones


Struts


Design Patterns, Design metrics

  • JDepend JDepend traverses Java class file directories and generates design quality metrics for each Java package. JDepend allows you to automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to manage package dependencies effectively.

Java and IM


IRC


IRC Articles

Java Content Repository API


Autocompletion


CI - Continuous Integration


Dependency Injection


Java Graph/Report packages

  • Linguine MapsProvides clean object-oriented diagramming API for graph visualization. It visualizes Apache Ant files, Hibernate and Apache Object Relational Bridge mapping files, DTD's for XML and more.
  • Graphviz - Graph Visualization Software

Java GUI


Java GUI Libraries

UFace


SWT

  • SWT SnippetsSnippets are minimal stand-alone programs that demonstrate specific techniques or functionality

DMS - Document Management Systems

CMS - Content Management Systems

Eclipse IDE and Application build on Eclipse


Eclipse Easy Shell plugin

gnome-terminal --working-directory {1}
  • Seetings for windows
cmd.exe /C start /D{1} cmd.exe /K "rxvt.exe -fn "Console" -vb +sb -sl 1000 -e bash -I"

Script Languages


Eclipse plugin

Java FTP Libraries and Articles


Posts regarding FTP and SSL


Commercial which support FTPS (FTP Over SSL)

OpenXava hints

  • Naming convention
    • Utility classes are in org.openxava.util package.
    • An utility class must be in plural and its methods have to be static.
    • Example utility class: For dates called Dates.


OpenXava User hints

Hint.1 How do to search in detail mode?

Click on 'new', fill the fields, and click on 'Search'.


OpenXava Developer hints

Hint.1 Always use different properties names

Let's have component Organization

<component name="Organization">
	<entity>
		<property name="orgId" type="String" key="true" hidden="true" >
			<default-value-calculator class="org.openxava.calculators.UUIDCalculator" on-create="true" />
		</property>
		<property name="orgName" type="String" size="30" required="false"/>
...
</component>

and component Warehouse

<component name="Warehouse">
	<entity>
		<property name="warehouseId" type="String" key="true" hidden="true" >
			<default-value-calculator class="org.openxava.calculators.UUIDCalculator" on-create="true" />
		</property>
		<property name="warehouseName" type="String" size="30" required="false"/>
...
</component>

by this way in Application_en.properties developer can define different names for properties:

organizationId=Organization ID
orgName=Organization Name
warehouseId=Warehouse ID
warehouseName=Warehouse Name

also it helps developer to understand well which exactly property he uses/modify.

Hint.2 Always create by hand DB migration scripts.

ORM(Hibernate) tools do not create proper DB migration scripts.

OpenXava Links & Info

  • OpenXava Wiki page
  • qaProjectManager Web based application used for keeping track of engineering and customer releases, Resource allocations and related information effectively in QA Projects. Powered by openXava.
  • Nice to have OpenXava features:
    • Icon in header of each column indicating that column can be sorted.
    • When hook over header of column to show more information for column. Information to be configured in OpenXava xml files.
    • Ability to align labels in forums.


==========================================================================================
                                                                  +----------------------+
                                                          Actions:|1.- Pick              |
                                                                  |2.- Edit              |
                                                                  |3.- Copy              |
                                                                  |4.- Delete            |
                                                                  |5.- See (Detail mode) |
                                                                  +----------------------+
                                                                  |A.- Detail of Subjects|
     +--------+-----+------------------------+----------------+   |B.- Send e-mail       |
     | ACTION |  ID | Pupil                  | Comments       |   |C.- Print curriculum  |
     +--------+-----+------------------------+----------------+   |D.- etc...            |
     |   A    |  1  | Eduard Escrihuela      | Firt pupil     |   +----------------------+
     +--------+-----+------------------------+----------------+
     |   C    |  2  | Enric Selfa            | Second pupil   |
     +--------+-----+------------------------+----------------+
     |  ..    | ..  | ..                     | ...            |
                                                                       +-----------------+
                                                                       | EXECUTE ACTIONS |
                                                                       +-----------------+
==========================================================================================

You can see to the left a grid whith the LIST mode of the PUPILS and the FIRST field is the ACTION to apply to the records. The A action (Detail of subjects of this pupil) is selected for the first pupil and the B action (Printing of his curriculum) is selected for the second pupil.

The actions possible are detailed in the combo on the TOP RIGHT of the window. Options 1 to 5 are standard (always available by default). The rest of actions are specific to the model .

Finally there is a button for executing ALL the actions at the same time.

The default actions are:

1.-Pick: For instance to select a Customer for a invoice. By using this action you choose your customer and return to previous model (invoice)

2.- Edit: To modifiy the record

3.- Copy: To create a new record but previously copying the information of an existing record that is very similar to the new one

4.- Delete: to delete the record

5.- See: To see the record in detail mode and READ ONLY

OpenXava Q & A

Created an entity ticketClass with a method GenerateTickets. Implemented the calculator using an IModelCalculator class.

Want to create a button/link when ticketClass is displayed so that user click on it the method gets executed.


Q.1 How do I set this up?

  • A1. Have to create an action and include it in the controller of your module.

In this action, you can obtain the object and call to you method, something like this:

public void execute() throws Exception {
  ...
  TicketClass ticketClass = (TicketClass) MapFacade.findEntity(getModelName(), getView().getKeyValues());
  ticketClass.generateTickets();
  getView().findObject(); // This refresh the view (Q2)
  ...
}


Q.2 How can I get the view of the entity refreshed after the method is executed.

  • A2. See the above code


Q.3 How can i reload other modules to reflect the changes made by an action that was performed in one module?

An action in one module (module A) that changes the value of the data contained in another module (module B), when i execute an action button (in module A), it executes successfully and updates the data in the other entity (entity B) in the database, but when i view module B, the module list view (of module B) is still showing the old data!

  • A3. In a Liferay 2.1.3 with OX2.2 it works fine, that is, I modify data in a portlet, I move to another and the data

is refreshed without touch filter nor any other action. Look at your web/WEB-INF/portlet.xml, have you <expiration-cache>0</expiration-cache> for your portlets? Since OX2.1 expiration-cache is 0 in the portlet.xml generated by OpenXava. Hence, if you are using OX2.1 or better you only need to execute the ant target 'redeployPortlets' in order to fix your portlet.xml file.


Q.4 How to avoid warnings that messages are not translated

  • A4.

This messages warn you about the labels that you need to put in your i18n/YourProyectName-labels_en.properties. Developer can avoid this messages putting the next line:

i18nWarnings=false

in the file properties/xava.properties of your project.


Q.5 Example TestCase

public class ExampleTest extends ModuleTestBase { 
 
  public DepartmentsTest(String testName) { 
  
  super(testName,"ExampleManager", "ExampleModlue");
  } 
  
  public void testCreateReadUpdateDelete() throws Exception { 
  
    //Test Create
    execute("CRUD.new");
    setValue("id", "ENG");
    setValue("name", "Example Name");
    setValue("description", "Example description");
    assertNoErrors();
  } 
}


Q.6 How to provide a web API for accessing the OpenXava application?

Just use Web Services. The OpenXava applications are standard Java Web applications, therefore you can use any Java API from your OpenXava application.

In this case you can create a simple Java class, with the services of you application that you want to expose. And use from it MapFacade or the model objects generated by OpenXava, or whatever code of your application you want. Something like this:

public class MyService {

  public Address getCustomerAddress(String customerId) throws Exception {
    // Here you use the POJOs generated by OpenXava
    Customer customer = (Customer) Customer.findById(customerId);
    return customer.getAddress();
  }
}

Now you can create a Web Service from MyService class using AXIS, or the wizard included in Eclipse WTP. But, remember, all this is a Java issue, not an OpenXava one.


Q.7 Magic numbers

It is possible to define some magic numbers in OX? The Environment Variables are not enough. I want to use the magic numbers in components.

  • A7. Use standard techniques for Java and XML.

In Java you can use "public final static" variables:

public class MyMagicNumbers {
  public final static int MY_MAGIC = 24324;
}

In XML you can use XML ENTITIES:

<!ENTITY mymagic "24324">

and then use &mymagic; instead of 34324.

These techniques are not from OpenXava but from Java and XML.

In XML you can use @mymagic@, and the filter of OpenXava ant build changes it from a value of your properties file. This allows you to have a different value of @mymagic@ for each customer or configuration. This is a technique from OpenXava.


Q.8 How to access EJB from OpenXava

  • Reference Guide section 3.14.
  • There is a example of using a EJB inside validator.
  • Developer can access EJB code in any part of OpenXava applications, for example:
Delivery delivery = DeliveryUtil.getHome().findByNumber(33);
delivery.generateInvoice();


Q.9 Access rights depending on the user profile

  • sf.net thread
  • User should only see fields or to execute actions depending on his user profile (or role).
  • Certain users to be able to update certain fields while others may only read them.


1. Option - provided by the container portal

  • Create two groups of users:
    • First with create-delete-edit rights.
    • Second only with read rights.
  • Define two modules(portlets):
    • First with CRUD controller.
    • Second with Print controller.

The admin may assign First or Second module (portlet) for each group of users with the portal administrative tools.

2. Option

Not completly implemented in OpenXava, but there are some useful tools in OX that can help:

  • Users.getCurrent() return the current user if application is started in portal. This value may be used in any point of the code.
  • Filters: filters the data displayed in the mode list according to the current user.

A full management of users in OX project implies creation of several modules for storing the info about users, interfaces for change rights and create new users, roles and rights, overwrite standard controllers, to write new actions (typically "save" action, frequently "new" action too), to write specific validator, to write filters for tabs in list mode, and more...

Javier's opinion: I think that part of this stuff can be moved to a new project, instead of be included in OX core. This new project would manage access rights and user profiles, and will be reusable for other projects.

Links


Q.10 Property displayed as Radio button

  • Existing test case: CustomerWithRadioButtons
  • Section 4.7 of reference guide shows how editors are full configurable in OpenXava.
  • /components/SomeComponent.xml file
<entity>
  <property name="gender" >
	<valid-values>
		<valid-value value="Male"/>
		<valid-value value="Female"/>
	</valid-values>
  </property>
</entity>
<view>
  <property-view property="gender" editor="ValidValuesRadioButton"></property-view>
  <members >
    name;
    gender;
  </members >
<view>
  • OpenXava/xava/default-editors.xml contains definition of:
    • ValidValuesRadioButton
<editor name="ValidValuesRadioButton" url="radioButtonEditor.jsp">
	<property name="horizontal" value="true" />
</editor>
    • ValidValuesVerticalRadioButton
<editor name="ValidValuesVerticalRadioButton"
	url="radioButtonEditor.jsp">
	<property name="horizontal" value="true" />
</editor>
    • ValidValuesHorizontalRadioButton
<editor name="ValidValuesHorizontalRadioButton"
	url="radioButtonEditor.jsp">
	<property name="horizontal" value="true" />
</editor>

It looks both last have the same value for horizontal request parameter <property name="horizontal" value="true" />. Probably this is a mistake.


Q.11 OpenXava design

  • All model classes implement org.openxava.model.IModel interface:
/**
 * Interface to be implemented by all model classes. <p>
 * 
 * The model classes may be EntityBeans EJB 2 or POJOs (for JDO, EJB3 or Hibernate).
 * 
 * @author Javier Paniza
 */
public interface IModel {
	
	/**
	 * Returns metadata about object. <p>
	 * 
	 * @return  Not null.
	 * @exception XavaException  Any problem related to OpenXava.
	 * @exception RemoteException  System problem.
	 */
	MetaModel getMetaModel() throws XavaException, RemoteException;

}


Q.12 How to get logger

OpenXava uses Apache Commons Loggin

private static Log log = LogFactory.getLog(Users.class);


Q.13 Using the <transient> tag

Section 4.10 of Reference guide says:

"put <transient/> at the end of the component definition (1), just in the part for the mappings"

Make sure you write the following:


<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE component SYSTEM "dtds/component.dtd">
<component name="YourComponent">
     <entity>
         ...
     </entity>
     ...
     <transient/>   <!--If you put it anywhere else you will see error in the
document-->
</component>


Q.14 Search criteria customization in List mode

Requirement: The user writes his search criteria (Type employee salary for example) and then presses the search button.

Create a module that start in detail mode. Use a view that show just the data for filtering.

Define a controller with your "Search" actions, and in this action change to list mode.

In this way you can achieve your goal.

Read the chapters 7 and 8 of Reference Guide.


Q.15 How to change Action view from link to button?

1. Create a new property called 'buttonsForNoImageActions' (or so), for use in xava.properties.

2. Add the property in the class XavaPreferences.

3. Modify the class ActionTag.

By default, buttonsForNoImageActions must be 'false', in order to not change the current OX behavior (by default).


Temporary solution. Change actionEditor.jsp

- <xava:link action="<%=p.getAction()%>"/> 
+ <xava:button action="<%=p.getAction()%>"/> 


Q.16 How to open/goto custom jsp?

DECLARATIVE jsp navigation, as following:

<action name="goToMyJSP" class="org.openxava.actions.NavigationAction">				
  <set property="customView" value="mypage.jsp"/>
  <set property="nextController" value="MyController"/>
</action>				

In general, action classes can be made reusable, and can be configured in controllers.xml. In this way can do more configuration and less programming.


Q.17 How to make a property as a NOT persistent or view only field in the entity element?

Yes, it's possible.

Two options:

Option 1. Calculated properties (section 3.8.4 of reference guide)

It is possible to use qualified properties!

<component name="Engagement">
	<entity>
...
<property name="cmpContactName" type="String" size="60" >
	<calculator class="org.openxava.calculators.StringCalculator" > 
		<set property="string" from="cmpContact.compName.custCompName"/> 
	</calculator>
</property>
...
</component>

No need to create special Calculator!

<component name="Engagement">
	<entity>
...
<property name="cmpContactName" type="String" size="60" >
	<calculator class="bg.d3soft.openxava.calculators.CompanyContactNameCalculator" >
	</calculator>
</property-->
...
</component>


Option 2. View properties (section 4.5 of reference guide)

View properties are used for the case that you want to have something editable in the view, but you do not want to save it in DB. View properties do not have same functionality as properties. That's why this behavior is normal. For some reason view property do not show the same result:

<component>
...
<view>
	<property name="cmpContactName" type="String" size="60" >
		<calculator class="org.openxava.calculators.StringCalculator" > 
			<set property="string" from="cmpContact.compName.custCompName"/> 
		</calculator>
	</property>
...
</view>
</component>


Q.18 How to implement Wizard form

First consider seriously to use a single view with several sections. This is more flexible in most cases and easy to implement with OpenXava.

Steps: Your action for navigate must implements IChangeControllersAction, this allows you to change the actions to show in each page, and using

getView().setViewName( ... );

inside execute() of your action, you can change the view in each step.

Look at the Reference Guide and OpenXavaTest for IChangeControllersAction, and also for INavigationAction.


Q.19 How to forward to a JSP

Action obtains two values which are important for the JSP.

Create a IForwardAction with a code like:

 
public String getForwardURI() { 
    return "/mypage.jsp?a=" + getA() + "&b=" + getB(); 
}

And put mypage.jsp in the 'web' folder of your project.


Q.20 How to change order of error messages?

Method 'validate' of MapFacadeBean:

private void validate(Messages errors, MetaModel metaModel, Map values, Map
keyValues, Object containerKey, boolean creating)
		throws XavaException, RemoteException {		
		Iterator it = values.entrySet().iterator();		
		while (it.hasNext()) {
			Map.Entry en = (Map.Entry) it.next();
			String name = (String) en.getKey();
			Object value = en.getValue();
			validate(errors, metaModel, name, value, creating);
		}
		if (metaModel.containsValidadors()) {
			validateWithModelValidator(errors, metaModel, values, keyValues,
 containerKey,
creating);
		}
	}

In this case the loop is over entrySet of a Map, hence the order is unknown. You can modify this method in order to work by the correct order, some method of MetaModel returns the member names in order of declaration.

Q.21 How to disable the icon in the corner most column in column arrangement view?

Modify list.jsp.


Q.22 How to open custom JSP view in a pop up window?

Is it possible to open custom JSP view in a pop up window?

No. The custom JSP must be inside the module. Use IForwardAction that has a method (inNewWindow()) for create a pop up windows. You can put your JSP in a public folder, and send the parameters for this jsp using OX session objects.

Q.23 How to hide/show view section depending on user rights?

Some users must be able to see given section from the view while other users must NOT be able to see this section.

At the moment developer can hide (using View.setHidden) members and groups, but not sections.

There are 4 (at least) options:

  • Use OpenXava/src/org.openxava.view.View.setSectionEditable.
  • Put your sensible data in a group, and hide/show it.
  • Create 2 views (one with the critical section, another without it).
  • Modify OpenXava to allow to hide programatically sections.


  • Which class should change view or hide section?
    • SEARCH_ACTION and 'new' Action are good places.
    • Other options as in an on-each-request action, or an on-init action.


  • Guide how to develop option 4?
    • Look at OpenXava/src/org.openxava.view.View.setHidden method.

Q.24 How to display only label in view?

Use a property of the view with stereotype LABEL.

<view>
  <property name="selectLabel" stereotype="LABEL" type="String" >
  </property>
  <members>
     selectLabel;
     a;
     b;
  </members>
</view>

File Application_en.properties must contain translation of property:

selectLabel=Select at least one:


Another option may be to have a property with no content and 'Select at least one:' as label.

File: xava/editors.xml

<?xml version = "1.0" encoding = "ISO-8859-1"?>
<!DOCTYPE editors SYSTEM "dtds/editors.dtd">
<editors>
	<editor url="void.jsp">
		<for-stereotype stereotype="VOID" />
	</editor>
</editors>

Create empty file: web/xava/editors/void.jsp


Difference is only in stereotype:

<view>
  <property name="selectLabel" stereotype="VOID" type="String">
  </property>
  <members>
     selectLabel;
     a;
     b;
  </members>
</view>


Q.25 How to make property required from Action?

Make a property 'X' required depending on the value of other property 'A'. If property 'A' has value 111 than property 'X' must became required.

<property-view property="A">
    <on-change class="bg.d3soft.openxava.actions.OnChangeA"/> 
</property-view>
  • Use a validator for property X (reference guide 3.8.6), and inject in the validator the property A (using <set />).
  • Use a model level validator (section 3.16).

You cannot change the state of a property from 'required' to 'not required' at runtime (well, you can, but you shouldn't), because required is a feature of the model, not of a view. You can access to the MetaModel at runtime and change the value of required, but if you do it in this way the value will be change for all modules, and all users at the same time, because you are modifying the meta data of the model.


Q.26 How to display property of a reference?

View properties are used for the case that you want to have something editable in the view, but you do not want to save it in DB.

  • If property must be read only than use a calculated property.
  • If property must be editable than:

Use a property of the view, populate it in the code in SEARCH_ACTION, and save its content in your own Save action.


Q.27 How to add EMAIL stereotype and validation class

Will be part of OpenXava 2.2.3! sf.net post

1) Add to Application/xava/default-size.xml

<for-stereotype name="EMAIL" size="50"/>


2) Add to Application/xava/editors.xml

<editor url="textEditor.jsp">
  <for-stereotype stereotype="EMAIL"/>
</editor>


3) Add to Application/xava/stereotype-type-default.xml

<for stereotype="EMAIL" type="String"/>


4) Add to Application/i18n/messages_en.properties file

email_validation_error={0} must be a valid email address


5) Validation class

package org.openxava.validators;

import org.openxava.util.*;
import org.openxava.validators.IPropertyValidator;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class EmailValidator implements IPropertyValidator {

    Pattern pat=Pattern.compile(".+@.+\\.[a-z]+");

    public void validate(Messages errors, Object value, String propertyName,
String modelName) throws Exception {

        if (value == null || value.toString().length() ==0 ) return;
        Matcher matcher = pat.matcher(value.toString());
        if (! matcher.find()) {
           errors.add("email_validation_error", propertyName);
           return;
        }
    }
}


5.1) Second version of Validator class using Apache Commons validator

import org.apache.commons.validator.GenericValidator;
import org.openxava.util.Messages;
import org.openxava.validators.IPropertyValidator;

/**
 * @author Janesh Kodikara
 */
public class EmailValidator implements IPropertyValidator {

    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {

        if (value == null || value.toString().length() == 0) 
          return;

        if (! GenericValidator.isEmail(value.toString())) {
            errors.add("email_validation_error", propertyName);
            return;
        }
    }
}


Q.28 How to translate OpenXava

For example to Bulgarian (bg).

  • Copy OpenXava/i18n/Labels_en.properties to OpenXava/i18n/Labels_bg.properties.
  • Copy OpenXava/i18n/Messages_en.properties to OpenXava/i18n/Messages_bg.properties.

Translate Labels_bg.properties and Messages_bg.properties!

Thread which can be useful: here


Q.29 How to translate application based on OpenXava

For example to Bulgarian (bg).

  • Copy <ApplictionName>/i18n/Labels_en.properties to <ApplictionName>/i18n/Labels_bg.properties.
  • Copy <ApplictionName>/i18n/Messages_en.properties to <ApplictionName>/i18n/Messages_bg.properties.

Translate Labels_bg.properties and Messages_bg.properties!

Thread which can be useful: here


Q.30 How to add PASSWORD stereotype

1) Create new file in Application/web/xava/editors/passwordEditor.jsp

<%@ page import="org.openxava.model.meta.MetaProperty" %>
<%@ page import="org.openxava.util.Strings" %>
<%@ page import="org.openxava.util.Align" %>

<jsp:useBean id="style" class="org.openxava.web.style.Style" scope="request"/>

<%
String propertyKey = request.getParameter("propertyKey");
MetaProperty p = (MetaProperty) request.getAttribute(propertyKey);
String fvalue = (String) request.getAttribute(propertyKey + ".fvalue");
String align = p.isNumber()?"style='text-align:right'":"";
boolean editable="true".equals(request.getParameter("editable"));
String disabled=editable?"":"disabled";
String script = request.getParameter("script");
boolean label = org.openxava.util.XavaPreferences.getInstance().isReadOnlyAsLabel();
String smaxSize = request.getParameter("maxSize");
int maxSize = 0;
if (!org.openxava.util.Is.emptyString(smaxSize)) {
	maxSize = Integer.parseInt(smaxSize);
}
else {
	maxSize = org.openxava.util.XavaPreferences.getInstance().getMaxSizeForTextEditor();
}
int size = p.getSize() > maxSize ? maxSize : p.getSize(); 

/*
boolean fillWithZeros = "true".equals(request.getParameter("fillWithZeros"));
if (fillWithZeros && fvalue.length() > 0) {	
	fvalue = Strings.fix(fvalue, size, Align.RIGHT, '0');
}
*/

if (editable || !label) {
%>
<input name="<%=propertyKey%>" class=<%=style.getEditor()%>
	type="password" 
	title="<%=p.getDescription(request)%>"
	<%=align%>
	maxlength="<%=p.getSize()%>" 
	size="<%=size%>" 
	value="<%=Strings.change(fvalue, "\"", """)%>"
	<%=disabled%>
	<%=script%>
	/>
<%
} else {
%>
<%=fvalue%> 
<%
}
%>
<% if (!editable) { %>
	<input type="password" name="<%=propertyKey%>" value="<%=fvalue%>">
<% } %>			


2) Add to Application/xava/editors.xml

<editor url="passwordEditor.jsp">
  <for-stereotype stereotype="PASSWORD"/>
</editor>


3) Add to Application/xava/Stereotype-type-default.xml

<for stereotype="PASSWORD" type="String"/>


4) Example usage Application/components/Employee.xml

<component name="Employee">
  <entity>
...
    <property name="empPassword" stereotype="PASSWORD" size="20" required="true"/>
...


Q.31 How to develop import functionality

1) Create new file in Application/web/xava/editors/loadCSVFile.jsp

<%@ include file="../imports.jsp"%>

<jsp:useBean id="style" class="org.openxava.web.style.Style" scope="request"/>

<table>
<th align='left' class="<%=style.getLabel()%>">
<xava:message key="enter_new_csv_file"/>
</th>
<td>
<input name = "newCsvFile" class=<%=style.getEditor()%> type="file" size='60'/>
</td>
</table>


2) Add new class to Application/src/bg/d3soft/openxava/actions/LoadCSVFileAction.java

package bg.d3soft.openxava.actions;

import org.openxava.actions.BaseAction;
import org.openxava.actions.ILoadFileAction;

public class LoadCSVFileAction extends BaseAction implements ILoadFileAction {
	
	private String newCsvFileProperty;	
	
	
	public void execute() throws Exception {
		
	}
	
	public String[] getNextControllers() {
		return new String [] { "ImportCSVFile" };
	}

	public String getCustomView() {
		return "xava/editors/loadCSVFile";
	}

	public boolean isLoadFile() {
		return true;
	}

	public String getNewCsvFileProperty() {
		return newCsvFileProperty;
	}

	public void setewCsvFileProperty(String string) {
		newCsvFileProperty = string;
	}
}


3) Add new class to Application/src/bg/d3soft/openxava/actions/ImportCsvFileAction.java

package bg.d3soft.openxava.actions;

public class ImportCsvFileAction extends BaseAction implements INavigationAction, IProcessLoadedFileAction {
	
	private static Log log = LogFactory.getLog(ImportCsvFileAction.class);
	
	private List fileItems;
	
	private View view;
	
	private String newCsvFileProperty;
	
	public void execute() throws Exception {		
		Iterator i = getFileItems().iterator();
		while (i.hasNext()) {
			FileItem fi = (FileItem)i.next();
			String fileName = fi.getName();
			log.info("fileName = [" + fileName + "]");
			
			if (!Is.emptyString(fileName)) {
				//getView().setValue(getNewCsvFileProperty(), fi.get());
				log.info("getNewCsvFileProperty = [" + getNewCsvFileProperty() + "]");
				log.info("fi.getSize() = [" + fi.getSize() + "]");
				
				ImportUtil impUtil = new ImportUtil();
				impUtil.importCustomerCompanyFromCSV(fi);
			}			
		}		
	}

	public String[] getNextControllers() {		
		return DEFAULT_CONTROLLERS;
	}
	public String getCustomView() {		
		return DEFAULT_VIEW;
	}
	public View getView() {
		return view;
	}
	public void setView(View view) {
		this.view = view;
	}
	public String getNewCsvFileProperty() {
		return newCsvFileProperty;
	}
	public void setNewCsvFileProperty(String string) {
		newCsvFileProperty = string;	
	}
	public List getFileItems() {
		return fileItems;
	}
	public void setFileItems(List fileItems) {
		this.fileItems = fileItems;
	}
}


4) Add to Application/i18n/Application-labels_en.properties

loadCSVFile=Import CSV File
importCSVFile=Import CSV File


5) Add to Application/i18n/Application-messages_en.properties

enter_new_csv_file=Enter CSV File


6) Add new class to Application/src/bg/d3soft/openxava/actions/LoadCSVFileAction.java



7) Add to Application/xava/controllers.xml

<?xml version = "1.0" encoding = "ISO-8859-1"?>
<!DOCTYPE controllers SYSTEM "dtds/controllers.dtd">
<controllers> 
...	
	<object name="xava_newCsvFileProperty" class="java.lang.String"/>
...
	<controller name="LoadCSVFile">
		<action name="loadCSVFile"
			class="bg.d3soft.openxava.actions.LoadCSVFileAction"
			hidden="false"
			mode="detail"
			image="images/db_update.png"
		>
			<!-- set value="" property=""/-->
			<!-- use-object name="xava_newCsvFileProperty"/-->
		</action>
		
	</controller>
	
	<controller name="ImportCSVFile">
		<action name="importCSVFile"
			class="bg.d3soft.openxava.actions.ImportCsvFileAction"
			hidden="false"
			mode="detail"
		>
			<use-object name="xava_view"/>
			<use-object name="xava_newCsvFileProperty"/>
		</action>
		
		<action name="cancel"
			class="org.openxava.actions.CancelAction">			
		</action>
	</controller>
...
</controllers>


8) Add to Application/web/xava/images/db_update.png


9) Example usage Application/xava/application.xml

...
	<module name="CustomerCompanies">
		<model name="CustomerCompany" />
		<controller name="TypicalNotResetOnSave" />
		<controller name="LoadCSVFile" />
	</module>
...


10) Example csv file

"Date Created","Name","Web Address","Corp Location"
"ERROR","CustCompName-5","www.web005.com","Corp. location-5"
"ERROR","CustCompName-6","www.web006.com","Corp. location-6"
"ERROR","CustCompName-7","www.web007.com","Corp. Location-7"


Q.32 How to create formatter for java.util.Date

Option A - Create your own formatter (IFormatter) =

Create your own formatter (IFormatter) and assign it to the java.util.Date type in editors.xml of your project.

OpenXava version 2.2.2 OpenXavaTest/xava/editors

<editor name="DateCalendar" url="dateCalendarEditor.jsp"> 
  <formatter class="org.openxava.formatters.DateFormatter" /> 
  <for-type type="java.util.Date" /> 
</editor>


Option B - Modify DateFormatter (and DateTimeFormatter) of OpenXava

Look at DateFormatter (and DateTimeFormatter) of OpenXava. They are tuned for work better for Spanish and Polish.

Changes in the DateFormatter and in the DateTimeFormatter.

In DateFormater added:

private static DateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy"); // modified
private static DateFormat spanishDateFormat = new SimpleDateFormat("dd/MM/yyyy");
	
private static DateFormat [] spanishDateFormats = {
	spanishDateFormat,
	germanDateFormat, // modified
	new SimpleDateFormat("ddMMyyyy"),
	new SimpleDateFormat("dd.MM.yyyy"),		
};	

In method getDateFormat(HttpServletRequest request)

if ("de".equals(request.getLocale().getLanguage())) return germanDateFormat; // modified

In DateTimeFormatter added:

private static DateFormat germanDateFormat = new  SimpleDateFormat("dd.MM.yyyy"); //modified

In the method getDateFormat(HttpServletRequest request)

if ("de".equals(request.getLocale().getLanguage())) return germanDateFormat; // modified


full source code of Formatter:

import java.text.*;

import javax.servlet.http.*;

import org.openxava.util.*;
import org.openxava.formatters.*;

public class GermanDateFormatter implements IFormatter {
	
	private static DateFormat germanDateFormat = new SimpleDateFormat("dd.MM.yyyy");
	private static DateFormat spanishDateFormat = new SimpleDateFormat("dd/MM/yyyy");
	
	private static DateFormat [] spanishDateFormats = {
		spanishDateFormat,
		germanDateFormat,   
		new SimpleDateFormat("ddMMyyyy"),
		new SimpleDateFormat("dd.MM.yyyy"),		
	};	
	
	public String format(HttpServletRequest request, Object date) {
		if (date == null) return "";
		if (Dates.getYear((java.util.Date)date) < 2) return "";
		return getDateFormat(request).format(date);
	}
		
	public Object parse(HttpServletRequest request, String string) throws ParseException
{
		if (Is.emptyString(string)) return null;
		if (string.indexOf('-') >= 0) { // SimpleDateFormat does not work well with -
			string = Strings.change(string, "-", "/");
		}		
		DateFormat [] dateFormats = getDateFormats(request); 
		for (int i=0; i<dateFormats.length; i++) {
			try {
				return dateFormats[i].parseObject(string);
			}
			catch (ParseException ex) {
			}						
		}
		throw new ParseException(XavaResources.getString("bad_date_format",string),-1);
	}
	
	private DateFormat getDateFormat(HttpServletRequest request) {
		if ("de".equals(request.getLocale().getLanguage())) 
                  return germanDateFormat;
		if ("es".equals(request.getLocale().getLanguage()) ||
		    "pl".equals(request.getLocale().getLanguage())
                ) 
                  return spanishDateFormat;
		return DateFormat.getDateInstance(DateFormat.SHORT, request.getLocale());		
	}
	
	private DateFormat[] getDateFormats(HttpServletRequest request) {
		if ("es".equals(request.getLocale().getLanguage()) ||
                    "de".equals(request.getLocale().getLanguage()) ||
		    "pl".equals(request.getLocale().getLanguage())
                ) 
                  return spanishDateFormats;
		return new DateFormat [] { getDateFormat(request) };
	}
}


Q.33 Possible properties in Application/properties/xava.properties

Java class responsible for loading xava.properties: org.openxava.util.XavaPreferences

Since version > 2.2.2.

User can hide/show the filter part on init in list and collections.

showFilterByDefaultInList=true
showFilterByDefaultInCollections=true


Since version 2.2.1.

Users.getCurrent() returns the user email instead of the user id inside a portal.

emailAsUserNameInPortal=true|false(false)
readOnlyAsLabel=true|false(false)
tabAsEJB=true|false(false)
showCountInList=true|false(true)  - avoid the initial select count(*) in the model list. It takes time when number of rows is big.
formLineSpacing=integer(1)
csvSeparator=character(;)
persistenceProviderClass=String(org.openxava.model.impl.HibernatePersistenceProvider)org.openxava.model.impl.EJBPersistenceProvider
mapFacadeAsEJB=true|false(false)
detailOnBottomInCollections=true|false(false)
jpaCodeInPOJOs=
i18nWarnings=true|false(true)
duplicateComponentWarnings=true|false(true)
failOnAnnotationMisuse=true|false(true)
maxSizeForTextEditorinteger(100)
javaLoggingLevel=String(INFO);FINEST|INFO
hibernateJavaLoggingLevel=String(INFO);FINEST|INFO

How to access Xava Properties from jsp file?

<%
boolean label = org.openxava.util.XavaPreferences.getInstance().isReadOnlyAsLabel();
%>


Q.34 How to add WEBURL stereotype and validation class

Will be part of OpenXava 2.2.3! sf.net post

1) Add to Application/xava/default-size.xml

<for-stereotype name="WEBURL" size="50"/>

2) Add to Application/xava/editors.xml

<editor url="textEditor.jsp">
  <for-stereotype stereotype="WEBURL"/>
</editor>

3) Add to Application/xava/stereotype-type-default.xml

<for stereotype="WEBURL" type="String"/>

4) Add to Application/i18n/messages_en.properties file

url_validation_error={0} must be a valid url

5) Validation class

import org.openxava.util.*;
import org.openxava.validators.IPropertyValidator;
import org.apache.commons.validator.UrlValidator;

/**
 * @author Janesh Kodikara
 */
public class URLValidator implements IPropertyValidator {

    UrlValidator urlValidator = new UrlValidator();

    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {

        if (value == null || value.toString().length() == 0 ) 
          return;

        if ( !urlValidator.isValid(value.toString()) ) {
          errors.add("url_validation_error", propertyName);
        }
    }
}

6) Add following jar files

A) jakarta-oro-2.0.8.jar http://jakarta.apache.org/site/downloads/downloads_oro.cgi?Preferred=http%3A%2F%2Fgovernment-grants.org%2Fmirrors%2Fapache.org

B) commons-validator-1.3.1.jar http://commons.apache.org/downloads/download_validator.cgi


Q.35 How to add TELEPHONE stereotype and validation class

Will be part of OpenXava 2.2.3! sf.net post

1) Add to Application/xava/default-size.xml

<for-stereotype name="TELEPHONE" size="15"/>

2) Add to Application/xava/editors.xml

<editor url="textEditor.jsp">
  <for-stereotype stereotype="TELEPHONE"/>
</editor>

3) Add to Application/xava/stereotype-type-default.xml

<for stereotype="TELEPHONE" type="String"/>

4) Add to Application/i18n/messages_en.properties file

phone_valid_number_error= {0} must be a valid number
phone_minimum_size_error= {0} must be at least  {2} {1} long

5) Validation class

package org.openxava.validators;

import org.openxava.util.*;
import org.openxava.validators.IPropertyValidator;

/**
 * @author Janesh Kodikara
 */
public class PhoneNumberValidator implements IPropertyValidator {
    private long minSize = 8;
    private Long phoneNumber;

    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {

        if (value == null || value.toString().length() ==0 ) 
          return;

        //Check if input is a number
        try {
          phoneNumber = new  Long(value.toString());
        } catch(NumberFormatException ex){
           errors.add("phone_valid_number_error", propertyName);
           return;
        }

        //Check if input length is at least greater than specified minimum length
        if ( phoneNumber.toString().length() < minSize) {
            errors.add("phone_minimum_size_error", propertyName, "digits", new Long(minSize));
            return;
        }
    }
    public long getMinSize() {
        return minSize;
    }
    public void setMinSize(long minSize) {
        this.minSize= minSize;
    }
}


Q.36 How to hide field/property

Section 3.8 of Reference Guide:

A hidden property has a meaning for the developer but not for the user.
The hidden properties are excluded when the automatic user interface is generated. 
However at Java code level they are present and fully functional. 
Even if you put it explicitly into a view the property will be shown in the user interface.

Hidden property is used mainly for hidden keys, but if you put the property in the view, the property will be show.

Example code:

When the user click 'Others' from languages combo box, the Others text field should be displayed. Entity part:

<!-- The Combo box -->
<property name="languages">
  <valid-values>
    ....
    <valid-value value="English"/>
    <valid-value value="Others"/>
  </valid-values> 
</property> 

The Others property:

<property name="otherLanguages" hidden="true" type="String" size="20"/>

View part:

<property-view property="languages"> 
  <on-change class="com.sami.actions.OnLanguagesChange"/> 
</property-view>

'OnLanguagesChange' action:

...
getView().setHidden("otherLanguages", false);
...

The action is perfect, when user choose the Others from the combo box, the Others text field displayed, but the problem is, that Others text field displayed when user request the form always (On the initial view).

Can not hide properties in the initial view, when user click any action the hidden properties disappear?!

The solution in this case is to refine the 'new' action and the 'search' action to hide the 'otherLanguage' property. But, before, try to define your module in this way:

<module name="YourModule"> 
  <env-var name="XAVA_SEARCH_ACTION" value="CRUD.searchExecutingOnChange"/> 
... 
</module> 

Look at section 7.6 of reference guide !


Q.37 How to set rows count in tab


Q.38 How to separate translations for each portlet

Source file which handle this: org.openxava.util.Labels

For properties in tabs, in i18n file (assuming there are ComponentFoo and ComponentBar, both with references to Example Component)

ComponentFoo.tab.properties.example.description=Example foo 
ComponentBar.tab.properties.example.description=Example bar 

For properties in detail mode:

ComnponentFoo.view.level=Level Foo 
ComnponentBar.view.level=Level Bar 

For properties which are part of view:

# CustomerContact tab inside Engagement
CustomerContact.views.CustomerContact.custName=Customer Name
CustomerContact.views.CustomerContact.custName[description]=Customer Name
CustomerContact.views.<View Name Here>.custName[description]=Customer Name

CustomerContact.tab.properties.custName=Customer Name
CustomerContact.tab.properties.custName[description]=Customer Name


Q.39 How to create custom JasperReport which uses JDBC connection to DB

Need returning null in the method getDataSource() of your JasperReport action (derived from JasperReportBaseAction).

public class EngagementReportAction extends JasperReportBaseAction {
...
protected JRDataSource getDataSource() throws Exception {
  return null;
}
...
}


Q.40 Since version 2.2.1 Calendar overlaps with Main Horizontal line of Portal

In order to change this behavior modify file OpenXava/web/script.jsp Old line:

97:   _dynarch_popupCalendar.showAtElement(el.nextSibling, "Br");        // show the calendar

New line

97:   _dynarch_popupCalendar.showAtElement(el.nextSibling, "tr");        // show the calendar

"tr" is need for IE6, for working fine when date fields are at the bottom of the page. Will be available in OX2.2.3 Correct one is:

  <% 
  // Date fields at end of the windows is not shown correctly in IE6,
  // hence, we align at top in IE6, and at botton in other browsers.
  String browser = request.getHeader("user-agent");
  String calendarAlign = browser != null && browser.indexOf("MSIE 6") >= 0 ? "tr" : "Br";  
  %>
  _dynarch_popupCalendar.showAtElement(el.nextSibling, "<%=calendarAlign%>"); // show the calendar


Q.41 How to filter by property of Reference?

All fields by which developer wants to make filtering MUST be described in 'properties' tag!

Example code:

<tab>
	<filter class="bg.d3soft.openxava.filters.UserFilter"/>
	<properties>custCrtdBy, engDealMkr.empLogonID, rptProMng.empLogonID</properties>
	<base-condition>${custCrtdBy} = ? or ${engDealMkr.empLogonID} = ? or ${rptProMng.empLogonID} = ?</base-condition>
	...
</tab>


Q.42 How to display confirmation message?

Confirmation message can be shown using the 'confirm' attribute of <action /> element in controllers.xml. Section 7.3 of reference guide.

This is a generic feature that can be applied to any action that show a JavaScript dialog to confirm the action. Given that it's generic (not only for list mode), it cannot revise if some item is selected (or any other condition). It simply ask before action to be execute.

A solution can be to define your list action using confirm=false, and then create your logic that move to other controller for confirmation before execute your definitive action, in this way you can control exactly your logic, but you will lost the agility of using a JavaScript dialog.


Q.43 Openxava and Cross Site Scripting (XSS)?


Q.44 How to use Identity Column?

Identity must be declared in DB as an auto increment column.

Hibernate will create proper DB script. When updateSchema Ant target is executed( on OpenXava project which uses hibernate), it will generates the correct SQL script. For example, if you are using AS/400 dialect, hibernate will generate a line like:

ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY

If in your OX componentes you write:

<property name="number" type="Integer" key="true" size="5" required="false">
	<default-value-calculator class="org.openxava.calculators.IdentityCalculator"
on-create="true"/>
</property>

OpenXava generates a .hbm.xml with the next content:

<id name="number" column="NUMBER" access="field" type='java.lang.Integer'
 length='5'>
	<generator class='identity'/>
</id>


Q.45 How to add IP stereotype and validation class

Will be part of OpenXava 2.2.4!

sf.net post

1) Add to Application/xava/default-size.xml

<for-stereotype name="IP" size="15"/>

2) Add to Application/xava/editors.xml

<editor url="textEditor.jsp"> 
  <for-stereotype stereotype="IP"/> 
</editor> 

3) Add to Application/xava/stereotype-type-default.xml

<for stereotype="IP" type="String"/> 

4) Add to Application/i18n/messages_en.properties file

ip_validation_error={0} must be a valid IP address

5) Validation class

package org.openxava.validators;

import org.openxava.validators.IPropertyValidator;
import org.openxava.util.Messages;
import org.apache.commons.validator.GenericValidator;

/**
 * @author Janesh Kodikara
 */
public class IPValidator implements IPropertyValidator {

    public void validate(Messages errors, Object value, String propertyName,
String modelName) throws Exception 
{

        String numberRegExp = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
        String ipRegExp = "\\b" + numberRegExp + "\\." + numberRegExp + "\\." +  numberRegExp +"\\." + numberRegExp + "\\b";

        if (value == null || value.toString().length() == 0) return;

        if (! GenericValidator.matchRegexp(value.toString(), ipRegExp)) {
            errors.add("invalid_ip_error", propertyName);
        }
    }
}


Q.46 How to add Reachable IP stereotype and validation class

Will be part of OpenXava 2.2.4 and 3.0beta5!

sf.net post

1) Add to Application/xava/default-size.xml

<for-stereotype name="IP" size="15"/>

2) Add to Application/xava/editors.xml

<editor url="textEditor.jsp"> 
  <for-stereotype stereotype="IP"/> 
</editor> 

3) Add to Application/xava/stereotype-type-default.xml

<for stereotype="IP" type="String"/> 

4) Add to Application/i18n/messages_en.properties file

ip_not_reachable={0} is Not Reachable

5) Validation class

package org.openxava.validators;

import org.openxava.validators.IPropertyValidator;
import org.openxava.util.Messages;
import org.apache.commons.validator.GenericValidator;

/**
 * @author Janesh Kodikara
 */
public class IPValidator implements IPropertyValidator {

    public void validate(Messages errors, Object value, String propertyName,
String modelName) throws Exception 
{

        if (value == null || value.toString().length() == 0) return;

        /*String address = "192.168.0.60";
        InetAddress addr = InetAddress.getByName( value );
        boolean isValidAddress = addr.isReachable(myTimeout);
        System.out.println(" Reachable " + isValidAddress);*/
        if (! GenericValidator.matchRegexp(value.toString(), ipRegExp)) {
            errors.add("ip_not_reachable", propertyName);
        }
    }
}

Q.47 How to avoid Warnings during Generate Portlet ant task?

Will be included in OX2.2.4!

Go to OpenXava/build.xml, and examine the target "generatePortletXml" ant task. It looks like:

<classpath> 
	<pathelement path="../OpenXava/bin"/>
	<fileset dir="../OpenXava/web/WEB-INF/lib"> 
		<include name="**/*.jar"/> 
	</fileset> 
	<fileset dir="web/WEB-INF/lib"> 
		<include name="**/*.jar"/>		
	</fileset>
...
</classpath>

Because we include ../OpenXava/bin and web/WEB-INF/lib that contains openxava.jar, the default-controllers.xml is duplicated in the path, then you get the warning.

Solution is just to exclude the openxava.jar from the classpath. Modify the build.xml of your OpenXava project.

<classpath> 
	<pathelement path="../OpenXava/bin"/>
	<fileset dir="../OpenXava/web/WEB-INF/lib"> 
		<include name="**/*.jar"/> 
	</fileset> 
	<fileset dir="web/WEB-INF/lib"> 
		<include name="**/*.jar"/>
		<exclude name="openxava.jar"/>
	</fileset>
...
</classpath>


Q.48 How to add ISBN stereotype and validation class

Will be part of OpenXava 2.2.4 and 3.0beta5!

sf.net post

1) Add to Application/xava/default-size.xml

<for-stereotype name="ISBN" size="13"/>

2) Add to Application/xava/editors.xml

<editor url="textEditor.jsp"> 
  <for-stereotype stereotype="ISBN"/> 
</editor> 

3) Add to Application/xava/stereotype-type-default.xml

<for stereotype="ISBN" type="String"/> 

4) Add to Application/i18n/messages_en.properties file

isbn_validation_error={0} must be a valid ISBN address

5) Validation class

package org.openxava.validators; 
 
import org.openxava.validators.IPropertyValidator;
import org.openxava.util.Messages;
/**
 *
 * @author Janesh Kodikara
 */

public class ISBNValidator implements IPropertyValidator {

    private  org.apache.commons.validator.ISBNValidator validator = new org.apache.commons.validator.ISBNValidator();

    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {

        if (value == null || value.toString().length() ==0 ) return;

        if (! validator.isValid(value.toString())) {
           errors.add("isbn_validation_error", propertyName);
        }
    }

}

Q.49 How to add Credit Card stereotype and validation class

Will be part of OpenXava 2.2.4 and 3.0beta5!

sf.net post

1) Add to Application/xava/default-size.xml

<for-stereotype name="CREDIT_CARD" size="19"/>

2) Add to Application/xava/editors.xml

<editor url="textEditor.jsp"> 
  <for-stereotype stereotype="CREDIT_CARD"/> 
</editor> 

3) Add to Application/xava/stereotype-type-default.xml

<for stereotype="CREDIT_CARD" type="String"/> 

4) Add to Application/i18n/messages_en.properties file

creditcard_validation_error={0} must be a valid Credit card number

5) Validation class

package org.openxava.validators;

import org.openxava.validators.IPropertyValidator;
import org.openxava.util.Messages;
import org.apache.commons.validator.GenericValidator;

/**
 * @author Janesh Kodikara
 */
public class CreditCardValidator implements IPropertyValidator {


    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {

        if (value == null || value.toString().length() == 0) return;

        if (! GenericValidator.isCreditCard(value.toString())) {
            errors.add("creditcard_validation_error", propertyName);
        }

    }

}

Q.50 How to add EMAIL_LIST stereotype and validation class?

Will be part of OpenXava 2.2.4 and 3.0beta5!

sf.net post

1) Add to Application/xava/default-size.xml

<for-stereotype name="EMAIL_LIST" size="200"/>

2) Add to Application/xava/editors.xml

<editor url="textEditor.jsp"> 
  <for-stereotype stereotype="EMAIL_LIST"/> 
</editor> 

3) Add to Application/xava/stereotype-type-default.xml

<for stereotype="EMAIL_LIST" type="String"/> 

4) Add to Application/i18n/messages_en.properties file

email_list_validation_error=Email list should contain valid emails separated by commas

5) Validation class

package org.openxava.validators;

import org.openxava.validators.IPropertyValidator;
import org.openxava.util.Messages;

import org.apache.commons.validator.GenericValidator;
import java.util.StringTokenizer;

/**
 * @author Janesh Kodikara
 */

public class EmailListValidator implements IPropertyValidator {

    public void validate(Messages errors, Object value, String propertyName, String modelName) throws Exception {


        if (value == null || value.toString().length() == 0) 
            return;

        StringTokenizer emailAddresses = new StringTokenizer(value.toString(), ",");
        while(emailAddresses.hasMoreTokens()) {
            if (! GenericValidator.isEmail(emailAddresses.nextToken())) {
                errors.add("email_list_validation_error", propertyName);
            }
        }
    }

}

Q.51 How to save model details when a action is called?

Is it possible to save model details when a action is called?

Yes.

An option is to make your action a child of SaveAction, and put the property resetAfter to false. Then you only need to:

public void execute() throws Exception {
  super.execute();
  // Here the code of you action.
}

Or you can save the data from the view directly using MapFacade.

Look at the code of SaveAction in order to learn how to use MapFacade.


Q.52 Converter for TIME stereotype.

Will be part of OpenXava 2.2.5.


  • By default, when you use "TIME" stereotype you want to work with String for manage time data, both at Java level and DB level. This case is:
  <property name="mytime" stereotype="TIME"/>


  • If you want to work with java.sql.Time usually you use the Java type directly, and you don't use TIME stereotype. In this way you use java.sql.Time for Java and DB. Code is:
  <property name=mytime" type="java.sql.Time"/>


  • New converter is only for the case that you want to work with String at Java level and with java.sql.Time at DB level:
  <property name="mytime" stereotype="TIME"/>
  ...
  <property-mapping ... >
    <converter class="org.openxava.converters.StringTimeConverter"/>
  </property-mapping>
  ...
  • New converter:
package org.openxava.converters;

import org.openxava.converters.IConverter;
import org.openxava.converters.ConversionException;

import java.sql.Time;

/**
 * In java a <tt>String</tt> and in database a
 * <tt>java.sql.Time</tt>. <p>
 *
 * @author Janesh Kodikara
 */
public class StringTimeConverter implements IConverter {

    private Time time;
    private String timeStamp;

    public Object toDB(Object o) throws ConversionException {


        if (o == null) return null;
        if (!(o instanceof String)) {
            throw new ConversionException("conversion_db_string_expected");
        }

        timeStamp = o.toString() + ":00";
        time = Time.valueOf(timeStamp);
        return time;
    }

    public Object toJava(Object o) throws ConversionException {
        if (o == null) return null;
        if (!(o instanceof java.sql.Time)) {
            throw new ConversionException("conversion_java_sqltime_expected");
        }

        time = (Time) o;
        timeStamp = time.toString();
        timeStamp = timeStamp.substring(0, 5);

        return timeStamp;
    }
}


Q.53 How to add a string to description list?

Section 4.3.6 of Reference guide.

Is it possible to add text to a description list?

Need to display book title along with Author and separate the variable with a string (e.g ":" or "by")

<reference-view reference="book">
  <descriptions-list description-properties="title, author.firstName, author.secondName"/>
</reference-view>

or

<reference-view reference="subfamily" create="false">

	<!-- In this case description-property can be omited -->
	<descriptions-list  
		description-property="description" 
		depends="family"
		condition="${family.number} = ?"/>

</reference-view>


First suggestion: Use Calculated property

<component name="Book">
  <entity>
    ...
    <property name="authorFullName" type="String" size="25">
	<calculator class="org.openxava.calculators.ConcatCalculator">
		<set property="string1" from="author.firstName"/>				
		<set property="separator" value=" "/>
		<set property="string2" from="author.secondName"/>
	</calculator>
    </property>

    <property name="fullTitle" type="String" size="60">
	<calculator class="org.openxava.calculators.ConcatCalculator">
		<set property="string1" from="title"/>				
		<set property="separator" value=" by "/>
		<set property="string2" from="authorFullName"/>
	</calculator>
    </property>

  </entity>
...
</component>

<component ... >
  <view>
    <reference-view reference="book"> 
      <descriptions-list description-properties="fullTitle"/> 
    </reference-view> 
  </view>
</component>


Second suggestion: Develop new functionality

> Way to distinguish properties from strings.

Your way is good, and I think that natural for an OX developer. Use other attribute, 'description-message-id'.


> Guide how to develop new functionality?

The code for concatenating the description of description list is in the class.

org.openxava.calculators.DescriptionsCalculator

After this works, we can consider using 'description-message-id', this will involve to modify the dtd and parser.

Third suggestion: New functionality with i18n

<descriptions-list description-properties="title, author.firstName, author.secondName" pattern-id="descriptions_list_book_title"
/>


And in YourApplication-messages_en.properties you have:

descriptions_list_book_title={0} by {1} {2} 

Q.54 How to remove image?

Edit imageEditor.jsp, and add a new action to reset the image, inside the below block.

<% if (editable) { %>

Add the action in ImageEditor controller of default-controllers.xml.

Have a look to the code of LoadImageAction.


Q.55 How to modify OpenXava DTD?

Add new XML element or xml attribute to below class. Java class which holds all dtd element and attribute names is:

OpenXava/src/org/openxava/util/xmlparse/XmlElementsNames.java


Q.56 How to add new property to xava.properties file?

Edit file:

OpenXava/src/org/openxava/util/XavaPreferences.java

Added new method which returns value of new property:

public boolean isMapFacadeAutoCommit() 
{
    return "true".equalsIgnoreCase(getProperties().getProperty("mapFacadeAutoCommit", "false").trim());
}


Q.57 How to sort reference list with condition?

Error is thrown if column in condition is not included in the FROM part.

Because OX uses description-properties to determine which tables must be included in FROM part.

A simple workaround is to add your property to description properties, in this way:

<reference-view reference="releasebyQA" frame="false">
  <descriptions-list description-property="name, designation.department.id" 
                     condition="${designation.department.id} ='QA'"/>
</reference-view>


Q.58 How to create Date Validation class?

package org.openxava.validators;

import org.apache.commons.validator.routines.DateValidator;
import org.openxava.util.Messages;
import java.util.Date;


/**
 * @author Janesh Kodikara
 */

public class XavaDateValidator {

    DateValidator validator;

    public XavaDateValidator() {
        validator = new DateValidator();
    }

    public boolean isSameDate(Date startDate, Date endDate) {
        boolean isSame = false;

        if (validator.compareDates(startDate, endDate, null) == 0) {
            isSame = true;
        }
        return isSame;
    }

    public void isSameDate(Messages errors, String startFieldName, Date startDate, String endFieldName, Date endDate) {

        if (startDate == null || endDate == null) return;

        if (validator.compareDates(startDate, endDate, null) == 0) {
            errors.add("same_dates_error", endFieldName, startFieldName);
        }
    }

    public boolean isFutureDate(Date value) {
        boolean isSame = false;
        Date today = new Date();
        if (validator.compareDates(value, today, null) > 0) {
            isSame = true;
        }
        return isSame;
    }

    public void isFutureDate(Messages errors, String fieldName, Date value) {
        Date today = new Date();

        if (value == null) return;

        if (validator.compareDates(value, today, null) > 0) {
            errors.add("date_in_future_error", fieldName);
        }
    }

    public boolean isPastDate(Date value) {
        boolean isSame = false;
        Date today = new Date();
        if (validator.compareDates(value, today, null) < 0) {
            isSame = true;
        }
        return isSame;
    }
    public void isPastDate(Messages errors, String fieldName, Date value) {
        Date today = new Date();

        if (value == null) return;

        if (validator.compareDates(value, today, null) > 0) {
            errors.add("past_date_error", fieldName);
        }
    }


    public void isStartDateAfter(Messages errors, String startFieldName, Date startDate, String endFieldName, Date endDate) {
        if (startDate == null || endDate == null) return;

        if (validator.compareDates(startDate, endDate, null) > 0) {
            errors.add("start_date_greater_error", endFieldName, startFieldName);
        }
    }
}

Liquibase

  • Articles

Liquibase Questions and Hints

Hint.1 How to update data?

Is there any way to update a row that already exists in a table (besides using <sql>)?

Currently there is not. I have considered creating an update tag but have not yet. The main reason I did not create it originally is that it seemed to not add a lot of value over the standard <sql> update statement and created a lot of typing.

For example:

<update table="person">
	<column name="username" value="newUsername">
	<where>username = 'oldUsername'</where>
</update>

seems like a lot of work compared to

<sql>UPDATE person SET username='newUsername' WHERE username='oldUsername'</sql>

Now that there is support for standardizing dates, Boolean values, etc. it may be worth creating however.


Web Services


Web Service Providers

Ajax


Ajax Frameworks

Mashups


Portlets


GWT - Google Web Toolkit

Portals, JCR, ECM, Groupware


Liferay Portal

I am trying to get user atributes using the JSR-186 specified way.
Here is the extract from portlet.xml:
<user-attribute>
  <name>user.name.given</name>
</user-attribute>
<user-attribute>
  <name>user.name.family</name>
</user-attribute>
<user-attribute>
  <name>user.business-info.postal.street</name>
</user-attribute>
<user-attribute>
  <name>user.business-info.postal.city</name>
</user-attribute>
<user-attribute>
  <name>user.business-info.postal.country</name>
</user-attribute>
<user-attribute>
  <name>user.business-info.postal.organization</name>
</user-attribute>
<user-attribute>
  <name>user.business-info.telecom.telephone.number</name>
</user-attribute>

Here is the code to get user attributes:

HashMap hmUserInfo = (HashMap)request.getAttribute(PortletRequest.USER_INFO);'
log.debug((String)hmUserInfo.get(UserAttributes.USER_NAME_GIVEN));
log.debug(((String)hmUserInfo.get(UserAttributes.USER_NAME_FAMILY));
log.debug((String)hmUserInfo.get(UserAttributes.USER_BUSINESS_INFO_POSTAL_CITY));
log.debug((String)hmUserInfo.get(UserAttributes.USER_BUSINESS_INFO_POSTAL_COUNTRY));
log.debug((String)hmUserInfo.get(UserAttributes.USER_BUSINESS_INFO_POSTAL_ORGANIZATION));
log.debug((String)hmUserInfo.get(UserAttributes.USER_BUSINESS_INFO_POSTAL_STREET));
log.debug((String)hmUserInfo.get(UserAttributes.USER_BUSINESS_INFO_TELECOM_TELEPHONE_NUMBER));

Liferay return first/last names ONLY in spite of the fact that all other information is presented for this user.
I entered it using Organization Admin portlet.


Liferay Web Services


Liferay Hints

Hint.1 Multiple Instances of Portlet

Portlets which allowed multiple instances to be instantieted in portal. Add this tag to the portlet configuration in liferay-portlet-ext.xml

<instanceable>true</instanceable>


Hint.2 How to add new layout

Edit file: portal\webapps\ROOT\WEB-INF\liferay-layout-templates-ext.xml

<?xml version="1.0"?>
<!DOCTYPE layout-templates PUBLIC "-//Liferay//DTD Layout Templates 4.0.0//EN" "http://www.liferay.com/dtd/liferay-layout-templates_4_0_0.dtd">

<layout-templates>
	<custom>
		
		<layout-template id="2_columns_iv" name="2 Columns (20/80)">
			<template-path>/html/layouttpl/custom/2_columns_iv.tpl</template-path>
		</layout-template>
		
	</custom>
</layout-templates>

Add new file: portal\webapps\ROOT\html\layouttpl\custom\2_columns_iv.tpl

<div id="layout-content-outer-decoration">
	<div id="layout-content-inner-decoration">
		<div id="layout-content-container">
			<table border="0" cellpadding="0" cellspacing="0" width="100%">
			<tr>
				<td valign="top" width="19%">
					$processor.processColumn("column-1")
				</td>
				<td class="layout-column-spacer" width="1%">
					<div> </div>
				</td>
				<td valign="top" width="80%">
					$processor.processColumn("column-2")
				</td>
			</tr>
			</table>
		</div>
	</div>
</div>

Enjoy new layout!

XML

  • ServingXMLOpen source, Apache 2.0 licensed, framework for flat/XML data transformations.





XForms

  • [7]Integrate XForms with the Google Web Toolkit, Part 1: Creating an artist and album management form
  • [8] Integrate XForms with the Google Web Toolkit, Part 2: Creating an artist and album management form


XForms Server-side Transformation Engines


XForms Browser extensions

  • Mozilla XForms
  • formsPlayer a full-featured XForms processor that provides a complete implementation of the W3C's XForms specification. Workis with IE only.


XForms Browser-based scripts

  • FormFaces perform the required XForms processing, also without installing extensions on the browser.


XForms for Mobile devices

XSLT


  • Identity Transform
<!-- identity transform -->
<xsl:template match="*|@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="*|@*|node()"/>
  </xsl:copy>
</xsl:template>

XML databases

REST


REST Articles


REST Frameworks

  • Cetia4Java Servlet-based REST Framework


Restlet REST Framewrok


Jersey REST framework


Project Zero REST framework


Mattress REST framework

BPM


BPM Articles

Rule Engines

ESB - Enterprise Service Bus and JBI - Java Business Integration


ESB/JBI Articles

Linux

  • Clam AntiVirusOpen source (GPL) anti-virus toolkit for UNIX, designed especially for e-mail scanning on mail gateways.
  • how to download xampp from command line:
wget http://www.apachefriends.org/download.php?xampp-linux-1.6.4.tar.gz


Virtual Machines


Applications based on VM

Live CDs

Linux based

  • Vixta
  • Postgre DB Live CD
    • Description what is on CD
    • netepi Has a shell script in the latest tarball release for NetEpi Collection which takes the Ubuntu LiveCD distribution and strips out unnecessary stuff, installs PostgreSQL and NetEpi and various screencast demo movies and the manuals etc, and then creates an ISO for burning.


Windows based

Ant related


HTML, CSS, RSS


How to add URL to My Yahoo RSS Reader

http://add.my.yahoo.com/rss?url=http://www.someSite.com/rss/press_release_todays_newsfeed.xml


DB Related

  • Schema Spy Good tool which can create graphical representation of DB Schema
    • Schema Spy GUI
    • Install Debian package "gsfonts" in order to solve the issue with 'dot'.
  • DBsql2XMLJava tool (class) for transformation (export, convert) relational database into hierarchical XML.
  • Useful scripts related to Tables/Indexes in Oracle.


Query to look Sessions of users in Postgre:

select pg_class.relname, pg_locks.transaction, pg_locks.mode, 
pg_locks.granted as "g",
       pg_stat_activity.query_start,
   age(now(),pg_stat_activity.query_start) as "age", 
pg_stat_activity.procpid,
   pg_database.datname , pg_stat_activity.client_addr, 
   pg_locks.page, pg_locks.tuple, pg_locks.relation, 
rpad(pg_stat_activity.current_query, 200)
   from pg_stat_activity,pg_database , pg_locks 
   left outer join pg_class on
   (pg_locks.relation = pg_class.oid) 
   where pg_locks.pid=pg_stat_activity.procpid 
     and pg_locks.database = pg_database.oid
     and pg_locks.mode       like '%ExclusiveLock'
   order by query_start;

usie  pg_cancel_backend(pid) function to cancel

Following query lists all open sessions and the relevant PIDs.

SELECT Activity.datname, Activity.procpid, Shadow.usename,
Activity.current_query
FROM pg_stat_activity Activity 
INNER JOIN pg_shadow Shadow 
ON (Activity.usesysid=Shadow.usesysid);


  • Table oriented frameworks


DB Replication


LDAP

DB Structure and Data comparison

Security, SQL Injection


Oracle to/from Postgre porting/conversion

ER Diagrams


Druid


Changes which i made to Druid

Show class name in modules dialog

Menu "Config" -> "Modules..." now shows class name of loaded module. This allows developer to find responsible class and modify it if necessary.

Loaded modules window


package druid.dialogs.modules;

import java.awt.Color;

import javax.swing.JTextField;

import org.dlib.gui.FlexLayout;
import org.dlib.gui.TLabel;
import org.dlib.gui.TPanel;
import org.dlib.gui.TTextArea;
import org.dlib.gui.TTextField;

import druid.interfaces.BasicModule;

public class GeneralPanel extends TPanel
{
	private JTextField txtId      = new TTextField();
	private JTextField txtVersion = new TTextField();
	private JTextField txtAuthor  = new TTextField();
	private TTextArea  txaDescr   = new TTextArea(6, 40);
	private JTextField txtClass	  = new TTextField();  // @Trifon

	public GeneralPanel()
	{
		super("General");

		FlexLayout flexL = new FlexLayout(2,5,4,4);  // @Trifon
		flexL.setColProp(1, FlexLayout.EXPAND);
		setLayout(flexL);

		//--- setup textfields

		txtId.setEditable(false);
		txtVersion.setEditable(false);
		txtAuthor.setEditable(false);
		txaDescr.setEditable(false);
		txtClass.setEditable(false);  // @Trifon

		txtId.setBackground(Color.white);
		txtVersion.setBackground(Color.white);
		txtAuthor.setBackground(Color.white);
		txtClass.setBackground(Color.white);  // @Trifon

		//--- setup panel

		add("0,0",     new TLabel("Id"));
		add("0,1",     new TLabel("Version"));
		add("0,2",     new TLabel("Author"));
		add("0,3,l,t", new TLabel("Descr"));
		add("0,4",     new TLabel("Class"));  // @Trifon

		add("1,0,x", txtId);
		add("1,1,x", txtVersion);
		add("1,2,x", txtAuthor);
		add("1,3,x", txaDescr);
		add("1,4,x", txtClass);  // @Trifon
	}

	public void setCurrentModule(BasicModule mod)
	{
		txtId.setText(mod.getId());
		txtVersion.setText(mod.getVersion());
		txtAuthor.setText(mod.getAuthor());
		txaDescr.setText(mod.getDescription());
		txtClass.setText(mod.getClass().getCanonicalName());  // @Trifon
	}
}


TODO SQL constant remapping

class: factory.sql.AbstractSqlGenModule

	protected String genFieldAttrib(FieldNode node, AttribSet asAttrib, Object obj)
	{
		StringBuffer sb = new StringBuffer();

		String faSqlName = asAttrib.getString("sqlName");

		if (obj instanceof Boolean)
		{
			boolean b = ((Boolean)obj).booleanValue();

			if (b)
				sb.append(faSqlName);
		}

		else if (obj instanceof String || obj instanceof Integer)
		{
			String value = obj.toString().trim();

			if (!value.equals("")) {
				// TODO - Trifon
				// Here we can make SQL constant remapping!
				// SYSDATE -> NOW()
				BasicDatabaseSettings sett = new BasicDatabaseSettings(node.getDatabase().modsConfig, this);

				AttribList alSqlMapping = sett.getSqlMapping();
				if (alSqlMapping.size() > 0) {
					sb.append(faSqlName + " " + remapSqlType(value, alSqlMapping));
				} else {
					sb.append(faSqlName + " " + value);
				}
			}
				
		}

		else
			throw new DruidException(DruidException.INC_STR, "Unknown type of object", obj);

		return sb.toString();
	}

Druid Hints

Hint.1 Remapping of DB Types

Druid fully supports remapping of database types. This feature allows developer to build his initial DB model against specific DB(Oracle for example) and generate SQL scripts for any DB (Postgre for example). Or developer can define abstract DB types and create appropriate mapping for each DB!

Field "Sql Type" can contain any Regular expression.

Java Pattern class : java.util.regex.Pattern


Example remapping from Oracle to Postgre.

Sql Type:

NUMBER\(10,0\)

Mappend type:

NUMERIC(10)

BI - Business Intelligence

SEO - Search Engine Optimization


Open Source Report Engines/Frameworks

JDOReports


JDOReports Developer Tips

Hint.1 How to open template document which is password protected

Templates to be protected against unauthorised changes to at least some extent.

Opening a password protected template is not supported. If what you want is to protect the output document (rather than the template) then you can post-process the document through JODConverter and OpenOffice.org and specify a password at that stage (optionally also converting the document to PDF or another format).

Could use JODConverter to unprotect the template before processing it through JOOReports. Convert the document from ODT to ODT (!) passing the password as an import option. Need OpenOffice.org installed and running on the server for JODConverter to work though.

DocumentConverter converter = new OpenOfficeDocumentConverter(connection); 

DocumentFormat inFormat = new DocumentFormat("OpenDocument Text", DocumentFamily.TEXT, "application/vnd.oasis.opendocument.text", "odt"); 
inFormat.setImportOption("Password", "testpwd"); 

DocumentFormat outFormat = new DocumentFormat("OpenDocument Text", DocumentFamily.TEXT, "application/vnd.oasis.opendocument.text", "odt");
outFormat.setExportFilter(DocumentFamily.TEXT, "writer8");

File inFile = new File(getDocumentsPath() + "\\" + templateName); 
File outFile = new File(getDocumentsPath() + "\\temp.odt"); 
converter.convert(inFile, inFormat, outFile, outFormat); 

or

Alternatively could use the registry to get the default ODT format:

DocumentFormatRegistry registry = new DefaultDocumentFormatRegistry();
DocumentConverter converter = new OpenOfficeDocumentConverter(connection, registry);

DocumentFormat odt = registry.getFormatByFileExtension("odt");
        
DocumentFormat odtWithPassword = new DocumentFormat(odt.getName(), odt.getFamily(), odt.getMimeType(), odt.getFileExtension());
odtWithPassword.setImportOption("Password", "secret");

converter.convert(inputFile, odtWithPassword, outputFile, odt);

Open Reports

  • Open Reports I like it very much. It has report scheduling, dashboard in professional edition with AJAX interface. Works with multiple report engines like: JasperReports, Eclipse BIRT, JXLS.
  • www.linux.com article


Jasper Reports


Jasper Reports Tips

Hint.1 How to convert field from Boolean to String

Field RptSgnEngLtr is defined as java.lang.Boolean.

( $F{RptSgnEngLtr}.equals(new Boolean (true)) ? "YES" : "NO" )

or shorter

$F{RptSgnEngLtr}.booleanValue() ? "YES" : "NO" 


Hint.2 How to sum two double fields

new Double($F{f1}.doubleValue() + $F{f2}.doubleValue())


Hint.3 How to compare numbers

new Boolean($F{f}.intValue() == 1)


Hint.4 How to compare strings

new Boolean($F{f} != null && $F{f}.equals("test"))


Hint.5 How to Highlight odd or even rows


Hint.6 How to Build Dynamic JasperReports

JBoss


Open Source Integration Projects


CSV/Ini/Excel Readers/Parsers/Writers

Super CSV


Ini4J

OSGi


Security


OpenID


Projects

kTable

Move Table Header

Create following Header Listener

public class HeaderListener implements Listener, ControlListener { 
 
KTable table_ = null; 
 
Point initPoint = null; 
 
Tracker tracker = null; 
 
public HeaderListener(KTable table) { 
table_ = table; 
} 
 
public void mouseDoubleClick(MouseEvent e) {  
} 
 
public void mouseUp(int x , int y ) { 
Point p = table_.getCellForCoordinates(x, y); 
 
System.out.println("Up " + p); 
 
if ( 
(p.y < table_.getModel().getFixedHeaderRowCount()) &&  
(p.x >= table_.getModel().getFixedHeaderColumnCount()) && 
(p.x != initPoint.x) && 
(p.y == initPoint.y) 
){ 
 
//if (p.y == initPoint.y) { 
System.out.println("Move " + initPoint + " to " + p); 
((SpanModel)table_.getModel()).switchColumn(p.x, initPoint.x); 
} 
initPoint = null; 
//tracker.close(); 
} 
 
public void mouseDown(Event e) { 
 
Point p = table_.getCellForCoordinates(e.x, e.y); 
if ( 
(p.y < table_.getModel().getFixedHeaderRowCount()) &&  
(p.x >= table_.getModel().getFixedHeaderColumnCount()) 
) 
initPoint = p; 
 
System.out.println("Down " + p); 

} 
 
public void mouseMove(Event event) {  
int JITTER = 8; 
Display display = event.display; 
Shell shell = display.getActiveShell(); 
 
Rectangle tableLocation = display.map(table_, null, shell.getClientArea ()); 
System.out.println("table location " + tableLocation);  
 
Point p = table_.getCellForCoordinates(event.x, event.y);  
Rectangle rect = table_.getCellRect(p.x, p.y); 
 
 
int deltaX = initPoint.x - event.x, deltaY = initPoint.y - event.y; 
if (Math.abs (deltaX) < JITTER && Math.abs (deltaY) < JITTER) { 
return; 
} 
 
tracker = new Tracker (table_, SWT.LEFT | SWT.RIGHT); 
 
tracker.setRectangles (new Rectangle [] {rect}); 
tracker.open (); 
//FALL THROUGH 
 
Rectangle finalPosition = tracker.getRectangles()[0];  
System.out.println(finalPosition); 
 
int posX = finalPosition.x + finalPosition.width / 2 ;//- tableLocation.x; 
int posY = finalPosition.y + finalPosition.height / 2 ;//- tableLocation.y; 
mouseUp (posX,posY); 
 
} 
 
public void handleEvent(Event event) { 
switch (event.type) { 
case SWT.MouseDown: 
mouseDown((event)); 
break; 
case SWT.MouseMove: 
if (initPoint == null) return; 
mouseMove(event); 
 
case SWT.MouseUp: 
break; 
}  
} 
 
public void controlMoved(ControlEvent e) { 
} 
 
public void controlResized(ControlEvent e) { 
// TODO Auto-generated method stub  
} 

Security Frameworks and Articles

VoIP, IPTV


Fun


Travian

Fork developers work in their free time! Excuse Me???

What Compiere defenders think.

Can you belive? I work for free? Please do not tell it to my wife... This is top secret.


  • sf.net post It looks that this post was deleted from Compiere forums. Compiere Inc. do not like what friends of Compiere think??? Just to prove that such post exist i posted whole post here

Having been in the ERP game for a very long time, I just find the bazaar a bit too risky for real life scenario and most of the clever developers involved are doing out of free time. I honestly dont even have free time to write this email, but I guess some people have more free time than others. So what people do in their free times is entirely up to them? The product is becoming massive yes, and to expect the couple of clever developers to maintain it within their "free" time would be EXTREMELY risky for any enterprise to put reliance on. Yes it may be more clever and even more transparrent and yes many more extremely clever things will be released out of it. Question though is who is going to maintain it in their free time over the next couple of years and who actually needs to get paid to support it.

Site Meter