User:Trifonnt

From ADempiere ERP Wiki

Revision as of 15:26, 18 May 2011 by Trifonnt (Talk | contribs)
Jump to: navigation, search
My Pages
Name This user real name is : Trifon Nikolaev Trifonov
This user has a Sourceforge account.
This user has a Wikipedia account.


Facebook_logo This user has a Facebook account.
Blogspot_logo This user has blogs.
Twitter Logo Follow him on twitter


Contents

About Me

  • High School of Economics and Computer Science. It helped me to understand accounting and economics.
  • Bachelor degree in Mathematics. Helped me to like mathematics and especially cryptography. Attended many courses in programming, which helped me to became good developer.
  • SUN Certified Programmer 1.4. Maybe should try to pass other Certifications programs... But no time last years.

I started my first company in 2006 year providing ADempiere/Compiere consultancy, training and development services. I like developing business systems and traveling.


Some nice words about me on the net :)

My Blogs

Trifon's Paid Services

ADempiere Technical Support

This support consists of answering questions and providing advices. Unlimited number of questions. Technical support is available monthly or in chunks of 6 and 12 months from the Adempiere developer, Trifon Trifonov. For the duration, you can ask Trifon direct questions via a special support mailing address. Contact is email-only and replies are sent within one business day, often within hours.

Prices:

1 month ADempiere tech support  :  500 USD
6 months ADempiere tech support : 2700 USD - 10% discount
12 months ADempiere tech support: 4800 USD - 20% discount

Contract based ADempiere Support

  • Please call for the price.
  • Included 5 support hours per month. Hours above that are at 40 euro per hour.
  • Up to 10 registered ADempiere users.
  • One contact person from the side of the customer.
  • Communication channels: Phone, Email, Skype, Ticketing system.
  • Free bugfixes.
  • Free migration to next version of ADempiere.
  • Free installation of ADempiere on customer server.
  • Free integration with osCommerce.
  • Free integration with Google Documents. User can import data from Google Docs and Spreadsheets.
  • Free integration with Google Calendar. All events created in Adempiere calendar are exported to Google Calendar.
  • Optional - Dedicated Server
    • 130 EURO per month.
    • 650 EURO server setup fee.
    • 4 GB RAM.
    • 2 x 250 GB HDD. Hardware-RAID 1.
    • Traffic 5 000 GB.

ADempiere customized with client's own brand

  • Please call for the price.
  • Client must send two images.
  • 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 Images

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

  • Please call for the price.
  • Build of Adempiere upon user request.
  • 10% will be donated to Adempiere.
  • Build can include additional functionality like Fixed Asset or other not included in trunk.

Adempiere DVD by Trifon

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

Developer need to copy one directory to his local hard drive and can start customizing Adempiere.

Paid Adempiere Urgent support

  • 3 EURO per minute.



  • Ether Another pay per call service

Paid On-Site ADempiere User training(1 week)

  • 1500 EUR per week + ticket + hotel
  • Training plan customized to fit client needs.
  • Example training plan:
01) General overview of ADempiere ERP-CRM system.
02) Introduction to user interface.
03) How to setup new Company in ADempiere.
04) How to setup new Organization in ADempiere.
05) How to create and import Chart of Accounts. Introduction to ADempiere Chart of Accounts Editor.
06) How to create new Product, Product Category and set Product Price and Price List.
07) How to create hierarchical Categories of Services and Products (categories, subcategories, etc)
08) How to import Products from external sources/systems.
09) How to create Discount Schema and Price List and apply specific discount/overcharge for specific Product Group/Product, e.t.c. How to create Discount based on a percent or fixed amount.
10) How to create new Business Partner(Client, Vendor and Employee).
11) How set credit limit for Business Partners. Apply a credit limit to a client and ADempiere lock sales when limit is reached.
12) How to assign discount to specific Business Partner, and change it in every sell.
13) How to import Business Partners from external sources/systems.
14) How to create Purchase Order.
15) How to track purchases: list purchases that are not received, due dates.
15) How to create Material Receipt.
16) How to create Invoice (Vendor)
17) How to enter Landed Costs.
18) How to create Sales Order.
19) How to create Shipment (Customer).
20) How to create Shipment Confirmation.
21) How to create Invoice (Customer).
22) how to enter RMA.
23) How to create Payment.
24) How to match Purchase Order - Material Receipt - Invoice (Vendor).
25) How to match Sales Order - Shipment - Invoice (Customer).
26) How to create Cash Payment and Cash Receipt.
27) How to create Bank Account and Bank transaction.
28) How to modify Print Format of documents.
29) How to setup emails of ADempiere users and send emails with attached document(Purchase Order, Invoice, e.t.c) to clients.
30) How to create Users and assign User permissions.
31) How to setup Window, Tab and Field permissions for specific Roles and Users.
32) How to share data between Organizations and users.
33) How to setup records to be readable only by their creators.
34) How to setup taxes.

