Friday, July 31, 2015

Bills of Material

Bills of Material

What is Bills of Material?

The Bill of Material is a list of all items that make an assembly, and is structured level by level so as to show the parent/component relationship.

Let us take the simple case of a bicycle. It is made of two wheels. Here the bicycle is the parent and wheel is its component. The wheel consists of a rim. The wheel here is the parent item and the rim is the component (child). Thus the first level of the BOM is Bicycle, the second level is Wheel, and the third level is Rim. You could even continue further to the level of Spokes. Thus, depending upon the item, one can go further and further down in the BOM level.

However, the maximum BOM level that Oracle supports is 60.

We use BOM for various purposes, namely:
- To manufacture assemblies and sub-assemblies
- To configure sales orders
- To calculate standard cost
- To forecast (planning)

BOM Conversion
First before stepping into boms we have to seriously study the client requirement. Once we are through with the client requirement, we have to check the legacy data that is provided by the client. The obtained legacy data should be entered into the staging table, the column of the staging table will be the same as our legacy data columns, and also we will be given the columns and data for two mapping tables by the client.

We need to construct a convertion staging table as xx_bom_bill_of_mtls_conv_stg, this staging table contains the following columns. The conversion staging table is as fallows

row_id
old_organization_code
new_organization_code
organization_id
old_assembly_item_number
new_assembly_item_number
assembly_item_id
old_operation_seq_num
new_operation_seq_num
old_component_item_number
new_component_item_number
component_item_id
item_num
component_quantity
component_yield_factor
effectivity_date
disable_date
planning_factor
wip_supply_type_meaning
wip_supply_type
supply_subinventory
supply_locator_code
supply_locator_id
operation_lead_time_percent
status_flag

Some of the validations to be performed are

1. Validating the orgnization_code for null
2. Validating the organization_code and geting the organization_id from mtl_parameters
3. Validating the assembly_item_number and getting the related inventory_item_id
4. Validating component_item_number for null
5. Validating and getting the inventory_item_id for component_item_number
6. Validating the wip_supply_type_meaning and getting the corresponding wip_supply_type
7. Validating the supply_locator_code and getting the supply_locator_id related to supply_locator_code

How to Compile and port a Form (fmb) in Oracle

How to Compile and port a Form (fmb) in Oracle

1. Port the attached form to unix directory to any top using FTP (Preferable we port the form to the AU_TOP)

NOTE: Copy .fmb files (form files) in Binary mode.

2. Connect to the telnet and change the directory to the top where we have ported the fmd.

Run the following commands in the above directory in Telnet:

a) FORMS60_PATH=$FORMS60_PATH:$AU_TOP/forms/US
b) f60gen module=formname.fmb userid=apps/apps output_file=formname.fmx module_type=form batch=no compile_all=special
example:
f60gen module=XXTRRBT.fmb userid=apps/apps output_file=XXTRRBT.fmx module_type=form batch=no compile_all=special

Deadlocks and how to break them?

Deadlocks and how to break them?

What is a deadlock?

Whenever you have competing DML running against the same data, you run the risk of a deadlock. This deadlock condition is an age-old issue known as the "perpetual embrace"! The doc note that a retry may work:

ORA-00060: deadlock detected while waiting for resource

Cause: Transactions deadlocked one another while waiting for resources.

Action: Look at the trace file to see the transactions and resources involved. Retry if necessary.


Deadlocks in Oracle result in this error:

ORA-00060: deadlock detected while waiting for resource

If your ORA-00060 is caused by competing resources, the perpetual embrace happens when the aborted task (Task B) attempts to lock a row which is being held by another task (Task A), which, in-turn, is waiting for task B to release a lock. To prevent a perpetual wait, Oracle aborts the transaction that caused the deadlock.

How to Break them?

SELECT a.object_name, b.process, b.session_id
FROM all_objects a, v$locked_object b
WHERE a.object_id = b.object_id

SELECT SID, serial#
FROM v$session
WHERE SID = '[SESSION_ID]'

