Skip Headers

Agile Product Lifecycle Management SDK Developer Guide - Using APIs Release 9.3.3 E39307-01 |
| Contents

Previous | Next |

# 19 Working with Product Cost Management

This chapter includes the following:

- Overview

- Working with Price Objects

- Working with Suppliers

- Working with Sourcing Projects

## 19.1 Overview

The Product Sourcing module of the Agile PLM supports, enhances, and simplifies the handling of all product cost-related data throughout the product lifecycle. This enables you to effectively manage and manipulate Sourcing content, collaborate with suppliers to establish new Sourcing content, and analyze the data. Product Sourcing supports the following functions:

- Create Sourcing Projects

- Gather and prepare product content

- Leverage pricing contracts and history

- Create Request for Quote (RFQ) objects

- Manage supplier RFQ responses and negotiate pricing (Not supported by PCM SDK)

- Conduct Sourcing Project analysis

The Agile API supports the following Product Sourcing objects:

- IChange - This interface is for the Change class, which includes Price Change Orders (PCOs).

- IPrice - This interface is for the Price class, which handles both published prices and historical prices.

- IProject - This interface is for the Sourcing Projects class, which is the container used for product Sourcing data.

- IRequestForQuote - This interface is for the RequestForQuote class, which represents an RFQ for a Sourcing Project.

- ISupplier - This interface is for the Supplier class.

Except for the ISupplierResponse object, the Agile API allows you to read and modify all Product Sourcing objects. The following table lists the create, read, and modify rights for Product Sourcing objects.

Object | Create | Read | Modify
--- | --- | --- | ---
IChange (including PCO) | Yes | Yes | Yes
IPrice | Yes | Yes | Yes
IProject | Yes | Yes | Yes
IRequestForQuote | Yes | Yes | Yes
ISupplier | Yes | Yes | Yes

## 19.2 Working with Price Objects

Agile PLM's price management solution replaces inefficient manual systems, where prices are often stored in files, spreadsheets, or databases in disparate locations. The Agile PLM system allows you to create and centrally manage prices and terms for items and manufacturer parts.

There are two out-of-the-box Price classes provided with the system:

- Historical Quotes - This is a historical Quote object that contains price quotes from previous Sourcing projects or legacy data.

- Published Prices - This is a historical Published Price that contains published prices or contract prices on current items and manufacturer parts.

These are the basic steps used to define pricing for an item or manufacturer part:

1. Users with the appropriate role can create a new Price object, specifying the Number, Description, Item or Manufacturer Part, Supplier, Site, and Customer.

2. After creating a Price object, users can build out a price/terms matrix for each associated item or manufacturer part. The price and terms matrix includes Effectivity Dates, Quantity, Price, and Cancellation Windows.

3. The Price object is submitted and goes through a Workflow approval process. Other users can approve or reject the object.

4. Users with the appropriate role can create a Price Change Order (PCO) to modify a Price object that has been released. The updated Price object is again submitted for approval.

### 19.2.1 Loading a Price Object

To load a Price object, use the IAgileSession.getObject() method. To uniquely identify a Price object, specify the value for the Title Block | Number attribute.

Example: Loading a Price object

    public IPrice getPrice() throws Exception {
    DateFormat df = new SimpleDateFormat("MM/dd/yy");

IPrice price = (IPrice)m_session.getObject(IPrice.OBJECT_TYPE, "PRICE10008");

return price;

    }

For a list of Price object tables, refer to the Javadoc generated HTML files that document the SDK code. You can find them in the HTML folder in SDK_samples (ZIP file). To access this file, see the Note in Client-Side Components on page 2.

### 19.2.2 Adding Price Lines

The Price Lines table of a Price object is where you define the prices and terms for the related item or manufacturer part. When you add a row to the Price Lines table, you must initialize the row with values. At a minimum, you must specify values for the following attributes:

- ATT_PRICE_LINES_SHIP_FROM

- ATT_PRICE_LINES_SHIP_TO

- ATT_PRICE_LINES_PRICE_EFFECTIVE_FROM_DATE

- ATT_PRICE_LINES_PRICE_EFFECTIVE_TO_DATE

- ATT_PRICE_LINES_QTY

If you fail to specify a value for one of these attributes, the Price Lines row is not created.

#### 19.2.2.1 Required Attributes to Create Price Lines

The minimum required attributes to create Price Lines are:

- ATT_PRICE_LINES_SHIP_TO

- ATT_PRICE_LINES_PRICE_EFFECTIVE_FROM_DATE

- ATT_PRICE_LINES_CURRENCY_CODE

Example: Adding price lines

    public void addPriceLines(IPrice price) throws Exception {

IAgileClass cls = price.getAgileClass();

ITable table = price.getTable(PriceConstants.TABLE_PRICELINES);

IAttribute attr = null;

IAgileList listvalues = null;

HashMap params = new HashMap();

//Set Ship-To Location (List field)

attr = cls.getAttribute(PriceConstants.ATT_PRICE_LINES_SHIP_TO);

listvalues = attr.getAvailableValues();

listvalues.setSelection(new Object[] { "San Jose" });

params.put(PriceConstants.ATT_PRICE_LINES_SHIP_TO, listvalues);

    //Set Ship-From Location (List field)
    //Get the PCO class

attr = cls.getAttribute(PriceConstants.ATT_PRICE_LINES_SHIP_FROM);

listvalues = attr.getAvailableValues();

listvalues.setSelection(new Object[] { "Hong Kong" });

params.put(PriceConstants.ATT_PRICE_LINES_SHIP_FROM, listvalues);

    //Set Effective From (Date field)
    //Set Effective To (Date field)

params.put(PriceConstants.ATT_PRICE_LINES_PRICE_EFFECTIVE_FROM_DATE, df.parse("10/01/03"));

params.put(PriceConstants.ATT_PRICE_LINES_PRICE_EFFECTIVE_TO_DATE, df.parse("10/31/03"));

    //Set Quantity (Number field)
    //Set Currency Code (List field)

params.put(PriceConstants.ATT_PRICE_LINES_QTY, new Integer(1000));

attr = cls.getAttribute(PriceConstants.ATT_PRICE_LINES_CURRENCY_CODE);

listvalues = attr.getAvailableValues();

listvalues.setSelection(new Object[] { "USD" });

params.put(PriceConstants.ATT_PRICE_LINES_CURRENCY_CODE, listvalues);

    //Set Total Price (Money field)
    //Set Total Material Price (Money field)

params.put(PriceConstants.ATT_PRICE_LINES_TOTAL_PRICE, new Money(new Double(52.95), "USD"));

params.put(PriceConstants.ATT_PRICE_LINES_TOTAL_MATERIAL_PRICE, new Money(new Double(45.90), "USD"));

    //Set Total Non-Materials Price (Money field)
    //Set Lead Time (Number field)

params.put(PriceConstants.ATT_PRICE_LINES_TOTAL_NON_MATERIAL_PRICE, new Money(new Double(7.05), "USD"));

params.put(PriceConstants.ATT_PRICE_LINES_LEAD_TIME, new Integer(5));

    //Set Transportation Time (List field)

attr = cls.getAttribute(PriceConstants.ATT_PRICE_LINES_TRANSPORTATION_TIME);

listvalues = attr.getAvailableValues();

listvalues.setSelection(new Object[] { "FOB" });

params.put(PriceConstants.ATT_PRICE_LINES_TRANSPORTATION_TIME, listvalues);

    //Set Country of Origin (List field)

attr = cls.getAttribute(PriceConstants.ATT_PRICE_LINES_COUNTRY_OF_ORIGIN);

listvalues = attr.getAvailableValues();

listvalues.setSelection(new Object[] { "United States" });

params.put(PriceConstants.ATT_PRICE_LINES_COUNTRY_OF_ORIGIN, listvalues);

    //Create a new Price Lines row and initialize it with data
    }

IRow row = table.createRow(params);

### 19.2.3 Creating a Price Change Order

Price objects such as published prices and contracts have a revision history. To modify a released Price object, you must first create a Price Change Order (PCO) and adding the Price object to the Affected Prices table. The PCO is then submitted for approval. Any changes made to the Price object take effect when the PCO completes its Workflow approval process.

A PCO is similar to other Change objects, such as ECOs and ECRs. You can create a PCO using the IAgileSession.createObject() method.

Example: Creating a PCO

    public void createPCO(IPrice price) throws Exception {

IAgileClass cls =

m_admin.getAgileClass(ChangeConstants.CLASS_PCO);

    //Get autonumber sources for the PCO class
    }

IAutoNumber[] numbers =

cls.getAutoNumberSources();

    //Create the PCO

IChange pco =

(IChange)m_session.createObject(ChangeConstants.CLASS_PCO, numbers[0]);

    //Get the Affected Prices table

ITable affectedPrices =

pco.getTable(ChangeConstants.TABLE_AFFECTEDPRICES);

    //Add the Price object to the Affected Prices table
    }

IRow row = affectedPrices.createRow(price);

### 19.2.4 Creating a Price Object

There are several steps to create a Price object. First, specify the object class and the unique identifying attributes, and then use IAgileSession.createObject() to return the new Price object.

Price objects are more complex than other Agile API objects because they have several key attributes that must be specified. Most other Agile API objects have only one key object, such as the object's number. With a Price object, you must specify a number, customer, item or manufacturer part, revision (for items), Program, site, and supplier. If any one of these attributes is missing, an exception will be thrown and the Price object won't be created.

Note: If you are not dealing with site-specific information, specify the Global site for the Manufacturing Site attribute.

After you create a Price object, you can further define it by setting values for Cover Page, Page Two, and Page Three fields. To define prices and terms for items and manufacturer parts, add rows to the Price Lines table. If there are files or documents to attach, add them to the Attachments table.

#### 19.2.4.1 Defaults

To create a price with Program==All and Customer==All, you do not need to pass values for PriceConstants.ATT_GENERAL_INFORMATION_CUSTOMER and PriceConstants.ATT_GENERAL_INFORMATION_Program during price creation. By default, the price will be created with Progam==All and Customer==All.

#### 19.2.4.2 Specifying Item Revision

When you specify the item revision during price creation, you need to pass the change number, instead of the revision number.

Example: Specifying Item Revision by Passing the Change Number

//Pass the change number

params.put(Priceconstants.ATT_GENERAL_INFORMATION_ITEM_REV, "CO-35884");

    //Instead of the revision number

params.put(PriceConstants.ATT_GENERAL_INFORMATION_ITEM_REV, "B")

#### 19.2.4.3 Creating a Published Price

The following example shows how to create a published price.