Paid On-Site Flash ADempiere User training(1 day)

  • 400 EUR + ticket + hotel
  • Training plan customized to fit client needs.
  • Example training plan:
+01) Introduction to ADempiere user interface.
+02) How to setup new Company in ADempiere.
+03) How to setup new Organization in ADempiere.
+04) How to create new Product, Product Category and set Product Price and Price List.
+05) How to create hierarchical Categories of Services and Products (categories, subcategories, etc)
+06) How to create Discount Schema and Price List and apply specific discount/overcharge for specific Product Group/Product, e.t.c. How to create Discount based on a percent or fixed amount.
+07) How to create new Business Partner(Client, Vendor and Employee).
+08) How to assign discount to specific Business Partner, and change it in every sell.
+09) How to create Purchase Order.
+10) How to track purchases: list purchases that are not received, due dates.
+11) How to create Material Receipt.
+12) How to create Invoice (Vendor)
+13) How to create Sales Order.
+14) How to create Shipment (Customer).
+15) How to create Invoice (Customer).
+16) How to create Payment.
+17) How to match Purchase Order - Material Receipt - Invoice (Vendor).
+18) How to match Sales Order - Shipment - Invoice (Customer).
+19) How to create Cash Payment and Cash Receipt.
+20) How to create Bank Account and Bank transaction.
+21) How to create Users and assign User permissions. (Needed in order to be able to experiment afterwards)

Paid on site Adempiere Developer training

  • 1500 EUR per week + ticket + hotel
  • Training plan customized to fit client needs.
  • Example training plan:
01) Overview of Adempiere setup in Eclipse.
02) Layers in adempiere and where clases are located in the source tree?
2.1) Model (Domain) layer.
2.2) Business logic layer.
2.3) GUI - Swing layer.
2.4) GUI - Web layer.
03) How to add new table and columns in Adempiere?
04) How to generate Adempiere model classes for the newly created table?
05) How to add validation, pre-pressing and post-processing logic for the new table?
    (beforeSave, afterSave, beforeDelete afterDelete)
    ModelValidator
06) How to add new Window, Tab and Fields?
06.1) How to add new Tab which has Tree?
06.2) How to add Translation Tab?
07) How to add GUI callout?
08) How to define new Document in Adempiere?
09) How to add business logic for the newly created document?
10) How to add Process in Adempiere?
11) How to add java code for the newly defined process?

Paid Adempiere development

  • 300 EURO / day
  • Please call for discount if you plan to book more than 150 hours

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 Liferay setup and extensions development

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


Paid OpenXava Development

  • 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.

Paid Java Development

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


ADempiere

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

Issues found

  • Posterita WP POS expect that TAX Category has only one Tax Rate assigned to it.
  • Posterita create AR Invoice while POS Order type in Adempiere creates Invoice Indirect. This allows to distinguish Invoices creates by POS. Of course Business partner also can allow sot distinguish POS invoices, but more consitent behavior is to create Invoice Indirect.

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.


Notes about installation

  • One Business partner must have column AD_OrgBP_ID set to Organization which is set in POS Terminal.
SELECT C_BPartner_ID FROM C_BPartner WHERE AD_OrgBP_ID=
  • Execution of migration scripts.
@"1.0-1.5 (AD331b)\oracle\001_ad_changes.sql"
@"1.0-1.5 (AD331b)\oracle\002_ad_message.sql"
@"1.0-1.5 (AD331b)\oracle\003_m_pricelist.sql"

@"1.6(AD340)\oracle\001_ad_Changes for C_Currency.sql"
@"1.6(AD340)\oracle\002_ad_message.sql"
@"1.6(AD340)\oracle\003_C_Currency.sql"

@"1.7.0\oracle\001_MixedPayment.sql"
@"1.7.0\oracle\002_Terminals_newTableStructure.sql"
@"1.7.0\oracle\003_Terminals_TransferConfiguration.sql"
@"1.7.0\oracle\004_Terminals_newTableDDL.sql"
@"1.7.0\oracle\005_Messages.sql"

