Архив

Архив автора

OAF-компоненты. Attachments

1. Динамическое создание компонента attachmentTable

import oracle.apps.fnd.framework.webui.beans.layout.OAAttachmentTableBean;
import oracle.apps.fnd.framework.webui.OAWebBeanConstants;
import java.util.Hashtable;
import java.util.Dictionary;
...
OAAttachmentTableBean attTable = (OAAttachmentTableBean)pageContext.getWebBeanFactory().createWebBean(pageContext, OAWebBeanConstants.ATTACHMENT_TABLE_BEAN, null, null);

attTable.setID("xxTestAttachmentId");
attTable.setViewUsageName("ApplicantAssignmentVO");
attTable.setSearchRegionDisplayed(false);
attTable.setDocumentCatalogEnabled(true);

attTable.setText("Сводка дополнений");

Hashtable<String, Object> entity = new Hashtable<String, Object>();
entity.put("entityId", "PER_ASSIGNMENTS_F"); // entity
entity.put("showAll", Boolean.FALSE);
entity.put("insertAllowed", Boolean.TRUE);
entity.put("deleteAllowed", Boolean.TRUE);
entity.put("updateAllowed", Boolean.TRUE);

String[] pkAttrNames = new String[1];
pkAttrNames[0] = "AssignmentId";
entity.put("pkColumns", pkAttrNames);

Dictionary[] entityMaps = new Dictionary[1];
entityMaps[0] = entity;
attTable.setEntityMappings(entityMaps);

webBean.addIndexedChild(attTable);

https://community.oracle.com/thread/2249676
https://community.oracle.com/thread/2404025

2. Не появляются всплывающие popup-ы (Inline Attachments)

В некоторых невыясненных ситуациях, при добавлении компонента attachmentTable на стандартную форму динамически или через персонализацию, не работают popup-ы для просмотра/добавления/редактирования/удаления вложений (Inline Attachments). Было обнаружено, как минимум, 2 условия, которые влияют на эту ситуацию (полный список условий выяснить не удалось):

  • Страница открывается 1-й раз
  • У компонента attachmentTable отключен регион поиска (searchRegionRendered="false")

Для устранения этого неудобства удалось найти workaround. Нужно добавить в контроллер (processRequest) следующий код:

// Тут важен процесс создания компонента, оказывающий положительное влияние на popup-ы, если они не хотят всплывать.
// На форме компонент показывать не нужно.
OAMessageChoiceBean akAttachmentCategory = (OAMessageChoiceBean)createWebBean(pageContext, "MESSAGE_POPLIST", null, "XxTmp");
akAttachmentCategory.setPickListViewObjectDefinitionName("oracle.apps.fnd.server.FndCategoryNameVO");
akAttachmentCategory.setValue(pageContext, "1");

3. Изменения в модели данных
Если форма работает с вложениями (attachmentLink, attachmentTable), то в модели данных происходят следующие динамические изменения:

  • Добавляется дочерний Application Module с именем oracle_apps_fnd_server_OAAttachmentsAM
  • В этом AM, для каждого компонента, работающего с вложениями, создается набор ViewObject-ов. Наиболее интересные — VO, связанные с таблицами fnd_documents и fnd_attached_documents. Именуются они по шаблону Attach_<num>_FndDocumentsDomExtensionVO и Attach_<num>_FndAttachedDocumentsDomExtensionVO. Например, Attach_0_FndAttachedDocumentsDomExtensionVO.

Перед проходом по строкам VO, нужно обязательно проверить, что заданы bind-переменные. Это наиболее вероятная ситуация, но попадались случаи, когда для объекта нет привязанных вложений, и bind-переменные в Attach…VO были не установлены. Попытка сделать проход по строкам VO, в такой ситуации, приведет к тому, что SQL-запрос вернет данные из таблиц без фильтра (например, все записи из fnd_attached_documents). Cтраница зависнет, а потом упадет по timeout-у.
Пример кода.