Example: Creating a published price

    public void createPublishedPrice(ICustomer customer, ISupplier supplier) throws Exception {

HashMap params = new HashMap();

IAgileClass cls =

m_admin.getAgileClass(PriceConstants.CLASS_PUBLISHED_PRICE);

IAutoNumber an =

cls.getAutoNumberSources()[0];

params.put(PriceConstants.ATT_GENERAL_INFORMATION_NUMBER, an);

params.put(PriceConstants.ATT_GENERAL_INFORMATION_CUSTOMER, customer);

params.put(PriceConstants.ATT_GENERAL_INFORMATION_ITEM_NUMBER, "1000-02");

params.put(PriceConstants.ATT_GENERAL_INFORMATION_ITEM_REV, "CO-35884");

params.put(PriceConstants.ATT_GENERAL_INFORMATION_PROGRAM, "PROGRAM0023");

params.put(PriceConstants.ATT_GENERAL_INFORMATION_MANUFACTURING_SITE, "San Jose");

params.put(PriceConstants.ATT_GENERAL_INFORMATION_SUPPLIER, supplier);

    IPrice price = (IPrice)m_session.createObject(cls, params);

## 19.3 Working with Suppliers

The Agile PLM system comes with five out-of-the-box supplier classes:

- Broker

- Component Manufacturer

- Contract Manufacturer

- Distributor

- Manufacturer Rep

There are two primary key attributes that uniquely identify each supplier: GENERAL_INFO_NUMBER and GENERAL_INFO_NAME.

### 19.3.1 Loading a Supplier

To load a supplier, use the IAgileSession.getObject() method. To uniquely identify the supplier, specify the General Info | Number attribute.

Example: Loading a supplier

    public ISupplier getSupplier() throws APIException {
    IAutoNumber number = agClass.getAutoNumberSources()[0];
    }

ISupplier supplier = (ISupplier)m_session.getObject(ISupplier.OBJECT_TYPE, "SUP20013"); return supplier;

Note The Agile API does not support adding new rows to Supplier tables.

### 19.3.2 Modifying Supplier Data

The Agile API lets you read and update all read/write Supplier fields. For General Info, Page One, and Page Three fields, you can access the cells directly. To access cells on multirow tables like the Contact Users table, you must first load the table and select a particular row.

Example: Modifying supplier data

    public void updateSupplierGenInfo(ISupplier supplier) throws Exception {

ICell cell = null;

IAgileList listvalues = null;

//Update Name (Text field)

cell = supplier.getCell(SupplierConstants.ATT_GENERAL_INFO_NAME);

cell.setValue("Global Parts");

    //Update URL (Text field)

cell = supplier.getCell(SupplierConstants.ATT_GENERAL_INFO_URL);

cell.setValue("")`http://wwww.globalpartscorp.com`;

    //Update Corporate Currency (List field)

cell = supplier.getCell(SupplierConstants.ATT_GENERAL_INFO_CORPORATE_CURRENCY);

listvalues = cell.getAvailableValues();

listvalues.setSelection(new Object[] { "EUR" });

cell.setValue(listvalues);

    }
    public void updateSupplierContactUsers(ISupplier supplier) throws Exception {

ICell cell = null;

IAgileList listvalues = null;

//Load the Contact Users table

ITable contactusers = supplier.getTable(SupplierConstants.TABLE_CONTACTUSERS);

    //Get the first row
    //Update Email (Text field)

ITwoWayIterator i = contactusers.getTableIterator(); IRow row = (IRow)i.next();

cell = row.getCell(SupplierConstants.ATT_CONTACT_USERS_EMAIL);

cell.setValue("")wangsh@globalpartscorp.com;

    }

### 19.3.3 Importing Data for Sourcing Projects

SDK exposes the following API to support importing Items into a Sourcing project:

    byte[]
    importDataForSourcingProject (String projectNumber, byte[] srcFile, String srcFileType, byte[] mappingFile, byte[] transformFile, String[] operations, List options) throws APIException

This example uses the importDataForSourcingProject to import data into a Sourcing Project

Importing BOM and AML with Parent-Child data into Sourcing Projects

        String srcFilePath = ".//ImportSource//9312HF54//Assembly_BOM_AML_PC.xls";            String srcFileType = "ExcelFile";    String mappingPath = ".//ImportSource//9312HF54//Assembly_BOM_AML_PC.xml";      String transformPath = null

        String[] operations = new String[] { "project.item", "project.bom", "project.aml"};//Valid operations "project.item", "project.bom", "project.aml"            List options = new ArrayList();            options.add("BusinessRuleOptions|ChangeMode=Authoring");            options.add("BusinessRuleOptions|BehaviorUponNonExistingObjects=Accept");            String _output = ".//Log//9312HF54//Ass_BOM_AML_PC_log.xml";                        options.add("Template|TemplateType=com.agile.imp.template.TemplateParentChildFilter");            FileOutputStream fop = new FileOutputStream(_output);            IImportManager imgr = (IImportManager)session.getManager(IImportManager.class);            byte[] logData = null;            logData = imgr.importDataForSourcingProject(projectNumber,                                     stream2byte(new FileInputStream(srcFilePath)), srcFileType, convertFiletoStream(mappingPath),options);  convertFiletoStream(transformPath), operations, byte buf[] = new byte[1024 * 4];            int n = 0;            InputStream logStream = byte2stream(logData);            while ((n = logStream.read(buf)) != -1) {                fop.write(buf, 0, n);            }            fop.close();System.out.println("Import Ass_BOM_AML with ParentChild Template successfully, the log file is "+ _output );

## 19.4 Working with Sourcing Projects

A Sourcing Project is where you prepare content for Sourcing tasks, such as Requests for Quotes (RFQs) and Sourcing analysis. Sourcing Project is a centralized, collaborative solution. Multiple users can add data to a Sourcing Project and perform analysis of Sourcing results. Because Sourcing projects serve as the home for all Sourcing activities, they are linked to many classes of objects, including Supplier, RequestForQuote (RFQ), and SupplierResponse.

You can use the Agile API to:

- Load an existing Sourcing Project

- Create Sourcing Projects by quantity breaks

- Create Sourcing Projects by price periods

- Open and close a Sourcing Project

- Add items, including AMLs to Sourcing Project items

- Access and modify objects, tables, and attributes in Sourcing Projects

- Access and modify Sourcing Project status

- Update Sourcing Project AMLs

- Update Page 1, Page 2, and Page 3 in Sourcing projects

- Read and update a nested Pricing table in Sourcing projects

- Set quantity for an item in Sourcing Projects

- Update the target price for items in Sourcing Projects

- Set partners for items in Sourcing Projects

- Perform quantity Rollups in Sourcing Projects

- Set a response designated as best in Sourcing Projects

Unlike the Web Client which provides additional functionality for Sourcing projects, the Agile API exposes Sourcing projects for simple data extraction and updating. Consequently, the Agile API does not support the following functions:

- Validation for items, commodities, or manufacturer parts.

- Filter Sourcing Project tables

- Modify the price scenario for Sourcing Projects (change quantity breaks and effectivity periods)

### 19.4.1 Supported API Methods

The SDK supports the following API methods for Sourcing projects. For information on these interfaces, refer to the Javadoc generated HTML files that document the SDK code. You can find them in the HTML folder in SDK_samples (ZIP file). To access this file, see the Note in Client-Side Components on page 2.

- IAgileSession.createObject(Object, Object)

- IAgileSession.createObject(int, Object)

- IAgileSession.getObject(Object, Object)

- IAgileSession.getObject(int, Object)

- IProject.assignSupplier (Object partnerParams)

- IProject.Costrollup()

- IProject.lookupPrices()

- IProject.rollupQuantity()

- IProject.getName()

- IProject.changeStatusToOpen()

- IProject.changeStatusToClose()

- IProject.getTable(Object)

- IRow.getValue(Object)

- IRow.setValue(Object, Object)

- ITable.iterator()

- ITable.getName()

- ITable.getTableDescriptor()

- ITable.size()

- ITable.createRow(Object)

Note: The PCM SDK does not support the IRow.getReferent() method.

### 19.4.2 Loading an Existing Sourcing Project

To load existing Sourcing Projects, use the IAgileSession.getObject() method. To uniquely identify the Sourcing Projects, specify the value for the Cover Page | Number attribute.

Example: Loading Sourcing Projects

    public IProject getProject() throws APIException {

String prjnum = "PRJACME_110";

IProject prj = (IProject)m_session.getObject(IProject.OBJECT_TYPE, prjnum);

return prj;

    }

### 19.4.3 Creating Sourcing Projects by Quantity Breaks

Defining Sourcing projects uses the generic IAgileSession method.

Example: Creating Sourcing Projects

    IAgileObject createObject (Object objectType, Object params)

throws APIException;

Creating Sourcing Projects requires specifying one of the following set of parameters:

- Sourcing Project number and quantity breaks

Or,

- Sourcing Project number, quantity breaks, and price period information

Note: Quantity breaks is a required parameter and is always specified. The example below creates a Sourcing Project using the quantity break parameter.

Example: Creating Sourcing Projects by quantity breaks

    IAgileClass agClass = m_admin.getAgileClass(ProjectConstants.CLASS_SOURCING_PROJECT);
    HashMap map = new HashMap();
    map.put(ProjectConstants.ATT_GENERAL_INFORMATION_NUMBER, number);
    map.put(ProjectConstants.ATT_GENERAL_INFORMATION_NUMBER_OF_QTY_BREAKS, new Integer(4));

IProject prj = (IProject) m_session.createObject(agClass, map);

Important Do not pass numbers that are greater than two digits to the QUANTITY_BREAK attribute.

### 19.4.4 Creating Sourcing Projects by Quantity Breaks and Price Periods

Alternatively, you can create Sourcing Projects by specifying quantity breaks and price period information such as the number of periods, period type, and start date. Example below creates a Sourcing Project using these parameters.

Note: When you create a Sourcing Project with price period information set to period type, you must specify the Period Type attribute. The supported values are Monthly, Quarterly, Semi-Annually, and Yearly. However, Period Type is not correctly returned afterwards when you check the value of period type, for example, by invoking getValue(ProjectConstants.ATT_GENERAL_INFORMATION_PERIOD_TYPE). That is, instead of returning the value that you set when creating the Sourcing Project, the future returned value is always "Weekly". This is not an error. It is normal SDK behavior and the specified period type value is not altered, because it is for internal use only.

Example: Creating a Sourcing Project by quantity breaks and price periods

    /*
    Descriptions

ATT_GENERAL_INFORMATION_PERIOD_TYPE is described in ProjectConstants

Name: Period Type

Description: Period Type indicates the recurrence of price periods in a Sourcing Project.

Type: List

List: Period Type List

List Id: 4565

List Valid Values: {Monthly, Quarterly, Semi-Annually, Yearly}

Restrictions: Required, Read Only. Used only when creating Sourcing Projects. Internal use only. Not available through Agile UI clients.

ATT_GENERAL_INFORMATION_PERIOD_START_DATE is described in ProjectConstants

Name: Period Start Date

Description: Period Start Date indicates the start date for price periods in a Sourcing Project

Type: Date

Valid Values: any Date object.

Restrictions: Required, Read only, Used only when creating Sourcing Projects, Internal use only /Not available through Agile UI clients

    */
    IItem assembly = (IItem)m_session.getObject(IItem.OBJECT_TYPE, "P00001");
    IAgileClass agClass =

m_admin.getAgileClass(ProjectConstants.CLASS_SOURCING_PROJECT);

    IAutoNumber number =

agClass.getAutoNumberSources()[0];

HashMap map =

new HashMap();

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_NUMBER, number);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_NUMBER_OF_QTY_BREAKS, new Integer(4));

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_NUMBER_OF_PERIODS, new Integer(4));

    IAgileList list =
    String TYPE = "Monthly";
    list.setSelection(new Object[]{TYPE});

