OAF: Правила разработки
No | Правило/Причина |
1 | Всегда пытайтесь создать новый элемент декларативно (через персонализацию страницы). Определяйте программно, Только если невозможно создать декларативно. |
Программно созданный элемент невозможно персонализировать, сложнее расширять и использовать. | |
2 | Если вы создаёте новый элемент программно, Никогда не использовать конструктор
new OA*Bean(). Всегда использовать createWebBean. |
Не все свойства элемента инициализируются корректно, когда используется конструктор new | |
3 | Никогда не искать элемент по индексу, для изменения его свойств. |
Индекс элемента может изменяться в процессе работы. | |
4 | Никогда не изменять свойства элемента в processFormRequest(). Всегда изменять свойства в processRequest(). Любая информация, которая влияет на отображение элемента, должна быть добавлена в URL в виде параметра. |
Гарантирует постоянное состояние при формировании страницы. | |
5 | Никогда не изменяйте свойства родительского элемента из дочернего. |
Эта плохая практика препятствует повторному использованию кода. | |
6 | Для доступа к методу, имеющему разные версии [ например setText(String text) или setText(OAPageContext pageContext, String text)], всегда используйте метод в котором присутствует параметр OAPageContext. |
Обеспечивает наиболее безопасный способ изменения объекта. | |
7 | Никогда программно не использовать неявную структуру созданную OA Framework.
Выполнять findChildRecursive() для поиска элементов. |
Определённые элементы — defaultRenderers, PageLayoutBean, TableBean – создают добавочные объекты. Эти объекты могут меняться в разных версиях, вы не можете достоверно распарсить данную структуру. | |
8 | Когда необходим доступ к Application module, использовать getApplicationModule(webBean) вместо getRootApplicationModule() там где это возможно. |
Улучшает модульность и повторное использование. | |
9 | При переходе на первую страницу определенного функционала, всегда использовать функцию меню, вместо прямой сслыки на страницу. |
Позволяет изменять адресс назначения меняя только описание функции. Не требуется изменение и перекомпиляция кода. | |
10 | Никогда не создавать программно OAFormBean. |
Страница должна иметь только один OAFormBean и он определяется декларативно для региона pageLayout | |
11 | Всегда устанавливать точность (размер) для всех колонок view objecs (VO).
Всегда указывать точность вызывая registerOutParameters. |
Например: eсли не установить точность, то для колонки типа String размер по умолчанию 4KB. | |
12 | Всегда использовать Oracle-style binding (:1, :2) и не использовать JDBC style binding (?). |
Это отменяет разбор SQL во время выполнения для замены строковых значений. | |
13 | Всегда используйте спроектированные VO вместо динамических (программно созданных). |
Динамические VO осуществляют дополнительный вызов для разбора запроса и возможный результат может иметь различные комбинации. | |
14 | Никогда не рассчитывать, что Application module будет использовать одно соединение с БД для запросов. |
Для быстродействия, Framework организует пул соединений и переиспользует их. Не держит одно соединение в течении жизни Application module. |
Преобразование типов переменных в Java
Каждое выражение в Java имеет тип, который определяется структурой выражения и типами составляющих его операндов (констант, переменных и методов). Иногда нам может потребоваться явное преобразование выражения в другой тип. Рассмотрим ряд способов преобразования:
Тип | Конвертирование | |
STRING to NUMBER | ||
byte | Byte.parseByte(«123») | |
byte | Byte.valueOf(«123»).byteValue() | |
short | Short.parseShort(«123») | |
short | Short.valueOf(«123»).shortValue() | |
int | Integer.parseInt(«123») | |
int | Integer.valueOf(“123”).intValue() | |
long | Long.parseLong(«123») | |
long | Long.valueOf(«123»).longValue() | |
float | Float.parseFloat(«123.4») | |
float | Float.valueOf(«123.4»).floatValue() | |
double | Double.parseDouble(«123.4e10») | |
double | Double.valueOf(«123.4e10»).doubleValue() | |
Number | new Number(Integer.parseInt(«123»)) | |
NUMBER to STRING | ||
String | “” + 123 | |
String | Number | pageContext.getOANLSServcies().NumberToString(num,»###,###,##0.00000;-###,###,##0.00000″); |
String | int | Integer.toString(123) |
String | double | Double.toString(123.4e10) |
String | long | Long.toString(123) |
String | float | Float.toString(123.4) |
STRING to DATE | ||
Date | String DATE_FORMAT = «dd-mm-yyyy»;
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(DATE_FORMAT); Date myDate = sdf.parse(“01-10-2010”) |
|
oracle.jbo.domain.Date | java.sql.Date myDate = pageContext.getOANLSServcies().stringToDate(“01-10-2010”);
oracle.jbo.domain.Date date1 = new Date(myDate); |
|
oracle.sql.DATE |
String lOriginalDate = "2014-05-15"; SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); long lTime = format.parse(lOriginalDate).getTime(); java.sql.Timestamp t = new java.sql.Timestamp(lTime); oracle.sql.DATE d = new oracle.sql.DATE(t); |
|
oracle.sql.DATE |
public java.sql.Date getSQLDate(String s) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); java.util.Date d = null; java.sql.Date sd = null; try { d = sdf.parse(s); sd = new java.sql.Date(d.getTime()); } catch(Exception e) { sd = null; } return sd; } |
|
oracle.jbo.domain.Date to oracle.sql.DATE | ||
oracle.sql.DATE |
new oracle.sql.DATE( pJboDomainDate.timestampValue() ) |
|
STRING to DATE to STRING (NLS) | ||
String |
import oracle.apps.fnd.framework.OANLSServices; ... String sEffectiveDate = "20-10-2014"; OANLSServices nls = am.getOADBTransaction().getOANLSServices(); String pEffectiveDate = nls.dateToString((nls.stringToDate(sEffectiveDate)) , "dd/MM/yyyy" , nls.getUserCalendar() ); |
Модуль PA (Проекты) — полезные запросы
Список проектов
select * from pa.pa_projects_all;
Просмотр позиций поставки
select * from pa.pa_proj_elements t where t.OBJECT_type = 'PA_DELIVERABLES'; select * from pa_deliverables_v; select * from oke_deliverables_b where source_code = 'PA';
Просмотр типов позиций поставки
select * from pa.pa_task_types t where t.object_type = 'PA_DLVR_TYPES';
Просмотр статусов позиций поставки
select * from pa.pa_project_statuses s where 1 = 1 and s.status_type = 'DELIVERABLE' and trunc(sysdate) between nvl(s.start_date_active, trunc(sysdate)) and nvl(s.end_date_active, trunc(sysdate));
Список задач
select * from pa.pa_proj_elements t where t.OBJECT_type = 'PA_TASKS';
Типы задач
select * from PA_TASK_TYPES t where object_type = 'PA_TASKS';
Типы проектов
select * from PA_PROJECT_TYPES_ALL t;
Статьи затрат
select * from pa_expenditure_types_desc_v;
OAF: Controller
Oracle Application Framework Controller это простой java класс, являющийся подклассом oracle.apps.fnd.framework.webui.OAControllerImpl.
В контроллере можно определить:
1) реакция на действия пользователя на странице
2) инициализация или изменение свойств элементов страницы (web beans)
Пример java класса контроллера:
Workflow: Пример вызываемой процедуры
procedure XX_TEST( itemtype IN VARCHAR2 , itemkey IN VARCHAR2 , actid IN NUMBER , funcmode IN VARCHAR2 , resultout OUT VARCHAR2 ) is l_proj_element_id NUMBER; -- l_marker NUMBER; -- служит для обозначения шага begin l_marker := 10; xxdebug('XX_TEST'); xxdebug('itemtype = '||itemtype ,'itemkey = ' ||itemkey); xxdebug('actid = ' ||actid ,'funcmode = '||funcmode); xxdebug('--'); -- Проверяем статус workflow IF funcmode != WF_ENGINE.ENG_RUN THEN wf_log_pkg.string(5,'XX_TEST','Not in RUN mode'); xxdebug_error('funcmode = '||funcmode); RETURN; END IF; -- далее основная логика процедуры -- получаем ID позиции поставки l_proj_element_id := WF_ENGINE.GetItemAttrText ( itemtype => itemtype , itemkey => itemkey , aname => 'PROJ_ELEMENT_ID' ); xxdebug('proj_element_id='||l_proj_element_id); l_marker := 20; -- устанавливаем нового владельца WF_ENGINE.SetItemAttrText(itemtype, itemkey, 'NEW_DELIV_OWNER_ID', 141); resultout := WF_ENGINE.ENG_COMPLETED; RETURN; EXCEPTION WHEN OTHERS THEN xxdebug_error(SQLERRM, 'marker = '||l_marker); WF_CORE.context ( g_pkg_name , 'XX_TEST' , itemtype , itemkey , TO_CHAR(actid) , funcmode , SQLERRM , 'marker = '||l_marker ); RAISE; END;
Что такое Oracle Application Framework (OAF)
Oracle Application Framework (OA Framework) – служит для разработки и кастомизации HTML страниц Oracle E-Business Suite.
OA Framework основан на стандарте J2EE и использует шаблон проектирования Model–View-Controller (MVC).
Model – отвечает за бизнесс логику, использует Oracle Business Components for Java (BC4J) : AM (Application Module), VO (View Object), EO (Entity Object)
View — отвечает за отображение информации (пользовательский интерфейс).
Controller — интерпретирует данные, введённые пользователем, и информирует модель и представление о необходимости соответствующей реакции. Прочитать больше про контроллер.
PL/SQL Developer: Start debugger
Если при старте дебагера в окне Test выскакивает ошибка
необходимо зайти с правами админа и выполнить
grant debug connect session to user;
Модуль INV — Связь позиции с категорией
SELECT msi.organization_id, msi.inventory_item_id, msi.segment1, msi.description, mic.category_set_name, mic.segment1, mic.segment2 FROM mtl_system_items_vl msi, mtl_org_assign_v moa, mtl_item_categories_v mic WHERE moa.organization_id = msi.organization_id AND moa.inventory_item_id = msi.inventory_item_id AND mic.organization_id = msi.organization_id AND mic.inventory_item_id = msi.inventory_item_id AND moa.assigned_flag = 'Y' order by msi.organization_id, msi.inventory_item_id;
Workflow: Отправка уведомления
Данная статья описывает процесс создания workflow процесса для отправки уведомления.
Версия Oracle Workflow Builder 2.6.3.5
1 Создание нового Workflow
Открываем Oracle Workflow Builder
Workflow: WFLOAD (утилита загрузки)
Утилита WFLOAD позволяет перемещать данные workflow между файлом и базой данных.
DOWNLOAD
Копирует файл на сервер приложений.
WFLOAD username/password 0 Y DOWNLOAD XX_TEST.wft XX_TEST
UPGRADE
Загружает файл в БД.
WFLOAD username/password 0 Y UPGRADE XX_TEST.wft
Последние комментарии