@"1.7.1\oracle\001_M_Inventory.sql"

@"1.7.2\oracle\001_ADRole.sql"

@"trunk\oracle\002_ADMessage.sql"
@"trunk\oracle\003_AD_OrgInfo.sql"
@"trunk\oracle\004_AD_Changes for AD_OrgInfo.sql"
@"trunk\oracle\005_MissingIDs.sql"
@"trunk\oracle\006_PackSize_MProduct.sql"
@"trunk\oracle\007_CashPayment.sql"


  • Values of web.xml
	<context-param>
		<param-name>#AD_Client_ID</param-name>
		<param-value>11</param-value>
	</context-param>
	<context-param>
		<param-name>#AD_Language</param-name>
		<param-value>en_US</param-value>
	</context-param>
	<context-param>
		<param-name>#AD_Org_ID</param-name>
		<param-value>11</param-value>
	</context-param>
	<context-param>
		<param-name>#AD_User_ID</param-name>
		<param-value>102</param-value> <!-- GardenUSer -->
	</context-param>
	<context-param>
		<param-name>#C_BankAccount_ID</param-name>
		<param-value>100</param-value>
	</context-param>
	<context-param>
		<param-name>#SalesRep_ID</param-name>
		<param-value>102</param-value>
	</context-param>
	<context-param>
		<param-name>#AD_Role_ID</param-name>
		<param-value>103</param-value> <!-- Garden User -->
	</context-param>
	<context-param>
		<param-name>#W_Store_ID</param-name>
		<param-value>11</param-value>
	</context-param>
	<context-param>
		<param-name>REPORT_DIRECTORY</param-name>
		<param-value>/config/reports/</param-value>
	</context-param>
  • How to setup?

Explained by Colin in irc:

-01) Login as System Admin and add new window for the table "U_POSTerminal".
-02) Use the "Create Fields" button on the "Tab" tab to add all the fields of this table.
-03) Go to System Admin->Gerenral Rules->System Rules->Menu window and create a new menu item.
-04) Select Window as the Action and point it to the new window you just created (by selecting it in the window dropdown).
-05) Log out and log back in as Garden Admin.
-06) Using you new window create a new POS terminal. Chose what ever you wish for the settings.
-07) Go to Quote-to-Invoice->Sales Orders->Web POS->
-08) Go to the role menu here and create a new record with "Web Menu"=smenu.cash.sales and "Role" = "GardenWorld Admin".
     Uou can add more if you wish but I think this is all that's needed for basic sales.
  • Printing

Edit java.policy in

C:\Program Files\Java\jdk1.6.0_10\jre\lib\security

Add the code below

grant codeBase "http://192.168.0.100" {
       permission java.util.PropertyPermission "org.jpedal.rejectsuperimposedimages", "read, write";
       permission java.util.PropertyPermission "file.separator", "read, write";
OR
       permission java.security.AllPermission;
};

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.


How to import product from csv file?

MySQL script commands to import a simple CSV spreadsheet of products and a collection of image files.

CSV file MUST have these columns:

REFERENCE*, NAME*, PRICEBUY, PRICESELL, BARCODE*, CATEGORY

The columns with a * must have different values for every product, otherwise the script will fail. The category IDs in the CSV file also have to match the IDs in the 'categories' database table.

LOAD DATA
 INFILE 'C:\\temp\\products.csv'
 INTO TABLE products
 FIELDS TERMINATED BY ','
 LINES TERMINATED BY '\r\n'
 (REFERENCE, NAME, PRICEBUY, PRICESELL, CODE, CATEGORY)
 SET ID = UUID(), TAXCAT = '001', ISCOM = 0, ISSCALE = 0;
  1. the images are loaded by searching a directory for files that have the same names as the products
SET @IMAGE_DIR = 'C:\\temp\\products\\images\\';
UPDATE products
 SET IMAGE = IFNULL(LOAD_FILE(CONCAT(@IMAGE_DIR, products.NAME, '.jpg')),
             IFNULL(LOAD_FILE(CONCAT(@IMAGE_DIR, products.NAME, '.png')),
                    LOAD_FILE(CONCAT(@IMAGE_DIR, products.NAME, '.gif'))))
 WHERE IMAGE IS NULL;
  1. to make the products appear in the catalog, their ids must be added to this table