agClass.getAttribute(PERIODTYPE).getAvailableValues();

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_PERIOD_TYPE, list);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_PERIOD_START_DATE, (new GregorianCalendar()).getTime());

IProject prj =

(IProject) m_session.createObject(agClass, map);

### 19.4.5 Accessing and Modifying Objects, Tables, and Attributes

You can use the generic IDataObject method with standard calls such as getObject, getTable, getValue, setValue to access and subsequently modify objects, tables, and attributes as follows:

- Read Page 1 or Cover Page, Page 2, Page 3, Items, AML, Analysis, and nested pricing tables

- Update Page 1 or Cover Page, Page 2, Page 3, and AML tables

- Add items including AML to Items table

- Read RFQ table

- Load RFQ table

The com.agile.api.ProjectConstants.java file contains information about classes, tables, and attributes.

The SDK does not support the following table operations:

- Sourcing Projects class

· Sorting PCM specific tables that have a default sorting order. These tables are Sourcing Project Item, Sourcing Project AML, Sourcing Project Changes, Sourcing Project Analysis, and Sourcing Project RFQ, RFQ Response, RFQ Changes, Supplier Response, and Supplier Changes.

- Request for quote and RFQ responses classes

· Responses and Changes tables

- Removing items from RFQ Response and Sourcing Projects tables because the PCM SDK does not support ITable.clear() or ITable.removeRow()

#### 19.4.5.1 Setting Cover Page Values for Sourcing Projects

You can read and update all read/write Sourcing Projects cells. The following example updates the cells on a Sourcing project's Cover Page (Page 1).

Example: Setting values for a Sourcing project's Cover Page

    public void updateProjectGenInfo (IProject project) throws Exception {

ICell cell = null;

IAgileList listvalues = null;

    //Update Customer (List field)

cell =

project.getCell(ProjectConstants.ATT_GENERAL_INFORMATION_CUSTOMER);

listvalues =

cell.getAvailableValues();

listvalues.setSelection(new Object[] { "CUST00010" });

cell.setValue(listvalues);

    //Update Description (Text field)

cell =

project.getCell(ProjectConstants.ATT_GENERAL_INFORMATION_DESCRIPTION);

cell.setValue("Sourcing Projects for Odyssey III");

    //Update Manufacturing Site (List field)

cell =

project.getCell(ProjectConstants.ATT_GENERAL_INFORMATION_MANUFACTURING_SITE);

listvalues =

cell.getAvailableValues();

listvalues.setSelection(new Object[] { "Global" });

cell.setValue(listvalues);

    //Update Ship To Location (List field)

cell =

project.getCell(ProjectConstants.ATT_GENERAL_INFORMATION_SHIP_TO_LOCATION);

listvalues =

cell.getAvailableValues();

listvalues.setSelection(new Object[] { "San Jose" });

cell.setValue(listvalues);

    }

### 19.4.6 Understanding Nested Tables of PCM Sourcing Projects

A nested table is a table within a table. They are used to accesses and modify data in multi-level objects such as BOMs and Items with AMLs. The way the SDK fulfills this function is to treat the cell values in a nested table as a table. For example, when the SDK finds the next level in a cell in a BOM table, it treats and processes the cell as a table. Nested tables are unique to the PCM SDK.

#### 19.4.6.1 Sourcing Projects' Parent Table and Nested Child Table Constants

The list of parent Sourcing Projects table and the corresponding nested child table constants appear in the Parent Sourcing Projects Table Constants and the Corresponding Nested Sourcing Projects Tables.

Parent Table Constant | Nested Child Table Constant | Read/Write Mode
--- | --- | ---
TABLE_ITEMS | ATT_ITEMS_AML | Read/Write
TABLE_ITEMS | ATT_ITEMS_PRICING | Read/Write
TABLE_AML | ATT_AML_PRICETABLE | Read/Write
TABLE_ITEM | ATT_ITEM_PRICE_TABLE | Read/Write
TABLE_ITEM | ATT_ITEM_BOM_TABLE | Read
TABLE_ANALYSIS | ATT_ANALYSIS_AML | Read
TABLE_ANALYSIS | ATT_ANALYSIS_PRICING | Read

#### 19.4.6.2 Accessing and Modifying Nested Tables in Sourcing Projects or RFQs

The example below is a Read mode example that accesses a nested table. To modify/update a nested table, see the Example entitled "Nested RFQ table update" in RFQ Parent Table and Nested Child Table Constants on page 326.

Note: The Money type attribute in nested PCM Pricing tables always uses "USD" as the default currency unit. This applies even if the buyer specifies a different currency unit. In this case, the "United State Dollar" is the default and only supported currency.

Example: Accessing a nested table

    Row row = (IRow) table.iterator.next();
    ITable nested_table =(ITable)row.getValue(ProjectConstants.ATT_ITEMS_AML);

#### 19.4.6.3 Viewing Updates after Modifying a Nested Table

After modifying a nested table, it is necessary to reload the table as shown in the previous example for changes to take effect, otherwise, the old data will reappear and the new values are not displayed.

#### 19.4.6.4 Accessing and Modifying the Status of Sourcing Project

Because Sourcing Projects do not have a Workflow connected to them, their status change is controlled internally. They control their status with a set of methods. This is a special case for some PCM objects such as Sourcing Projects and Requests for Quote. This release supports changing the status of a Sourcing Project from Draft to Open and Open to Close.

You can access the status of Sourcing Projects using the standard IDataObject method for the lifecycle phase field on the Cover Page (Page 1). You can modify the status of Sourcing Projects with IProject methods which enable you to open, modify, and close a Sourcing Project. You must set the Ship to Location parameter in order to open a Sourcing Project, as shown in the following example.

Example: Setting values for a Sourcing project's Cover Page

    // add Ship To //

String sj = "San Jose";

IAgileList ship2List =

(IAgileList)prj.getValue(ProjectConstants.ATT_GENERAL_INFORMATION_SHIP_TO_LOCATION);

ship2List.setSelection(new Object[]{sj});

prj.setValue(ProjectConstants.ATT_GENERAL_INFORMATION_SHIP_TO_LOCATION, ship2List);

    // open Sourcing Project //
    // close Sourcing Project //

prj.changeStatusToOpen();

prj.changeStatusToClose();

### 19.4.7 Managing Data in Sourcing Projects

The following paragraphs provide descriptions and examples to prepare a Souring Project to issue an RFQ. You can then use the SDK to complete the RFQ-related tasks.

Note: The Sourcing Project Start date that you specify is converted to the GMT format for storage in the PLM database. Due to this conversion, the date value returned by IProject.getValue(ProjectConstants.ATT_GENERAL_INFORMATION_PERIOD_START_DATE) is not guaranteed to be the same that the user may expect.

#### 19.4.7.1 Setting Quantity for Items in Sourcing Projects

You can use the SDK to set the required quantity for the an Item object in a Sourcing Project. The code sample below sets this value in the Item table, under the Items tab, for a single price target. The end user can specify the target price using the displayed name which is QuantityBreak2 in the following example.

Example: Setting quantity for Items

    // Setting Quantity for an Item //

ITable tab_item = dObj.getTable(ProjectConstants.TABLE_ITEM);

IRow row = (IRow) tab_item.iterator().next()

ITable priceTable = row.getValue(ProjectConstants.ATT_ITEM_PRICE_TABLE);

for (Iterator iterator = priceTable.iterator(); iterator.hasNext();) {

Row row = (IRow) iterator.next();

String name = row.getName();

if(name.equals("QuantityBreak2")){

row.setValue(ProjectConstants.ATT_PRICEDETAILS_QUANTITY, new Double(123));

}

}

Note: For items, quantity is only set at the root level. Thus, if an item is not a root, the exception ExceptionConstants.PCM_PROJECT_ITEM_IS_NOT_ROOT is thrown.

In addition, because priceTable is a nested table, you must reload the table to get the updated value of Quantity. This is shown in the following example.

Example: Reloading a nested table to get an updated value

    // Getting the updated value //

priceTable = row.getValue(ProjectConstants.ATT_ITEM_PRICE_TABLE);

for (Iterator iterator = priceTable.iterator(); iterator.hasNext();) {

IRow iRow = (IRow) iterator.next();

String name = iRow.getName();

if(name.equals("QuantityBreak2")){

Object qty = row.getValue(ProjectConstants.ATT_PRICEDETAILS_QUANTITY));

}

}

#### 19.4.7.2 Adding Items to Sourcing Projects Using BOM Filters

The PLM Web Client supports setting up BOM filters to selectively add Items to Sourcing Projects. This filtering applies to all enabled attributes on the Cover page, P2, and BOM tabs of the Item object and includes the Parts and Documents fields in the Cover page. These attributes are enabled using the Java Client. For background information and procedures on BOM filtering, refer to Agile PLM Product Cost Management User Guide. To enable Item object attributes, refer to Agile PLM Administrator Guide.

The SDK enables replicating this Web Client feature programmatically. SDK filter operators that support this feature are implemented in the OperatorConstants class. The following code samples show how BOM filters are applied to Item object's numeric, multilist, money, and mass attributes. As indicated above, these attributes must be enabled in the Java Client by an Admin user.

Example: Applying BOM filter operators located in the OperatorConstants class

    IProject prj = (IProject)m_session.getObject(IProject.OBJECT_TYPE, "PRJ00001");
    //Applying BOM filter to numeric attributes

ProjectItemFilter itemfilter = new ProjectItemFilter();

itemfilter.addCriteria(ItemConstants.ATT_BOM_BOM_NUMERIC03, OperatorConstants.RELOP_EQ, new Integer(10));

itemfilter.addCriteria(ItemConstants.ATT_BOM_BOM_NUMERIC04, OperatorConstants.RELOP_GE, new Integer(100));

Map params = new HashMap();

params.put(ProjectConstants.ATT_ITEM_NUMBER, assembly);

params.put(ProjectConstants.ATT_ITEM_FILTER, itemfilter);

ITable ITEM = prj.getTable(ProjectConstants.TABLE_ITEM);

IRow row = ITEM.createRow(params);

    //Applying BOM filter to multilist attributes
    throws APIException, RemoteException, Exception;

ProjectItemFilter itemfilter = new ProjectItemFilter();

IAttribute list03 = m_session.getAdminInstance().getAgileClass(ItemConstants.CLASS_PARTS_CLASS).getAttribute(ItemConstants.ATT_PAGE_TWO_MULTILIST01);

IAgileList list3 = list03.getAvailableValues();

list3.setSelection(new Object[]{"Austria","India"});