ALTER SYSTEM KILL SESSION '[SID],[SERIAL#]'

To view quantity available and quantity on hand values:

Overview of Inventory Transactions

1. Transferring material between subinventories.
2. Performing miscellaneous transactions (miscellaneous issues and receipts).
3. Transferring material between Organizations.
4. Tracking lots and serial numbers for an item (Assigning Lot Numbers, Assigning Serial Numbers).
5. Generating material shortage alerts and material shortage notifications.
6. Entering and maintaining movement statistics information.
7. Viewing Material Transactions.
8. Viewing material transaction accounting distributions.
9. Viewing Transaction Summaries for a range of dates.
10. Viewing Pending Transactions.
11. Viewing and Updating pending Transaction Interface Activity.
12. Purging Transaction History.
13. Viewing Serial Genealogy.

Transferring Material Between Subinventories:
1. You can transfer material within your current organization between subinventories, or between two locators within the same subinventory.
2. You can transfer from asset to expense subinventories, as well as from tracked to non–tracked subinventories. (Here Asset, Expense, Tracked and Non-Tracked are the types of subinventories)
3. If an item has a restricted list of subinventories (Item is sub inventory controlled.), you can only transfer material from and to subinventories in that list.
4. Oracle Inventory allows you to use user–defined transaction types when performing a subinventory transfer.

Steps for entering a subinventory transfer:
1. Navigate to the Subinventory Transfer window.
2. Enter the date and time of entry for the transaction.
3. Enter a transaction type for the subinventory transfer. This can either be a predefined system type or one you defined.
4. Optionally, enter the source of the transaction type ex: Inventory
5. Optionally, indicate if inventory information should be defaulted from the serial number.
6. Choose Transaction Lines in the Subinventory Transfer window. The Transaction Lines Detail folder window appears.
7. Enter an inventory item to transfer. If you choose to default inventory information from the serial number (step5), enter a serial number.
8. Optionally, enter the revision for the item. You must enter a value here if the item is under revision control.
9. Enter the subinventories from and to which to transfer material. Enter the same subinventory in the Sub and To Sub fields to transfer material between locators.
10. Optionally, enter the locators from and to which to transfer the item. You must enter a value here if you established locator control. You can enter a new value in the To Locator field only if you defined locator control as dynamic entry.
11. Optionally, enter a lot number for the item. If you want to enter multiple lot numbers, complete the remaining steps then choose the Lot/Serial button to display the Lot Entry window.
12. Enter a unit of measure. This can be the primary unit of measure (the default) or any valid alternate unit of measure. If you enter an alternate unit of measure, Oracle Inventory issues the quantity you specify in this unit of measure. Oracle Inventory also converts the quantity to the primary unit of measure so that it can correctly update the on–hand quantity.
13. Enter the quantity of the inventory item to transfer, based on the unit of measure you specified.
14. Optionally, enter a reason code for the transaction. For example, you can use reason codes to allow you to mark exceptional charges to support a quality data collection and reporting system.
15. Optionally, enter up to 240 characters of free text that describes the transaction. (Reference field).

To view quantity available and quantity on hand values:
Look at the following fields in the form.

Available: Displays the quantity available to transfer, based on the unit of measure you specified. The available quantity is the quantity on hand less all reservations for the item. This amount could include the amount you have reserved if you enter a transaction source that has reservations against it. The available quantity includes reservations against current transaction source. The available quantity is specific to the revision level, lot number, From subinventory, and From locator you specify for the transfer.

Reservations will always be against a Transaction Source (Inventory, Purchase Order etc.)

On hand: Displays the current on–hand quantity for the item, based on the unit of measure you specified. The on–hand quantity is specific to the revision, lot number, From subinventory, and From locator you specify for the transfer. On–hand includes quantities for pending transactions in the MTL–MATERIAL–TRANSACTIONS table.

Performing Miscellaneous Transactions
With a miscellaneous transaction you can issue material to or receive material from general ledger accounts in your current organization.

Commonly used scripts

