Ariba eForm - Part II (Advanced)

Complete the Group definition
Last time we only created the aml class, but we did not define some groups in the class properties that will be used for details view or search view for example, so we’ll need to complete this. As eForm extends Approvable, they inherit a Name field (which is defaulted by Ariba) which we do not want to see here so the group definition will look as below:

  <inModule name="ariba.common.meta.Requisition">
    
    <group name="HeaderDetailsEditable">
        <groupClass name="config.sandbox.supplier.eform.SupplierEForm">
            <remove>
                <groupField name="Name"/>
            </remove>
        </groupClass>
    </group>
    
    <group name="HeaderDetailsNoneditable">
        <groupClass name="config.sandbox.supplier.eform.SupplierEForm">
            <groupField name="SupplierName"/>
            <groupField name="SupplierDUNSId"/>
        </groupClass>
    </group>
    
    <group name="SupplierEFormDetailsGroup">
        <groupClass name="config.sandbox.supplier.eform.SupplierEForm">
            <groupField name="SupplierName"/>
            <groupField name="SupplierDUNSId"/>
        </groupClass>
    </group>
    
    <group name="SupplierEFormSearchGroup">
        <groupClass name="config.sandbox.supplier.eform.SupplierEForm">
            <groupField name="SupplierName"/>
            <groupField name="SupplierDUNSId"/>
        </groupClass>
    </group>
    
  </inModule>

 

Wizard : make it nice
By default, we’ve seen that Ariba creates the eForm and associates the standard “3-steps” wizard. Actually as we have little information to enter, we can get rid of the first screen. Copy the file ariba/variants/Plain/wizards/Eform/Eform.awz to config/variants/Plain/wizards/Eform/SupplierEForm.awz (see wizardFile property in previous post) and remove the 2 lines that declares the first screens

        <step name="TitleFrame" file="Title.afr"/>
        <step name="FormFrame" file="Form.afr"/>

 Now when you open the eform, there’s only 1 screen with everything (summary and approval flow tab) :

Approval Rules : lets the eForm be approved
Create a new rule for the eForm we created (Go to the Administration Manager, then under Customization Manager click on Rule Editor and click on the Create New Rule Set (top left button))

    give a name to your file, generally JavaScript Rules, here we’ll have JavaScript SupplierEForm Rules
    Select your variant (Plain, you can define at a variant level if you want to have variant specific rule)
    From the Approvable drop down, select the class name
    Make it active and to be loaded at loaddb 9r1 has really simplified the creation of new rules, Before you would have add a simple rule and write in code both condition and action, something like:
function suppliermanager_condition (r) 
{
    return true;
}
suppliermanager_condition;

var SupplierManagerGroup = Group.getGroup("Supplier Manager");

function suppliermanager_action (r) 
{
    return ApprovalRequest.create(r,
                               SupplierManagerGroup,
                               true,
                               "ruleReasons", "SupplierManagerApproves");
}
suppliermanager_action;

Now you can do it via UI and it looks something like:

Again, you can create a new Edit Rule by UI

This Edit Rule tells the system that any user of the Supplier Manager group can edit the eForm and approval is not regenerated.


Workflow : let the supplier be created
The eForm workflow is like a state diagram; it describes the possible state of the eForm and declares action which will take place at the different state of the eForm. In our example, we want a supplier to be created once the eForm is approved, so we need to add a workflow file under config/variants/Plain/workflows/ SupplierEFormWorkflow.efm and define it as

<!DOCTYPE workflow SYSTEM "../../../../ariba/server/workflowserver/workflow.dtd">
<workflow name="SupplierEForm"
          workflowClass="config.sandbox.supplier.eform.SupplierEForm"
          description="This is our supplier eForm workflow - create suppliers once request is approved">
          
    <beginState name="BEGIN">
            <transition name="BEGIN_TO_APPROVED">
                <fromState name="BEGIN"/>
                <event type="SupplierEForm:Approved"/>
                <toState name="APPROVED"/>
            </transition >
    </beginState>
    
    <state name="APPROVED">
        <entry>
            <action implementation="config.sandbox.supplier.action.SupplierEFormApproved"/>
        </entry>
    </state>
</workflow>