itemfilter.addCriteria(ItemConstants.ATT_PAGE_TWO_MULTILIST01, OperatorConstants.RELOP_CONTAINS_ALL_VALUE, list3);

Map params = new HashMap();

params.put(ProjectConstants.ATT_ITEM_NUMBER, assembly);

params.put(ProjectConstants.ATT_ITEM_FILTER, itemfilter);

ITable ITEM = prj.getTable(ProjectConstants.TABLE_ITEM);

IRow row = ITEM.createRow(params);

    //Applying BOM filter to money attributes

Money mny = new Money(new Double(15.3), "USD");

ProjectItemFilter itemfilter = new ProjectItemFilter();

itemfilter.addCriteria(ItemConstants.ATT_PAGE_TWO_MONEY01, OperatorConstants.RELOP_EQ, mny);

Map params = new HashMap();

params.put(ProjectConstants.ATT_ITEM_NUMBER, assembly);

params.put(ProjectConstants.ATT_ITEM_FILTER, itemfilter);

ITable ITEM = prj.getTable(ProjectConstants.TABLE_ITEM);

IRow row = ITEM.createRow(params);

    //Applying BOM filter to mass attributes

IUnitOfMeasureManager uomm =(IUnitOfMeasureManager)m_session.getManager(IUnitOfMeasureManager.class);

IUnitOfMeasure uom = uomm.createUOM(10.1,"Gram");

ProjectItemFilter itemfilter = newProjectItemFilter();

itemfilter.addCriteria(ItemConstants.ATT_TITLE_BLOCK_MASS,OperatorConstants.RELOP_NEQ, uom);

Map params = new HashMap();

params.put(ProjectConstants.ATT_ITEM_NUMBER, assembly);

params.put(ProjectConstants.ATT_ITEM_FILTER, itemfilter);

ITable ITEM = prj.getTable(ProjectConstants.TABLE_ITEM);

IRow row = ITEM.createRow(params);

#### 19.4.7.3 Updating the QPA Attribute on the Item Table of Sourcing Projects

SDK supports updating the Quantity per Assembly (QPA) attribute on the Item Table of Open and Draft PCM Sourcing Projects. You can set the value of the QPA attributes directly in the Sourcing Project, or by using the values from the Item Master file. Although you can pass Sourcing Projects that their status is are neither Draft or Open, but the Agile code will automatically determine whether to update, or not update the QPA attribute

Example: Updating the QPA Attribute on the Item Table of Sourcing Projects

    public static void main(String[] args) {

try {

// Create an IAgileSession instance

session = connect(session);

IProject prj = (IProject)session.getObject(IProject.OBJECT_TYPE,"PRJ00011");

ITable items = prj.getTable(ProjectConstants.TABLE_ITEM);

Iterator iter = items.iterator();

int i = 0

int j = 0

while (iter.hasNext()){

IRow itemRow = (IRow)iter.next();

System.out.println(itemRow.getValue(ProjectConstants.ATT_ITEM_NUMBER).toString());

try{

ITable bom = (ITable) itemRow.getValue(ProjectConstants.ATT_ITEM_BOM_TABLE);

Iterator bomIter = bom.iterator();

while (bomIter.hasNext()){

IRow bomRow = (IRow) bomIter.next();

i++;

System.outprintln("bom : "+ bomRow.getValue(ProjectConstants.ATT_ITM_NUMBER).toString());

if(bomRow.getValue(ProjectConstants.ATT_ITEM_NUMBER).equals("P00440")){

j++;

// This example sets the Sourcing Project's QPA attribute to 5.

bomRow.setValue(ProjectConstants.ATT_ITEM_QPA, 5);

}

}

}catch(Exception e){

i++;

//e.printStackTrace();

continue;

}

}

System.outprintln("bom : "+ i + " and target bom child count: " + j);

} catch (Exception e) {

e.printStackTrace();

} finally {

session.close();

}

    }

Example: Updating the Selected Attributes on the Item Table of Sourcing Projects from the Item Master File

    public static void updateContentFromItemMaster() throws Exception {

IProject prj = (IProject)session.getObject(IProject.OBJECT_TYPE, "PRJ00011");

Map params = new HashMap();

//params.put(ProjectConstants.FLAG_CONTENT_UPDATE_MODE_OPTION_ALL, true);

//params.put(ProjectConstants.FLAG_CONTENT_UPDATE_MAINTAIN_AML_CHANGES, false);

params.put(ProjectConstants.FLAG_CONTENT_UPDATE_MODE_OPTION_ALL, false);

params.put(ProjectConstants.FLAG_CONTENT_UPDATE_MAINTAIN_AML_CHANGES, false);

params.put(ProjectConstants.FLAG_CONTENT_UPDATE_SELECTED_CONTENT_OPTION_BOM_AND_AML, true);

params.put(ProjectConstants.FLAG_CONTENT_UPDATE_SELECTED_CONTENT_OPTION_ITEM, true);

params.put(ProjectConstants.FLAG_CONTENT_UPDATE_SELECTED_CONTENT_OPTION_MANUFACTURER_PART, true);

List itemAttributes = new ArrayList();

itemAttributes.add(ProjectConstants.ATT_ITEM_QPA);// choose QPA attribute to update

params.put(ProjectConstants.FIELD_CONTENT_UPDATE_ITEM_ATTRIBUTES, itemAttributes);

List mfrPartAttributes = new ArrayList();

mfrPartAttributes.add("description");

params.put(ProjectConstants.FIELD_CONTENT_UPDATE_MFR_PART_ATTRIBUTES, mfrPartAttributes);

System.out.println("Updating Content from Item Master...."); prj.updateContentFromItemMaster(params);

System.out.println("Finish updating Content from Item Master....");

    }

#### 19.4.7.4 Updating PLM Contents from Item Master

The following API supports updating PLM content including the Universal Unit of Measure Attribute (UOM) from the Item master file:

void IProject.updateContentFromItemMaster (Object contentParams) throws APIException, RemoteException, Exception

Example: Updating contents in Item Master file

IProject prj = (IProject)session.getObject(IProject.OBJECT_TYPE, "PRJ000XX");

Map params = new HashMap();

params.put(ProjectConstants.FLAG_CONTENT_UPDATE_MODE_OPTION_ALL, false);

params.put(ProjectConstants.FLAG_CONTENT_UPDATE_MAINTAIN_AML_CHANGES, false);

params.put(ProjectConstants.FLAG_CONTENT_UPDATE_SELECTED_CONTENT_OPTION_BOM_AND_AML, true);

params.put(ProjectConstants.FLAG_CONTENT_UPDATE_SELECTED_CONTENT_OPTION_ITEM, true);

params.put(ProjectConstants.FLAG_CONTENT_UPDATE_SELECTED_CONTENT_OPTION_MANUFACTURER_PART, true);

List itemAttributes = new ArrayList(); itemAttributes.add(ProjectConstants.ATT_ITEMS_DESCRIPTION); itemAttributes.add(ProjectConstants.ATT_ITEMS_ATTACHMENTS);

itemAttributes.add(ProjectConstants.ATT_ITEMS_UOM); //'UOM' attribute

params.put(ProjectConstants.FIELD_CONTENT_UPDATE_ITEM_ATTRIBUTES, itemAttributes);

List mfrPartAttributes = new ArrayList();

mfrPartAttributes.add("description");

mfrPartAttributes.add("attachments");

params.put(ProjectConstants.FIELD_CONTENT_UPDATE_MFR_PART_ATTRIBUTES, mfrPartAttributes)

prj.updateContentFromItemMaster(params);

#### 19.4.7.5 Performing Quantity Rollup in Sourcing Projects

Quantity rollups generate data related the quantity values for the selected Item in a Sourcing Project. In the SDK, you can use the following API to invoke a Quantity rollup in a Sourcing Project.

public void rollupQuantity() throws APIException, RemoteException, Exception;

This code sample uses rollupQuantity() to do a Quantity rollup.

Example: Quantity Rollup

    IProject prj =
    prj.rollupQuantity();

(IProject)m_session.getObject(ProjectConstants.CLASS_SOURCING_PROJECT,"PRJ00001");

Note: To get the updated value of Quantity, it is necessary to invoke rollupQuantity() on the Sourcing Project similar to the example in Modifying Spplier Data on page 295. This is necessary because getValue() does not return the updated value of the affected item after setting Quantity.

#### 19.4.7.6 Performing Cost Rollup in Sourcing Projects

Cost Rollup (Rollup cost) generates an Assembly Cost Report (ACR) based on available prices. In this process, it picks up the lowest costs from filtered data, performs Set as Best (on user defined or default parameters) and costed BOM rollup (aggregation) to generate the ACR. In the UI, Rollup cost provides an intuitive mechanism for non PCM users to cost a BOM without going through PCM steps.

Note: Cost Rollup runs on existing Sourcing Project prices. If Cost Rollup needs to run on looked up prices, lookupPrices() must be invoked prior to running costRollup(). If there are no assemblies in the Sourcing Project, the ExceptionConstants.PCM_NO_ASSEMBLY_IN_PROJECT is thrown.

The PCM SDK supports the Cost Rollup function with the following API.

    public void costRollup()

Example: Using the costRollup API

IProject prj = (IProject) m_session.getObject(ProjectConstants.CLASS_SOURCING_PROJECT, "PRJ0001");

prj.costRollup();

Note: If you need to run quantity rollup immediately after cost rollup, be sure to provide some delay (For example as in Thread.currentThread().sleep(10000);) to allow the results of the cost rollup to be refreshed in the database.

#### 19.4.7.7 Performing Price Lookup in Sourcing Projects

You can use the SDK to verify the existence of a price scenario for a specified period and quantity in the Item Master. You can either use the price information of the Item, or modify the price information and send the RFQ to suppliers for requote. This is shown in the following code samples.

In Agile PCM, there are three types of price objects:

- Contracts - Predefined agreements with suppliers for Item prices over a specified time period

- Published Prices - The Item price information that has been published from other Sourcing projects

- Quote Histories - Quoted prices that were previously received for an Item

For information about price objects and price lookups in Sourcing projects, refer to the Agile PLM Product Cost Management User Guide.

#### 19.4.7.8 Price Lookup API and Price Lookup Options

- Supported API

The SDK supports price lookups with the following API in IProject.

public void lookupPrices(Object lookupParams)

throws APIException, RemoteException, Exception;

- Price lookup options

This API performs price lookups from Price history and price lookups from another Sourcing Project.

Note: lookupPrices()looks for an Item or an MPN one object at a time. To run lookup for multiple Items/MPNs, you must run the API one Item or one MPN at a time.

The following examples show price lookups from the Sourcing Project History and from another Sourcing Project. In addition, applicable parameters are grouped and listed as those that are specific to the price lookup type and necessary in the price lookup type.

This example shows a price lookup from Sourcing Project History and from another Sourcing Projects. It provides a list of specific and required parameters for the two price lookups.

Example: Price lookup from History and another Sourcing Projects

ArrayList priceTypes = new ArayList();