Commonly used scripts

Query to get responsibility and attached request groups
SELECT responsibility_name responsibility, request_group_name, frg.description
FROM fnd_request_groups frg, fnd_responsibility_vl frv
WHERE frv.request_group_id = frg.request_group_id
ORDER BY responsibility_name

Query to get all Request attached to a responsibility
SELECT responsibility_name, frg.request_group_name, fcpv.user_concurrent_program_name, fcpv.description
FROM fnd_request_groups frg, fnd_request_group_units frgu,
fnd_concurrent_programs_vl fcpv, fnd_responsibility_vl frv
WHERE frgu.request_unit_type = 'P'
AND frgu.request_group_id = frg.request_group_id
AND frgu.request_unit_id = fcpv.concurrent_program_id
AND frv.request_group_id = frg.request_group_id
ORDER BY responsibility_name;

Query to Count Module Wise Report
SELECT fa.application_short_name,
DECODE (fcpv.execution_method_code,
'B', 'Request Set Stage Function',
'Q', 'SQL*Plus',
'H', 'Host',
'L', 'SQL*Loader',
'A', 'Spawned',
'I', 'PL/SQL Stored Procedure',
'P', 'Oracle Reports',
'S', 'Immediate',
fcpv.execution_method_code
) exe_method, COUNT (concurrent_program_id) COUNT
FROM fnd_concurrent_programs_vl fcpv, fnd_application fa
WHERE fcpv.application_id = fa.application_id
GROUP BY fa.application_short_name, fcpv.execution_method_code
ORDER BY 1;

Query to calculate request time
SELECT f.request_id , pt.user_concurrent_program_name user_concurrent_program_name
, f.actual_start_date actual_start_date
, f.actual_completion_date actual_completion_date,
floor(((f.actual_completion_date-f.actual_start_date)*24*60*60)/3600)
|| ' HOURS ' ||
floor((((f.actual_completion_date-f.actual_start_date)*24*60*60) -
floor(((f.actual_completion_date-f.actual_start_date)*24*60*60)/3600)*3600)/60)
|| ' MINUTES ' ||
round((((f.actual_completion_date-f.actual_start_date)*24*60*60) -
floor(((f.actual_completion_date-f.actual_start_date)*24*60*60)/3600)*3600 -
(floor((((f.actual_completion_date-f.actual_start_date)*24*60*60) -
floor(((f.actual_completion_date-f.actual_start_date)*24*60*60)/3600)*3600)/60)*60) ))
|| ' SECS ' time_difference
, DECODE(p.concurrent_program_name,'ALECDC',p.concurrent_program_name||'['||f.description||']',p.concurrent_program_name) concurrent_program_name
, decode(f.phase_code,'R','Running','C','Complete',f.phase_code) Phase
, f.status_code
FROM apps.fnd_concurrent_programs p
, apps.fnd_concurrent_programs_tl pt
, apps.fnd_concurrent_requests f
WHERE f.concurrent_program_id = p.concurrent_program_id
and f.program_application_id = p.application_id
and f.concurrent_program_id = pt.concurrent_program_id
and f.program_application_id = pt.application_id
AND pt.language = USERENV('Lang')
and f.actual_start_date is not null
ORDER by f.actual_completion_date-f.actual_start_date desc;

Query to check responsibility assigned to a specific USER
SELECT UNIQUE u.user_id, SUBSTR (u.user_name, 1, 30) user_name,
SUBSTR (r.responsibility_name, 1, 60) responsiblity,
SUBSTR (a.application_name, 1, 50) application
FROM fnd_user u,
fnd_user_resp_groups g,
fnd_application_tl a,
fnd_responsibility_tl r
WHERE g.user_id(+) = u.user_id
AND g.responsibility_application_id = a.application_id
AND a.application_id = r.application_id
AND g.responsibility_id = r.responsibility_id
and a.application_name = 'Purchasing'
ORDER BY SUBSTR (user_name, 1, 30), SUBSTR (a.application_name, 1, 50),
SUBSTR (r.responsibility_name, 1, 60)

