Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Scout/Tutorial/3.8/Minicrm/Code Types"

< Scout‎ | Tutorial‎ | 3.8‎ | Minicrm
m (Add a Company Rating Field to the Company Dialog (Smart Field))
m (Update the Database Model)
 
(30 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{ScoutPage|cat=Tutorial 3.8}}
+
{{ScoutPage|cat=Tutorial 3.8}} {{note|Scout Tutorial|This page belongs to the [[{{BASEPAGENAME}}_Step-by-Step|Minicrm Step-by-Step Tutorial]]. It explains how to add and use Code Types. You need to finish at least step [[{{BASEPAGENAME}}/Add a form to edit the data|Add a form]] in order to continue.}}  
{{note|Scout Tutorial|This page belongs to the [[{{BASEPAGENAME}}_Step-by-Step|Minicrm Step-by-Step Tutorial]]. It explains how to add and use Code Types. You need to finish at least step [[{{BASEPAGENAME}}/Add a form to edit the data|Add a form]] in order to continue.}}  
+
  
 
== How to Create Code Types  ==
 
== How to Create Code Types  ==
Line 8: Line 7:
 
Open the shared node in Eclipse Scout and expand the tree until you reach the Enumerations node. Right-click on the node and choose ''New Codetype…'' menu.  
 
Open the shared node in Eclipse Scout and expand the tree until you reach the Enumerations node. Right-click on the node and choose ''New Codetype…'' menu.  
  
[[Image:Scout new company type codetype.jpg]]  
+
[[Image:Scout-NewCodeType0.PNG]]  
  
The Code ID needs to be an unique number, which helps to identify the values belonging to the Code Type.
+
The Code ID needs to be an unique number, which helps to identify the values belonging to the Code Type.  
  
The convention usually followed is that we always leave enough space between the Code Type's IDs, because the Code Type's ''values'' need IDs as well. The idea is that the IDs of Code Types and their values are close together (e.g. Code Type has the number 10000 and its values range from 10001 to 10099; the next Code Type has the number 10100).
+
The convention usually followed is that we always leave enough space between the Code Type's IDs, because the Code Type's ''values'' need IDs as well. The idea is that the IDs of Code Types and their values are close together (e.g. Code Type has the number 10000 and its values range from 10001 to 10099; the next Code Type has the number 10100).  
  
 
<br>  
 
<br>  
Line 18: Line 17:
 
Enter the information into the Code Type form according to the picture:  
 
Enter the information into the Code Type form according to the picture:  
  
[[Image:Scout company type codetype form.jpg]]  
+
[[Image:Scout-NewCodeType1.PNG]]  
  
 
<br>  
 
<br>  
  
Right-click on the newly created Code Type and choose ''New Code… ''
+
Right-click on the newly created Code Type and choose ''New Code… ''  
  
[[Image:Scout company type codetype new childcode.jpg]]  
+
[[Image:Scout-NewCode.PNG]]  
  
 
<br>  
 
<br>  
Line 30: Line 29:
 