priceTypes.add(PriceConstants.CLASS_PUBLISHED_PRICE);

priceTypes.add(PriceConstants.CLASS_QUOTE_HISTORY);

priceTypes.add(PriceConstants.CLASS_CONTRACT);

ArrayList suppliers = new ArrayList();

suppliers.add(supplier1);

suppliers.add(supplier2);

//supplier1, supplier2 are objects of ISupplier or String

ArrayList customers = new ArrayList();

customers.add(customer1);

customers.add(customer2);

//customer1, customer2 are objects of ICustomer or String

ArrayList programs = new ArrayList();

programs.add(program1);

programs.add(program2);

    //program1, program2 are objects of  IProgram or String
    items[0] = "P00001";

String shipTo = "berlin";

HashMap itemMap = new HashMap();

itemMap.put("IPN1","REV1");//itemMap.put("IPN1", null) if no revision

or

itemMap.put(item); //item is an object of IItem

HashMap mpnMap = new HashMap();

mpnMap.put("MPN1","MFR1");

or

mpnMap.put(mfrPart); //mfrPart is and object of IManufacturerPart

IProject srcPrj = (IProject)

m_session.getObject(ProjectConstants.CLASS_SOURCING_PROJECT, "PRJ_SRC");

Boolean isLookupFromPrice = new Boolean(false);

String priceScenario = null;

Map priceScenarios = new HashMap();

//if lookup from price history

priceScenario = "QuantityBreak1";

    //if lookup from Sourcing project

String destPricePoint1 = "QuantityBreak1";

String destPricePoint2 = "QuantityBreak2";

String srcPricePoint1 = "QuantityBreak1";

String srcPricePoint2 = "QuantityBreak2";

priceScenarios.put(destPricePoint2,srcPricePoint1);

priceScenarios.put(destPricePoint1,srcPricePoint2);

Boolean ignoreQtyRange = new Boolean(true);

Double qtyPercentRange = new Double(15);

Boolean ignoreDateRange = new Boolean(true);

Integer dateRange = new Integer(20);

HashMap map = new HashMap();

map.put(PriceConstants.ATT_GENERAL_INFORMATION_PRICE_TYPE,priceTypes);

map.put(ProjectConstants.ATT_ANALYSIS_SUPPLIER,suppliers);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_CUSTOMER,customers);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_PROGRAM,programs);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_SHIP_TO_LOCATION,shipTo);

map.put(ProjectConstants.ATT_ITEMS_NUMBER,itemMap);

map.put(ProjectConstants.ATT_ITEMS_AML,mpnMap);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_NUMBER,srcPrj);

map.put(LookupConstants.FLAG_IGNORE_ITEM_REVISION,ignoreItemRev);

map.put(LookupConstants.FLAG_CONSIDER_BEST_PRICES,considerBestPrices);

map.put(LookupConstants.FLAG_ALL_PRICE_SCENARIOS,allPriceScenarios);

map.put(LookupConstants.FIELD_PRICE_SCENARIO,priceScenario);

map.put(LookupConstants.FIELD_PRICE_SCENARIOS,priceScenarios);

map.put(LookupConstants.FLAG_IGNORE_QUANTITY,ignoreQtyRange);

map.put(LookupConstants.FIELD_QUANTITY_RANGE,qtyPercentRange);

map.put(LookupConstants.FLAG_IGNORE_DATE_RANGE,ignoreDateRange);

map.put(LookupConstants.FIELD_DATE_RANGE,dateRange);

map.put(LookupConstants.FIELD_SELECT_RESPONSE_BY,

LookupConstants.OPTION_LOWEST_PRICE);

map.put(LookupConstants.FIELD_LOOKUP_TYPE,

LookupConstants.OPTION_LOOKUP_FROM_PRICE);

prj.lookupPrices(map);

#### 19.4.7.9 Parameters specific to price lookups from price history

PriceConstants.ATT_GENERAL_INFORMATION_PRICE_TYPE

ProjectConstants.ATT_GENERAL_INFORMATION_CUSTOMER

ProjectConstants.ATT_GENERAL_INFORMATION_PROGRAM

ProjectConstants.ATT_GENERAL_INFORMATION_SHIP_TO_LOCATION

LookupConstants.FLAG_ALL_PRICE_SCENARIOS

LookupConstants.FIELD_PRICE_SCENARIO

LookupConstants.FLAG_IGNORE_QUANTITY

LookupConstants.FIELD_QUANTITY_RANGE

LookupConstants.FLAG_IGNORE_DATE_RANGE

LookupConstants.FIELD_DATE_RANGE

LookupConstants.FIELD_SELECT_RESPONSE_BY

#### 19.4.7.10 Parameters specific to price lookups from Sourcing Projects

ProjectConstants.ATT_GENERAL_INFORMATION_NUMBER

LookupConstants.FLAG_ALL_PRICE_SCENARIOS

LookupConstants.FLAG_IGNORE_ITEM_REVISION

LookupConstants.FLAG_CONSIDER_BEST_PRICES

Note The remaining parameters are common to both cases.

#### 19.4.7.11 Parameters required for price lookups from price history

PriceConstants.ATT_GENERAL_INFORMATION_PRICE_TYPE

ProjectConstants.ATT_ITEMS_NUMBER or ProjectConstants.ATT_ITEMS_AML

LookupConstants.FIELD_QUANTITY_RANGE if LookupConstants.FLAG_IGNORE_QUANTITY is 'false'

LookupConstants.FIELD_DATE_RANGE if LookupConstants.FLAG_IGNORE_DATE_RANGE is 'false'

LookupConstants.FIELD_PRICE_SCENARIO if LookupConstants.FLAG_ALL_PRICE_SCENARIOS is 'false'

#### 19.4.7.12 Parameters required for price lookups from Sourcing Projects

ProjectConstants.ATT_GENERAL_INFORMATION_NUMBER

LookupConstants.FLAG_ALL_PRICE_SCENARIOS

ProjectConstants.ATT_ITEMS_NUMBER or ProjectConstants.ATT_ITEMS_AML

Note: Parameters that are not required in one of the price lookups, for example, History, may be optional in price lookup from another Sourcing Project. Comparing the list of required parameters above, the LookupConstants.FLAG_ALL_PRICE_SCENARIOS parameter is optional when performing a price lookup from History. You can either omit the optional parameters, or set them to null.

Set LookupConstants.FIELD_LOOKUP_TYPE for lookup from history or Sourcing Projects as follows:

#### 19.4.7.13 Setting the price lookup from History or Sourcing Projects

- For lookup from price history - LookupConstants.OPTION_LOOKUP_FROM_PRICE

- For lookup from an existing Sourcing Project - LookupConstants.OPTION_LOOKUP_FROM_PROJECT

#### 19.4.7.14 Settings for Quantity Breaks in price lookups

You can set quantity breaks in a price lookup by cost, date, or leadtime by setting LookupConstants.FIELD_SELECT_RESPONSE_BY as follows:

- For break tie by cost - LookupConstants.OPTION_LOWEST_PRICE

- For break tie by date - LookupConstants.OPTION_MOST_RECENT_RESPONSE

- For break tie by leadtime- LookupConstants.OPTION_SHORTEST_LEAD_TIME

#### 19.4.7.15 Impact of improper parameter settings

If the following parameters are not set, or are improperly set, the API will take the following actions:

- LookupConstants.FIELD_LOOKUP_TYPE will default to LookupConstants.OPTION_LOOKUP_FROM_PRICE which corresponds to the lookup from price history

- LookupConstants.FLAG_IGNORE_QUANTITY orLookupConstants.FLAG_IGNORE_DATE_RANGE will default to true.

- LookupConstants.FIELD_SELECT_RESPONSE_BY will default to LookupConstants.OPTION_LOWEST_PRICE which corresponds to the break tie by cost

- LookupConstants.FLAG_IGNORE_ITEM_REVISION or LookupConstants.FLAG_CONSIDER_BEST_PRICES will default to false

- LookupConstants.LookupConstants.FLAG_ALL_PRICE_SCENARIOS is not set it will be defaulted to 'true'.

- ExceptionConstants.APDM_ADMIN_MISSINGREQUIREDFIELD exception is thrown when a required parameter is missing

- ExceptionConstants.API_INVALID_PARAM exception is thrown when the datatype or the value of a parameter is incorrectly set

#### 19.4.7.16 For RFQ lookup:

The settings are similar to Sourcing Project lookup from price history. Following is a code sample.

HashMap map = new HashMap();

map.put(PriceConstants.ATT_GENERAL_INFORMATION_PRICE_TYPE,priceTypes);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_CUSTOMER,customers);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_PROGRAM,programs);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_SHIP_TO_LOCATION,shipTo);

map.put(ProjectConstants.ATT_ITEMS_NUMBER,itemMap);

map.put(ProjectConstants.ATT_ITEMS_AML,mpnMap);

map.put(LookupConstants.FLAG_ALL_PRICE_SCENARIOS,allPriceScenarios);

map.put(LookupConstants.FIELD_PRICE_SCENARIO,priceScenario);

map.put(LookupConstants.FLAG_IGNORE_QUANTITY,ignoreQtyRange);

map.put(LookupConstants.FIELD_QUANTITY_RANGE,qtyPercentRange);

map.put(LookupConstants.FLAG_IGNORE_DATE_RANGE,ignoreDateRange);

map.put(LookupConstants.FIELD_DATE_RANGE,dateRange);

map.put(LookupConstants.FIELD_SELECT_RESPONSE_BY,LookupConstants.OPTION_LOWEST_PRICE);

map.put(LookupConstants.FLAG_EXCLUDE_AUTH_SUPPLIER,excludeAuthSupplier);

rfq.lookupPrices(map);

Following is the list of the required parameters for the RFQ lookup:

PriceConstants.ATT_GENERAL_INFORMATION_PRICE_TYPE

ProjectConstants.ATT_ANALYSIS_SUPPLIER,suppliers

ProjectConstants.ATT_ITEMS_NUMBER or ProjectConstants.ATT_ITEMS_AML

LookupConstants.FIELD_QUANTITY_RANGE if

LookupConstants.FLAG_IGNORE_QUANTITY is 'false'

LookupConstants.FIELD_DATE_RANGE if

LookupConstants.FLAG_IGNORE_DATE_RANGE is 'false'

LookupConstants.FIELD_PRICE_SCENARIO if

LookupConstants.FLAG_ALL_PRICE_SCENARIOS is 'false'

Note If you do not set the value of LookupConstants.FLAG_EXCLUDE_AUTH_SUPPLIER, it will default to false.

#### 19.4.7.17 Generating the Assembly Cost Report for Sourcing Projects

The PLM Web Client supports generating the Assembly Cost Report to help understand the total cost of a BOM, including the material and non-material costs. To simplify this operation, the Web Client provides a wizard to locate and select the required Sourcing Project, including the necessary parameters. See Understanding Assembly Cost Report Parameters for a description of these parameters.

A sample report is shown in the following screen shot. Once the report is prepared, the PLM user can invoke the Export command and send the data from the PLM to an external device in a supported format, for example, to an Excel worksheet.

