---
# System prepended metadata

title: Development Guide HD New FW

---

[TOC]
# Development Guide HD New FW
## 1. Create new model
### 1.1 Declare your model inside package "com.hde.module.models"
![](https://i.imgur.com/pypXZCV.png)

> **Steps:**
> 1. Declare necessary annotations (database table name)
> 1. Must implement from Iobject or IObject2 interface. (for import must implement IImport interface and Iemail for send email)
> 1. Declare database column name
> 1. Declare items which are showing on search screen
> 1. Declare items which are showing on edit and view screen


```java
...
// 1. Declare necessary annotations (database table name)
@Entity
@Table(name = "customers")
@Proxy(lazy = false)
// 2. Must implement from Iobject or IObject2 interface
// (for import must implement IImport interface and Iemail for send email)
public class Customer implements IObject {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;

    // 3. Declare database column name
    @Column(name = "firstName")
    // 4. Declare items which are showing on search screen
    @ListConfig(visible = true, searchable = true)
    // 5. Declare items which are showing on edit and view screen
    @EditConfig(label = "Họ", dataType = @EditConfig.DataType(fieldType = HDTextField.class),
            group = @EditConfig.Group(name = "THÔNG TIN CƠ BẢN"), columnIndex = EditConfig.ColumnIndex.FIRST)
    private String firstName;

    @Column(name = "lastName")
    @ListConfig(visible = true, searchable = true)
    @EditConfig(label = "Tên", dataType = @EditConfig.DataType(fieldType = HDTextField.class),
            group = @EditConfig.Group(name = "THÔNG TIN CƠ BẢN"), columnIndex = EditConfig.ColumnIndex.FIRST,
            validator = @EditConfig.IValidator(required = true, maxLength = 50))
    private String lastName;
    ...

}

```
### 1.2 ListConfig attributes 
No.|Attribute (require)|Return type|Value|Description
-------- | -------- | -------- | -------- | -------- |
1|visible|boolean|True / false|Show column in list view
2|queue|boolean|boolean|Set column wait for showing on list
3|name|String|Any text|Display column header
4|typeFormat|Class<? Extends Converter>|See “Converter component”|Format display value like email, number, date …
5|defaultSort|String|ASC / DESC|Sort column value by ASC or DESC
6|searchable|boolean|True / false|Show attribute on search panel
7|customSearch <br>+ fieldType <br>+ fieldQuery <br>+ defaultSearch <br>+ searchOnSet|@CustomSearch <br>+ Class <br>+ String <br>+ boolean|+ See “Search component” <br>+ See “Define search query” <br>+ True / false|+ Search field type <br>+ Search on field if there is a join <br>+ Default show in search panel <br>+ Search on link iobject m2one| m2m"
8|isMassUpdate|Boolean|True / false|Show in mass update panel
9|columnIndex|int||Order column from left to right
10|columnWidthPercent|int||Expand column with given percentage
11|defaultSearchValue|String|Depend on component|Default search with given value
12|useForAutocomplete<br>Component|boolean||Using for suggested component
13|columnIndex|int||Order column in list panel
14|columnWidthPercent|int||Set size coumn in list panel|


### 1.2 Edit config attributes

No.|Attribute (require)|Return type|Value|Description
-------- | -------- | -------- | -------- | -------- |
1|visible|boolean|True / false|Show column in list view
2|system|boolean|True / false|
3|group<br>+ name<br>+ iconClass<br>+ groupIndex<br>+viewOneColumn<br>InInfoPanel|@Group<br>+ String<br>+ String<br>+ @ColumnIndex<br>+ boolean|Any value<br>+ Class name<br>+ First / Second / Merge|Put some fields into group
4|Lable (*)|String|Any text|Display field label
5|dataType<br>+ fieldType<br>+ typeFormat<br>+ defaultValue|@Datatype<br>+ Class<br>+ Class<br>+ String|See “component”<br>+ See “Converter component”<br>+ Any string|Set field type and set text input format
6|description|String|Any value|
7|validator<br>+ typeValidator<br>+ required<br>+ minLength<br>+ maxLength<br>+ startDate<br>+ endDate|@Ivalidator<br>+ Class<br>+ boolean<br>+ int<br>+ String<br>|+ extends Validator<br>+ True / false<br>+ Integer value<br>+ Integer value<br>+ Date as string value<br>+ Date as string value|Set validate for field<br>+ Custom validation<br>+ Set field require <br>+ Set min length<br>+ Set max length<br>+ Set start date (date field)<br>+ Set end date (date field)
8|readOnly|boolean|True / false|Display in info panel only
9|hideIfZezo|boolean|True / false|Hide if value = 0
10|editOnly|boolean|True / false|Display in edit panel only
11|allowImport|boolean|True / false|Allow showing in import panel
12|columnIndex|@ColumnIndex|FIRST/SECOND/MERGE|


## 2. Create new module
### 2.1 Define package and class
> You have to create mudule with maven project and define classes and pakage look like this image:
> **Steps:**
> 1. Declare module name (replace all “customer” or "Customer" to your module name)
> 1. Declare module Customer class
> 1. Declare CustomerPanelProvider Customer class
> 1. Declare CustomerViewProvider Customer class
> 1. Declare CustomerManager Customer class
> 1. Declare file pom.xml

![](https://i.imgur.com/5bD7tEP.png)


### 2.2 Pom xml file
> file xml read only mode

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<parent>
		<artifactId>og-crm</artifactId>
		<groupId>com.hde</groupId>
		<version>${revision}</version>
	</parent>
	
	<modelVersion>4.0.0</modelVersion>
	<packaging>bundle</packaging>
    <!-- change       -->
	<artifactId>com.hde.module.customer</artifactId>
	<name>OGCRM - Modular Customer</name>
	<version>${revision}</version>
	
	<properties>
		<vaadin.version>7.6.4</vaadin.version>
		<felix.version>1.12.1</felix.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
 
		<dependency>
			<groupId>com.hde</groupId>
			<artifactId>com.hde.module.models</artifactId>
			<version>${revision}</version>
		</dependency>
		<dependency>
			<groupId>com.hde</groupId>
			<artifactId>com.hde.module.custom.component</artifactId>
			<version>${revision}</version>
		</dependency>

	</dependencies>
	<distributionManagement>

		<repository>
			<id>github-og-crm</id>
			<name>GitHub Packages</name>
			<url>https://maven.pkg.github.com/hdedev/og-crm</url>
		</repository>

	</distributionManagement>
	<build>

		<plugins>

			
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.7.0</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<version>3.5.0</version>
				<extensions>true</extensions>



				<dependencies>
					<dependency>
						<groupId>org.apache.felix</groupId>
						<artifactId>bnd-ipojo-plugin</artifactId>
						<version>1.12.1</version>
					</dependency>
				</dependencies>
			</plugin>

			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-ipojo-plugin</artifactId>
				<version>1.12.1</version>
				<executions>
					<execution>
						<goals>
							<goal>ipojo-bundle</goal>
						</goals>
					</execution>
				</executions>
				<dependencies>
					<dependency>
						<groupId>org.apache.felix</groupId>
						<artifactId>org.apache.felix.ipojo.manipulator</artifactId>
						<version>1.12.1</version>
					</dependency>
				</dependencies>
			</plugin>

<!--

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-install-plugin</artifactId>
				<version>2.5.2</version>
				<executions>
					<execution>
						<goals>
							<goal>install-file</goal>
						</goals>
						<phase>install</phase>
						<configuration>
							<skip>false</skip>
							<file>${project.build.directory}/${project.artifactId}-${revision}.jar</file>
							<generatePom>true</generatePom>
							<pomFile>${project.basedir}/pom.xml</pomFile>
							<version>${revision}</version>
						</configuration>
					</execution>
				</executions>
			</plugin>			
	        <plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-deploy-plugin</artifactId>
				<version>2.8.2</version>
				<executions>
	                <execution>
	                    <goals>
	                        <goal>deploy-file</goal>
	                    </goals>
	                    <phase>deploy</phase>
	                    <configuration>
							<repositoryId>github</repositoryId>
	                        <url>https://maven.pkg.github.com/hdedev/bs-app</url>
	                        <file>${project.build.directory}/${project.artifactId}-${revision}.jar</file>
	                        <generatePom>true</generatePom>
	                        <pomFile>${project.basedir}/pom.xml</pomFile>
	                        <version>${revision}</version>
						</configuration>
	                </execution>
            	</executions>
			</plugin> -->


		</plugins>
	</build>
	<repositories>
		<repository>
			<id>vaadin-addons</id>
			<url>http://maven.vaadin.com/vaadin-addons</url>
		</repository>
		<repository>
			<id>github</id>
			<name>GitHub Packages</name>
			<url>https://maven.pkg.github.com/hdedev/bs-app</url>
		</repository>

	</repositories>
	<organization>
		<url>http://www.hdexpertise.com</url>
		<name>HD Expertise Ltd.</name>
	</organization>
	
</project>
```
### 2.3 Module class
> Code in file CustomerModule.java

```java
package com.hde.module;

import java.util.ArrayList;
import java.util.List;

import com.hde.module.customer.db.manager.CustomerManager;
import com.hde.module.customer.gui.panel.CustomerPanelProvider;
import com.hde.module.customer.gui.view.CustomerViewProvider;
import com.hde.module.models.Customer;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Instantiate;
import org.apache.felix.ipojo.annotations.Provides;

import com.hde.app.gui.component.AppPanelProvider;
import com.hde.app.gui.component.AppViewProvider;
import com.hde.app.interfaces.IManager;
import com.hde.app.interfaces.IModule;

@Component
@Instantiate
@Provides(specifications = IModule.class)
public class CustomerModule implements IModule {
	private CustomerViewProvider viewProvider = new CustomerViewProvider(this);
	private CustomerPanelProvider panelProvider = new CustomerPanelProvider(this);
	private CustomerManager dataManager =  new CustomerManager();

	@Override
	public String getName() {
		return getModel().getSimpleName().toLowerCase();
	}

	@Override
	public AppViewProvider getViewProvider() {
		return viewProvider;
	}

	@Override
	public AppPanelProvider getPanelProvider() {
		return panelProvider;
	}
	
	@Override
	public IManager getManager() {
		return dataManager;
	}

	@Override
	public void test() {}

	@Override
	public String getMessages(String key) {
		return Messages.getInstance().getMessage(key);
	}

	@Override
	public Class getModel() {
		return Customer.class;
	}

	@Override
	public List<Class<?>> getRelatedModel() {
		List<Class<?>> relatedModels = new ArrayList<Class<?>>();

		return relatedModels;
	}

}

```
### 2.4 View provider class
### 2.5 Panel provider class
### 2.6 Model class

## 3. Import module into project (eclipse)
## 4. Build and run
## 5. Appendices
### 5.1 Components

No. | Name | Search component | Description|
-------- | -------- | -------- | -------- |
1|HDTextField|HDSearchTextField|
2|HDTextArea|HDSearchTextField|
3|HDPhoneField|HDSearchPhoneField|
4|HDPassword|-|
5|HDNumberField|HDSearchNumberField and HDSearchNumberRange|
6|HDIntegerNumberField|HDSearchIntegerField and HDSearchIntegerRange|
7|HDEmailField|HDSearchTextField|
8|HDDateField|HDSearchDateRange and HDSearchDateField|
9|HDCurrencyField|HDSearchNumberField and HDSearchNumberRange|
10|HDItemCodeListSelect|HDSearchItemCodeListSelect|
11|HDItemCodeGroupRadio|HDSearchGroupRatio|
12|HDItemCodeGroupCheckbox|HDSearchItemCodeListSelect|
13|HDItemCodeCombobox|HDSearchItemCodeComboBox|
14|HDFileUploader|-|
15|HDCheckBox|HDSearchBooleanField|
16|HDCombobox|-|
17|HDDateTimeField|HDSearchDateRange|
18|HDIObjectCombobox|HDSearchIObjectListSelect|
19|HDItemCodeGroupRadio|HDSearchItemCodeListSelect|
20|HDSingleSelectionItemBox|Using for custom search (for iobject has many to one relationship)|
21|HDMultiSelectionItemBox|Using for iobject has many to many relationship|
22|HDComplexSelection|Using for bach khoa project|
23|HDRoleGroupCheckbox|-|
24|HDYearCombobox|HDSearchYearCombobox|
25|HDUniqueTextField|HDSearchTextField|
26|HDTimeCombobox|-|
27|HDSuggestionField|HDSearchTextField|
28|HDSuggestionCombobox|Using for product in sale lines|
29|HDSingleSelectionCreateItemBox|For iobject has many to one relationship|
30|HDSingleRelatedComponent|For find duplicated|
31|HDPercentageField|-|
32|HDMonthCombobox|HDSearchMonthField|
33|HDListEditor (HDListCreateObject - depreciated)|This component is used for sale lines purchase lines|
34|HDLabelField|Using in edit config for displaying label only (form object)|
35|HDWebsiteField||
36|HDRichTextArea|-|For email template
37|HDMultiFileUploaderField|-|For upload multiple files|

:::info
:bulb: **Note:** Application is automatic convert edit component to search component. But we can use custom search component (place in fieldType of custom search annotation)
:::


### 5.2 Converter components
No.|Name|Description|
-------- | -------- | -------- |
1|HDDateToStringConverter||
2|HDIDToIObjectConverter||
3|HDItemCodeConverter||
4|HDMultiIObjectConverter||
5|HDMultiItemCodeConverter||
6|HDStringToDateConverter||
7|HDMultiSelectionConverter||
8|HDIObjectConverter|Using for writing components|
9|HDListIObjectConverter|Using for writing components|
10|HDStringToBooleanConverter||

:::info
:bulb: **Note: When we use converter component**
+ Display custom format
+ Display other (not default) column of link table
+ Define new converter class, must extends from converter class
:::

## 6. Service
### 6.1 Create service module
### 6.2 Generation doc (free marker)
### 6.3 Rule service
### 6.4 Bis service