Query to print the oracle apps version
SELECT substr(a.application_short_name, 1, 5) application_short_name,
substr(t.application_name, 1, 50) application_name,
p.product_version version
FROM fnd_application a,
fnd_application_tl t,
fnd_product_installations p
WHERE a.application_id = p.application_id
AND a.application_id = t.application_id
AND t.language = USERENV('LANG')

Script used to pick up the recent EBS users and their email addresses
SELECT DISTINCT ppf.full_name
, fu.user_name
, NVL(ppf.email_address,fu.email_address) email_address
FROM per_people_f ppf
, fnd_user fu
, fnd_logins fl
WHERE fl.start_time > SYSDATE - 2
AND fu.user_id = fl.user_id
AND ppf.person_id(+) = fu.employee_id
AND fu.user_name NOT IN ('SYSADMIN', 'GUEST')

Script to assign access to Oracle e-Business Suite responsoibilities via Workflow
DECLARE
v_user fnd_user.user_name%TYPE;
v_user_id PLS_INTEGER;

CURSOR c_get_user (cp_username IN VARCHAR2)
IS
SELECT user_orig_system_id user_id, user_orig_system orig_system
FROM wf_local_user_roles
WHERE user_name = cp_username;

CURSOR c_get_resp
IS
SELECT NAME, orig_system, orig_system_id, partition_id
FROM wf_roles
WHERE display_name = 'System Administrator'
AND orig_system = 'FND_RESP';

r_resp c_get_resp%ROWTYPE;
r_user c_get_user%ROWTYPE;
BEGIN
v_user := UPPER ('&username');

OPEN c_get_user (cp_username => v_user);

FETCH c_get_user
INTO r_user;

CLOSE c_get_user;

OPEN c_get_resp;

FETCH c_get_resp
INTO r_resp;

CLOSE c_get_resp;

INSERT INTO wf_local_user_roles
(user_name, role_name, user_orig_system, user_orig_system_id,
role_orig_system, role_orig_system_id, start_date,
expiration_date, security_group_id, partition_id, owner_tag,
created_by, creation_date, last_updated_by,
last_update_date, last_update_login, assignment_type,
parent_orig_system, parent_orig_system_id, user_start_date,
role_start_date, user_end_date, role_end_date,
effective_start_date, effective_end_date
)
VALUES (v_user, r_resp.NAME, r_user.orig_system, r_user.user_id,
r_resp.orig_system, r_resp.orig_system_id, SYSDATE - 1,
NULL, 0, r_resp.partition_id, 'SYSADMIN',
0, SYSDATE - 1, 0,
SYSDATE - 1, 0, 'D',
r_resp.orig_system, r_resp.orig_system_id, SYSDATE - 1,
TO_DATE ('01/01/1951', 'DD/MM/YYYY'), NULL, NULL,
SYSDATE - 1, NULL
);
END;

Query to fetch the managers managers information in HRMS
select
papf.employee_number
,papf.person_id employee_person_id
,papf.full_name employee_name
,papf.email_address emp_email_address
,papf.employee_number mgr_employee_number
,papf_mgr.person_id manager_person_id
,papf_mgr.FULL_NAME manager_full_name
,papf_mgr.email_address manager_email_address
from
per_all_people_f papf,
per_all_people_f papf_mgr
where
(papf.person_id,papf_mgr.person_id) in
( select
pasf.person_id,
pasf.supervisor_id
from
per_all_Assignments_f pasf
start with
( pasf.person_id = :x_person_id and
sysdate between pasf.effective_start_date and pasf.effective_end_date )
connect by prior
pasf.supervisor_id = pasf.person_id
and sysdate between pasf.effective_start_date and pasf.effective_end_date
)
and sysdate between papf.effective_start_date and papf.effective_end_date
and sysdate between papf_mgr.effective_start_date and papf_mgr.effective_end_date

Good Practices for Beginners

Good Practices for Beginners