Figure 19-1 Sample Assembly Cost Report

The SDK supports this Web Client feature by enhancing the ProductReport.execute() API. The extent of the SDK operation does not include invoking the Export command. The following is a code sample that uses the ProductReport.execute() API and the required parameters to programmatically generate this report.

Example: Generating Assembly Cost Reports

    String[] items = new String[1];
    String[] suppliers = new String[2];
    suppliers[0] = "-101";  //to include data for best suppliers
    suppliers[1] = "EMS1 COMPONENT SUPPLIER";
    String[] priceScenarios = new String[1];
    priceScenarios[0] = "QuantityBreak1";
    Boolean doCostRollup = new Boolean(true);
    HashMap map = new HashMap();

map.put(ProductReportConstants.REPORTPARAM_REPORT_TYPE,ProductReportConstants.REPORT_PROJECT_ASSEMBLY_COST);

map.put(ProductReportConstants.REPORTPARAM_REPORT_CATEGORY, "data");

map.put(ProductReportConstants.PROJECT_NUMBER, "PRJ00001");

map.put(ProductReportConstants.PROJECT_ITEMS, items);

map.put(ProductReportConstants.PROJECT_SUPPLIERS, suppliers);

map.put(ProductReportConstants.PROJECT_PRICEPOINTS, priceScenarios);

map.put(ProductReportConstants.PROJECT_DO_COST_ROLLUP, doCostRollup);

    try{
    IProductReport report = (IProductReport)m_session.createObject(IProductReport.OBJECT_TYPE, "My Reports");
               String result =report.execute(map);
     }
         catch (Exception e){
                   e.printStackTrace();
    }

Note: The returned value of the ProductReport.execute()API represents either the XML data of the Assembly Cost Report or the XML schema. To get the schema, you must set the values of the first two parameters in the map where the value of the parameter REPORTPARAM_REPORT_CATEGORY is set to "schema".

#### 19.4.7.18 Understanding Assembly Cost Report Parameters

The Assembly Cost Report parameters supported by ProductReport.execute()are defined as follows:

- items - The array of top level assembly items: "<itemNumber>::<revNumber>" if there is a revision, and "<itemNumber>" if there are no revisions.

- suppliers - The array of supplier names along with the optional indicators for the "Best of Suppliers": "-101" or the "Best Of Suppliers/Partners"

- pricescenarios - The array of price scenarios names

- doCostRollup - The flag to run the cost Rollup option for the report

If you want to generate a report for all assemblies, all suppliers/partners, or all price scenarios without specifying their names, you must provide the following corresponding parameters:

- String[] items = new String[1];

items[0] = "all";

- String[] suppliers = new String[2];

suppliers[0] = "-101";

suppliers[1] = "all";

- String[] priceScenarios = new String[0];

priceScenarios[0] = "all";

#### 19.4.7.19 Modifying the Target Price for Items in Sourcing Projects

Target Price is the market cost per unit of the item or the manufacturer part. It is specified when items are ordered. For each Item and for each Pricepoint, Target Price is set in the Items table, under the AML tab. A Pricepoint is the Target price quoted for a given quantity for an Item. For example, price quoted for X number of tires, which can be different for Y number of the same tires.

Note: The Target price is always a positive number. Setting a negative value for Target price will throw the ExceptionConstants.PCM_NEGATIVE_TARGET_PRICE exception.

Target Price is set at the Item level only. You cannott set a Target Price the AML level. The end user specifies a Pricepoint using the name displayed for the Pricepoint. In the following example, QuantityBreak2 is the Pricepoint.

Example: Setting the Target price in Sourcing Projects

ITable tab_item = dObj.getTable(ProjectConstants.TABLE_ITEMS);

IRow row = (IRow) tab_item.iterator().next();

ITable priceTable = row.getValue(ProjectConstants.ATT_ITEMS_PRICING);

for (Iterator iterator = priceTable.iterator(); iterator.hasNext();) {

IRow row = (IRow) iterator.next();

String name = row.getName();

if(name.equals("QuantityBreak2")){

row.setValue(ProjectConstants.ATT_PRICEDETAILS_TARGET_COST,

new Money(new Double(1.23), "USD") );

}

}

Because priceTable is a nested table, you must reload this table to get the updated value of the Target price as shown in the following example. This is similar to the example in Setting Quantity for Items in Sourcing Projects on page 305.

Example: Reloading the priceTable to get the updated value of the target price

priceTable = row.getValue(ProjectConstants. ATT_ITEMS_PRICING);

for (Iterator iterator = priceTable.iterator(); iterator.hasNext();) {

IRow iRow = (IRow) iterator.next();

String name = iRow.getName();

if(name.equals("QuantityBreak2")){

Object qty =

row.getValue(ProjectConstants.ATT_PRICEDETAILS_TARGET_COST));

}

}

#### 19.4.7.20 Setting the Best Response for Items in Sourcing Projects

The Best Response is set in the Analysis table under the Analysis tab for both the Item and Manufacturer Part number objects. The end user specifies three of these parameters: Lowest Cost, Lowest Cost Within Lead Time Constraint, Shortest Lead Time, Supplier Rating, and AML Preferred status. For more information, refer to Agile Product Lifecycle Management - Product Cost Management Supplier Guide.

You can use the SDK to find the best response for an Item Part Number (IPN), a Manufacturer Part Number (MPN), and for an IPN and an MPN as shown in the following code samples.

Example: Setting the Best Response for an IPN

    //set best response for ipn //
    ITable table_analysis = prj.getTable(ProjectConstants.TABLE_ANALYSIS);
    Iterator it = table_analysis.iterator();
    while(it.hasNext()) {

IRow row = (IRow) it.next();

String itemName = row.getValue(ProjectConstants.ATT_ANALYSIS_NUMBER);

String suppName = row.getValue(ProjectConstants.ATT_ANALYSIS_SUPPLIER);

if (itemName.equals("IPN1") && suppName.equals("suppName1 (suppNumber1)")) {

row.setValue(ProjectConstants.ATT_ANALYSIS_BEST_RESPONSE, "Yes");

}

    }
    ProjectConstants.ATT_ANALYSIS_SUPPLIER,suppliers
    ITable table_aml =

Example: Setting the Best Response for an MPN