From the workflow definition : You can name your workflow as you want but it is important (we’ll see in a minute) The workflow class must match our supplier eForm class so the system knows this workflow will act on this class Now you define the state. Here we say that the approval starts with state BEGIN; and we have a transition from BEGIN to APPROVED, note the event type is SupplierEForm:Approved, this is the name of the workflow with the new state, so you can reference other workflows. For example if you look at more advanced workflow like Purchasing or Invoicing workflows, the transition occurs when other workflow are triggered. We tell the system that when he enters the APPROVED state, it must run a given action. This action is a java class and will create our supplier. The action class is defined as following:

public class SupplierEFormApproved extends Action
{
    public static String className = SupplierEFormApproved.class.getName();

    /**
     * Entry point of the Action
     * 
     * @param object
     * @param params
     * @see ariba.base.fields.Action#fire(ariba.base.fields.ValueSource, ariba.util.core.PropertyTable)
     */
    public void fire (ValueSource obj, PropertyTable arg1)
    throws ActionExecutionException
    {
        ClusterRoot eform = (ClusterRoot) obj;
        createSupplier(eform);
    }

    private void createSupplier (ClusterRoot cr) {
        // create a new partitioned supplier
        Supplier supplier = createPartitionedSupplier(cr);

        // use post load integration event to link with common supplier
        IntegrationPostLoadSupplier updateSupplier = new IntegrationPostLoadSupplier();
        updateSupplier.fire(supplier, null);
    }

    /**
     * This method creates a new partitioned supplier with the minimum necessary values
     * based from values in eform and link to a common supplier.
     * @param eform the eform which contains the supplier values
     * @return a new partitioned supplier
     */
    private Supplier createPartitionedSupplier (ClusterRoot eform) {
        // ---------------------------------
        // create the new supplier
        // ---------------------------------
        Supplier supplier = new Supplier (eform.getPartition());

        // set header supplier values from eForm
        supplier.setUniqueName(eform.getUniqueName());
        supplier.setName((String)eform.getFieldValue("SupplierName"));
        
        supplier.setSupplierIDDomain(Organization.BuyerSystemID);
        supplier.setSupplierIDValue(eform.getUniqueName());

        // add the duns as a new organizationIdPart
        
        // ---------------------------------
        // save object
        // ---------------------------------
        supplier.save();

        return supplier;
    }

    /**
     * allowed types for the value
     */
    protected ValueInfo getValueInfo ()
    {
        return new ValueInfo(IsScalar, Approvable.ClassName);
    }
}

Okay, we’re done, when the eform will be approved a new supplier will automatically be created.

 

Comments 15 | Views: 15466 | Read more...

Analysis Dataload

A quick ticket to indicate procedure to load a new fields in Analysis using existing dataloads :

1. Create a field in sourcing project (ACM)

<extension name="config.variants.Plain.extensions.collaborate.sourcing.SourcingProjectExt">
    <inModule name="ariba.sourcing.rfx.Projects"> 
        <inClass name="ariba.sourcing.rfx.SourcingProject"> 
            <field name="Budgeted"> 
                <type class="boolean" /> 
                <properties controller="ariba.htmlui.fieldsui.fields.ARFYesNo"/> 
            </field> 
        </inClass> 
    </inModule> 
</extension>

 

2. Create the corresponding field in analysis fact

<inModule name="ariba.analytics.core.Analytics">
    <inFact name="ariba.analytics.fact.SourcingProject">
        <field name="Budgeted"
               nullAllowed="true"
               inlineDimension="true">
            <type class="boolean"/>
            <properties rank="100"
                        description="Budgeted"
                        label="Budgeted"/>
        </field>
    </inFact>
</pre>

 

3. In previous version we had the information about the dataload from the analysis admin console, this has been removed on 9r1 version, so you need to know the dataload model in order to know which dataload you want to extend.

4. Extend the dataload

<inDataLoad name="ACMSourcingProject">
    <fieldMappings>
        <field name="Budgeted">
            <aqlMapping selectField="Project.Budgeted"/>
        </field>
    </fieldMappings>
</inDataLoad>

 

5. run the incremental analysis load

Comments 0 | Views: 4242 | Read more...

Ariba eForm - Part I

