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. |
Модуль 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
Модуль ONT — Связь в заказах между складской и операционной организацией
select h.order_number, -- операционная единица h.org_id as operate_org_id, -- складская организация pla.organization_id as inventory_org_id, l.header_id, l.line_id, l.ordered_quantity as qty, l.request_date -- from oe_order_headers_all h, oe_order_lines_all l, po_location_associations_all pla, mtl_system_items_b msi where 1=1 and h.header_id = l.header_id and h.sold_to_org_id = pla.customer_id -- msi and msi.inventory_item_id = l.inventory_item_id and msi.organization_id = pla.organization_id;
Создание URL для доступа к форме OEBS
Используем стандартный API для генерации URL
declare url varchar2(32767); begin url:= fnd_run_function.get_run_function_url ( p_function_id =>1043600, p_resp_appl_id =>-1, p_resp_id =>-1, p_security_group_id =>0, p_parameters =>'TEST_ID=182'||' '||'TEST_ID2=548', p_encryptParameters =>true ) ; dbms_output.put_line(url); end;
В результате получаем URL:
http://.../OA_HTML/RF.jsp?function_id=1043600&resp_id=-1&resp_appl_id=-1&security_group_id=0&lang_code=RU¶ms=QU2-OJtLRJHeJif-a9I4tPUdx3zMf-CX4yR8feCtDVM
Регистрация приложения
1 | Создать структуру каталогов |
2 | Изменить файл (по умолчанию defaults.env) настроек переменных окружения для сервера форм. Его имя хранится в переменной окружения envFile в файле appsweb.cfg, имя и путь к которому в свою очередь хранятся в переменной окружения FORMS_WEB_CONFIG_FILE, добавив строку с установкой значения переменной окружения <префикс приложения (ЗАГЛАВНЫМИ)>_TOP. Тем самым будет определён каталог, в котором сервер Oracle Forms сможет найти файлы приложения |
3 | В файл $APPL_TOP/custom<имя инстанса>.env следует добавить инициализацию тех же переменных с последующим их экспортом (это необходимо для выполнения системных процедур и вызова параллельных запросов) и проверить наличие вызова это файла из $APPL_TOP/APPS<имя инстанса>.env. При наличии в составе приложения исполняемых операционной системой программ также следует добавлять <префикс приложения (ЗАГЛАВНЫМИ)>_TOP/bin к переменной окружения PATH (если используется) |
4 | Остановить менеджер параллельных программ (concurrent manager) $ADMIN_SCRIPTS_HOME/adcmctl.sh stop apps/apps |
5 | Выполнить файл, замещающий APPLSYS.env . / $APPL_TOP/APPS<имя инстанса>.env |
6 | Перезапустить concurrent manager $ADMIN_SCRIPTS_HOME/adcmctl.sh start apps/apps |
7 | Войдите в систему с полномочиями Разработчик приложений (Application Developer) и зарегистрируйте приложение |
8 | Войдите в систему с полномочиями System Administrator и добавьте приложение в группу данных (раздел меню «Security : ORACLE», пункт «Группа данных») |
Использование таймера
Таймер
Таймер (Timer) – это способ выполнения кода через определенное время. По истечении указанного времени вызывается тригер WHEN-TIMER-EXPIRED, в котором и обрабатывается реакция на запуск таймера.
Таймером очень хорошо пользоваться для непрерывного отслеживания каких-либо действий. Вы также можете использовать таймер как планировщик, закрывая формы по истечении указанного времени, для выполнения автосохранения в форме, для согласованного обновления данных в разных блоках формы и т.д.
Модуль GME/INV — Связка между заданиями и транзакциями
select * from gme_batch_header gbh, gme_material_details gmd, mtl_material_transactions mmt where 1=1 and gbh.batch_type = 0 -- gmd and gmd.batch_id = gbh.batch_id -- mmt and mmt.transaction_source_id = gmd.batch_id and mmt.trx_source_line_id = gmd.material_detail_id -- for test --and trunc(gbh.plan_start_date) > --and gbh.batch_no = --and mmt.attribute_category = and rownum<100;
Модуль GMD — Создание производственного задания
Модуль GMD R12.GMD.A.6 (Разработка продукции УНП; Process Manufacturing Product Development)
Процедура для создания производственного задания (batch).
Модуль INV — Текущее количество для позиции
-- текущее количество на складе Select moq.organization_id as org_id, sysdate as date_val, moq.inventory_item_id as item_id, msi.segment1 as item, msi.primary_uom_code as uom_code, sum(moq.primary_transaction_quantity) as actual_qty -- from mtl_onhand_quantities_detail moq, mtl_system_items_b msi where 1=1 -- msi and msi.inventory_item_id = moq.inventory_item_id and msi.organization_id = moq.organization_id group by moq.organization_id , sysdate, moq.inventory_item_id, msi.segment1, msi.primary_uom_code order by moq.organization_id, moq.inventory_item_id