OAApplicationModule am = pageContext.getApplicationModule(webBean);
// Опорные имена, по которым ищем AM и VO с вложениями
String attachmentsAMName = "oracle_apps_fnd_server_OAAttachmentsAM";
String attachDocsVOFlag = "FndAttachedDocumentsDomExtensionVO";
String docsVOFlag = "FndDocumentsDomExtensionVO";
// Application Module, в котором содержатся ViewObject-ы, имеющие отношения к вложениям (attachemnts)
OAApplicationModule amA = (OAApplicationModule)am.findApplicationModule(attachmentsAMName);
if (amA != null) {
    writeDiag(pageContext, "AM = " + amA.getDefFullName());
    String[] voNames = amA.getViewObjectNames();
    writeDiag(pageContext, "viewobjectNames Length = " + voNames.length);
    for (int j = 0; j < voNames.length; j++) {
        // Обрабатываем ViewObject-ы (их может быть несколько - свой для каждого претендентства), в которых находятся данные по fnd_attached_documents if (voNames[j].lastIndexOf(attachDocsVOFlag) > 0)
        if (voNames[j].lastIndexOf(attachDocsVOFlag) > 0) {
            String voDName = voNames[j].substring(0, voNames[j].indexOf("_", 8) + 1) + docsVOFlag; // "Attach__"
            writeDiag(pageContext, "     AttachedDocuments ViewObject Name = " + voNames[j]);
            writeDiag(pageContext, "     Documents ViewObject Name = " + voDName);
            
            OAViewObject voA = (OAViewObject)amA.findViewObject(voNames[j]);
            // ОБЯЗАТЕЛЬНО!!! Проверяем, чтобы были заданы bind-переменные.
            if (voA.getWhereClauseParams().length > 1) {
                Object[] params = voA.getWhereClauseParams();
                for(int p = 0; p < params.length; p++)
                    writeDiag(pageContext, "params[" + p + "] = " + params[p].toString());
                for (Row rowA = voA.first(); rowA != null; rowA = voA.next()) {
                    writeDiag(pageContext, "DocumentId = " + rowA.getAttribute("DocumentId"));
                    writeDiag(pageContext, "LastUpdateDate = " + rowA.getAttribute("LastUpdateDate"));
                    writeDiag(pageContext, "newRowState = " + ((ViewRowImpl)rowA).getNewRowState());
                }
            }
        }
    }
}

OAF-компоненты. AdvancedTable

1. Использование элементов ввода в области tableActions

Для элементов области tableActions, в которые предполагается ввод данных пользователем (например, MessageChoice или MessageTextInput), была замечена особенность: если ViewObject, связанный c AdvancedTable, не инициализирован, тогда нет доступа к новым значениям элементов, введенных на форме. Признаком того, что ViewObject не инициализирован, является надпись в табличной части «Поиск не выполнен». Если ViewObject инициализирован, но в нем нет строк, то надпись будет «Нет результатов поиска». В контроллере этот факт можно проверить с помощью функции VO isPreparedForExecution. Для кнопок таких проблем не возникает — с точки зрения обработки, важен только сам факт нажатия кнопки, который всегда можно отследить и обработать в контроллере.

Если есть необходимость работать с элементами, допускающими ввод данных пользователем в tableActions, то нужно чтобы VO был в инициализированном состоянии. Например, в контроллере processRequest, можно написать следующий код (чтобы состояние «VO НЕ инициализирован, строк нет» перевести в состояние «VO инициализирован, строк нет»)

if (!vo.isPreparedForExecution()) {
    vo.setWhereClause("1=0");
    vo.setWhereClauseParams(null);
    vo.executeQuery();
    vo.setWhereClause(null);
}

2. Доступ к элементам, находящимся в tableActions или tableSelection

Для доступа к элементам из областей tableActions или tableSelection, нужно сначала получить саму область, а потом искать элемент внутри нее

OAAdvancedTableBean tableBean = (OAAdvancedTableBean)webBean.findIndexedChildRecursive("invoicesTable");
OARowLayoutBean actionsBean = (OARowLayoutBean)tableBean.getTableActions(); // или OAFlowLayoutBean
OAMessageChoiceBean pt = (OAMessageChoiceBean)actionsBean.findIndexedChildRecursive("prepaymentTypesItem");
pt.setValue(pageContext, pageContext.getProfile("XXAP001_INVOICE_PREPAYMENT_DEFAULT"));

3. Связывание свойств с атрибутами VO для элементов внутри Столбца

Для некоторых элементов, являющихся дочерними по отношению к столбцу AdvancedTable, не удалось связать свойства с атрибутами VO. Такая особенность наблюдалась для любого региона (flowLayout, tableLayout и т.п.) и для компонента spacer. Например, свойство Rendered не получилось связать ни с использованием EL, ни через OADataBoundValueViewObject. Для spacer-а можно применить workaround:

  • вместо компонента spacer использовать компонент rawText
  • в свойстве Text указать HTML-код, который генерится компонентом spacer (задать нужные значения в атрибутах width и height): <img src="/OA_HTML/cabo/images/skyros/t.gif" width="10" height="10">
  • свойство Rendered связать с атрибутом VO
Categories: OA Framework Tags: ,