Most of the developers are like 'accidental developers' and they identify the database performance problems only when the client reports the issues. If you give importants to these guidelines, you can standardise the performance to a stable level. I wrote this article from my own experience and knowledge. Since internet is a wide resource, like most of the professionals I also got such information from the contributions which I read from browsing.

The statements provided here may not be applicable to all the databases since all the features (Eg: Stored Procedures) are not available on all the database systems.

Good Practices for Beginners
1. Divide your large table to small multiple tables. (In SQL terminology we call it as Normalization)
2. Use the lookup tables. This will help you reduce the overload of tables. Eg: if you have a product-sales table and want to store 3 pictures of the same product, rather than adding three columns to the table use one lookup table. This way you have the freedom to add any number of photos.
3. Also, use only necessary columns. Eg: If you have columns A & B and you have the sum in another column C. Simply, you don't need that C since we can re produce the same table effect with statement SELECT A, B, (A+B) AS C FROM TABLE1.
4. The performance of your database increases if the primary key is numeric or small in data width.
5. Do not use database to store your images. Good approach is store only URL in the table and store the image file in desk itself.
6. But sometimes the Normalization may fail if you have a large database, much calculations and frequent calls if the output table is almost static in result. (Eg: salary details of employees for years old data). In this case you can improve the performance by using a De-normalized table. But that too have much demerits like very large database etc.
7. Use the right data types and widths when defining columns. Eg: If you want to store the 'age', then you don't need to use the VARCHAR field since a INT can do the job. (INT can store integer data from 0 to 255. You know no 'age' value exceeds 255)
8. Start! If you don't have the practice of using Primary Key, Foreign Key etc.
9. Use stored procedures and functions instead of writing all the messy code in the program itself. It not only gives you the performance but also a matter of security.
10. Always try to keep one error table to log all the errors which comes from the stored procedures or functions. It helps you save time and avoid tension for finding 'Where is the bug?'
11. Use transactions to avoid loss of data while the execution of a stored procedure. The possibility of failure is high. It can be a data truncation problem, network problem etc. In MSSQL we have BEGIN TRANSACTION, COMMIT TRANSACTION and ROLLBACK TRANSACTION available. Use this along with the error handling methods. Regarding performance TRANSACTION is one step down when comparing with ordinary statements but when considering quality of the product it is very high.
12. Avoid using CURSORs. Use only when there is no other way exists. In most cases CURSOR consumes much time since it is a record-by-record process.
13. Avoid using GOTOs. This is not just for SQL but for all the programming languages. GOTO statement is considered unstructured and it have the possibility of jumping out of our hands. But there are circumstances which we cannot avoid GOTO.
14. Avoid IF and start using CASE.
15. Write your code readable.
a. User proper indents.
b. Keep all the statements in upper case.
c. Use lowercase for data-types
d. Use Upper Camel notations (also known as Pascal Casing) for all user created objects. Eg: @EmployeeCode
e. Use meaningful user-defined identifiers. Use only names which contain A-Z, a Z, 0-9 and underscore character. Do not use regional special characters.
f. Specify operation performed also in the name of stored procedure. Eg: spEmployeeUpdate
g. Always use the schema also while calling sql objects. Eg: EXEC dbo.spEmployeeUpdate
h. Use BEGIN and END to specify block of statements
i. User alias where we need operations including multiple tables
j. Even though the AS keyword is optional, use always.
16. Use proper commenting. Also add the purpose, author, date, version etc. details on top of all the procedures, functions etc.
17. Add test data with statements inside stored procedures and comment it. This helps you in future debugging. Also this helps another developer to get a quick start.
18. Do proper INDEX-ing. There will be noticeable difference when applying INDEX on very large tables.
19. Always use column names in SELECT, INSERT, UPDATE statements. Avoid using asterisks –(*).
20. Avoid using dynamic SQL statements inside stored procedures. i.e., Do not use SQL statements to create SQL statements.
21. Be careful while SELECT-ing strings with LIKE clause. If it is not used wisely, it will arise performance problems.