(ITable) row.getValue(ProjectConstants.ATT_ANALYSIS_AML);

    Iterator _it =
    while(it.hasNext()){

table_aml.iterator();

String itemName = row.getValue(ProjectConstants.ATT_ANALYSIS_NUMBER);

String suppName = row.getValue(ProjectConstants.ATT_ANALYSIS_SUPPLIER);

String mfrName = row.getValue(ProjectConstants. ATT_ANALYSIS_MANUFACTURER);

if (itemName.equals("MPN1") && suppName.equals("suppName1

(suppNumber1)" && mfrName.equals("MFR1"))) {

row.setValue(ProjectConstants.ATT_ANALYSIS_BEST_RESPONSE, "Yes");

}

    }

Note: Because you can only set the Best Response to Yes, if you pass any value other than Yes, the ExceptionConstants.API_INVALID_PARAM exception is thrown.

Example: Getting the Best Response for an IPN and an MPN

String bResp = row.getValue(ProjectConstants.ATT_ANALYSIS_BEST_RESPONSE).toString();

#### 19.4.7.21 Setting Partners in Sourcing Projects

Partners can view complete Sourcing Project BOMs in RFQs. You can assign partners to an item in the Sourcing Project when you add the item to the RFQ that will be sent to the partners. If multiple partners are selected, you can split the quantity among the partners by specifying what percentage of an item you want to receive from each supplier. For example, if two partners supply the same item, you can add both partners to the list and then assign a certain percentage to each, for example, 50%-50%, or 60%-40%, and so on.

In the SDK, the following API is used to set partners for an item in a Sourcing Project and split the percentage among the partners.

public void assignSupplier(Object partnerParams) throws APIException, RemoteException, Exception;

The behavior of this API and its use cases are similar to IRequestForQuote.assignSupplier(). However, when you add new partners for an item with this API, you will override the existing ones. Thus, to avoid removing existing partners, it is necessary to once again add the existing partners and set the split (Percentage for each) level for each one. This only occurs in the SDK, the GUI does not require adding the existing partners when you add new partners. You cannot remove a partner for an item, but assigning a split = 0, (Percentage of ownership/participation) will remove the partner. For more information on the GUI behavior, refer to the latest release of Agile Product Lifecycle Management - Product Cost Management Supplier Guide.

The following code sample sets partners and splits the percentages among the assigned partners.

Example: Setting partners and splitting percentages among partners

HashMap map = new HashMap();

HashMap supplierSplit = new HashMap();

HashMap partnerMap = new HashMap();

map.put(ProjectConstants.ATT_ITEM_NUMBER, item);

Double split1 =

new Double(55);

Double split2 =

new Double(75);

supplierSplit.put(supplier1, split1);

supplierSplit.put(supplier2, split2);

partnerMap.put(ProjectConstants.ATT_PARTNERS_PARTNER, supplierSplit);

map.put(ProjectConstants.ATT_ITEM_PARTNER_TABLE, partnerMap);

prj.assignSupplier(map);

An item or supplier can be an IItem object, a ISupplier object, or a String object. Partners can be assigned to any Item Part Number (IPN), but not a Manufacturer Part Number (MPN). If the item is not in the Sourcing Project, the ExceptionConstants.PCM_ERROR_INVALID_PROJECT_ITEM is thrown.

Split percentages can be any object representing a number. If it is not a number, the ExceptionConstants.API_INVALID_PARAM exception is thrown.

To get data about a given partner, you can use the Items or AML tabs as shown below.

Example: Getting partner data using Item or AML

    ITable tab_item =
    IRow row = (

prj.getTable(ProjectConstants.TABLE_ITEMS);

IRow) tab_item.iterator().next();

    ITable partnerTable =

(ITable) row.getValue(ProjectConstants.ATT_ITEMS_PARTNERS);

Or,

    ITable tab_item =
    IRow row =

prj.getTable(ProjectConstants.TABLE_ITEM);

(IRow) tab_item.iterator().next();

    ITable partnerTable =
    for (Iterator iterator =

(ITable) row.getValue(ProjectConstants.ATT_ITEM_PARTNER_TABLE);

partnerTable.iterator(); iterator.hasNext();) {

    IRow iRow =
    String partner =

(IRow) iterator.next();

iRow.getValue(ProjectConstants.ATT_PARTNERS_PARTNER).toString();

    String split =
    }

iRow.getValue(ProjectConstants.ATT_PARTNERS_PARTNER_SPLIT).toString();

### 19.4.8 Managing Sourcing Project Attachments for Items and AMLs

The following paragraphs provide descriptions and examples to perform the following operations:

- Loading Items and AMLs on Sourcing projects attachments tables

- Adding Items on Sourcing Project attachment tables

- Removing Items on Sourcing Project attachment tables

#### 19.4.8.1 Adding Sourcing Project Attachments by File Type

These examples demonstrate adding attachments by specifying the supported file types.

Example: Adding string file attachments

IRow row1 = attachments.createRow("D:\\test1.txt");

Example: Adding MAP file attachments

Map map = new HashMap();

map.put(FileFolderConstants.ATT_FILES_CONTENT,"D:\\test2.txt");

map.put(FileFolderConstants.ATT_FILES_FILE_NAME, "test2.txt");

IRow row2 = attachments.createRow(map);

Example: Adding new attachment files

IRow row3 = attachments.createRow(new File("D:\\test3.txt"));

Example: Adding URL attachments

IRow row4 = attachments.createRow("`http://www.oracle.com`");

#### 19.4.8.2 Deleting Sourcing Project Table Rows for Items

The following APIs support deleting a single or a collection of rows in Sourcing Project Attachment tables:

- Deleting a single Table row – `ITable.removeRow(IRow row)`

- Deleting all Table rows – `ITable.clear ()`

  Deleting multiple Table rows – `ITable.removeAll (ListRow row)`

Example 19-1 Removing Rows in Sourcing Project Attachment tables

    // Remove attachment by IRow   attachments.removeRow(row1);

##### 19.4.8.2.1 Importing Data into Sourcing Projects

SDK exposes the following APIs to support deleting different combinations of Table rows for Items and AML tabs of a Sourcing project:

        String srcFilePath = ".//ImportSource//9312HF54//Assembly_BOM_AML_PC.xls";            String srcFileType = "ExcelFile";    String mappingPath = ".//ImportSource//9312HF54//Assembly_BOM_AML_PC.xml";      String transformPath = null

        String[] operations = new String[] { "project.item", "project.bom", "project.aml"};//Valid operations "project.item", "project.bom", "project.aml"            List options = new ArrayList();            options.add("BusinessRuleOptions|ChangeMode=Authoring");            options.add("BusinessRuleOptions|BehaviorUponNonExistingObjects=Accept");            String _output = ".//Log//9312HF54//Ass_BOM_AML_PC_log.xml";                        options.add("Template|TemplateType=com.agile.imp.template.TemplateParentChildFilter");            FileOutputStream fop = new FileOutputStream(_output);            IImportManager imgr = (IImportManager)session.getManager(IImportManager.class);            byte[] logData = null;            logData = imgr.importDataForSourcingProject(projectNumber,                                       stream2byte(new FileInputStream(srcFilePath)), srcFileType, convertFiletoStream(mappingPath),options);  convertFiletoStream(transformPath), operations, byte buf[] = new byte[1024 * 4];            int n = 0;            InputStream logStream = byte2stream(logData);            while ((n = logStream.read(buf)) != -1) {                fop.write(buf, 0, n);            }            fop.close();System.out.println("Import Ass_BOM_AML with ParentChild Template successfully, the log file is "+ _output );

#### 19.4.8.3 Importing Data for Sourcing Projects

The SDK exposes the importDataForSourcingProject API to enable this feature.

Example 19-2 Importing data for a Souring Project

.

    byte[]      importDataForSourcingProject (String projectNumber, byte[] srcFile, String srcFileType, byte[] mappingFile, byte[] transformFile, String[] operations, List options) throws APIException

#### 19.4.8.4 Validating Items on the AML Tab of Sourcing Projects

The following API supports validating Items, Manufacturer sand Manufacturer parts on the AML tab of a Sourcing Project:

void IProject.validateItems (List itemRows, List amlRows) throws APIException, RemoteException, Exception

Example: Validating Items on AML tab of a Sourcing Project

IProject prj = (IProject)session.getObject(IProject.OBJECT_TYPE, "PRJ000XX");

ITable prjTableAML = prj.getTable(ProjectConstants.TABLE_AML);

Iterator itr = prjTableAML.iterator();

List itemRows = new ArrayList();

List amlRows = new ArrayList();

while (itr.hasNext()) {

IRow row = (IRow)itr.next();

if ("Yes".equals(row.getValue(ProjectConstants.ATT_ITEMS_ITEM_HAS_MFRS).toString())) {

ITable tableAML = (ITable)row.getValue(ProjectConstants.ATT_ITEMS_AML);

Iterator itrAML = tableAML.getTableIterator();

while (itrAML.hasNext()) {

IRow amlRow = (IRow)itrAML.next();

amlRows.add(amlRow);

}

}

itemRows.add(row);

}

prj.validateItems(itemRows, amlRows);

### 19.4.9 Working with RFQs

Requests for Quotes (RFQs) allow users to request pricing information from suppliers. RFQs serve as the instrument to negotiate pricing and terms for items or manufacturer parts. RFQs are defined for Sourcing projects. Thus, to define an RFQ, you must first create the Sourcing Project and then create the required RFQs for that Sourcing Project.

A single Sourcing Project can generate several RFQs. RFQs support a one-to-many relationship with suppliers. That is, one RFQ may generate several responses from suppliers.

The Agile API supports the following RFQ-related tasks.

- Create an RFQ for Sourcing a Project

- Load and modify RFQ objects, tables, and attributes

- Access and modify the Page 1, Page 2, and RFQ Response tables

- Add items to the RFQ Response table from the RFQ's Sourcing Project

- Read and update the nested tables in the Page 1, Page 2, and RFQ Response table

- Assign suppliers to items or manufacturer parts in the RFQ Response table

For a list of API methods that support these RFQ functions, see Supported API Methods on page 301.

Note: The PCM SDK RFQ objects do not have a Page three, and no Page three RFQ constant is supported. Do not invoke these constants because the RFQ will not produce the expected result.

#### 19.4.9.1 Supported API Methods

The SDK supports the following APIs for RFQs. For information on these interfaces, refer to the Javadoc generated HTML files that document the SDK code. You can find them in the HTML folder in SDK_samples (ZIP file). To access this file, see the Note in Client-Side Components on page 2.

- IAgileSession.createObject(Object, Object)

- IAgileSession.createObject(int, Object)

- IAgileSession.getObject(Object, Object)

- IAgileSession.getObject(int, Object)

- IRequestForQuote.getName()

- IRequestForQuote.assignSupplier(Object)

- IRequestForQuote.getTable(Object)

- IRequestForQuote.lookupPrices(Object)

- ITable.iterator()

- ITable.getTableDescriptor()

- ITable.size()

- ITable.createRow(Object)

- IRow.getValue(Object)

- IRow.setValue(Object, Object)

#### 19.4.9.2 Creating RFQs for Sourcing Projects

RFQs are defined for a specific Sourcing Project. Creating an RFQ uses the generic IAgileSession method. You can use IDataObject with standard calls such as getObject, getTable, getValue, setValue to access and modify objects, tables, and attributes as follows:

- Read Page 1 or Cover Page and Page 2 tables

- Update Page 1 or Cover Page and Page 2 tables

Example: Creating an object

IAgileObject createObject(Object objectType, Object params)

throws APIException;

To create an RFQ, you must open the Sourcing Project. However, to open the Sourcing Project, it is necessary to first set the ship to location. See the code example in Accessing and Modifying the Status of Sourcing Projects on page 305.

You cannot create an RFQ by specifying the Sourcing Project number only. You must also specify the related Sourcing Project as this is a required parameter. This is shown in the example below.

Example: Creating an RFQ for a Sourcing Project

    IAgileClass rfqClass =

m_admin.getAgileClass(RequestForQuoteConstants.CLASS_RFQ);

IAutoNumber rfqNumber = rfqClass.getAutoNumberSources()[0];

HashMap map = new HashMap();

    map.put(RequestForQuoteConstants.ATT_COVERPAGE_RFQ_NUMBER, rfqNumber); map.put(RequestForQuoteConstants.ATT_COVERPAGE_PROJECT_NUMBER, pnumber);

IRequestForQuote rfq =

(IRequestForQuote) m_session.createObject(rfqClass, map);

#### 19.4.9.3 Loading RFQs from Sourcing Project's RFQ Table

In addition to loading an RFQ using IAgileSession.getObject(), you can also select an RFQ from the RFQ table of the Sourcing Project object.

Example: Loading an RFQ from the Sourcing Project RFQ table

ITable table = prj.getTable(ProjectConstants.TABLE_RFQS);

Iterator it = table.iterator();

IRow row1 = (IRow) it.next();

IDataObject obj1 = (IDataObject) m_session.getObject(IRequestForQuote.OBJECT_TYPE,

row1.getValue(ProjectConstants.ATT_RFQS_RFQ_NUMBER));

Note: The getReferent() method does not support the PCM SDK, including the RFQ tables. A list of supported RFQ tables appears in the table below.

#### 19.4.9.4 Supported RFQ Tables

The supported RFQ tables and their respective constants are listed in the table below.

Table | Constant | Read/Write Mode
--- | --- | ---
Cover Page | TABLE_COVERPAGE | Read/Write
Page Two | TABLE_PAGETWO | Read/Write
Responses | TABLE_RESPONSES | Read/Write

Note: The Agile API does not support adding new rows to RFQ tables. However, you can add new rows to the RFQ response table.

#### 19.4.9.5 Accessing and Modifying RFQ Objects, Tables, Nested Tables, and Attributes

You can access RFQ objects, tables, and attributes using the generic IAgileSession and IDataObject methods and standard calls such as getObject, getValue, setValue. Information about these classes, tables, and attributes is provided in the com.agile.api.RequestForQuoteConstants.java file in the API HTML reference files. See Client-Side Components on page 2 to access these files.

#### 19.4.9.6 RFQ Parent Table and Nested Child Table Constants

The list of parent RFQ table and the corresponding nested child table constants appears in the table below.

Parent Table Constant | Nested Child Table Constant | Read/Write Mode
--- | --- | ---
TABLE_RESPONSES | ATT_RESPONSES_AML | Read/Write
TABLE_RESPONSES | ATT_RESPONSES_PRICING | Read/Write

Similar to Sourcing Projects, nested RFQ tables are accessed by treating their cell value as a table. See Accessing and Modifying Nested Tables in Sourcing Projects or RFQ on page 305. The following example updates a nested table.

Note: Do not use Project.ATT_RFQ_RFQ_STATE to get the status of an RFQ, because it is not exposed to the SDK and will not render the correct value of the RFQ row. To get the status of an RFQ, you must first load the RFQ, and then get the status from the RFQ itself.

Example: Nested RFQ table update

    ITable subtab1 =
    IRow pricing1 =

(ITable)row.getValue(RequestForQuoteConstants.ATT_RESPONSES_PRICING);

(IRow)subtab1.iterator().next();

    Integer nest =
    Object nre =

ProjectConstants.ATT_PRICEDETAILS_MATERIAL_PRICE;

pricing1.getValue(nest);

    Money tc =
    pricing1.setValue(nest, (Object)tc);

new Money(new Integer(100), "USD");

Note: You must assign the supplier before updating an RFQ response table entry.

#### 19.4.9.7 Performing Price Lookup in RFQs

Similar to Performing Price Lookup in a Sourcing Project, you can verify the existence of a price scenario for a specified period and quantity for RFQs. If they exist, you do not have to create an RFQ for the specified item. You can either use the price information of the item, or you can modify the price information and send the RFQ to suppliers for requote. This is shown in the following code sample.

Example: Price lookup from history and from another Sourcing Project

    HashMap map = new HashMap();

map.put(PriceConstants.ATT_GENERAL_INFORMATION_PRICE_TYPE,priceTypes);

map.put(ProjectConstants.ATT_ANALYSIS_SUPPLIER,suppliers);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_CUSTOMER,customers);