INSERT INTO products_cat (PRODUCT)
 SELECT products.ID FROM products;


OsCommerce db settings

/var/www/html/admin/includes/configure.php

Schemas in MySQL DB where OsCommerce is installed

information_schema
mysql
oscomm
test

osCommerce Tables

products

products_id			int(11)
products_quantity		int(4)
products_model			varchar(12)
products_image			varchar(64)
products_price			decimal(15,4)
products_date_added		datetime
products_last_modified		datetime
products_date_available		datetime
products_weight			decimal(5,3)
products_status			tinyint(1)
products_tax_class_id		int(11)
manufacturers_id		int(11)
products_ordered		int(11)
products_quanityt_discount	varchar(255)
products_weight_package		varchar(255)
products_status_hide		tinyint(1)

products_description

products_id			int(11)
language_id			int(11)
products_name			varchar(128)
products_description		text
products_description_short	text
products_url			varchar(255)
products_viewed			int(5)
products_status_translation	tinyint(1)
products_meta_title		varchar(255)
products_meta_keywords		text
products_meta_description	text

tax_class

tax_class_id			int(11)
tax_class_title			varchar(32)
tax_class_description		varchar(255)
last_modified			datetime
date_added			datetime

manufacturers

manufacturers_id		int(11)
manufacturers_name		varchar(32)
manufacturers_image		varchar(64)
date_added			datetime
last_modified			datetime

manufacturers_info

manufacturers_id		int(11)
languages_id			int(11)
manufacturers_url		varchar(255)
url_clicked			int(5)
date_last_click			datetime

languages

languages_id	int(11)
name			varchar(32)
code			char(2)
image			varchar(64)
directory		varchar(32)
sort_order		int(3)

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"


Eclipse Preprocessor Plugin

  • Adempiere Preprocessor Example code-1
/* $if isAdempiere $
  Env.setContext(Env.getCtx(), "#AD_Org_ID", AD_Org_ID);  // Adempiere
$else$ */
  Env.getCtx().setContext("#AD_Org_ID", AD_Org_ID);       // Compiere
/* $endif$ */


  • Adempiere Preprocessor Example code-2
			// =================
			/* $if isAdempiere $
			Env.setContext(Env.getCtx(), "#AD_User_ID", CreatedBy_ID);  // Adempiere
			$else$ */
			Env.getCtx().setContext("#AD_User_ID", CreatedBy_ID);       // Compiere
			/* $endif$ */
		}
		// =================
		/* $if isAdempiere $
		Env.setContext(Env.getCtx(), "#AD_Client_ID", AD_Client_ID);  // Adempiere
		$else$ */
		Env.getCtx().setContext("#AD_Client_ID", AD_Client_ID);       // Compiere
		/* $endif$ */
	    // =================
	    /* $if isAdempiere $
		Env.setContext(Env.getCtx(), "#AD_Org_ID", AD_Org_ID);  // Adempiere
		$else$ */
		Env.getCtx().setContext("#AD_Org_ID", AD_Org_ID);       // Compiere
		/* $endif$ */

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


DB change/migration tracking

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.

JSR-170 Note

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.

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  
} 


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 transparent 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.


Roses

1 роза - любов от пръв поглед; 2 рози - взаимна, дълбока любов; 3 рози - Обичам те!; 6 рози - искам да бъда твой; 7 рози - аз съм заслепен от теб; 9 рози - вечна любов, дълъг живот заедно; 10 рози - ти си перфектна; 11 рози - ти си моето съкровище, най-голямата любов в моя живот; 12 рози - бъди моя постоянна приятелка; 13 рози - таен обожател; 15 рози - аз съм наистина съжалявам, моля те не ме забравяй; 20 рози - повярвай ми, аз съм искрен с теб; 21 рози - аз съм отдаден на теб; 24 рози - не мога да спра да мисля за теб, мисля за теб денонощно; 33 рози - голяма привързаност; 36 рози - Ще помня нашите романтични моменти; 40 рози - Моята любов е истинска; 50 рози - любов изпълнена със съжаление; 99 рози - Ще те обичам до деня на смъртта; 100 рози - хармонична любов, останала запазена до дълбока старост; 101 рози - Ти си единствена за мен; 108 рози - Ще се омъжиш ли за мен?; 365 рози - не мога да спра да мисля за теб, всеки ден мисля за теб; 999 рози - вечна любов;

Site Meter

Personal tools