I’ve been amazed when I reviewed a thread on Ariba exchange talking about Ariba eForm (http://exchange.ariba.com/thread/1279), the thread reached more than 500 views.
Seems like a lot of people have an interest about Ariba eForms but as it is said in the thread, there’s little information/documentation about them, so let this blog adds some piece of documentation.

So what's an eForm ?

Let’s make it simple, Ariba eForm is a way to make any form-like in an electronic manner. Think about all those excel and pdf files that are floating around and you have to exchange by mail or signed paper; there’s many occasions where an eForm could replace them.
An eForm can contain any data field, simple type like text, number, and dates or object type like user, supplier … and even documents can be stored in eForm.
EForm supports approval workflow so it’s perfect to replace your signed paper that you exchange by envelope or scanned documents exchanged by mail.
Examples of eForm (among others) are timesheet report, expense report (Ariba leverage the original eForm and make it a module by itself in newer version) and supplier creation request.
Let’s take this last example to walkthrough an EForm creation. Many organizations already implemented their own supplier management eForm; this post is just to take an example to present the feature of eForm.

EForm Requirement

Users can request for a supplier to be created, this will be approved by a supplier manager who will review and complete the information given and process the creation of a new supplier.
In the first part, we will discuss the creation of the metadata for the new eform and enable the eform in the application. In a second part we will discuss more the UI of an eform through the wizard, the approval rules associated to the eForm and the workflow.

Declare the eForm class

We will dive into some aml coding. EForms are just standard aml class that needs to extend Approvable.

    <class name="config.sandbox.supplier.eform.SupplierEForm"
           prefix="fhsef"
           partitioned="true"
           super="ariba.approvable.core.Approvable">
        
        <field name="SupplierName">
            <type class="java.lang.String" length="255"/>
            <properties label="@config.sandbox.eform.supplier/SupplierNameLabel"
                        rank="100"
                        required="true"/>
        </field>

        <field name="SupplierDUNSId">
            <type class="java.lang.String" length="15"/>
            <properties label="@config.sandbox.eform.supplier/SupplierDunsLabel"
                        rank="200"
                        prototypeValue="12-345-6789"
                        format="DD-DDD-DDDD"/>
        </field>

        <overrides>
            <override name="ClassProperties">
                <properties uiName = "Supplier Request"
                            copyable="false"
                            printable="true"
                            detailsGroup="SupplierEFormDetailsGroup"
                            searchGroup="SupplierEFormSearchGroup"
                            wizardFile="Eform/Eform.awz"
                            _workflowName="SupplierEForm"
                            _workflowEvent="SupplierEForm:Approved"/>
             </override>
        </overrides>

I will not detail line by line but pick the interesting part:

  • Line 1-4 : this is the class declaration, a eForm must be a subclass of the ariba.approvable.core.Approvable class
  • Line 6-11 : declare a first field, this will be our supplier name, this field should be required to save an eForm
  • Line 13-19 : declare a second field, this will be our duns Id, this is required if the current user is from the Supplier Manager group (we will see later that this group has to approve the request)
  • Line 23-30 : this is the properties of the class eForm. You cannot make a copy of the request (the copy button is not visible) and we enabled the print button
  • The uiName is the name that will appear under the create menu – XXXX check if reload or only load at approvabletype run
  • We reference the default wizard file provided by Ariba (we’ll change this in the second part)

Declare the new eForm as Approvable

You would need to edit the ApprovableType.csv file for all the partitions where you will want to use the new eForm and add a line such as:

"config.sandbox.supplier.eform.SupplierEForm", "true", "CreateRequisition", "false", "", "", "EditApprovable", "RemoveAnyApprovalRequest", "AddApprovalRequest", "SEFR", "10", "ariba.common.core.ApprovableNotificationPreferences", "27", "true", "true", "true", "true", "true", "true", "true", "Eform", "", "1000"

The principal fields for the ApprovableType file are:

"ApprovableClassName",

Name of the eForm class

"Restricted",

Is the creation of the eForm restricted – if yes, the next value (ie "Permission") must be set with a valid permission

"QueryRestricted",

If there is restriction on searching the eForm

If yes, the next value (ie QueryPermission") must be set with a valid permission

"EditApprovable",

Specifies who can edit the eForm after it has been submitted for approval

"ApprovableIdPrefix",

The prefix for the Id of documents we’ll create, set to SEFR (Supplier EForm)

"ApprovableIdInitialValue",

The starting number for new approvables of this type. It defaults to 10.

"ModuleName",

Must be Eform (as it is defined in your p.table file, see below)

"DoctypeCategory",

Leave it empty if you want users to access the creation eform link directly from the create portlet

You can use an existing category or create new one of you have many eform that you want to group

  

Configuration for eForm

You would need to check your config/Parameters.table file (aka p.table file) and make sure the eForm value is properly set:

System.Base.Modules = (…., Eform, …);

System.Base.UIModules = (…,ariba.htmlui.eform.EformModule, .…);

Once all the above is done, you can restart Ariba Buyer.

After the system is up and running, run the ApprovableTypePull event with the updated file. You will need to run the event for each of the partition where you want the eform to be available.
Your eForm will be available when you log in a partition where the eForm is enabled:

Comments 4 | Views: 19594 | Read more...

Develop new custom Ariba portlet for your dashboard

With Ariba 9r1 you can customize your dashboard to add/edit the content which is super cool. The Ariba dashboard is made of portlet, each portlet is defined from an xml file, Ariba documents how to create new portlet but the different examples given in the documentation always refer to another web page, which is nice but limited if you want to have your own data displayed in a portlet.
In this example, I will write a portlet to pull some exchange rate between different currencies and display them to the user.
Basically and to keep it short, a portlet is defined in xml file and the content of the portlet is nothing more than an Ariba component (awl)

 

1. Define your portlet in config/variants/Plain/portlets/Portlet.xml

<PortletProviders>
    <PortletProvider stringFile="&lt;ProviderURL&gt;/ad/stringFile/PortletProviderActions?stringFile=ariba.analytics.portlets">
        <UniqueName>FHSolution Ariba Sandbox</UniqueName>
        <DisplayName>FHSolution Ariba Sandbox - Portlet Example</DisplayName>
        <Description>Custom content provided by www.fhsolution.com</Description>
        <HttpUR<&HttpURL;</HttpUR<
        <ServerUR<&ServerURL;</ServerUR<
        <Portlets>
            <Portlet>
                <UniqueName>PortletDemo</UniqueName>
                <DisplayName>Demo Ariba Portlet</DisplayName>
                <Description>Ariba Custom Portlet pulling financial exchange rate data</Description>
                <Controller>&lt;ProviderURL&gt;/ad/&lt;action&gt;/config.sandbox.dashboard.DemoPortletController</Controller>
                <ContentType>HTML</ContentType>
                <IsSingleton>true</IsSingleton>
                <IsEditable>false</IsEditable>
                <IsTOC>false</IsTOC>
                <SetupRequired>true</SetupRequired>
            </Portlet>
        </Portlets>
    </PortletProvider>
</PortletProviders>


In my example, I am using the analytics portlet provider so the portlet controller I am writing will extend AnalysisPortletController

2. Define the controller config.sandbox.dashboard.DemoPortletController

public class DemoPortletController extends AnalysisPortletController {

    protected boolean isUserAuthorizedForContent(User realUser, User effectiveUser) {
        return super.isUserAuthorizedForContent(realUser, effectiveUser);
    }

    @Override
    protected String editComponentName() {
        return null;
    }

    @Override
    protected String viewComponentName() {
        return DemoPortletContent.class.getName();
    }

    protected String portletTypeName () {
        return "Ariba Portlet Demo";
    }
}

The 2 main methods are

    protected String editComponentName() 

and

    protected String viewComponentName()

In this example, I only want to display information and the users cannot edit the component (you could imagine the user can edit the component to select the currency he wants to have appear) The viewComponentName refers to the awl component defined to display the exchange rate

3. Writing the portlet component

If you never wrote an awl component, it is (generally) made of 2 files :

  • The awl view
  • The corresponding java model

It is good practice (and the default) to have the 2 files in the same package/corresponding directory even if you can override some methods to have the awl in the directory you want.

In my case, the awl will be define in config/sandbox/dashboard/

<awconditional iftrue="$hasErrors">
    <span class="error">
        <awlocal key="a001">
            Error getting content for demo portlet.
        </awlocal>
    </span>
    <awelse equalnull="$content">
        <awlocal key="a002">
          The webservice site is not accessible and rendering of the portlet is not possible.
        </awlocal>
    <awelse>
       <awprimitivestring value="$content"/>
    </awelse>
    </awelse>
</awconditional>

The java model class will be define in package config.sandbox.dashboard :

public class DemoPortletContent extends PortletContent {

    public String _content;
    public boolean _hasErrors;

    public void initialize(PortletConfig portletConfig) {
        super.initialize(portletConfig);
        _content = null;
        _hasErrors = false;
        try {
            _content = getContent();
        } catch (IOException ex) {
            _hasErrors = true;
        }
    }

    public final static String getContent() throws IOException {
        String content = "";

        content += Fmt.S("1 EUR = %s USD<br/>", getRate("EUR", "USD"));
        content += Fmt.S("1 EUR = %s CHF<br/>", getRate("EUR", "CHF"));
        content += Fmt.S("1 EUR = %s GBP<br/>", getRate("EUR", "GBP"));

        return content;
    }

    /**
     * @see ariba.portlet.component.PortletContent#getContentType()
     */
    @Override
    public String getContentType() {
        return Constants.TypeHTML;
    }
    ...

It is not the scope of this post but here is the method to retrieve the currency rate (I know there are better methods but for the purpose of this blog it works fine) – if you are interested you can review the DemoPortletContent.java file

4. Add your portlet to the dashboard

You will need to restart your Ariba instance and after that you can add your new content to the dashboard
select the content to add :

Adding content to dashboard

And see your new portlet added on the dasboard :

New portlet on dashboard

Happy coding,

Fred

Tags: Ariba
Comments 0 | Views: 0 | Read more...

Remote debugging with Eclipse for Ariba development

Hello everyone,

I believe most people will already know it but for new comers on Ariba development, it can be of an help.

If you develop a lot on Java for your Ariba customization you might want to set up remote debugging (I do it anyway for any new instances that I set up) so you can actually debug your code and do not need tons of logging.

1. Modify the launch of your instance (can be sourcing (upstream) or buyer (downstream)) , so for example with weblogic modify the config.xml and in the serverstart tag change the Arguments property to add the following arguments "-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=<port>" so the ServerStart will look like

  
<server>
    <name>asmserver1</name>
    ....
    <listen-address>127.0.0.1</listen-address>
    <server-start>
      <class-path>...</class-path>
      <arguments>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=50005 -Xms256m -Xmx512m -Xss1m -XX:MaxPermSize=256M -Dweblogic.net.http.URLStreamHandlerFactory=ariba.util.net.URLStreamHandlerFactory -Dariba.server.home=D:\ariba\customer9r1\Sandbox\Sourcing\Server</arguments>
</server-start>
</server>

2. Configure Eclipse

go to Run/debug...
create a new Remote Java Application
select your ariba project and under connection properties,
select Host : 127.0.0.1 (it must match the value you have for the listen-address argument)
Port : 50005

click Apply

14-10-2011 09-02-23


If the parameters are not correct and eclipse cannot link to the JVM it will pop up an error message.

14-10-2011 09-24-08


Most probably the port is already in use or one of the parameter is not correct and does not match with your configuration.

3. In your java file, just put breakpoint where you want your code to stop (make sure your build is set up to compile with the debug flag set to true)

when everything is configured :

  • start eclipse
  • start your ariba instance
  • launch debug

when the program will encounter a breakpoint, it will stop and pop up eclipse debug view.

14-10-2011 09-09-09

 

of course this is only for dev purpose and should not be use in any case on prod instance

 

Hope this helps,

Fred

Tags: Ariba, Java
Comments 4 | Views: 3935 | Read more...

Warning: Illegal string offset 'active' in /homepages/11/d292190974/htdocs/templates/fh_solution/html/pagination.php on line 94

Warning: Illegal string offset 'active' in /homepages/11/d292190974/htdocs/templates/fh_solution/html/pagination.php on line 100

Warning: Illegal string offset 'active' in /homepages/11/d292190974/htdocs/templates/fh_solution/html/pagination.php on line 94

Warning: Illegal string offset 'active' in /homepages/11/d292190974/htdocs/templates/fh_solution/html/pagination.php on line 100