map.put(ProjectConstants.ATT_GENERAL_INFORMATION_PROGRAM,programs);

map.put(ProjectConstants.

ATT_GENERAL_INFORMATION_SHIP_TO_LOCATION,shipTo);

map.put(ProjectConstants.ATT_ITEMS_NUMBER,itemMap);

map.put(ProjectConstants.ATT_ITEMS_AML,mpnMap);

map.put(LookupConstants.FLAG_ALL_PRICE_SCENARIOS,allPriceScenarios);

map.put(LookupConstants.FIELD_PRICE_SCENARIO,priceScenario);

map.put(LookupConstants.FLAG_IGNORE_QUANTITY,ignoreQtyRange);

map.put(LookupConstants.FIELD_QUANTITY_RANGE,qtyPercentRange);

map.put(LookupConstants.FLAG_IGNORE_DATE_RANGE,ignoreDateRange);

map.put(LookupConstants.FIELD_DATE_RANGE,dateRange);

map.put(LookupConstants.

FIELD_SELECT_RESPONSE_BY,LookupConstants.OPTION_LOWEST_PRICE);

map.put(LookupConstants.FLAG_EXCLUDE_AUTH_SUPPLIER,excludeAuthSupplier);

rfq.lookupPrices(map);

Example: Required parameters to perform an RFQ price lookup

    PriceConstants.ATT_GENERAL_INFORMATION_PRICE_TYPE
    ProjectConstants.ATT_ITEMS_NUMBER or ProjectConstants.ATT_ITEMS_AML
    LookupConstants.FIELD_QUANTITY_RANGE if LookupConstants.FLAG_IGNORE_QUANTITY is 'false'
    LookupConstants.FIELD_DATE_RANGE if LookupConstants.FLAG_IGNORE_DATE_RANGE is 'false'
    LookupConstants.FIELD_PRICE_SCENARIO if LookupConstants.FLAG_ALL_PRICE_SCENARIOS is 'false'

Example: Impact of Improper parameter settings

LookupConstants.FLAG_EXCLUDE_AUTH_SUPPLIER will default to false if not set.

#### 19.4.9.8 Working with RFQ Responses

The PCM SDK supports the following operations for RFQ responses, nested table of items responses, and Child AML responses:

- Read RFQ tables with different views (price scenarios, currency modes)

This is supported through generic SDK API.

- Add items to RFQs

- Add Response lines (Assign Suppliers)

PCM RFQ provides the following method for assigning suppliers to items or manufacturer parts.

public void assignSupplier(Object supplierParams)

throws APIException, RemoteException, Exception;

You can assign supplier data such as Manufacturer Part Number (mpn) or supplier name as a String or an Object to the RFQ response.

Example: Adding supplier data as String constants

    IRequestForQuote dObj =
    ITable tab =

(IRequestForQuote)m_session.getObject(RequestForQuoteConstants.CLASS_RFQ, number);

dObj.getTable(RequestForQuoteConstants.TABLE_RESPONSES);

    Map mp = new HashMap();

mp.put(ProjectConstants.ATT_RESPONSES_NUMBER, "P00007");

mp.put(ProjectConstants.ATT_RESPONSES_SUPPLIER, "SDKSUP");

dObj.assignSupplier(mp);

Example: Adding supplier data as Objects

You can also add an item as an IItem object as shown below.

    mp.put(ProjectConstants.ATT_RESPONSES_NUMBER, itemObject);

If you are assigning a supplier to an mpn, you must specify the mpn as an IManufacturerPart Object, or as a pair of Objects. One for the mpn name and one for mfr name.

mp.put(RequestForQuoteConstants.ATT_RESPONSES_NUMBER, mpnObject);

Or,

mp.put(RequestForQuoteConstants.ATT_RESPONSES_NUMBER, mpnName); mp.put(RequestForQuoteConstants.ATT_RESPONSES_MANUFACTURER, mfrName);

Caution: When you invokeRequestForQuote.TABLE_RESPONSE to assign suppliers to item components, the table size may change if there is more than one supplier for that item component. That is, if an item has a single supplier, each item and the corresponding supplier will occupy their own distinct separate rows in the TABLE_RESPONSE table. However, if the item has more than one supplier, then the row for this item component is split into the number of suppliers, thus changing TABLE_RESPONSE by increasing the number of rows in the table. It is therefore necessary to immediately reload the ITERATOR to reflect the change in TABLE_RESPONSE table. This is not an SDK defect and is due to SUN J2SE ITERATOR behavior.

- Update Response Lines

The PCM SDK supports the RFQ response table through generic SDK API. It does not support the RFQ Response Class or Supplier Response.

Note: The response currency in the RFQ response line is determined by the response currency attribute. This causes the server to ignore the currency parameter in the material price. Buyers can modify the response currency in the response line and it will be applied to all pricing attributes in the response line. The supplier RFQ response currency is set to your RFQ currency preference and cannot be modified in the supplier responses. Once the response line is opened to suppliers, the response line must be locked before buyers can modify them.

#### 19.4.9.9 Locking and Unlocking RFQ Responses

The following APIs support these two functions:

- void IRequestForQuote.lockResponses (List rows, boolean background) throws APIException, RemoteException, Exception

- void IRequestForQuote.unlockResponses (List rows) throws APIException, RemoteException, Exception

Example: Locking and unlocking RFQ responses

ITable response = rfq.getTable(RequestForQuoteConstants.TABLE_RESPONSES);

ArrayList <IRow> respRow = new ArrayList<IRow>();

Iterator it = response.iterator();

while(it.hasNext()){

IRow row = (IRow)it.next();

respRow.add(row);

}

//lock the response rows

rfq.lockResponses(respRow,false);

//unlock the response rows

rfq.unlockResponses(respRow);

#### 19.4.9.10 Editing RFQ Responses Submitted by Suppliers

The `API submitAll()` API implemented on `ISupplierResponse` API enables suppliers submitting suppliers to submit their RFQ responses. In addition, a PCM server API supports editing supplier supplier's response and prices tables.

The following functions are supported these APIs:

- Editing response tables

- Editing price tables

- Submitting the editted data in response and price tables

Example 19-3 Editing response tables

    //Editing of Item/AML rows for Response table dataMap responseMap = new HashMap();//Bid DecisionresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_BID_DECISION, "Bid");//Currency -read only from Supplier Response//responseMap.put(SupplierResponseConstants.ATT_RESPONSES_CURRENCY, "FRF");//Lead-TimeresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_LEADTIME, new Integer(3));//Inventory AvailableresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_INVENTORY_AVAILABLE, new Integer(222));//MinresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_MIN, 1);//MultresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_MULT, 10);//Transportation TermsresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_TRANSPORTATION_TERMS, "EXW - EX WORKS");//Country of OriginresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_COUNTRY_OF_ORIGIN, "Canada");//EOL DateresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_EOL_DATE, eolDate);//NCNRresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_NCNR, "Yes");;

    //Valid FromresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_VALID_FROM, validFrom);//Valid until - is required only for Quantity Break type project. Not valid for price period projectresponseMap.put(SupplierResponseConstants.ATT_RESPONSES_VALID_UNTIL, validUntil);//resp Money 1responseMap.put(SupplierResponseConstants.ATT_RESPONSES_RESP_MONEY_1, new Money(value, "INR"));//resp Date 1SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy");responseMap.put(SupplierResponseConstants.ATT_RESPONSES_RESP_DATE_1, df.parse("12/29/2010"));//resp Text 1responseMap.put(SupplierResponseConstants.ATT_RESPONSES_RESP_TEXT_1, new String("EMS1 Supplier Edited from SDK - Text1"));//resp Number1responseMap.put(SupplierResponseConstants.ATT_RESPONSES_RESP_NUMBER_1, 11);//resp list 1responseMap.put(SupplierResponseConstants.ATT_RESPONSES_RESP_LIST_1, "USD");//resp MultiText 1responseMap.put(SupplierResponseConstants.ATT_RESPONSES_RESP_MULTITEXT_1, new String("EMS1 Supplier Edited from SDK - MultiText1"));//resp MultiList 1responseMap.put(SupplierResponseConstants.ATT_RESPONSES_RESP_MULTILIST_1, "USD");ISupplierResponse rfq = (ISupplierResponse)agileSession.getObject(ISupplierResponse.OBJECT_TYPE, params);ITable tableResp = rfq.getTable(SupplierResponseConstants.TABLE_RESPONSES);for (Iterator rowIter = tableResp.iterator(); rowIter.hasNext(); ) {IRow rowResp = (IRow)rowIter.next();rowResp.setValues(responseMap);}//Editing Item/AML rows for Price table dataMap responsePriceMap = new HashMap();responsePriceMap.put(ProjectConstants.ATT_PRICEDETAILS_MATERIAL_PRICE, new Money(new Double(227.50), "USD"));responsePriceMap.put(ProjectConstants.ATT_PRICEDETAILS_NRE, new Money(new Double(0.85), "USD"));// Non Material prices for assemblyresponsePriceMap.put(ProjectConstants.ATT_PRICEDETAILS_NONMATERIAL_PRICE_1, new Money(new Double(33.5), "USD"));responsePriceMap.put(ProjectConstants.ATT_PRICEDETAILS_NONMATERIAL_PRICE_25, new Money(new Double(1.55), "INR"));responsePriceMap.put(ProjectConstants.ATT_PRICEDETAILS_MATERIAL_PRICE_ADDER_6, new Money(new Double(10.50), "USD"));responsePriceMap.put(ProjectConstants.ATT_PRICEDETAILS_MATERIAL_PRICE_ADDER_7, new Money(new Double(222.50), "INR"));

    ISupplierResponse rfq = (ISupplierResponse)agileSession.getObject(ISupplierResponse.OBJECT_TYPE, params);ITable tableResp = rfq.getTable(SupplierResponseConstants.TABLE_RESPONSES);for (Iterator rowIter = tableResp.iterator(); rowIter.hasNext(); ) {IRow rowResp = (IRow)rowIter.next();ITable pricing_table = (ITable)rowResp.getValue(SupplierResponseConstants.ATT_RESPONSES_PRICING);Iterator priceIter = pricing_table.iterator();while (priceIter.hasNext()) {IRow priceRow = (IRow)priceIter.next();priceRow.setValues(responsePriceMap);}}//New API for Submit All action from ISupplierResponseISupplierResponse rfqResponse = (ISupplierResponse)agileSession.getObject(ISupplierResponse.OBJECT_TYPE, params);rfqResponse.submitAll();