Increase the CompanyType Code Type's ID by 1 and assign it to the Code ID field. Give it a name like '''Customer'''.  
 
Increase the CompanyType Code Type's ID by 1 and assign it to the Code ID field. Give it a name like '''Customer'''.  
  
[[Image:Scout company type codetype new childcode form.jpg]]  
+
[[Image:Scout-newCode.png]]  
  
 
Repeat these last two steps for two other codes called '''Supplier''' (Code ID: 10002), and '''Other''' (Code ID: 10003).  
 
Repeat these last two steps for two other codes called '''Supplier''' (Code ID: 10002), and '''Other''' (Code ID: 10003).  
  
<br>
+
<br>  
  
== How to Use a Code Type in a Dialog (Radio Button Group) ==
+
== How to Use a Code Type in a Dialog (Radio Button Group) ==
  
So let's use the code type inside the Company Form: we are going to add a Radio Button Group containing those two values.  
+
So let's use the code type inside the Company Form: we are going to add a Radio Button Group containing those values.  
  
 
In a Radio Button Group only one item can be selected at a time. This is exactly what we need here, as we don't like a company being both, customer and supplier.  
 
In a Radio Button Group only one item can be selected at a time. This is exactly what we need here, as we don't like a company being both, customer and supplier.  
Line 44: Line 43:
 
Back in Scout Explorer we expand the tree like: client &gt; Forms &gt; CompanyForm and right-click on MainBox to choose New Form Field…  
 
Back in Scout Explorer we expand the tree like: client &gt; Forms &gt; CompanyForm and right-click on MainBox to choose New Form Field…  
  
Choose Radio Button Group as Type, give it a name like CompanyType and press Finish.  
+
Choose ''RadioButtonGroup'' as Type, give it a name like CompanyType and press Finish.  
  
[[Image:Scout company type codetype new radiobutton group.jpg]]  
+
[[Image:Scout-NewRadioButtonGroup.PNG]]  
  
 
<br>  
 
<br>  
Line 52: Line 51:
 
In the properties editor go to the property Code Type and choose the Code Type CompanyTypeCodeType we have previously created. That’s all we need to do to fill the Code Type's values into the Radio Button Group.  
 
In the properties editor go to the property Code Type and choose the Code Type CompanyTypeCodeType we have previously created. That’s all we need to do to fill the Code Type's values into the Radio Button Group.  
  
[[Image:Scout company type codetype radiobutton group add codetype.jpg]]  
+
[[Image:Scout-RadioButtonGroupSetCodeType.PNG]]  
  
 
<br>  
 
<br>  
Line 58: Line 57:
 
After adding this additional field, don't forget to update the form data: right-click on the CompanyForm and choose "Update Form Data"  
 
After adding this additional field, don't forget to update the form data: right-click on the CompanyForm and choose "Update Form Data"  
  
<br>  
+
<br>
 +
 
 +
== Update the Database Model  ==
 +
 
 +
The demo database already comes with a TYPE_UID column, so this is where we will store the company type. The following section explains how you would add other columns to the existing tables in your database.
 +
 
 +
{{note|Access Derby database|Eclipse Scout comes with the JDBC drivers and this tutorial comes with a database but in order to make changes to the database you need to [https://db.apache.org/derby/derby_downloads.html download Derby itself].}}
 +
 
 +
Install a binary distribution such as '''db-derby-10.9.1.0-bin.zip'''. Switch to the bin subdirectory and start '''ij.bat'''. Connect to your database using the same connect string you used for the SQL service.
 +
 
 +
<pre>
 +
ij version 10.9
 +
ij> connect 'jdbc:derby:c:/derbydb';
 +
ij>
 +
</pre>
 +
 
 +
{{warning|Troubleshooting|<code>ERROR XJ040: Failed to start database 'c:/derbydb' with class loader sun.misc.Launcher$AppClassLoader...</code>
 +
 
 +
<code>ERROR XSDB6: Another instance of Derby may have already booted the database C:\DerbyDB</code>
 +
These error messages indicate that you might still have your Scout server running. It is locking the database. Stop the server in the Scout perspective and try again.}}
 +
 
 +
Once connected here is how to examine the tables available:
  
== Update the Database Model ==
+
  ij> show schemas;
 +
  TABLE_SCHEM
 +
  ------------------------------
 +
  APP
 +
  MINICRM
 +
  ...
  
{{note|Access Derby database|Check the following link for [http://wiki.eclipse.org/Scout/Tutorial/Database_Development_Perspective#Access_the_Derby_database_on_the_Command_Line Derby command line access]
+
  ij> show tables in minicrm;
}}
+
  TABLE_SCHEM        |TABLE_NAME                    |REMARKS
 +
  ------------------------------------------------------------------------
 +
  MINICRM            |COMPANY                      |
 +
  MINICRM            |COMPANY_FIGURES              |
 +
  MINICRM            |CRM_SEQ                      |
 +
  ...
 +
 
 +
  ij> describe minicrm.company;
 +
  COLUMN_NAME        |TYPE_NAME|DEC&|NUM&|COLUM&|COLUMN_DEF|CHAR_OCTE&|IS_NULL&
 +
  ------------------------------------------------------------------------------
 +
  COMPANY_NR          |DECIMAL  |0  |10  |5    |NULL      |NULL      |NO
 +
  SHORT_NAME          |VARCHAR  |NULL|NULL|60    |NULL      |120      |NO
 +
  ...
  
If you want to add a new code type to your application, you probably need a new column in the database model as well. For our example you may use
+
This is how you might have added the missing column:
  
 
<code lang="sql">ALTER TABLE minicrm.company ADD COLUMN type_uid int;</code>
 
<code lang="sql">ALTER TABLE minicrm.company ADD COLUMN type_uid int;</code>
  
== Update the Form's Process Service ==
+
Finally:
 +
 
 +
  ij> disconnect;
 +
  ij> exit;
 +
 
 +
== Update the Form's Process Service ==
  
 
To read and write the values for the new Radio Button Field on the company dialog from and to the database, we need to adjust the CompanyProcessService:  
 
To read and write the values for the new Radio Button Field on the company dialog from and to the database, we need to adjust the CompanyProcessService:  
Line 76: Line 118:
 
public CompanyFormData create(CompanyFormData formData) throws ProcessingException {
 
public CompanyFormData create(CompanyFormData formData) throws ProcessingException {
 
     if (!ACCESS.check(new CreateCompanyPermission())) {
 
     if (!ACCESS.check(new CreateCompanyPermission())) {
       throw new VetoException(Texts.get("AuthorizationFailed"));
+
       throw new VetoException(TEXTS.get("AuthorizationFailed"));
 
     }
 
     }
 
     SQL.selectInto("" +
 
     SQL.selectInto("" +
Line 98: Line 140:
 
   public CompanyFormData load(CompanyFormData formData) throws ProcessingException {
 
   public CompanyFormData load(CompanyFormData formData) throws ProcessingException {
 
     if (!ACCESS.check(new ReadCompanyPermission())) {
 
     if (!ACCESS.check(new ReadCompanyPermission())) {
       throw new VetoException(Texts.get("AuthorizationFailed"));
+
       throw new VetoException(TEXTS.get("AuthorizationFailed"));
 
     }
 
     }
  
Line 121: Line 163:
 
   public CompanyFormData store(CompanyFormData formData) throws ProcessingException {
 
   public CompanyFormData store(CompanyFormData formData) throws ProcessingException {
 
     if (!ACCESS.check(new UpdateCompanyPermission())) {
 
     if (!ACCESS.check(new UpdateCompanyPermission())) {
       throw new VetoException(Texts.get("AuthorizationFailed"));
+
       throw new VetoException(TEXTS.get("AuthorizationFailed"));
 
     }
 
     }
  
Line 140: Line 182:
 
</source>  
 
</source>  
  
== Add a Company Rating Field to the Company Dialog (Smart Field) ==
+
== Add a Company Rating Field to the Company Dialog (Smart Field) ==
  
Repeat the steps above for a new code type '''CompanyRatingCodeType''' with the values A, B, C, D for both the database and the new enumeration on the shared node in the Scout Explorer.
+
Repeat the steps above for a new code type '''CompanyRatingCodeType''' with the values A, B, C, D for both the database and the new enumeration on the shared node in the Scout Explorer.  
  
Use 10100 for the parent code type, so that you have enough space to add other company types.
+
Use id 10100 for the CompanyRatingCodeType, so that you have enough space to add other company types.  
  
The result should look similar to
+
The result should look similar to  
  
[[Image:Scout company rating codetype overview.jpg]]  
+
[[Image:Scout-CodeTypeResult.PNG]]  
  
Back in Scout Explorer expand the tree: client &gt; Forms &gt; CompanyForm &gt; MainBox, right-click on ''MainBox'' and use context menu ''New Form Field… ''
+
Back in Scout Explorer expand the tree: client &gt; Forms &gt; CompanyForm &gt; MainBox, right-click on ''MainBox'' and use context menu ''New Form Field… '' Add a new form field of type ''SmartField'' with the name '''Company Rating''' and select '''CompanyRatingCodeType''' as the code type.  
Add a new form field of type ''SmartField'' with the name '''Company Rating''' and select '''CompanyRatingCodeType''' as the code type.
+
  
[[Image:Scout company rating new smartfield.jpg]]  
+
[[Image:Scout-NewSmartFieldCompanyRating.PNG]]  
  
As in the case abovee for the code type '''Company Type''' you will need to update the database model.
+
As in the case abovee for the code type '''Company Type''' you will need to update the database model. For reading and writing from and to the database we need to update the methods of the '''CompanyProcessService''' once more  
For reading and writing from and to the database we need to update the methods of the '''CompanyProcessService''' once more
+
  
 
<source lang="java">
 
<source lang="java">
 
public CompanyFormData create(CompanyFormData formData) throws ProcessingException {
 
public CompanyFormData create(CompanyFormData formData) throws ProcessingException {
 
     if (!ACCESS.check(new CreateCompanyPermission())) {
 
     if (!ACCESS.check(new CreateCompanyPermission())) {
       throw new VetoException(Texts.get("AuthorizationFailed"));
+
       throw new VetoException(TEXTS.get("AuthorizationFailed"));
 
     }
 
     }
 
     SQL.selectInto("" +
 
     SQL.selectInto("" +
Line 183: Line 223:
 
   public CompanyFormData load(CompanyFormData formData) throws ProcessingException {
 
   public CompanyFormData load(CompanyFormData formData) throws ProcessingException {
 
     if (!ACCESS.check(new ReadCompanyPermission())) {
 
     if (!ACCESS.check(new ReadCompanyPermission())) {
       throw new VetoException(Texts.get("AuthorizationFailed"));
+
       throw new VetoException(TEXTS.get("AuthorizationFailed"));
 
     }
 
     }
  
Line 208: Line 248:
 
   public CompanyFormData store(CompanyFormData formData) throws ProcessingException {
 
   public CompanyFormData store(CompanyFormData formData) throws ProcessingException {
 
     if (!ACCESS.check(new UpdateCompanyPermission())) {
 
     if (!ACCESS.check(new UpdateCompanyPermission())) {
       throw new VetoException(Texts.get("AuthorizationFailed"));
+
       throw new VetoException(TEXTS.get("AuthorizationFailed"));
 
     }
 
     }
  
Line 226: Line 266:
 
     return formData;
 
     return formData;
 
   }
 
   }
</source>
+
</source>  
  
== Conditional Dependencies Between Fields and Controlling Field Visibility ==
+
== Conditional Dependencies Between Fields and Controlling Field Visibility ==
  
In the Example above we added a Smart Field to choose a rating between A and D on the Company Form. To improve the usability of the company form, the rating field should only become visible, when the users selects '''Customer'' as the company type.
+
In the Example above we added a Smart Field to choose a rating between A and D on the Company Form. To improve the usability of the company form, the rating field should only become visible, when the users selects '''Customer'' as the company type.  
  
 
As there is a dependency between fields, we have to define a ''Master – Slave'' relation between the company type and the company rating field. For this we specify the master field on the (slave) form field.  
 
As there is a dependency between fields, we have to define a ''Master – Slave'' relation between the company type and the company rating field. For this we specify the master field on the (slave) form field.  
Line 236: Line 276:
 
Expand the tree in the Scout Explorer like: client &gt; Forms &gt; CompanyForm &gt; MainBox &gt; CompanyRatingField. Set the ''Master Field'' and ''Master Required'' as shown in the picture below.  
 
Expand the tree in the Scout Explorer like: client &gt; Forms &gt; CompanyForm &gt; MainBox &gt; CompanyRatingField. Set the ''Master Field'' and ''Master Required'' as shown in the picture below.  
  
[[Image:Scout company rating codetype smartfield master.jpg]]  
+
[[Image:Scout-CompanyRatingMaster.png]]  
  
Clicking on the green plus right of method ''Exec Changed Master Value'' adds the method ''execChangedMasterValue'' to the (slave) company rating field. Now we can control the fields visibility depending on the selected company type as follows
+
Untick ''Visible'' in the scout object properties of the ''CompanyRatingField''.
 +
 
 +
Clicking on the green plus right of method ''Exec Changed Master Value'' adds the method ''execChangedMasterValue'' to the (slave) company rating field. Now we can control the fields visibility depending on the selected company type as follows  
  
 
<source lang="java">
 
<source lang="java">
Line 256: Line 298:
 
         }
 
         }
 
       }
 
       }
</source>  
+
</source> <br>  
<br>  
+
  
 
When execChangedMasterValue is called, we check if the customer type value equals the Customer code. If so, the fields is set visible and enabled. In all other cases the field has to be invisible and disabled, as well as set to null  nothing must be written to the database.  
 
When execChangedMasterValue is called, we check if the customer type value equals the Customer code. If so, the fields is set visible and enabled. In all other cases the field has to be invisible and disabled, as well as set to null  nothing must be written to the database.  
  
This method ''execChangedMasterValue'' is called whenever the value in the defined master field (the company type field in this example) of the slave field (company rating field here) is changed.
+
This method ''execChangedMasterValue'' is called whenever the value in the defined master field (the company type field in this example) of the slave field (company rating field here) is changed.  
  
{{tip|Scout Utility Classes|calling a member means to make sure that the object is not null. Standard operations like comparisons etc. always follow the same pattern: first check for null values, second call the actual operation. To prevent the programmer from coding the same thing all over again, Scout often provides so called Utility classes, which make sure that no unnecessary Exceptions will be thrown.
+
{{tip|Scout Utility Classes|Calling a member means to make sure that the object is not null. Standard operations like comparisons etc. always follow the same pattern: first check for null values, second call the actual operation. To prevent the programmer from coding the same thing all over again, Scout often provides so called Utility classes, which make sure that no unnecessary Exceptions will be thrown.
  
Have a look at those Utility classes by pressing ctrl + alt + T and type *Utility. It's highly recommended to use these classes whenever possible.}}  
+
Have a look at those Utility classes by pressing ctrl + shift + T and type *Utility. It's highly recommended to use these classes whenever possible.}}  
  
Now that the Form works, we have to make sure that the rating value can be read and written from and to the database. So let's change the CompanyProcessService once more.  
+
Now that the Form works, we have to make sure that the rating value can be read and written from and to the database. So let's change the CompanyProcessService once more.
  
 
== Display Code Types in Tables  ==
 
== Display Code Types in Tables  ==
  
Whenever we want to display a Code Type in a table, we cannot just use the value returned by the database query. This out of the reason that Code Types IDs are stored and displaying IDs would mean nothing to a user.  
+
Whenever we want to display a Code Type in a table, we cannot just use the value returned by the database query: the table stores the Code Types IDs. Displaying these to the user would be confusing.
  
Instead we use a Smart Column, tell it which Code Type will be returned and let it translate the ID into a name. So let's add a new column to the CompanyTablePage and extend the StandardOutlineService.  
+
Instead, we use a Smart Column. If we tell it which Code Type to display, it can translate the ID to a name. So let's add a new column to the CompanyTablePage and extend the StandardOutlineService.
  
 
Expand the tree in Scout Explorer like: client &gt; All pages and right-click on CompanyTablePage &gt; Table &gt; Columns and choose New Column…  
 
Expand the tree in Scout Explorer like: client &gt; All pages and right-click on CompanyTablePage &gt; Table &gt; Columns and choose New Column…  
Line 281: Line 322:
 
Choose type Smart Column and fill in the information according to the picture.  
 
Choose type Smart Column and fill in the information according to the picture.  
  
[[Image:Scout company rating codetype smartcolumn.jpg]]  
+
[[Image:Scout-NewSmartTableColumn.PNG]]  
  
 
<br>  
 
<br>  
Line 300: Line 341:
 
</source>  
 
</source>  
  
[[Image:Scout company type rating codetype table.jpg]]
+
[[Image:Scout-SmartTableColumnResult.png]]

Latest revision as of 11:14, 24 October 2012

The Scout documentation has been moved to https://eclipsescout.github.io/.
Note.png
Scout Tutorial
This page belongs to the Minicrm Step-by-Step Tutorial. It explains how to add and use Code Types. You need to finish at least step Add a form in order to continue.


How to Create Code Types

Code Types always contain of an ID and a list of values.

Open the shared node in Eclipse Scout and expand the tree until you reach the Enumerations node. Right-click on the node and choose New Codetype… menu.

Scout-NewCodeType0.PNG

The Code ID needs to be an unique number, which helps to identify the values belonging to the Code Type.

The convention usually followed is that we always leave enough space between the Code Type's IDs, because the Code Type's values need IDs as well. The idea is that the IDs of Code Types and their values are close together (e.g. Code Type has the number 10000 and its values range from 10001 to 10099; the next Code Type has the number 10100).


Enter the information into the Code Type form according to the picture:

Scout-NewCodeType1.PNG


Right-click on the newly created Code Type and choose New Code…

Scout-NewCode.PNG


Increase the CompanyType Code Type's ID by 1 and assign it to the Code ID field. Give it a name like Customer.

Scout-newCode.png

Repeat these last two steps for two other codes called Supplier (Code ID: 10002), and Other (Code ID: 10003).


How to Use a Code Type in a Dialog (Radio Button Group)

So let's use the code type inside the Company Form: we are going to add a Radio Button Group containing those values.

In a Radio Button Group only one item can be selected at a time. This is exactly what we need here, as we don't like a company being both, customer and supplier.

Back in Scout Explorer we expand the tree like: client > Forms > CompanyForm and right-click on MainBox to choose New Form Field…

Choose RadioButtonGroup as Type, give it a name like CompanyType and press Finish.

Scout-NewRadioButtonGroup.PNG


In the properties editor go to the property Code Type and choose the Code Type CompanyTypeCodeType we have previously created. That’s all we need to do to fill the Code Type's values into the Radio Button Group.

Scout-RadioButtonGroupSetCodeType.PNG


After adding this additional field, don't forget to update the form data: right-click on the CompanyForm and choose "Update Form Data"


Update the Database Model

The demo database already comes with a TYPE_UID column, so this is where we will store the company type. The following section explains how you would add other columns to the existing tables in your database.

Note.png
Access Derby database
Eclipse Scout comes with the JDBC drivers and this tutorial comes with a database but in order to make changes to the database you need to download Derby itself.


Install a binary distribution such as db-derby-10.9.1.0-bin.zip. Switch to the bin subdirectory and start ij.bat. Connect to your database using the same connect string you used for the SQL service.

ij version 10.9
ij> connect 'jdbc:derby:c:/derbydb';
ij>
Warning2.png
Troubleshooting
ERROR XJ040: Failed to start database 'c:/derbydb' with class loader sun.misc.Launcher$AppClassLoader...

ERROR XSDB6: Another instance of Derby may have already booted the database C:\DerbyDB

These error messages indicate that you might still have your Scout server running. It is locking the database. Stop the server in the Scout perspective and try again.


Once connected here is how to examine the tables available:

 ij> show schemas;
 TABLE_SCHEM
 ------------------------------
 APP
 MINICRM
 ...
 ij> show tables in minicrm;
 TABLE_SCHEM         |TABLE_NAME                    |REMARKS
 ------------------------------------------------------------------------
 MINICRM             |COMPANY                       |
 MINICRM             |COMPANY_FIGURES               |
 MINICRM             |CRM_SEQ                       |
 ...
 
 ij> describe minicrm.company;
 COLUMN_NAME         |TYPE_NAME|DEC&|NUM&|COLUM&|COLUMN_DEF|CHAR_OCTE&|IS_NULL&
 ------------------------------------------------------------------------------
 COMPANY_NR          |DECIMAL  |0   |10  |5     |NULL      |NULL      |NO
 SHORT_NAME          |VARCHAR  |NULL|NULL|60    |NULL      |120       |NO
 ...

This is how you might have added the missing column:

ALTER TABLE minicrm.company ADD COLUMN type_uid int;

Finally:

 ij> disconnect;
 ij> exit;

Update the Form's Process Service

To read and write the values for the new Radio Button Field on the company dialog from and to the database, we need to adjust the CompanyProcessService:

public CompanyFormData create(CompanyFormData formData) throws ProcessingException {
    if (!ACCESS.check(new CreateCompanyPermission())) {
      throw new VetoException(TEXTS.get("AuthorizationFailed"));
    }
    SQL.selectInto("" +
        "SELECT MAX(COMPANY_NR)+1 " +
        "FROM   COMPANY " +
        "INTO   :companyNr"
        , formData);
 
    /*
     * NEW: TYPE_UID behind INSERT INTO
     * NEW: :companyTypeGroup in VALUES, field is named according to the inner class CompanyTypeGroup
     *      of CompanyForm
     */
    SQL.insert("" +
        "INSERT INTO COMPANY (COMPANY_NR, SHORT_NAME, NAME, TYPE_UID) " +
        "VALUES (:companyNr, :shortName, :name, :companyTypeGroup)"
        , formData);
    return formData;
  }
 
  public CompanyFormData load(CompanyFormData formData) throws ProcessingException {
    if (!ACCESS.check(new ReadCompanyPermission())) {
      throw new VetoException(TEXTS.get("AuthorizationFailed"));
    }
 
    /*
     * NEW: TYPE_UID in SELECT
     * NEW: :companyTypeGroup behind INTO, field is named according to the inner class CompanyTypeGroup
     *      of CompanyForm
     */
    SQL.selectInto("" +
        "SELECT SHORT_NAME, " +
        "       NAME," +
        "       TYPE_UID " +
        "FROM   COMPANY " +
        "WHERE  COMPANY_NR = :companyNr " +
        "INTO   :shortName," +
        "       :name, " +
        "       :companyTypeGroup"
          , formData);
    return formData;
  }
 
  public CompanyFormData store(CompanyFormData formData) throws ProcessingException {
    if (!ACCESS.check(new UpdateCompanyPermission())) {
      throw new VetoException(TEXTS.get("AuthorizationFailed"));
    }
 
    /*
     * NEW: TYPE_UID = :companyTypeGroup in SET, field is named according to
     *      the inner class CompanyTypeGroup of CompanyForm
     */
    SQL.update("" +
        "UPDATE COMPANY " +
        " SET SHORT_NAME = :shortName, " +
        "     NAME = :name, " +
        "     TYPE_UID = :companyTypeGroup " +
        "WHERE  COMPANY_NR = :companyNr "
        , formData);
 
    return formData;
  }

Add a Company Rating Field to the Company Dialog (Smart Field)

Repeat the steps above for a new code type CompanyRatingCodeType with the values A, B, C, D for both the database and the new enumeration on the shared node in the Scout Explorer.

Use id 10100 for the CompanyRatingCodeType, so that you have enough space to add other company types.

The result should look similar to

Scout-CodeTypeResult.PNG

Back in Scout Explorer expand the tree: client > Forms > CompanyForm > MainBox, right-click on MainBox and use context menu New Form Field… Add a new form field of type SmartField with the name Company Rating and select CompanyRatingCodeType as the code type.

Scout-NewSmartFieldCompanyRating.PNG

As in the case abovee for the code type Company Type you will need to update the database model. For reading and writing from and to the database we need to update the methods of the CompanyProcessService once more

public CompanyFormData create(CompanyFormData formData) throws ProcessingException {
    if (!ACCESS.check(new CreateCompanyPermission())) {
      throw new VetoException(TEXTS.get("AuthorizationFailed"));
    }
    SQL.selectInto("" +
        "SELECT MAX(COMPANY_NR)+1 " +
        "FROM   COMPANY " +
        "INTO   :companyNr"
        , formData);
 
    /*
     * NEW: RATING_UID behind INSERT INTO
     * NEW: :companyRating in VALUES, field is named according to the inner class CompanyRating
     *      of CompanyForm
     */
    SQL.insert("" +
        "INSERT INTO COMPANY (COMPANY_NR, SHORT_NAME, NAME, TYPE_UID, RATING_UID) " +
        "VALUES (:companyNr, :shortName, :name, :companyTypeGroup, :companyRating)"
        , formData);
    return formData;
  }
 
  public CompanyFormData load(CompanyFormData formData) throws ProcessingException {
    if (!ACCESS.check(new ReadCompanyPermission())) {
      throw new VetoException(TEXTS.get("AuthorizationFailed"));
    }
 
    /*
     * NEW: RATING_UID in SELECT
     * NEW: :companyRating behind INTO, field is named according to the inner class CompanyRating
     *      of CompanyForm
     */
    SQL.selectInto("" +
        "SELECT SHORT_NAME, " +
        "       NAME," +
        "       TYPE_UID, " +
        "       RATING_UID " +
        "FROM   COMPANY " +
        "WHERE  COMPANY_NR = :companyNr " +
        "INTO   :shortName," +
        "       :name, " +
        "       :companyTypeGroup, " +
        "       :companyRating "
          , formData);
    return formData;
  }
 
  public CompanyFormData store(CompanyFormData formData) throws ProcessingException {
    if (!ACCESS.check(new UpdateCompanyPermission())) {
      throw new VetoException(TEXTS.get("AuthorizationFailed"));
    }
 
    /*
     * NEW: RATING_UID = :companyRating in SET, field is named according to
     * the inner class CompanyRating of CompanyForm
     */
    SQL.update("" +
        "UPDATE COMPANY " +
        " SET SHORT_NAME = :shortName, " +
        "     NAME = :name, " +
        "     TYPE_UID = :companyTypeGroup, " +
        "     RATING_UID = :companyRating " +
        "WHERE  COMPANY_NR = :companyNr "
        , formData);
 
    return formData;
  }

Conditional Dependencies Between Fields and Controlling Field Visibility

In the Example above we added a Smart Field to choose a rating between A and D on the Company Form. To improve the usability of the company form, the rating field should only become visible, when the users selects 'Customer as the company type.

As there is a dependency between fields, we have to define a Master – Slave relation between the company type and the company rating field. For this we specify the master field on the (slave) form field.

Expand the tree in the Scout Explorer like: client > Forms > CompanyForm > MainBox > CompanyRatingField. Set the Master Field and Master Required as shown in the picture below.

Scout-CompanyRatingMaster.png

Untick Visible in the scout object properties of the CompanyRatingField.

Clicking on the green plus right of method Exec Changed Master Value adds the method execChangedMasterValue to the (slave) company rating field. Now we can control the fields visibility depending on the selected company type as follows

      @Override
      protected void execChangedMasterValue(Object newMasterValue) throws
ProcessingException {
 
        if (CompareUtility.equals(getCompanyTypeGroup().getValue(), 
            CompanyTypeCodeType.CustomerCode.ID)) {
          setEnabled(true);
          setVisible(true);
        }
        else {
          setEnabled(false);
          setVisible(false);
          setValue(null);
        }
      }

When execChangedMasterValue is called, we check if the customer type value equals the Customer code. If so, the fields is set visible and enabled. In all other cases the field has to be invisible and disabled, as well as set to null  nothing must be written to the database.

This method execChangedMasterValue is called whenever the value in the defined master field (the company type field in this example) of the slave field (company rating field here) is changed.

Idea.png
Scout Utility Classes
Calling a member means to make sure that the object is not null. Standard operations like comparisons etc. always follow the same pattern: first check for null values, second call the actual operation. To prevent the programmer from coding the same thing all over again, Scout often provides so called Utility classes, which make sure that no unnecessary Exceptions will be thrown. Have a look at those Utility classes by pressing ctrl + shift + T and type *Utility. It's highly recommended to use these classes whenever possible.


Now that the Form works, we have to make sure that the rating value can be read and written from and to the database. So let's change the CompanyProcessService once more.

Display Code Types in Tables

Whenever we want to display a Code Type in a table, we cannot just use the value returned by the database query: the table stores the Code Types IDs. Displaying these to the user would be confusing.

Instead, we use a Smart Column. If we tell it which Code Type to display, it can translate the ID to a name. So let's add a new column to the CompanyTablePage and extend the StandardOutlineService.

Expand the tree in Scout Explorer like: client > All pages and right-click on CompanyTablePage > Table > Columns and choose New Column…

Idea.png
All roads lead to Rome
Wherever CompanyTablePage has been linked to, we'll find it (e.g. client > Desktop > StandardOutline > Child Pages > CompanyTablePage). Nevertheless, all pages, no matter where they are linked to, are situated in: client > All pages.


Choose type Smart Column and fill in the information according to the picture.

Scout-NewSmartTableColumn.PNG


Adjust the getCompanyTableData method in the StandardOutlineService (server > Outline Services > StandardOutlineService):

/*
 * NEW: TYPE_UID behind SELECT
 */
 statement.append(
 "SELECT COMPANY_NR, " +
 "       SHORT_NAME, " +
 "       NAME, " +
 "       TYPE_UID " +
 " FROM COMPANY " +
 " WHERE 1 = 1 ");

Scout-SmartTableColumnResult.png

Back to the top